### Install Dependencies Source: https://docs.rs/applevisor Command to install the jq utility required for running project tests. ```bash brew install jq ``` -------------------------------- ### Example: Create Virtual Machine Memory Source: https://docs.rs/applevisor/latest/src/applevisor/vm.rs.html Demonstrates how to create a memory object for a virtual machine using the memory_create function. Ensure the size is page-aligned. ```rust use applevisor::prelude::* # fn main() -> Result<()> { let vm = VirtualMachine::new()?; let mem = vm.memory_create(PAGE_SIZE * 10)?; # Ok(()) # } ``` -------------------------------- ### Default VCPU Configuration Source: https://docs.rs/applevisor/latest/src/applevisor/vcpu.rs.html Creates a default VCPU configuration. This is a starting point for setting up a new virtual CPU. ```rust let config = VcpuConfig::default(); ``` -------------------------------- ### GET /api/vm/instance Source: https://docs.rs/applevisor/latest/src/applevisor/vm.rs.html Retrieves a handle to the current VM global instance. This function returns an `Option` containing a `VirtualMachineInstance` if the VM has been initialized, otherwise `None`. ```APIDOC ## GET /api/vm/instance ### Description Retrieves a handle to the current VM global instance. This function returns an `Option` containing a `VirtualMachineInstance` if the VM has been initialized, otherwise `None`. ### Method GET ### Endpoint /api/vm/instance ### Response #### Success Response (200) - **VirtualMachineInstance** (Option) - A handle to the VM instance if available. #### Response Example ```json { "instance": "..." } ``` ``` -------------------------------- ### GET /api/vm/instance/gic Source: https://docs.rs/applevisor/latest/src/applevisor/vm.rs.html Retrieves a [`GicEnabled`] handle to the current VM global instance, only if the current instance has a GIC configured. This is only available when the `macos-15-0` feature is enabled. ```APIDOC ## GET /api/vm/instance/gic ### Description Retrieves a [`GicEnabled`] handle to the current VM global instance, only if the current instance has a GIC configured. This is only available when the `macos-15-0` feature is enabled. ### Method GET ### Endpoint /api/vm/instance/gic ### Parameters This endpoint does not accept any parameters. ### Response #### Success Response (200) - **VirtualMachineInstance** (Option) - A handle to the GIC-enabled VM instance if available. #### Response Example ```json { "instance": "..." } ``` ``` -------------------------------- ### VcpuConfig Methods Source: https://docs.rs/applevisor/latest/applevisor/vcpu/struct.VcpuConfig.html Provides methods for interacting with the VcpuConfig, including instantiation, retrieving feature registers, and getting cache configuration details. ```APIDOC ## impl VcpuConfig ### pub fn new() -> Self #### Description Instanciates a new configuration. ### Method ```rust pub fn new() -> Self ``` ### Endpoint N/A (Constructor) ### pub fn get_feature_reg(&self, reg: FeatureReg) -> Result #### Description Retrieves the value of a feature register. ### Method ```rust pub fn get_feature_reg(&self, reg: FeatureReg) -> Result ``` ### Parameters #### Query Parameters - **reg** (FeatureReg) - Required - The feature register to retrieve. ### pub fn get_ccsidr_el1_sys_reg_values(&self, cache_type: CacheType) -> Result #### Description Returns the Cache Size ID Register (CCSIDR_EL1) values for the vCPU configuration and cache type you specify. ### Method ```rust pub fn get_ccsidr_el1_sys_reg_values(&self, cache_type: CacheType) -> Result ``` ### Parameters #### Query Parameters - **cache_type** (CacheType) - Required - The type of cache to query. ``` -------------------------------- ### Run the program Source: https://docs.rs/applevisor Execute the signed binary from the release directory. ```bash target/release/${PROJECT_NAME} ``` -------------------------------- ### Get and Set SME P-Register Source: https://docs.rs/applevisor/latest/src/applevisor/vcpu.rs.html Tests the functionality of getting and setting SME P-registers. It checks for `BadArgument` error on initial get, then sets a value and verifies it by reading back. ```rust let vm = VirtualMachineStaticInstance::get().unwrap(); let vcpu = vm.vcpu_create().unwrap(); // Enabling streaming mode. let state = SmeState { streaming_sve_mode_enabled: true, za_storage_enabled: false, }; assert_eq!(vcpu.set_sme_state(&state), Ok(())); let size: usize = VirtualMachineConfig::get_max_svl_bytes().unwrap() / 8; let write_data = vec![0x42u8; size]; let mut read_data = vec![0x0u8; size]; // Set the register to an arbitrary value and check that the same one is // read from it. assert_eq!(vcpu.get_sme_p_reg( SmePReg::$reg, &mut vec![0; 1]), Err(HypervisorError::BadArgument)); assert_eq!(vcpu.set_sme_p_reg(SmePReg::$reg, &write_data), Ok(())); assert_eq!(vcpu.get_sme_p_reg(SmePReg::$reg, &mut read_data), Ok(())); assert_eq!(write_data, read_data); ``` -------------------------------- ### Initialization Methods Source: https://docs.rs/applevisor/latest/applevisor/vm/enum.VirtualMachineStaticInstance.html Methods for initializing the global virtual machine instance with default or custom configurations. ```APIDOC ## Initialization Methods ### `pub fn init() -> Result<()>` Initializes the global vm instance with a `VirtualMachine` created with a default config. #### Example ```rust use applevisor::prelude::*; VirtualMachineStaticInstance::init()?; ``` ### `pub fn init_with_config(vm_config: VirtualMachineConfig) -> Result<()>` Initializes the global vm instance with a `VirtualMachine` created with a custom config. #### Parameters - **vm_config** (VirtualMachineConfig) - Required - The custom configuration for the virtual machine. #### Example ```rust use applevisor::prelude::*; // Custom configuration for the virtual machine. let mut config = VirtualMachineConfig::default(); config.set_el2_enabled(true)?; // Creates the global instance using the configuration above. let _ = VirtualMachineStaticInstance::init_with_config(config)?; ``` ### `pub fn init_with_gic(vm_config: VirtualMachineConfig, gic_config: GicConfig) -> Result<()>` Initializes the global vm instance with a `VirtualMachine` created with a custom config and a GIC. #### Parameters - **vm_config** (VirtualMachineConfig) - Required - The custom configuration for the virtual machine. - **gic_config** (GicConfig) - Required - The custom configuration for the GIC. #### Example ```rust use applevisor::prelude::*; // Custom configuration for the virtual machine. let mut vm_config = VirtualMachineConfig::default(); vm_config.set_el2_enabled(true)?; // Custom configuration for the GIC. let mut gic_config = GicConfig::default(); gic_config.set_redistributor_base(0x2000_0000)?; // Creates the global instance using the configurations above. let _ = VirtualMachineStaticInstance::init_with_gic(vm_config, gic_config)?; ``` ``` -------------------------------- ### Get Type ID Source: https://docs.rs/applevisor/latest/applevisor/vcpu/struct.VcpuHandle.html Gets the `TypeId` of `self`. This is part of the `Any` trait implementation. ```rust fn type_id(&self) -> TypeId ``` -------------------------------- ### Create and Run a Virtual Machine Source: https://docs.rs/applevisor Demonstrates the lifecycle of a virtual machine, including memory mapping, register configuration, and execution. ```rust use applevisor::prelude::*; fn main() -> Result<()> { // Creates a new virtual machine. There can be one, and only one, per process. Operations // on the virtual machine remains possible as long as this object is valid. let vm = VirtualMachine::new()?; // Creates a new virtual CPU. This object abstracts operations that can be performed on // CPUs, such as starting and stopping them, changing their registers, etc. let vcpu = vm.vcpu_create()?; // Enables debug features for the hypervisor. This is optional, but it might be required // for certain features to work, such as breakpoints. vcpu.set_trap_debug_exceptions(true)?; vcpu.set_trap_debug_reg_accesses(true)?; // Creates a mapping object that represents a 0x1000-byte physical memory range. let mut mem = vm.memory_create(0x1000)?; // This mapping needs to be mapped to effectively allocate physical memory for the guest. // Here we map the region at address 0x4000 and set the permissions to Read-Write-Execute. mem.map(0x4000, MemPerms::RWX)?; // Writes a `mov x0, #0x42` instruction at address 0x4000. mem.write_u32(0x4000, 0xd2800840)?; // Writes a `brk #0` instruction at address 0x4004. mem.write_u32(0x4004, 0xd4200000)?; // Sets PC to 0x4000. vcpu.set_reg(Reg::PC, 0x4000)?; // Starts the Vcpu. It will execute our mov and breakpoint instructions before stopping. vcpu.run()?; // The *exit information* can be used to used to retrieve different pieces of // information about the CPU exit status (e.g. exception type, fault address, etc.). let exit_info = vcpu.get_exit_info(); // If everything went as expected, the value in X0 is 0x42... assert_eq!(vcpu.get_reg(Reg::X0), Ok(0x42)); // ... the vcpu has stopped because of an exception ... assert_eq!(exit_info.reason, ExitReason::EXCEPTION); // ... and the exception syndrome corresponds to a breakpoint exception (which would // have been a different value without the call to `set_trap_debug_exceptions()`). assert_eq!(exit_info.exception.syndrome >> 26, 0b111100); Ok(()) } ``` -------------------------------- ### Create VM with Custom Configuration Source: https://docs.rs/applevisor/latest/src/applevisor/vm.rs.html Initializes a virtual machine using a custom configuration, including optional EL2 and IPA size settings. ```rust #[cfg(feature = "macos-13-0")] #[test] #[serial] fn create_a_vm_with_a_custom_config() { // Making sure there's no static instance when this test starts running. vm_static_instance_reset(); let mut config = VirtualMachineConfig::default(); #[cfg(feature = "macos-15-0")] { if VirtualMachineConfig::get_el2_supported().unwrap() { config.set_el2_enabled(true).unwrap(); } } let max_ipa_size = VirtualMachineConfig::get_max_ipa_size().unwrap(); config.set_ipa_size(max_ipa_size).unwrap(); let vm = VirtualMachine::with_config(config); assert!(vm.is_ok()); } ``` ```rust #[cfg(feature = "macos-13-0")] #[test] #[serial] fn create_a_static_vm_instance_with_a_custom_config() { // Making sure there's no static instance when this test starts running. vm_static_instance_reset(); let mut config = VirtualMachineConfig::default(); #[cfg(feature = "macos-15-0")] { if VirtualMachineConfig::get_el2_supported().unwrap() { config.set_el2_enabled(true).unwrap(); } } let max_ipa_size = VirtualMachineConfig::get_max_ipa_size().unwrap(); config.set_ipa_size(max_ipa_size).unwrap(); let ret = VirtualMachineStaticInstance::init_with_config(config); assert!(ret.is_ok()); let vm = VirtualMachineStaticInstance::get(); assert!(vm.is_some()); } ``` -------------------------------- ### Macro for Get and Set SME P-Register Source: https://docs.rs/applevisor/latest/src/applevisor/vcpu.rs.html A macro that generates test functions for getting and setting various SME P-registers (P0-P15). ```rust get_and_set_sme_p_reg!( get_and_set_sme_p_reg_p0: P0, get_and_set_sme_p_reg_p1: P1, get_and_set_sme_p_reg_p2: P2, get_and_set_sme_p_reg_p3: P3, get_and_set_sme_p_reg_p4: P4, get_and_set_sme_p_reg_p5: P5, get_and_set_sme_p_reg_p6: P6, get_and_set_sme_p_reg_p7: P7, get_and_set_sme_p_reg_p8: P8, get_and_set_sme_p_reg_p9: P9, get_and_set_sme_p_reg_p10: P10, get_and_set_sme_p_reg_p11: P11, get_and_set_sme_p_reg_p12: P12, get_and_set_sme_p_reg_p13: P13, get_and_set_sme_p_reg_p14: P14, get_and_set_sme_p_reg_p15: P15, ); ``` -------------------------------- ### Build and sign the binary Source: https://docs.rs/applevisor Compile the project and sign the resulting binary with the required entitlements. ```bash cargo build --release codesign --sign - --entitlements entitlements.xml --deep --force target/release/${PROJECT_NAME} ``` -------------------------------- ### Get Virtual Timer Mask Source: https://docs.rs/applevisor/latest/src/applevisor/vcpu.rs.html Gets the current state of the virtual timer mask. Returns true if the timer is masked, false otherwise. ```rust pub fn get_vtimer_mask(&self) -> Result { let mut vtimer_is_masked = false; hv_unsafe_call!(hv_vcpu_get_vtimer_mask(self.vcpu, &mut vtimer_is_masked))?; Ok(vtimer_is_masked) } ``` -------------------------------- ### Create VM with GIC Configuration Source: https://docs.rs/applevisor/latest/src/applevisor/vm.rs.html Initializes a virtual machine with GIC settings, requiring a valid redistributor base address. ```rust #[cfg(feature = "macos-15-0")] #[test] #[serial] fn create_a_vm_with_a_gic() { // Making sure there's no static instance when this test starts running. vm_static_instance_reset(); // A default GIC config will fail. { let vm_config = VirtualMachineConfig::default(); let gic_config = GicConfig::new(); let vm = VirtualMachine::with_gic(vm_config, gic_config); assert!(matches!(vm, Err(HypervisorError::BadArgument))); } // We need to at least provide the redistributor for the GIC to work. { let vm_config = VirtualMachineConfig::default(); let mut gic_config = GicConfig::new(); assert!(gic_config.set_redistributor_base(0x20000).is_ok()); let vm = VirtualMachine::with_gic(vm_config, gic_config); assert!(vm.is_ok()); } } ``` ```rust #[cfg(feature = "macos-15-0")] #[test] #[serial] fn create_a_static_vm_instance_with_a_gic() { // Making sure there's no static instance when this test starts running. vm_static_instance_reset(); let vm_config = VirtualMachineConfig::default(); let mut gic_config = GicConfig::new(); assert!(gic_config.set_redistributor_base(0x20000).is_ok()); let ret = VirtualMachineStaticInstance::init_with_gic(vm_config, gic_config); assert!(ret.is_ok()); let vm = VirtualMachineStaticInstance::get(); assert!(vm.is_some()); } ``` -------------------------------- ### Get Trap Debug Register Accesses Source: https://docs.rs/applevisor/latest/src/applevisor/vcpu.rs.html Gets whether debug-register accesses exit the guest. This controls if the guest is notified when debug registers are accessed. ```rust pub fn get_trap_debug_reg_accesses(&self) -> Result { let mut value = false; hv_unsafe_call!(hv_vcpu_get_trap_debug_reg_accesses(self.vcpu, &mut value))?; Ok(value) } ``` -------------------------------- ### Manage VM Instance Lifecycle Source: https://docs.rs/applevisor/latest/src/applevisor/vm.rs.html Demonstrates creating, cloning, and dropping virtual machine instances, highlighting the 'Busy' error state when multiple instances are attempted. ```rust assert!(vm1.is_ok()); // Creating a second instance should fail. let vm2 = VirtualMachine::new(); assert!(matches!(vm2, Err(HypervisorError::Busy))); // But cloning the first instance should work. let vm3 = vm1.clone(); drop(vm1); assert!(vm3.is_ok()); // And creating a new instance should still fail. let vm4 = VirtualMachine::new(); assert!(matches!(vm4, Err(HypervisorError::Busy))); // Then, if we drop all VM instances created until now... } // ... creating a brand new instance should work. let vm5 = VirtualMachine::new(); assert!(vm5.is_ok()); } ``` -------------------------------- ### Get Trap Debug Exceptions Source: https://docs.rs/applevisor/latest/src/applevisor/vcpu.rs.html Gets whether debug exceptions exit the guest. This setting controls if the guest is notified when a debug exception occurs. ```rust pub fn get_trap_debug_exceptions(&self) -> Result { let mut value = false; hv_unsafe_call!(hv_vcpu_get_trap_debug_exceptions(self.vcpu, &mut value))?; Ok(value) } ``` -------------------------------- ### Get and Set ZA Register Source: https://docs.rs/applevisor/latest/src/applevisor/vcpu.rs.html Tests the functionality of getting and setting the ZA register. It enables ZA storage, sets a value, and verifies it by reading back. ```rust let vm = VirtualMachineStaticInstance::get().unwrap(); let vcpu = vm.vcpu_create().unwrap(); // Enabling ZA storage. let state = SmeState { streaming_sve_mode_enabled: false, za_storage_enabled: true, }; assert_eq!(vcpu.set_sme_state(&state), Ok(())); let size: usize = VirtualMachineConfig::get_max_svl_bytes().unwrap(); let size = size * size; let write_data = vec![0x42u8; size]; let mut read_data = vec![0x0u8; size]; // Set the register to an arbitrary value and check that the same one is // read from it. assert_eq!( vcpu.get_sme_za_reg(&mut vec![0; 1]), Err(HypervisorError::BadArgument) ); assert_eq!(vcpu.set_sme_za_reg(&write_data), Ok(())); assert_eq!(vcpu.get_sme_za_reg(&mut read_data), Ok(())); assert_eq!(write_data, read_data); ``` -------------------------------- ### Get and Set System Registers (macOS 15.2) Source: https://docs.rs/applevisor/latest/src/applevisor/vcpu.rs.html Provides functions to get and set system registers for macOS 15.2 and later. Requires the 'macos-15-2' feature. ```rust get_and_set_sys_reg!( get_and_set_icv_reg_id_aa64zfr0_el1: ID_AA64ZFR0_EL1, get_and_set_icv_reg_id_aa64smfr0_el1: ID_AA64SMFR0_EL1, get_and_set_icv_reg_smpri_el1: SMPRI_EL1, get_and_set_icv_reg_smcr_el1: SMCR_EL1, get_and_set_icv_reg_scxtnum_el1: SCXTNUM_EL1, get_and_set_icv_reg_tpidr2_el0: TPIDR2_EL0, get_and_set_icv_reg_scxtnum_el0: SCXTNUM_EL0, ); ``` -------------------------------- ### Initialize with GIC Configuration Source: https://docs.rs/applevisor/latest/src/applevisor/vm.rs.html Initializes the global VM instance with both VM and GIC configurations. Requires the macos-15-0 feature. ```rust use applevisor::prelude::*; # #[cfg(feature="macos-15-0")] # fn main() -> Result<()> { // Custom configuration for the virtual machine. let mut vm_config = VirtualMachineConfig::default(); vm_config.set_el2_enabled(true)?; // Custom configuration for the GIC. let mut gic_config = GicConfig::default(); gic_config.set_redistributor_base(0x2000_0000)?; // Creates the global instance using the configurations above. let _ = VirtualMachineStaticInstance::init_with_gic(vm_config, gic_config)?; # Ok(()) # } ``` -------------------------------- ### Get and Set System Registers (macOS 15.0) Source: https://docs.rs/applevisor/latest/src/applevisor/vcpu.rs.html Provides functions to get and set system registers for macOS 15.0 and later. Requires the 'macos-15-0' feature. ```rust get_and_set_sys_reg!( get_and_set_icv_reg_actlr_el1: ACTLR_EL1, get_and_set_icv_reg_cnthctl_el2: CNTHCTL_EL2, get_and_set_icv_reg_cntvoff_el2: CNTVOFF_EL2, get_and_set_icv_reg_cptr_el2: CPTR_EL2, get_and_set_icv_reg_elr_el2: ELR_EL2, get_and_set_icv_reg_esr_el2: ESR_EL2, get_and_set_icv_reg_far_el2: FAR_EL2, get_and_set_icv_reg_hcr_el2: HCR_EL2, get_and_set_icv_reg_hpfar_el2: HPFAR_EL2, get_and_set_icv_reg_mair_el2: MAIR_EL2, get_and_set_icv_reg_sctlr_el2: SCTLR_EL2, get_and_set_icv_reg_spsr_el2: SPSR_EL2, get_and_set_icv_reg_sp_el2: SP_EL2, get_and_set_icv_reg_tcr_el2: TCR_EL2, get_and_set_icv_reg_tpidr_el2: TPIDR_EL2, get_and_set_icv_reg_ttbr0_el2: TTBR0_EL2, get_and_set_icv_reg_ttbr1_el2: TTBR1_EL2, get_and_set_icv_reg_vbar_el2: VBAR_EL2, get_and_set_icv_reg_vmpidr_el2: VMPIDR_EL2, get_and_set_icv_reg_vpidr_el2: VPIDR_EL2, get_and_set_icv_reg_vtcr_el2: VTCR_EL2, get_and_set_icv_reg_vttbr_el2: VTTBR_EL2, ); ``` -------------------------------- ### Create Virtual Machine with Custom Configuration Source: https://docs.rs/applevisor/latest/applevisor/vm/struct.VirtualMachine.html Creates a new virtual machine instance with a user-provided configuration. Allows customization of VM settings and GIC configuration. Ensure `applevisor::prelude::*` is imported. ```rust use applevisor::prelude::*; // Custom configuration for the virtual machine. let mut vm_config = VirtualMachineConfig::default(); vm_config.set_el2_enabled(true)?; // Custom configuration for the GIC. let mut gic_config = GicConfig::default(); gic_config.set_redistributor_base(0x2000_0000)?; // Creates the global instance using the configurations above. let vm = VirtualMachineInstance::with_config(vm_config)?; ``` -------------------------------- ### Get and Set SIMD/FP Registers Source: https://docs.rs/applevisor/latest/src/applevisor/vcpu.rs.html Macro to define tests for getting and setting SIMD and Floating-Point registers. It handles different value types based on the 'simd-nightly' feature. ```rust macro_rules! get_and_set_simd_fp_reg { ($($name:ident: $reg:ident,)*) => { $( #[test] #[parallel] fn $name() { let _ = VirtualMachineStaticInstance::init(); let vm = VirtualMachineStaticInstance::get().unwrap(); // Set the register to an arbitrary value and check that the same one is // read from it. #[cfg(feature = "simd-nightly")] let value = simd::u8x16::from_array([ 0xde,0xad,0xbe,0xef, 0xde,0xad,0xbe,0xef, 0xde,0xad,0xbe,0xef, 0xde,0xad,0xbe,0xef ]); #[cfg(not(feature = "simd-nightly"))] let value = 0xdeadbeefdeadbeefdeadbeefdeadbeef; let vcpu = vm.vcpu_create().unwrap(); assert_eq!(vcpu.set_simd_fp_reg(SimdFpReg::$reg, value), Ok(())); assert_eq!(vcpu.get_simd_fp_reg(SimdFpReg::$reg), Ok(value)); } )* } } get_and_set_simd_fp_reg!( get_and_set_simd_fp_reg_q0: Q0, get_and_set_simd_fp_reg_q1: Q1, get_and_set_simd_fp_reg_q2: Q2, get_and_set_simd_fp_reg_q3: Q3, get_and_set_simd_fp_reg_q4: Q4, get_and_set_simd_fp_reg_q5: Q5, get_and_set_simd_fp_reg_q6: Q6, get_and_set_simd_fp_reg_q7: Q7, get_and_set_simd_fp_reg_q8: Q8, get_and_set_simd_fp_reg_q9: Q9, get_and_set_simd_fp_reg_q10: Q10, get_and_set_simd_fp_reg_q11: Q11, ); ``` -------------------------------- ### Create Default Static VM Instance Source: https://docs.rs/applevisor/latest/src/applevisor/vm.rs.html Initializes and retrieves a static virtual machine instance. ```rust #[test] #[serial] fn create_a_default_static_vm_instance() { // Making sure there's no static instance when this test starts running. vm_static_instance_reset(); let ret = VirtualMachineStaticInstance::init(); assert!(ret.is_ok()); let vm = VirtualMachineStaticInstance::get(); assert!(vm.is_some()); } ``` -------------------------------- ### Get and Set Pending Interrupt Source: https://docs.rs/applevisor/latest/src/applevisor/vcpu.rs.html Demonstrates how to get and set the pending interrupt status for a VCPU. It checks the initial state, sets an interrupt, and then verifies the updated state. ```rust let _ = VirtualMachineStaticInstance::init().unwrap(); let vm = VirtualMachineStaticInstance::get().unwrap(); let vcpu = vm.vcpu_create().unwrap(); assert_eq!(vcpu.get_pending_interrupt(InterruptType::IRQ), Ok(false)); assert_eq!(vcpu.set_pending_interrupt(InterruptType::IRQ, true), Ok(())); assert_eq!(vcpu.get_pending_interrupt(InterruptType::IRQ), Ok(true)); ``` -------------------------------- ### Retrieve GIC-enabled VM instance Source: https://docs.rs/applevisor/latest/src/applevisor/vm.rs.html Demonstrates how to initialize and retrieve a GIC-enabled virtual machine instance. ```rust use applevisor::prelude::*;\n\n# #[cfg(feature = "macos-15-0")]\n# fn main() -> Result<()> {\n# let mut vm_config = VirtualMachineConfig::default();\n# vm_config.set_el2_enabled(true)?;\n# let mut gic_config = GicConfig::default();\n# gic_config.set_redistributor_base(0x2000_0000)?;\n// No instance has been created yet.\nassert!(VirtualMachineStaticInstance::get_gic().is_none());\n\nlet _ = VirtualMachineStaticInstance::init_with_gic(vm_config, gic_config)?;\n// The VM instance can be retrieved once it has been initialized.\nassert!(VirtualMachineStaticInstance::get_gic().is_some());\n# Ok(())\n# } ``` -------------------------------- ### Get and Set ZT0 Register Source: https://docs.rs/applevisor/latest/src/applevisor/vcpu.rs.html Tests the functionality of getting and setting the ZT0 register. It enables both streaming SVE mode and ZA storage, then sets and reads the ZT0 register. ```rust let vm = VirtualMachineStaticInstance::get().unwrap(); let vcpu = vm.vcpu_create().unwrap(); // Enabling ZA storage. let state = SmeState { streaming_sve_mode_enabled: true, za_storage_enabled: true, }; assert_eq!(vcpu.set_sme_state(&state), Ok(())); #[cfg(feature = "simd-nightly")] let write_data: SmeZt0 = simd::u8x64::from_array([0x42; 64]); #[cfg(feature = "simd-nightly")] let mut read_data: SmeZt0 = simd::u8x64::from_array([0; 64]); #[cfg(not(feature = "simd-nightly"))] let write_data: SmeZt0 = [0x42; 64]; #[cfg(not(feature = "simd-nightly"))] let mut read_data: SmeZt0 = [0; 64]; // Set the register to an arbitrary value and check that the same one is // read from it. assert_eq!(vcpu.set_sme_zt0_reg(&write_data), Ok(())); assert_eq!(vcpu.get_sme_zt0_reg(&mut read_data), Ok(())); assert_eq!(write_data, read_data); ``` -------------------------------- ### Get Redistributor Base Address Source: https://docs.rs/applevisor/latest/src/applevisor/vcpu.rs.html Gets the redistributor base guest physical address for the given vcpu. Must be called after the affinity of the given vCPU has been set in its MPIDR_EL1 register. ```rust #[cfg(feature = "macos-15-0")] pub fn get_redistributor_base(&self) -> Result { let mut redistributor_base_address = 0; hv_unsafe_call!(hv_gic_get_redistributor_base( self.vcpu, &mut redistributor_base_address, ))?; Ok(redistributor_base_address) } ``` -------------------------------- ### Initialize with Custom Configuration Source: https://docs.rs/applevisor/latest/src/applevisor/vm.rs.html Initializes the global VM instance using a custom VirtualMachineConfig. Requires the macos-13-0 feature. ```rust use applevisor::prelude::*; # fn main() -> Result<()> { // Custom configuration for the virtual machine. let mut config = VirtualMachineConfig::default(); config.set_el2_enabled(true)?; // Creates the global instance using the configuration above. let _ = VirtualMachineStaticInstance::init_with_config(config)?; # Ok(()) # } ``` -------------------------------- ### VirtualMachineStaticInstance::init_with_gic Source: https://docs.rs/applevisor/latest/src/applevisor/vm.rs.html Initializes the global virtual machine instance with both a custom configuration and a GIC configuration. ```APIDOC ## VirtualMachineStaticInstance::init_with_gic ### Description Initializes the global VM instance with custom VM and GIC configurations. Requires the 'macos-15-0' feature. ### Parameters - **vm_config** (VirtualMachineConfig) - Required - The configuration object for the virtual machine. - **gic_config** (GicConfig) - Required - The configuration object for the GIC. ### Response - **Result<()>** - Returns Ok(()) on success or an error if initialization fails. ``` -------------------------------- ### GET /vtimer_offset Source: https://docs.rs/applevisor/latest/applevisor/vcpu/struct.Vcpu.html Returns the vTimer offset for the vCPU. ```APIDOC ## GET /vtimer_offset ### Description Returns the vTimer offset for the vCPU ID you specify. ### Response #### Success Response (200) - **offset** (u64) - The current vTimer offset. ``` -------------------------------- ### VirtualMachine::with_config Source: https://docs.rs/applevisor/latest/applevisor/vm/struct.VirtualMachine.html Creates a new virtual machine instance using a user-provided configuration. ```APIDOC ## VirtualMachine::with_config ### Description Creates a new virtual machine instance for the current process using a user-provided VirtualMachineConfig. ### Parameters - **config** (VirtualMachineConfig) - Required - The configuration object for the VM. ### Response - **Result>** - A result containing the new virtual machine instance or an error. ### Request Example ```rust let mut vm_config = VirtualMachineConfig::default(); vm_config.set_el2_enabled(true)?; let vm = VirtualMachineInstance::with_config(vm_config)?; ``` ``` -------------------------------- ### GET /redistributor_reg Source: https://docs.rs/applevisor/latest/applevisor/vcpu/struct.Vcpu.html Reads a GIC redistributor register. ```APIDOC ## GET /redistributor_reg ### Description Read a GIC redistributor register. Must be called by the owning thread. ### Parameters #### Query Parameters - **reg** (GicRedistributorReg) - Required - The GIC redistributor register to read. ### Response #### Success Response (200) - **value** (u64) - The register value. ``` -------------------------------- ### Create Default Virtual Machine Source: https://docs.rs/applevisor/latest/src/applevisor/vm.rs.html Initializes a standard virtual machine instance after resetting the static instance state. ```rust #[test] #[serial] fn create_a_default_vm() { // Making sure there's no static instance when this test starts running. vm_static_instance_reset(); let vm = VirtualMachine::new(); assert!(vm.is_ok()); } ``` -------------------------------- ### impl Any for T Source: https://docs.rs/applevisor/latest/applevisor/error/enum.HypervisorError.html Provides the `type_id` method to get the `TypeId` of a type. ```APIDOC ## impl Any for T ### Description Provides the `type_id` method to get the `TypeId` of a type. ### Method `type_id` ### Endpoint N/A (Rust implementation detail) ### Parameters None ### Request Body None ### Response #### Success Response - **TypeId** (TypeId) - The unique identifier for the type. ### Response Example ```rust // Example usage (conceptual) let id = my_value.type_id(); ``` ``` -------------------------------- ### Configure and Manage GIC State Source: https://docs.rs/applevisor/latest/src/applevisor/gic.rs.html Demonstrates initializing a VM with GIC configuration, creating a state object, and performing get/set operations with buffer validation. ```rust vm_static_instance_reset(); // Configure a VM with a GIC. let vm_config = VirtualMachineConfig::default(); let mut gic_config = GicConfig::default(); gic_config.set_distributor_base(0x2000_0000).unwrap(); let vm = VirtualMachine::with_gic(vm_config, gic_config).unwrap(); let state = vm.gic_state_create(); assert!(state.is_ok()); let mut state = state.unwrap(); let state_size = state.size(); assert!(state_size.is_ok()); let state_size = state_size.unwrap(); let mut data = vec![0u8; state_size]; assert_eq!(state.get(&mut data), Ok(())); assert_eq!(state.set(&data), Ok(())); // Trying to set an invalid state. data[0] = 0; assert_eq!(state.set(&data), Err(HypervisorError::BadArgument)); // Trying to get and set a state with a buffer too small. let mut data = vec![0u8; state_size - 0x10]; assert_eq!(state.get(&mut data), Err(HypervisorError::BadArgument)); assert_eq!(state.set(&data), Err(HypervisorError::BadArgument)); ``` -------------------------------- ### GET /vcpu/sme-za-reg Source: https://docs.rs/applevisor/latest/src/applevisor/vcpu.rs.html Retrieves the value of the vCPU ZA matrix register. ```APIDOC ## GET /vcpu/sme-za-reg ### Description Returns the value of the vCPU ZA matrix register. Returns an error if ZA storage is disabled or if the provided buffer size is incorrect. ### Parameters #### Query Parameters - **value** (mut [u8]) - Required - Buffer to store the ZA matrix data. ``` -------------------------------- ### Create vCPU from VM Instance Source: https://docs.rs/applevisor/latest/src/applevisor/vm.rs.html Basic vCPU creation using the static VM instance. ```rust #[test] #[parallel] fn create_a_vcpu_from_a_vm_instance() { let _ = VirtualMachineStaticInstance::init(); let vm = VirtualMachineStaticInstance::get().unwrap(); let vcpu = vm.vcpu_create(); assert!(vcpu.is_ok()); } ``` -------------------------------- ### Get Memory Size Source: https://docs.rs/applevisor/latest/applevisor/memory/struct.Memory.html Retrieves the size of the memory mapping in bytes. ```rust pub fn size(&self) -> usize ``` -------------------------------- ### Initialize Global VM Instance Source: https://docs.rs/applevisor/latest/applevisor/vm/enum.VirtualMachineStaticInstance.html Methods for initializing the global virtual machine instance with various configurations. ```rust use applevisor::prelude::*; VirtualMachineStaticInstance::init()?; ``` ```rust use applevisor::prelude::*; // Custom configuration for the virtual machine. let mut config = VirtualMachineConfig::default(); config.set_el2_enabled(true)?; // Creates the global instance using the configuration above. let _ = VirtualMachineStaticInstance::init_with_config(config)?; ``` ```rust use applevisor::prelude::*; // Custom configuration for the virtual machine. let mut vm_config = VirtualMachineConfig::default(); vm_config.set_el2_enabled(true)?; // Custom configuration for the GIC. let mut gic_config = GicConfig::default(); gic_config.set_redistributor_base(0x2000_0000)?; // Creates the global instance using the configurations above. let _ = VirtualMachineStaticInstance::init_with_gic(vm_config, gic_config)?; ``` -------------------------------- ### Get VCPU ID Source: https://docs.rs/applevisor/latest/applevisor/vcpu/struct.VcpuHandle.html Returns the ID of the vCPU associated with this handle. ```rust pub fn id(&self) -> u64 ``` -------------------------------- ### Get Guest Address Source: https://docs.rs/applevisor/latest/applevisor/memory/struct.Memory.html Returns the guest address of the memory mapping, if it has been mapped. ```rust pub fn guest_addr(&self) -> Option ``` -------------------------------- ### Configure IPA Granule Source: https://docs.rs/applevisor/latest/src/applevisor/vm.rs.html Demonstrates setting and verifying IPA granule sizes for a virtual machine configuration. ```rust let granule_size = VirtualMachineConfig::get_default_ipa_granule(); assert!(granule_size.is_ok()); assert_eq!( config.set_ipa_granule(IpaGranule::HV_IPA_GRANULE_4KB), Ok(()) ); assert_eq!(config.get_ipa_granule(), Ok(IpaGranule::HV_IPA_GRANULE_4KB)); assert_eq!( config.set_ipa_granule(IpaGranule::HV_IPA_GRANULE_16KB), Ok(()) ); assert_eq!( config.get_ipa_granule(), Ok(IpaGranule::HV_IPA_GRANULE_16KB) ); } ``` -------------------------------- ### SIMD/FP Register Access Source: https://docs.rs/applevisor/latest/src/applevisor/vcpu.rs.html Provides functions to get and set SIMD and Floating-Point registers (Q0-Q11). ```APIDOC ## SIMD/FP Register Access ### Description Functions to get and set SIMD and Floating-Point registers. ### Method GET/POST (Implicit) ### Endpoint N/A (Function calls within the library) ### Parameters N/A ### Request Example ```json { "example": "(Value depends on the register and feature flag. See code for details.)" } ``` ### Response N/A ## SIMD/FP Registers: - `get_and_set_simd_fp_reg_q0`: Q0 - `get_and_set_simd_fp_reg_q1`: Q1 - `get_and_set_simd_fp_reg_q2`: Q2 - `get_and_set_simd_fp_reg_q3`: Q3 - `get_and_set_simd_fp_reg_q4`: Q4 - `get_and_set_simd_fp_reg_q5`: Q5 - `get_and_set_simd_fp_reg_q6`: Q6 - `get_and_set_simd_fp_reg_q7`: Q7 - `get_and_set_simd_fp_reg_q8`: Q8 - `get_and_set_simd_fp_reg_q9`: Q9 - `get_and_set_simd_fp_reg_q10`: Q10 - `get_and_set_simd_fp_reg_q11`: Q11 ``` -------------------------------- ### Create a VCPU Instance with Default Configuration Source: https://docs.rs/applevisor/latest/src/applevisor/vcpu.rs.html Creates a new Virtual Machine VCPU instance using default configuration. Asserts that the creation is successful. ```rust let _ = VirtualMachineStaticInstance::init(); let vm = VirtualMachineStaticInstance::get().unwrap(); let vcpu_config = VcpuConfig::default(); // The vCPU should be created without issue. let vcpu = vm.vcpu_with_config(vcpu_config); assert!(vcpu.is_ok()); ``` -------------------------------- ### GET /vcpu/sme-p-reg Source: https://docs.rs/applevisor/latest/src/applevisor/vcpu.rs.html Retrieves the value of a vCPU P predicate register in streaming SVE mode. ```APIDOC ## GET /vcpu/sme-p-reg ### Description Returns the value of a vCPU P predicate register in streaming SVE mode. Returns an error if not in streaming SVE mode or if the storage size is incorrect. ### Parameters #### Query Parameters - **reg** (SmePReg) - Required - The P register identifier. - **value** (mut [u8]) - Required - Buffer to store the register value. ``` -------------------------------- ### VirtualMachineStaticInstance::init_with_config Source: https://docs.rs/applevisor/latest/src/applevisor/vm.rs.html Initializes the global virtual machine instance using a custom VirtualMachineConfig. ```APIDOC ## VirtualMachineStaticInstance::init_with_config ### Description Initializes the global VM instance with a specific configuration. Requires the 'macos-13-0' feature. ### Parameters - **vm_config** (VirtualMachineConfig) - Required - The configuration object for the virtual machine. ### Response - **Result<()>** - Returns Ok(()) on success or an error if initialization fails. ``` -------------------------------- ### VirtualMachineStaticInstance::init Source: https://docs.rs/applevisor/latest/src/applevisor/vm.rs.html Initializes the global virtual machine instance if it has not been created yet. ```APIDOC ## VirtualMachineStaticInstance::init ### Description Initializes the global VM instance. If the instance is already initialized, the function returns immediately. ### Parameters None ### Response - **Result<()>** - Returns Ok(()) on success or an error if initialization fails. ``` -------------------------------- ### GET /vcpu/sme-z-reg Source: https://docs.rs/applevisor/latest/src/applevisor/vcpu.rs.html Retrieves the value of a vCPU Z vector register in streaming SVE mode. ```APIDOC ## GET /vcpu/sme-z-reg ### Description Returns the value of a vCPU Z vector register in streaming SVE mode. Returns an error if not in streaming SVE mode or if the storage size is incorrect. ### Parameters #### Query Parameters - **reg** (SmeZReg) - Required - The Z register identifier. - **value** (mut [u8]) - Required - Buffer to store the register value. ``` -------------------------------- ### GIC State Management Source: https://docs.rs/applevisor/latest/src/applevisor/gic.rs.html Methods for creating, getting, and setting the GIC state for migration or restoration. ```APIDOC ## POST /gic/state/create ### Description Creates a global interrupt controller configuration object. ## GET /gic/state/data ### Description Retrieves the current GIC state data. ## PUT /gic/state/data ### Description Sets the state for the GIC device to be restored. ``` -------------------------------- ### Create Virtual Machine with GIC Support Source: https://docs.rs/applevisor/latest/src/applevisor/vm.rs.html Creates a new virtual machine instance with a user-provided VirtualMachineConfig and an ARM Generic Interrupt Controller (GIC) v3 device. Requires the 'macos-15-0' feature. Discusses GIC v3 specifics like affinity-based routing and MSI support. ```rust /// Creates a new virtual machine instance for the current process using a user-provided /// [`VirtualMachineConfig`], as well as an ARM Generic Interrupt Controller (GIC) v3 device. /// /// # Discussion /// /// There must only be a single GIC instance per virtual machine. The device supports a /// distributor, redistributors, msi and GIC CPU system registers. When EL2 is enabled, the /// device supports GIC hypervisor control registers which are used by the guest hypervisor for /// injecting interrupts to its guest. /// /// GIC v3 uses affinity based interrupt routing. vCPU's must set affinity values in their /// [`SysReg::MPIDR_EL1`] register. Once the virtual machine vcpus are running, its topology /// is considered final. Destroy vcpus only when you are tearing down the virtual machine. /// /// GIC MSI support is only provided if both an MSI region base address is configured and an /// MSI interrupt range is set. /// /// # Example /// /// ```no_run /// use applevisor::prelude::*; /// /// # fn main() -> Result<()> { /// // Custom configuration for the virtual machine. /// let mut vm_config = VirtualMachineConfig::default(); /// vm_config.set_el2_enabled(true)?; /// // Custom configuration for the GIC. /// let mut gic_config = GicConfig::default(); /// gic_config.set_redistributor_base(0x2000_0000)?; /// /// // Creates the global instance using the configurations above. /// let vm = VirtualMachineInstance::with_gic(vm_config, gic_config)?; /// # Ok(()) /// # } /// ``` #[cfg(feature = "macos-15-0")] pub fn with_gic( vm_config: VirtualMachineConfig, gic_config: GicConfig, ) -> Result> { // Creating the VM using `with_config()` is deliberate. This ensures that if ``` -------------------------------- ### GET /sme_zt0_reg Source: https://docs.rs/applevisor/latest/applevisor/vcpu/struct.Vcpu.html Retrieves the current value of the vCPU ZT0 register in streaming SVE mode. ```APIDOC ## GET /sme_zt0_reg ### Description Returns the current value of the vCPU ZT0 register in streaming SVE mode. Must be called by the owning thread. ### Parameters #### Request Body - **value** (SmeZt0) - Required - Mutable reference to store the register value. ### Response #### Success Response (200) - **Result** (()) - Returns an empty result on success. ### Error Handling - Returns an error if PSTATE.ZA is 0 (za_storage_enabled is false). ``` -------------------------------- ### Define hypervisor entitlements Source: https://docs.rs/applevisor Create an entitlements file to grant the necessary hypervisor permissions to your binary. ```xml com.apple.security.hypervisor ``` -------------------------------- ### Get Host Address Pointer Source: https://docs.rs/applevisor/latest/applevisor/memory/struct.Memory.html Returns the raw pointer to the host address of the memory mapping. ```rust pub fn host_addr(&self) -> *mut u8 ``` -------------------------------- ### VirtualMachine::new Source: https://docs.rs/applevisor/latest/applevisor/vm/struct.VirtualMachine.html Creates a new virtual machine instance for the current process using default settings. ```APIDOC ## VirtualMachine::new ### Description Creates a new virtual machine instance for the current process. ### Response - **Result>** - A result containing the new virtual machine instance or an error. ### Request Example ```rust let vm = VirtualMachine::new()?; ``` ``` -------------------------------- ### Get Single GIC Redistributor Size Source: https://docs.rs/applevisor/latest/applevisor/gic/struct.GicConfig.html Retrieves the size, in bytes, of a single GIC redistributor structure. ```rust pub fn get_redistributor_size() -> Result ``` -------------------------------- ### Generate local documentation Source: https://docs.rs/applevisor Use cargo to generate and open the crate documentation locally. ```bash cargo doc --open ``` -------------------------------- ### Get Virtual Timer Offset Source: https://docs.rs/applevisor/latest/src/applevisor/vcpu.rs.html Returns the vTimer offset for the specified vCPU. This offset can affect timer behavior. ```rust pub fn get_vtimer_offset(&self) -> Result { let mut vtimer_offset = 0; hv_unsafe_call!(hv_vcpu_get_vtimer_offset(self.vcpu, &mut vtimer_offset))?; Ok(vtimer_offset) } ```