Skip to content

Commit

Permalink
Initializes Hypervisor (#692)
Browse files Browse the repository at this point in the history
  • Loading branch information
ultimaweapon authored Feb 25, 2024
1 parent 4c98b9e commit 53e9fa6
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ We have a Discord server for discussion about Obliteration and its development.

## System requirements

- Windows 10, Linux or macOS.
- Windows 10, Linux or macOS 11+.
- x86-64 CPU.
- A jailbroken PS4 with FTP server that supports SELF decryption.

Expand Down
1 change: 1 addition & 0 deletions src/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ members = [
"fs",
"ftp",
"gmtx",
"hv",
"kernel",
"llt",
"macros",
Expand Down
10 changes: 10 additions & 0 deletions src/hv/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "hv"
version = "0.1.0"
edition = "2021"

[dependencies]
thiserror = "1.0.57"

[target.'cfg(unit)'.dependencies]
libc = "0.2.153"
7 changes: 7 additions & 0 deletions src/hv/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
fn main() {
let os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();

if os == "macos" {
println!("cargo:rustc-link-lib=framework=Hypervisor");
}
}
11 changes: 11 additions & 0 deletions src/hv/src/darwin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#![allow(non_camel_case_types)]

use std::ffi::c_int;

#[repr(C)]
pub struct hv_vm_config_t([u8; 0]);

extern "C" {
pub fn hv_vm_create(config: *mut hv_vm_config_t) -> c_int;
pub fn hv_vm_destroy() -> c_int;
}
76 changes: 76 additions & 0 deletions src/hv/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use std::sync::atomic::{AtomicBool, Ordering};
use thiserror::Error;

#[cfg(target_os = "macos")]
mod darwin;

/// Manage a virtual machine of the current process.
///
/// Each process can have only one VM. The reason this type is not a global variable is because we
/// want to be able to drop it.
pub struct Hypervisor {
#[allow(dead_code)]
active: Active, // Drop as the last one.
}

impl Hypervisor {
pub fn new() -> Result<Self, NewError> {
let active = Active::new().ok_or(NewError::Active)?;

#[cfg(target_os = "macos")]
match unsafe { self::darwin::hv_vm_create(std::ptr::null_mut()) } {
0 => {}
v => return Err(NewError::HostFailed(v)),
}

Ok(Self { active })
}
}

impl Drop for Hypervisor {
#[cfg(target_os = "linux")]
fn drop(&mut self) {}

#[cfg(target_os = "windows")]
fn drop(&mut self) {}

#[cfg(target_os = "macos")]
fn drop(&mut self) {
let status = unsafe { self::darwin::hv_vm_destroy() };

if status != 0 {
panic!("hv_vm_destroy() was failed with {status:#x}");
}
}
}

/// RAII object to set release ACTIVE.
struct Active;

impl Active {
fn new() -> Option<Self> {
ACTIVE
.compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
.map(|_| Self)
.ok()
}
}

impl Drop for Active {
fn drop(&mut self) {
ACTIVE.store(false, Ordering::Release);
}
}

/// Represents an error when [`Hypervisor::new()`] was failed.
#[derive(Debug, Error)]
pub enum NewError {
#[error("there is an active hypervisor")]
Active,

#[cfg(target_os = "macos")]
#[error("the host failed to create the hypervisor ({0:#x})")]
HostFailed(std::ffi::c_int),
}

static ACTIVE: AtomicBool = AtomicBool::new(false);
1 change: 1 addition & 0 deletions src/kernel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ clap = { version = "4.1", features = ["derive"] }
discord-rich-presence = "0.2"
elf = { path = "../elf" }
gmtx = { path = "../gmtx" }
hv = { path = "../hv" }
iced-x86 = { version = "1.18", features = ["code_asm"] }
libc = "0.2"
llt = { path = "../llt" }
Expand Down
7 changes: 7 additions & 0 deletions src/kernel/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use crate::time::TimeManager;
use crate::tty::{TtyInitError, TtyManager};
use crate::ucred::{AuthAttrs, AuthCaps, AuthInfo, AuthPaid, Gid, Ucred, Uid};
use clap::{Parser, ValueEnum};
use hv::Hypervisor;
use llt::{OsThread, SpawnError};
use macros::vpath;
use param::Param;
Expand Down Expand Up @@ -347,6 +348,9 @@ fn run<E: crate::ee::ExecutionEngine>(
todo!("statically linked eboot.bin");
}

// Setup hypervisor.
let hv = Hypervisor::new().map_err(KernelError::CreateHypervisorFailed)?;

// Get entry point.
let boot = ld.kernel().unwrap();
let mut arg = Box::pin(EntryArg::<E>::new(&proc, mm, app.clone()));
Expand Down Expand Up @@ -549,6 +553,9 @@ enum KernelError {
#[error("libSceLibcInternal couldn't be loaded")]
FailedToLoadLibSceLibcInternal(#[source] Box<dyn Error>),

#[error("couldn't create a hypervisor")]
CreateHypervisorFailed(#[from] hv::NewError),

#[error("main thread couldn't be created")]
FailedToCreateMainThread(#[from] SpawnError),

Expand Down

0 comments on commit 53e9fa6

Please sign in to comment.