applevisor_sys/
lib.rs

1//! Unsafe Rust bindings for the Apple Silicon Hypervisor.framework
2//!
3//! These unsafe bindings provide access to the Apple Silicon `Hypervisor.framework` from Rust
4//! programs. It is recommended to use the safe version of this library available at the following
5//! locations:
6//!
7//!  * [Applevisor GitHub repository](https://github.com/impalabs/applevisor)
8//!  * [Applevisor crates.io page](https://crates.io/crates/applevisor)
9//!  * [Applevisor docs.rs page](https://docs.rs/applevisor)
10
11#![cfg_attr(feature = "simd_nightly", feature(portable_simd), feature(simd_ffi))]
12#![allow(non_camel_case_types)]
13#![allow(improper_ctypes)]
14
15use core::ffi::c_void;
16
17#[cfg_attr(target_os = "macos", link(name = "Hypervisor", kind = "framework"))]
18extern "C" {}
19
20/// The return type of framework functions.
21pub type hv_return_t = i32;
22
23/// Errors returned by Hypervisor functions.
24#[repr(C)]
25#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
26pub enum hv_error_t {
27    /// The operation completed successfully.
28    HV_SUCCESS = 0,
29    /// The operation was unsuccessful.
30    HV_ERROR = 0xfae94001,
31    /// The operation was unsuccessful because the owning resource was busy.
32    HV_BUSY = 0xfae94002,
33    /// The operation was unsuccessful because the function call had an invalid argument.
34    HV_BAD_ARGUMENT = 0xfae94003,
35    /// The operation was unsuccessful because the guest is in an illegal state.
36    HV_ILLEGAL_GUEST_STATE = 0xfae94004,
37    /// The operation was unsuccessful because the host had no resources available to complete the
38    /// request.
39    HV_NO_RESOURCES = 0xfae94005,
40    /// The operation was unsuccessful because no VM or vCPU was available.
41    HV_NO_DEVICE = 0xfae94006,
42    /// The system didn’t allow the requested operation.
43    HV_DENIED = 0xfae94007,
44    /// HV_FAULT
45    HV_FAULT = 0xfae94008,
46    /// The operation requested isn’t supported by the hypervisor.
47    HV_UNSUPPORTED = 0xfae9400f,
48}
49
50// -----------------------------------------------------------------------------------------------
51// Virtual Machine Management
52// -----------------------------------------------------------------------------------------------
53
54/// The type that defines a virtual-machine configuration.
55pub type hv_vm_config_t = *mut c_void;
56
57extern "C" {
58    /// Creates a VM instance for the current process.
59    ///
60    /// # Parameters
61    ///
62    /// * `config`: The configuration of the vCPU, which must be nil.
63    ///
64    /// # Return Value
65    ///
66    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
67    /// [`hv_return_t`].
68    pub fn hv_vm_create(config: hv_vm_config_t) -> hv_return_t;
69
70    /// Destroys the VM instance associated with the current process.
71    ///
72    /// # Return value
73    ///
74    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
75    /// [`hv_return_t`].
76    pub fn hv_vm_destroy() -> hv_return_t;
77}
78
79// -----------------------------------------------------------------------------------------------
80// vCPU Management - Configuration
81// -----------------------------------------------------------------------------------------------
82
83/// The type that defines a vCPU configuration.
84pub type hv_vcpu_config_t = *mut c_void;
85
86/// The type that defines feature registers.
87#[repr(C)]
88#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
89pub enum hv_feature_reg_t {
90    /// The value that identifies debug feature register 0, EL1 (DFR0_EL1).
91    HV_FEATURE_REG_ID_AA64DFR0_EL1,
92    /// The value that identifies debug feature register 1, EL1 (DFR1_EL1).
93    HV_FEATURE_REG_ID_AA64DFR1_EL1,
94    /// The value that identifies instruction set attribute register 0, EL1 (ISAR0_EL1).
95    HV_FEATURE_REG_ID_AA64ISAR0_EL1,
96    /// The value that identifies instruction set attribute register 1, EL1 (ISAR_EL1).
97    HV_FEATURE_REG_ID_AA64ISAR1_EL1,
98    /// The value that identifies memory model feature register 0, EL1(MMFR0_EL1).
99    HV_FEATURE_REG_ID_AA64MMFR0_EL1,
100    /// The value that identifies memory model feature register 1, EL1 (MMFR1_EL1).
101    HV_FEATURE_REG_ID_AA64MMFR1_EL1,
102    /// The value that identifies memory model feature register 2, EL1 (MMFR2_EL1).
103    HV_FEATURE_REG_ID_AA64MMFR2_EL1,
104    /// The value that identifies processor feature register 0, EL1 (PFR0_EL1).
105    HV_FEATURE_REG_ID_AA64PFR0_EL1,
106    /// The value that identifies processor feature register 1, EL1 (PFR1_EL1).
107    HV_FEATURE_REG_ID_AA64PFR1_EL1,
108    /// The value that describes Cache Type Register, EL0.
109    HV_FEATURE_REG_CTR_EL0,
110    /// The value that describes Cache Level ID Register, EL1.
111    HV_FEATURE_REG_CLIDR_EL1,
112    /// The values that describes Data Cache Zero ID Register, EL0.
113    HV_FEATURE_REG_DCZID_EL0,
114}
115
116/// The structure that describes an instruction or data cache element.
117#[repr(C)]
118#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
119pub enum hv_cache_type_t {
120    /// The value that describes a cached data value.
121    HV_CACHE_TYPE_DATA,
122    /// The value that describes a cached instuction value.
123    HV_CACHE_TYPE_INSTRUCTION,
124}
125
126extern "C" {
127    /// Creates a vCPU configuration object.
128    ///
129    /// # Return
130    ///
131    /// A new vCPU configuration object.
132    pub fn hv_vcpu_config_create() -> hv_vcpu_config_t;
133
134    /// Gets the value of a feature register.
135    ///
136    /// # Parameters
137    ///
138    /// * `config`: The vCPU configuration.
139    /// * `feature_reg`: The ID of the feature register.
140    /// * `value`: The value of `feature_reg` on output. Undefined if the call doesn’t succeed.
141    ///
142    /// # Return Value
143    ///
144    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
145    /// [`hv_return_t`].
146    pub fn hv_vcpu_config_get_feature_reg(
147        config: hv_vcpu_config_t,
148        feature_reg: hv_feature_reg_t,
149        value: *mut u64,
150    ) -> hv_return_t;
151
152    /// Returns the Cache Size ID Register (CCSIDR_EL1) values for the vCPU configuration and
153    /// cache type you specify.
154    ///
155    /// # Parameters
156    ///
157    /// * `config`: The vCPU configuration.
158    /// * `cache_type`: The cache type from the available [`hv_cache_type_t`] types.
159    /// * `values`: A pointer to the location for the return values.
160    ///
161    /// # Return Value
162    ///
163    /// A [`hv_return_t`] value that indicates that result of the function.
164    pub fn hv_vcpu_config_get_ccsidr_el1_sys_reg_values(
165        config: hv_vcpu_config_t,
166        cache_type: hv_cache_type_t,
167        values: *mut u64,
168    ) -> hv_return_t;
169}
170
171// -----------------------------------------------------------------------------------------------
172// vCPU Management - Creation and Destruction
173// -----------------------------------------------------------------------------------------------
174
175/// An opaque value that represents a vCPU instance.
176pub type hv_vcpu_t = u64;
177
178/// The structure that describes information about an exit from the virtual CPU (vCPU) to the host.
179#[repr(C)]
180#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
181pub struct hv_vcpu_exit_exception_t {
182    /// The vCPU exception syndrome causing the exception.
183    pub syndrome: u64,
184    /// The vCPU virtual address of the exception.
185    pub virtual_address: u64,
186    /// The intermediate physical address of the exception in the client.
187    pub physical_address: u64,
188}
189
190/// The type that describes the event that triggered a guest exit to the host.
191#[repr(C)]
192#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
193pub enum hv_exit_reason_t {
194    /// The value that identifies exits requested by exit handler on the host.
195    HV_EXIT_REASON_CANCELED,
196    /// The value that identifies traps caused by the guest operations.
197    HV_EXIT_REASON_EXCEPTION,
198    /// The value that identifies when the virtual timer enters the pending state.
199    HV_EXIT_REASON_VTIMER_ACTIVATED,
200    /// The value that identifies unexpected exits.
201    HV_EXIT_REASON_UNKNOWN,
202}
203
204/// Information about an exit from the vCPU to the host.
205#[repr(C)]
206#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
207pub struct hv_vcpu_exit_t {
208    /// Information about an exit from the vcpu to the host.
209    pub reason: hv_exit_reason_t,
210    /// Information about an exit exception from the vcpu to the host.
211    pub exception: hv_vcpu_exit_exception_t,
212}
213
214extern "C" {
215    /// Returns the maximum number of vCPUs that the hypervisor supports.
216    ///
217    /// # Parameters
218    ///
219    /// * `max_vcpu_count`: The maximum number of vCPUs on output. Undefined if the call doesn’t
220    ///                     succeed.
221    ///
222    /// # Return Value
223    ///
224    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
225    /// [`hv_return_t`].
226    pub fn hv_vm_get_max_vcpu_count(max_vcpu_count: *mut u32) -> hv_return_t;
227
228    /// Creates a vCPU instance for the current thread.
229    ///
230    /// # Parameters
231    ///
232    /// * `vcpu`: An argument that the hypervisor populates with the instance of a vCPU on a
233    ///           successful return.
234    /// * `exit`: The pointer to the vCPU exit information. The function hv_vcpu_run updates this
235    ///           structure on return.
236    /// * `config`: The configuration of the vCPU or nil for a default configuration.
237    ///
238    /// # Return Value
239    ///
240    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
241    /// [`hv_return_t`].
242    pub fn hv_vcpu_create(
243        vcpu: *mut hv_vcpu_t,
244        exit: *mut *const hv_vcpu_exit_t,
245        config: hv_vcpu_config_t,
246    ) -> hv_return_t;
247
248    /// Destroys the vCPU instance associated with the current thread.
249    ///
250    /// # Parameters
251    ///
252    /// * `vcpu`: The instance of the vCPU.
253    ///
254    /// # Return Value
255    ///
256    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
257    /// [`hv_return_t`].
258    pub fn hv_vcpu_destroy(vcpu: hv_vcpu_t) -> hv_return_t;
259}
260
261// -----------------------------------------------------------------------------------------------
262// vCPU Management - Runtime
263// -----------------------------------------------------------------------------------------------
264
265/// The type that defines the vCPU’s interrupts.
266#[repr(C)]
267#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
268pub enum hv_interrupt_type_t {
269    /// ARM Fast Interrupt Request.
270    HV_INTERRUPT_TYPE_FIQ,
271    /// ARM Interrupt Request.
272    HV_INTERRUPT_TYPE_IRQ,
273}
274
275extern "C" {
276    /// Starts the execution of a vCPU.
277    ///
278    /// # Parameters
279    ///
280    /// * `vcpu`: The instance of the vCPU.
281    ///
282    /// # Return Value
283    ///
284    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
285    /// [`hv_return_t`].
286    pub fn hv_vcpu_run(vcpu: hv_vcpu_t) -> hv_return_t;
287
288    /// Forces an immediate exit of a set of vCPUs of the VM.
289    ///
290    /// # Parameters
291    ///
292    /// * `vcpus`: An array of vCPU instances.
293    /// * `vcpu_count`: The number of vCPUs in the array.
294    ///
295    /// # Return Value
296    ///
297    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
298    /// [`hv_return_t`].
299    pub fn hv_vcpus_exit(vcpus: *const hv_vcpu_t, vcpu_count: u32) -> hv_return_t;
300
301    /// Gets pending interrupts for a vCPU.
302    ///
303    /// # Parameters
304    ///
305    /// * `vcpu`: The instance of the vCPU.
306    /// * `type`: The interrupt from Interrupt Constants.
307    /// * `pending`: A variable that indicates whether, on output, the interrupt of type is
308    ///              pending or not.
309    ///
310    /// # Return Value
311    ///
312    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
313    /// [`hv_return_t`].
314    pub fn hv_vcpu_get_pending_interrupt(
315        vcpu: hv_vcpu_t,
316        _type: hv_interrupt_type_t,
317        pending: *mut bool,
318    ) -> hv_return_t;
319
320    /// Sets pending interrupts for a vCPU.
321    ///
322    /// # Parameters
323    ///
324    /// * `vcpu`: The instance of the vCPU.
325    /// * `type`: The interrupt from Interrupt Constants.
326    /// * `pending`: A Boolean that indicates whether the interrupt is pending.
327    ///
328    /// # Return Value
329    ///
330    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
331    /// [`hv_return_t`].
332    pub fn hv_vcpu_set_pending_interrupt(
333        vcpu: hv_vcpu_t,
334        _type: hv_interrupt_type_t,
335        pending: bool,
336    ) -> hv_return_t;
337
338    /// Returns, by reference, the cumulative execution time of a vCPU, in nanoseconds.
339    ///
340    /// # Parameters
341    ///
342    /// * `vcpu`: The instance of the vCPU.
343    /// * `time`: The execution time on output, in nanoseconds.
344    ///
345    /// # Return Value
346    ///
347    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
348    /// [`hv_return_t`].
349    pub fn hv_vcpu_get_exec_time(vcpu: hv_vcpu_t, time: *mut u64) -> hv_return_t;
350}
351
352// -----------------------------------------------------------------------------------------------
353// vCPU Management - General Registers
354// -----------------------------------------------------------------------------------------------
355
356/// The type that defines general registers.
357#[repr(C)]
358#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
359pub enum hv_reg_t {
360    /// The value that identifies register X0.
361    HV_REG_X0,
362    /// The value that identifies register X1.
363    HV_REG_X1,
364    /// The value that identifies register X2.
365    HV_REG_X2,
366    /// The value that identifies register X3.
367    HV_REG_X3,
368    /// The value that identifies register X4.
369    HV_REG_X4,
370    /// The value that identifies register X5.
371    HV_REG_X5,
372    /// The value that identifies register X6.
373    HV_REG_X6,
374    /// The value that identifies register X7.
375    HV_REG_X7,
376    /// The value that identifies register X8.
377    HV_REG_X8,
378    /// The value that identifies register X9.
379    HV_REG_X9,
380    /// The value that identifies register X10.
381    HV_REG_X10,
382    /// The value that identifies register X11.
383    HV_REG_X11,
384    /// The value that identifies register X12.
385    HV_REG_X12,
386    /// The value that identifies register X13.
387    HV_REG_X13,
388    /// The value that identifies register X14.
389    HV_REG_X14,
390    /// The value that identifies register X15.
391    HV_REG_X15,
392    /// The value that identifies register X16.
393    HV_REG_X16,
394    /// The value that identifies register X17.
395    HV_REG_X17,
396    /// The value that identifies register X18.
397    HV_REG_X18,
398    /// The value that identifies register X19.
399    HV_REG_X19,
400    /// The value that identifies register X20.
401    HV_REG_X20,
402    /// The value that identifies register X21.
403    HV_REG_X21,
404    /// The value that identifies register X22.
405    HV_REG_X22,
406    /// The value that identifies register X23.
407    HV_REG_X23,
408    /// The value that identifies register X24.
409    HV_REG_X24,
410    /// The value that identifies register X25.
411    HV_REG_X25,
412    /// The value that identifies register X26.
413    HV_REG_X26,
414    /// The value that identifies register X27.
415    HV_REG_X27,
416    /// The value that identifies register X28.
417    HV_REG_X28,
418    /// The value that identifies register X29.
419    HV_REG_X29,
420    /// The value that identifies register X30.
421    HV_REG_X30,
422    /// The value that identifies the program counter (PC).
423    HV_REG_PC,
424    /// The value that identifies the floating-point control register (FPCR).
425    HV_REG_FPCR,
426    /// The value that identifies the floating-point status register (FPSR).
427    HV_REG_FPSR,
428    /// The value that identifies the current program status register (CPSR).
429    HV_REG_CPSR,
430}
431
432impl hv_reg_t {
433    /// The value that identifies the frame pointer (FP).
434    pub const HV_REG_FP: Self = Self::HV_REG_X29;
435    /// The value that identifies the link register (LR).
436    pub const HV_REG_LR: Self = Self::HV_REG_X30;
437}
438
439extern "C" {
440    /// Gets the current value of a vCPU register.
441    ///
442    /// # Parameters
443    ///
444    /// * `vcpu`: The vCPU instance.
445    /// * `reg`: The ID of the general register.
446    /// * `value`: The value of the register reg on output.
447    ///
448    /// # Return Value
449    ///
450    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
451    /// [`hv_return_t`].
452    pub fn hv_vcpu_get_reg(vcpu: hv_vcpu_t, reg: hv_reg_t, value: *mut u64) -> hv_return_t;
453
454    /// Sets the value of a vCPU register.
455    ///
456    /// # Parameters
457    ///
458    /// * `vcpu`: The vCPU instance.
459    /// * `reg`: The ID of the general register.
460    /// * `value`: The new value of the register.
461    ///
462    /// # Return Value
463    ///
464    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
465    /// [`hv_return_t`].
466    pub fn hv_vcpu_set_reg(vcpu: hv_vcpu_t, reg: hv_reg_t, value: u64) -> hv_return_t;
467}
468
469// -----------------------------------------------------------------------------------------------
470// vCPU Management - SIMD & Floating-Point Registers
471// -----------------------------------------------------------------------------------------------
472
473/// The value that represents an ARM SIMD and FP register.
474#[cfg(feature = "simd_nightly")]
475pub type hv_simd_fp_uchar16_t = std::simd::i8x16;
476#[cfg(not(feature = "simd_nightly"))]
477pub type hv_simd_fp_uchar16_t = u128;
478
479/// The type that defines SIMD and floating-point registers.
480#[repr(C)]
481#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
482pub enum hv_simd_fp_reg_t {
483    /// The value representing SIMD register Q0.
484    HV_SIMD_FP_REG_Q0,
485    /// The value representing SIMD register Q1.
486    HV_SIMD_FP_REG_Q1,
487    /// The value representing SIMD register Q2.
488    HV_SIMD_FP_REG_Q2,
489    /// The value representing SIMD register Q3.
490    HV_SIMD_FP_REG_Q3,
491    /// The value representing SIMD register Q4.
492    HV_SIMD_FP_REG_Q4,
493    /// The value representing SIMD register Q5.
494    HV_SIMD_FP_REG_Q5,
495    /// The value representing SIMD register Q6.
496    HV_SIMD_FP_REG_Q6,
497    /// The value representing SIMD register Q7.
498    HV_SIMD_FP_REG_Q7,
499    /// The value representing SIMD register Q8.
500    HV_SIMD_FP_REG_Q8,
501    /// The value representing SIMD register Q9.
502    HV_SIMD_FP_REG_Q9,
503    /// The value representing SIMD register Q10.
504    HV_SIMD_FP_REG_Q10,
505    /// The value representing SIMD register Q11.
506    HV_SIMD_FP_REG_Q11,
507    /// The value representing SIMD register Q12.
508    HV_SIMD_FP_REG_Q12,
509    /// The value representing SIMD register Q13.
510    HV_SIMD_FP_REG_Q13,
511    /// The value representing SIMD register Q14.
512    HV_SIMD_FP_REG_Q14,
513    /// The value representing SIMD register Q15.
514    HV_SIMD_FP_REG_Q15,
515    /// The value representing SIMD register Q16.
516    HV_SIMD_FP_REG_Q16,
517    /// The value representing SIMD register Q17.
518    HV_SIMD_FP_REG_Q17,
519    /// The value representing SIMD register Q18.
520    HV_SIMD_FP_REG_Q18,
521    /// The value representing SIMD register Q19.
522    HV_SIMD_FP_REG_Q19,
523    /// The value representing SIMD register Q20.
524    HV_SIMD_FP_REG_Q20,
525    /// The value representing SIMD register Q21.
526    HV_SIMD_FP_REG_Q21,
527    /// The value representing SIMD register Q22.
528    HV_SIMD_FP_REG_Q22,
529    /// The value representing SIMD register Q23.
530    HV_SIMD_FP_REG_Q23,
531    /// The value representing SIMD register Q24.
532    HV_SIMD_FP_REG_Q24,
533    /// The value representing SIMD register Q25.
534    HV_SIMD_FP_REG_Q25,
535    /// The value representing SIMD register Q26.
536    HV_SIMD_FP_REG_Q26,
537    /// The value representing SIMD register Q27.
538    HV_SIMD_FP_REG_Q27,
539    /// The value representing SIMD register Q28.
540    HV_SIMD_FP_REG_Q28,
541    /// The value representing SIMD register Q29.
542    HV_SIMD_FP_REG_Q29,
543    /// The value representing SIMD register Q30.
544    HV_SIMD_FP_REG_Q30,
545    /// The value representing SIMD register Q31.
546    HV_SIMD_FP_REG_Q31,
547}
548
549extern "C" {
550    /// Gets the current value of a vCPU SIMD and FP register.
551    ///
552    /// # Parameters
553    ///
554    /// * `vcpu`: The vCPU instance.
555    /// * `reg`: The ID of the SIMD and FP register.
556    /// * `value`: The value of the register reg on output.
557    ///
558    /// # Return Value
559    ///
560    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
561    /// [`hv_return_t`].
562    pub fn hv_vcpu_get_simd_fp_reg(
563        vcpu: hv_vcpu_t,
564        reg: hv_simd_fp_reg_t,
565        value: *mut hv_simd_fp_uchar16_t,
566    ) -> hv_return_t;
567
568    /// Sets the value of a vCPU SIMD&FP register.
569    ///
570    /// # Parameters
571    ///
572    /// * `vcpu`: The vCPU instance.
573    /// * `reg`: The ID of the SIMD and FP register.
574    /// * `value`: The new value of the register.
575    ///
576    /// # Return Value
577    ///
578    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
579    /// [`hv_return_t`].
580    pub fn hv_vcpu_set_simd_fp_reg(
581        vcpu: hv_vcpu_t,
582        reg: hv_simd_fp_reg_t,
583        value: hv_simd_fp_uchar16_t,
584    ) -> hv_return_t;
585}
586
587// -----------------------------------------------------------------------------------------------
588// vCPU Management - System Registers
589// -----------------------------------------------------------------------------------------------
590
591/// The type of system registers.
592#[repr(C)]
593#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
594pub enum hv_sys_reg_t {
595    /// The value that represents the system register DBGBVR0_EL1.
596    HV_SYS_REG_DBGBVR0_EL1 = 0x8004,
597    /// The value that represents the system register DBGBCR0_EL1.
598    HV_SYS_REG_DBGBCR0_EL1 = 0x8005,
599    /// The value that represents the system register DBGWVR0_EL1.
600    HV_SYS_REG_DBGWVR0_EL1 = 0x8006,
601    /// The value that represents the system register DBGWCR0_EL1.
602    HV_SYS_REG_DBGWCR0_EL1 = 0x8007,
603    /// The value that represents the system register DBGBVR1_EL1.
604    HV_SYS_REG_DBGBVR1_EL1 = 0x800c,
605    /// The value that represents the system register DBGBCR1_EL1.
606    HV_SYS_REG_DBGBCR1_EL1 = 0x800d,
607    /// The value that represents the system register DBGWVR1_EL1.
608    HV_SYS_REG_DBGWVR1_EL1 = 0x800e,
609    /// The value that represents the system register DBGWCR1_EL1.
610    HV_SYS_REG_DBGWCR1_EL1 = 0x800f,
611    /// The value that represents the system register MDCCINT_EL1.
612    HV_SYS_REG_MDCCINT_EL1 = 0x8010,
613    /// The value that represents the system register MDSCR_EL1.
614    HV_SYS_REG_MDSCR_EL1 = 0x8012,
615    /// The value that represents the system register DBGBVR2_EL1.
616    HV_SYS_REG_DBGBVR2_EL1 = 0x8014,
617    /// The value that represents the system register DBGBCR2_EL1.
618    HV_SYS_REG_DBGBCR2_EL1 = 0x8015,
619    /// The value that represents the system register DBGWVR2_EL1.
620    HV_SYS_REG_DBGWVR2_EL1 = 0x8016,
621    /// The value that represents the system register DBGWCR2_EL1.
622    HV_SYS_REG_DBGWCR2_EL1 = 0x8017,
623    /// The value that represents the system register DBGBVR3_EL1.
624    HV_SYS_REG_DBGBVR3_EL1 = 0x801c,
625    /// The value that represents the system register DBGBCR3_EL1.
626    HV_SYS_REG_DBGBCR3_EL1 = 0x801d,
627    /// The value that represents the system register DBGWVR3_EL1.
628    HV_SYS_REG_DBGWVR3_EL1 = 0x801e,
629    /// The value that represents the system register DBGWCR3_EL1.
630    HV_SYS_REG_DBGWCR3_EL1 = 0x801f,
631    /// The value that represents the system register DBGBVR4_EL1.
632    HV_SYS_REG_DBGBVR4_EL1 = 0x8024,
633    /// The value that represents the system register DBGBCR4_EL1.
634    HV_SYS_REG_DBGBCR4_EL1 = 0x8025,
635    /// The value that represents the system register DBGWVR4_EL1.
636    HV_SYS_REG_DBGWVR4_EL1 = 0x8026,
637    /// The value that represents the system register DBGWCR4_EL1.
638    HV_SYS_REG_DBGWCR4_EL1 = 0x8027,
639    /// The value that represents the system register DBGBVR5_EL1.
640    HV_SYS_REG_DBGBVR5_EL1 = 0x802c,
641    /// The value that represents the system register DBGBCR5_EL1.
642    HV_SYS_REG_DBGBCR5_EL1 = 0x802d,
643    /// The value that represents the system register DBGWVR5_EL1.
644    HV_SYS_REG_DBGWVR5_EL1 = 0x802e,
645    /// The value that represents the system register DBGWCR5_EL1.
646    HV_SYS_REG_DBGWCR5_EL1 = 0x802f,
647    /// The value that represents the system register DBGBVR6_EL1.
648    HV_SYS_REG_DBGBVR6_EL1 = 0x8034,
649    /// The value that represents the system register DBGBCR6_EL1.
650    HV_SYS_REG_DBGBCR6_EL1 = 0x8035,
651    /// The value that represents the system register DBGWVR6_EL1.
652    HV_SYS_REG_DBGWVR6_EL1 = 0x8036,
653    /// The value that represents the system register DBGWCR6_EL1.
654    HV_SYS_REG_DBGWCR6_EL1 = 0x8037,
655    /// The value that represents the system register DBGBVR7_EL1.
656    HV_SYS_REG_DBGBVR7_EL1 = 0x803c,
657    /// The value that represents the system register DBGBCR7_EL1.
658    HV_SYS_REG_DBGBCR7_EL1 = 0x803d,
659    /// The value that represents the system register DBGWVR7_EL1.
660    HV_SYS_REG_DBGWVR7_EL1 = 0x803e,
661    /// The value that represents the system register DBGWCR7_EL1.
662    HV_SYS_REG_DBGWCR7_EL1 = 0x803f,
663    /// The value that represents the system register DBGBVR8_EL1.
664    HV_SYS_REG_DBGBVR8_EL1 = 0x8044,
665    /// The value that represents the system register DBGBCR8_EL1.
666    HV_SYS_REG_DBGBCR8_EL1 = 0x8045,
667    /// The value that represents the system register DBGWVR8_EL1.
668    HV_SYS_REG_DBGWVR8_EL1 = 0x8046,
669    /// The value that represents the system register DBGWCR8_EL1.
670    HV_SYS_REG_DBGWCR8_EL1 = 0x8047,
671    /// The value that represents the system register DBGBVR9_EL1.
672    HV_SYS_REG_DBGBVR9_EL1 = 0x804c,
673    /// The value that represents the system register DBGBCR9_EL1.
674    HV_SYS_REG_DBGBCR9_EL1 = 0x804d,
675    /// The value that represents the system register DBGWVR9_EL1.
676    HV_SYS_REG_DBGWVR9_EL1 = 0x804e,
677    /// The value that represents the system register DBGWCR9_EL1.
678    HV_SYS_REG_DBGWCR9_EL1 = 0x804f,
679    /// The value that represents the system register DBGBVR10_EL1.
680    HV_SYS_REG_DBGBVR10_EL1 = 0x8054,
681    /// The value that represents the system register DBGBCR10_EL1.
682    HV_SYS_REG_DBGBCR10_EL1 = 0x8055,
683    /// The value that represents the system register DBGWVR10_EL1.
684    HV_SYS_REG_DBGWVR10_EL1 = 0x8056,
685    /// The value that represents the system register DBGWCR10_EL1.
686    HV_SYS_REG_DBGWCR10_EL1 = 0x8057,
687    /// The value that represents the system register DBGBVR11_EL1.
688    HV_SYS_REG_DBGBVR11_EL1 = 0x805c,
689    /// The value that represents the system register DBGBCR11_EL1.
690    HV_SYS_REG_DBGBCR11_EL1 = 0x805d,
691    /// The value that represents the system register DBGWVR11_EL1.
692    HV_SYS_REG_DBGWVR11_EL1 = 0x805e,
693    /// The value that represents the system register DBGWCR11_EL1.
694    HV_SYS_REG_DBGWCR11_EL1 = 0x805f,
695    /// The value that represents the system register DBGBVR12_EL1.
696    HV_SYS_REG_DBGBVR12_EL1 = 0x8064,
697    /// The value that represents the system register DBGBCR12_EL1.
698    HV_SYS_REG_DBGBCR12_EL1 = 0x8065,
699    /// The value that represents the system register DBGWVR12_EL1.
700    HV_SYS_REG_DBGWVR12_EL1 = 0x8066,
701    /// The value that represents the system register DBGWCR12_EL1.
702    HV_SYS_REG_DBGWCR12_EL1 = 0x8067,
703    /// The value that represents the system register DBGBVR13_EL1.
704    HV_SYS_REG_DBGBVR13_EL1 = 0x806c,
705    /// The value that represents the system register DBGBCR13_EL1.
706    HV_SYS_REG_DBGBCR13_EL1 = 0x806d,
707    /// The value that represents the system register DBGWVR13_EL1.
708    HV_SYS_REG_DBGWVR13_EL1 = 0x806e,
709    /// The value that represents the system register DBGWCR13_EL1.
710    HV_SYS_REG_DBGWCR13_EL1 = 0x806f,
711    /// The value that represents the system register DBGBVR14_EL1.
712    HV_SYS_REG_DBGBVR14_EL1 = 0x8074,
713    /// The value that represents the system register DBGBCR14_EL1.
714    HV_SYS_REG_DBGBCR14_EL1 = 0x8075,
715    /// The value that represents the system register DBGWVR14_EL1.
716    HV_SYS_REG_DBGWVR14_EL1 = 0x8076,
717    /// The value that represents the system register DBGWCR14_EL1.
718    HV_SYS_REG_DBGWCR14_EL1 = 0x8077,
719    /// The value that represents the system register DBGBVR15_EL1.
720    HV_SYS_REG_DBGBVR15_EL1 = 0x807c,
721    /// The value that represents the system register DBGBCR15_EL1.
722    HV_SYS_REG_DBGBCR15_EL1 = 0x807d,
723    /// The value that represents the system register DBGWVR15_EL1.
724    HV_SYS_REG_DBGWVR15_EL1 = 0x807e,
725    /// The value that represents the system register DBGWCR15_EL1.
726    HV_SYS_REG_DBGWCR15_EL1 = 0x807f,
727    /// The value that represents the system register MIDR_EL1.
728    HV_SYS_REG_MIDR_EL1 = 0xc000,
729    /// The value that represents the system register MPIDR_EL1.
730    HV_SYS_REG_MPIDR_EL1 = 0xc005,
731    /// The value that describes the AArch64 Processor Feature Register 0.
732    HV_SYS_REG_ID_AA64PFR0_EL1 = 0xc020,
733    /// The value that describes the AArch64 Processor Feature Register 1.
734    HV_SYS_REG_ID_AA64PFR1_EL1 = 0xc021,
735    /// The value that describes the AArch64 Debug Feature Register 0.
736    HV_SYS_REG_ID_AA64DFR0_EL1 = 0xc028,
737    /// The value that describes the AArch64 Debug Feature Register 1.
738    HV_SYS_REG_ID_AA64DFR1_EL1 = 0xc029,
739    /// The value that describes the AArch64 Instruction Set Attribute Register 0.
740    HV_SYS_REG_ID_AA64ISAR0_EL1 = 0xc030,
741    /// The value that describes the AArch64 Instruction Set Attribute Register 1.
742    HV_SYS_REG_ID_AA64ISAR1_EL1 = 0xc031,
743    /// The value that describes the AArch64 Memory Model Feature Register 0.
744    HV_SYS_REG_ID_AA64MMFR0_EL1 = 0xc038,
745    /// The value that describes the AArch64 Memory Model Feature Register 1.
746    HV_SYS_REG_ID_AA64MMFR1_EL1 = 0xc039,
747    /// The value that describes the AArch64 Memory Model Feature Register 2.
748    HV_SYS_REG_ID_AA64MMFR2_EL1 = 0xc03a,
749    /// The value that represents the system register SCTLR_EL1.
750    HV_SYS_REG_SCTLR_EL1 = 0xc080,
751    /// The value that represents the system register CPACR_EL1.
752    HV_SYS_REG_CPACR_EL1 = 0xc082,
753    /// The value that represents the system register TTBR0_EL1.
754    HV_SYS_REG_TTBR0_EL1 = 0xc100,
755    /// The value that represents the system register TTBR1_EL1.
756    HV_SYS_REG_TTBR1_EL1 = 0xc101,
757    /// The value that represents the system register TCR_EL1.
758    HV_SYS_REG_TCR_EL1 = 0xc102,
759    /// The value that represents the system register APIAKEYLO_EL1.
760    HV_SYS_REG_APIAKEYLO_EL1 = 0xc108,
761    /// The value that represents the system register APIAKEYHI_EL1.
762    HV_SYS_REG_APIAKEYHI_EL1 = 0xc109,
763    /// The value that represents the system register APIBKEYLO_EL1.
764    HV_SYS_REG_APIBKEYLO_EL1 = 0xc10a,
765    /// The value that represents the system register APIBKEYHI_EL1.
766    HV_SYS_REG_APIBKEYHI_EL1 = 0xc10b,
767    /// The value that represents the system register APDAKEYLO_EL1.
768    HV_SYS_REG_APDAKEYLO_EL1 = 0xc110,
769    /// The value that represents the system register APDAKEYHI_EL1.
770    HV_SYS_REG_APDAKEYHI_EL1 = 0xc111,
771    /// The value that represents the system register APDBKEYLO_EL1.
772    HV_SYS_REG_APDBKEYLO_EL1 = 0xc112,
773    /// The value that represents the system register APDBKEYHI_EL1.
774    HV_SYS_REG_APDBKEYHI_EL1 = 0xc113,
775    /// The value that represents the system register APGAKEYLO_EL1.
776    HV_SYS_REG_APGAKEYLO_EL1 = 0xc118,
777    /// The value that represents the system register APGAKEYHI_EL1.
778    HV_SYS_REG_APGAKEYHI_EL1 = 0xc119,
779    /// The value that represents the system register SPSR_EL1.
780    HV_SYS_REG_SPSR_EL1 = 0xc200,
781    /// The value that represents the system register ELR_EL1.
782    HV_SYS_REG_ELR_EL1 = 0xc201,
783    /// The value that represents the system register SP_EL0.
784    HV_SYS_REG_SP_EL0 = 0xc208,
785    /// The value that represents the system register AFSR0_EL1.
786    HV_SYS_REG_AFSR0_EL1 = 0xc288,
787    /// The value that represents the system register AFSR1_EL1.
788    HV_SYS_REG_AFSR1_EL1 = 0xc289,
789    /// The value that represents the system register ESR_EL1.
790    HV_SYS_REG_ESR_EL1 = 0xc290,
791    /// The value that represents the system register FAR_EL1.
792    HV_SYS_REG_FAR_EL1 = 0xc300,
793    /// The value that represents the system register PAR_EL1.
794    HV_SYS_REG_PAR_EL1 = 0xc3a0,
795    /// The value that represents the system register MAIR_EL1.
796    HV_SYS_REG_MAIR_EL1 = 0xc510,
797    /// The value that represents the system register AMAIR_EL1.
798    HV_SYS_REG_AMAIR_EL1 = 0xc518,
799    /// The value that represents the system register VBAR_EL1.
800    HV_SYS_REG_VBAR_EL1 = 0xc600,
801    /// The value that represents the system register CONTEXTIDR_EL1.
802    HV_SYS_REG_CONTEXTIDR_EL1 = 0xc681,
803    /// The value that represents the system register TPIDR_EL1.
804    HV_SYS_REG_TPIDR_EL1 = 0xc684,
805    /// The value that represents the system register CNTKCTL_EL1.
806    HV_SYS_REG_CNTKCTL_EL1 = 0xc708,
807    /// The value that represents the system register CSSELR_EL1.
808    HV_SYS_REG_CSSELR_EL1 = 0xd000,
809    /// The value that represents the system register TPIDR_EL0.
810    HV_SYS_REG_TPIDR_EL0 = 0xde82,
811    /// The value that represents the system register TPIDRRO_EL0.
812    HV_SYS_REG_TPIDRRO_EL0 = 0xde83,
813    /// The value that represents the system register CNTV_CTL_EL0.
814    HV_SYS_REG_CNTV_CTL_EL0 = 0xdf19,
815    /// The value that represents the system register CNTV_CVAL_EL0.
816    HV_SYS_REG_CNTV_CVAL_EL0 = 0xdf1a,
817    /// The value that represents the system register SP_EL1.
818    HV_SYS_REG_SP_EL1 = 0xe208,
819}
820
821extern "C" {
822    /// Gets the current value of a vCPU system register.
823    ///
824    /// # Parameters
825    ///
826    /// * `vcpu`: The vCPU instance.
827    /// * `reg`: The ID of the system register.
828    /// * `value`: The value of the register reg on output.
829    ///
830    /// # Return Value
831    ///
832    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
833    /// [`hv_return_t`].
834    pub fn hv_vcpu_get_sys_reg(vcpu: hv_vcpu_t, reg: hv_sys_reg_t, value: *mut u64) -> hv_return_t;
835
836    /// Sets the value of a vCPU system register.
837    ///
838    /// # Parameters
839    ///
840    /// * `vcpu`: The vCPU instance.
841    /// * `reg`: The ID of the system register.
842    /// * `value`: The new value of the register.
843    ///
844    /// # Return Value
845    ///
846    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
847    /// [`hv_return_t`].
848    pub fn hv_vcpu_set_sys_reg(vcpu: hv_vcpu_t, reg: hv_sys_reg_t, value: u64) -> hv_return_t;
849}
850
851// -----------------------------------------------------------------------------------------------
852// vCPU Management - Trap Configuration
853// -----------------------------------------------------------------------------------------------
854
855extern "C" {
856    /// Gets whether debug exceptions exit the guest.
857    ///
858    /// # Parameters
859    ///
860    /// * `vcpu`: The vCPU instance.
861    /// * `value`: Indicates whether debug exceptions in the guest trap to the host on output.
862    ///
863    /// # Return Value
864    ///
865    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
866    /// [`hv_return_t`].
867    pub fn hv_vcpu_get_trap_debug_exceptions(vcpu: hv_vcpu_t, value: *mut bool) -> hv_return_t;
868
869    /// Sets whether debug exceptions exit the guest.
870    ///
871    /// # Parameters
872    ///
873    /// * `vcpu`: The vCPU instance.
874    /// * `value`: A Boolean value that if true indicates debug exceptions in the guest trap to
875    ///            the host.
876    ///
877    /// # Return Value
878    ///
879    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
880    /// [`hv_return_t`].
881    pub fn hv_vcpu_set_trap_debug_exceptions(vcpu: hv_vcpu_t, value: bool) -> hv_return_t;
882
883    /// Gets whether debug-register accesses exit the guest.
884    ///
885    /// # Parameters
886    ///
887    /// * `vcpu`: The vCPU instance.
888    /// * `value`: Indicates whether debug-register accesses in the guest trap to the host on
889    ///            output.
890    ///
891    /// # Return Value
892    ///
893    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
894    /// [`hv_return_t`].
895    pub fn hv_vcpu_get_trap_debug_reg_accesses(vcpu: hv_vcpu_t, value: *mut bool) -> hv_return_t;
896
897    /// Sets whether debug-register accesses exit the guest.
898    ///
899    /// # Parameters
900    ///
901    /// * `vcpu`: The vCPU instance.
902    /// * `value`: A Boolean value that if true indicates debug-register accesses in the guest
903    ///            trap to the host.
904    ///
905    /// # Return Value
906    ///
907    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
908    /// [`hv_return_t`].
909    pub fn hv_vcpu_set_trap_debug_reg_accesses(vcpu: hv_vcpu_t, value: bool) -> hv_return_t;
910}
911
912// -----------------------------------------------------------------------------------------------
913// Memory Management
914// -----------------------------------------------------------------------------------------------
915
916/// The type of an intermediate physical address, which is a guest physical address space of the
917/// VM.
918pub type hv_ipa_t = u64;
919/// The permissions for guest physical memory regions.
920pub type hv_memory_flags_t = u64;
921
922/// The value that represents the memory-read permission.
923pub const HV_MEMORY_READ: hv_memory_flags_t = 1u64 << 0;
924/// The value that represents the memory-write permission.
925pub const HV_MEMORY_WRITE: hv_memory_flags_t = 1u64 << 1;
926/// The value that represents the memory-execute permission.
927pub const HV_MEMORY_EXEC: hv_memory_flags_t = 1u64 << 2;
928
929extern "C" {
930    /// Maps a region in the virtual address space of the current process into the guest physical
931    /// address space of the VM.
932    ///
933    /// # Parameters
934    ///
935    /// * `addr`: The address in the current process. It must be page-aligned.
936    /// * `ipa`: The address in the intermediate physical address space. It must be page-aligned.
937    /// * `size`: The size of the mapped region in bytes. It must be a multiple of the page size.
938    /// * `flags`: The permissions for the mapped region. For a list of valid options, see
939    ///            [`hv_memory_flags_t`].
940    ///
941    /// # Return Value
942    ///
943    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
944    /// [`hv_return_t`].
945    pub fn hv_vm_map(
946        addr: *const c_void,
947        ipa: hv_ipa_t,
948        size: usize,
949        flags: hv_memory_flags_t,
950    ) -> hv_return_t;
951
952    /// Unmaps a region in the guest physical address space of the VM.
953    ///
954    /// # Parameters
955    ///
956    /// * `ipa`: The address in the intermediate physical address space. It must be page-aligned.
957    /// * `size`: The size of the region to unmap, in bytes. It must be a multiple of the page
958    ///           size.
959    ///
960    /// # Return Value
961    ///
962    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
963    /// [`hv_return_t`].
964    pub fn hv_vm_unmap(ipa: hv_ipa_t, size: usize) -> hv_return_t;
965
966    /// Modifies the permissions of a region in the guest physical address space of the VM.
967    ///
968    /// # Parameters
969    ///
970    /// * `ipa`: The address in the intermediate physical address space. It must be page-aligned.
971    /// * `size`: The size of the region to unmap, in bytes. It must be a multiple of the page
972    ///           size.
973    /// * `flags`: The permissions for the protected region. For a list of valid options, see
974    ///            [`hv_memory_flags_t.
975    ///
976    /// # Return Value
977    ///
978    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
979    /// [`hv_return_t`].
980    pub fn hv_vm_protect(ipa: hv_ipa_t, size: usize, flags: hv_memory_flags_t) -> hv_return_t;
981}
982
983// -----------------------------------------------------------------------------------------------
984// Timer Functions
985// -----------------------------------------------------------------------------------------------
986
987extern "C" {
988    /// Gets the virtual timer mask.
989    ///
990    /// # Parameters
991    ///
992    /// * `vcpu`: The ID of the vCPU instance.
993    /// * `vtimer_is_masked`: The value of the mask.
994    ///
995    /// # Return Value
996    ///
997    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
998    /// [`hv_return_t`].
999    pub fn hv_vcpu_get_vtimer_mask(vcpu: hv_vcpu_t, vtimer_is_masked: *mut bool) -> hv_return_t;
1000
1001    /// Sets or clears the virtual timer mask.
1002    ///
1003    /// # Parameters
1004    ///
1005    /// * `vcpu`: The ID of the vCPU instance.
1006    /// * `vtimer_is_masked`: A Boolean value that indicates whether the vTimer has a mask set.
1007    ///
1008    /// # Return Value
1009    ///
1010    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
1011    /// [`hv_return_t`].
1012    pub fn hv_vcpu_set_vtimer_mask(vcpu: hv_vcpu_t, vtimer_is_masked: bool) -> hv_return_t;
1013
1014    /// Returns the vTimer offset for the vCPU ID you specify.
1015    ///
1016    /// # Parameters
1017    ///
1018    /// * `vcpu`: The ID of the vCPU instance.
1019    /// * `vtimer_offset`: A pointer to vTimer offset; the Hypervisor writes to this value on
1020    ///                    success.
1021    ///
1022    /// # Return Value
1023    ///
1024    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
1025    /// [`hv_return_t`].
1026    pub fn hv_vcpu_get_vtimer_offset(vcpu: hv_vcpu_t, vtimer_offset: *mut u64) -> hv_return_t;
1027
1028    /// Sets the vTimer offset to a value that you provide.
1029    ///
1030    /// # Parameters
1031    ///
1032    /// * `vcpu`: The ID of the vCPU instance.
1033    /// * `vtimer_offset`: The new vTimer offset.
1034    ///
1035    /// # Return Value
1036    ///
1037    /// `HV_SUCCESS` if the operation was successful, otherwise an error code specified in
1038    /// [`hv_return_t`].
1039    pub fn hv_vcpu_set_vtimer_offset(vcpu: hv_vcpu_t, vtimer_offset: u64) -> hv_return_t;
1040}
1041
1042#[cfg(test)]
1043mod tests {
1044    // Tests must be run with `--test-threads=1`, since only one VM instance is allowed per
1045    // process. Tests could fail because `hv_vm_create` is called multiple times in concurrent
1046    // threads.
1047
1048    use super::*;
1049    use std::alloc::{alloc, Layout};
1050    use std::ptr;
1051
1052    #[test]
1053    fn vm_create_destroy() {
1054        let config = ptr::null_mut();
1055        // Creates a VM instance for the current process.
1056        let ret = unsafe { hv_vm_create(config) };
1057        assert_eq!(ret, hv_error_t::HV_SUCCESS as i32);
1058        // Trying to create a second instance leads to a HV_BUSY error.
1059        let ret = unsafe { hv_vm_create(config) };
1060        assert_eq!(ret, hv_error_t::HV_BUSY as i32);
1061        // Destroys the process instance.
1062        let ret = unsafe { hv_vm_destroy() };
1063        assert_eq!(ret, hv_error_t::HV_SUCCESS as i32);
1064    }
1065
1066    #[test]
1067    pub fn vcpu_create_destroy() {
1068        let config = ptr::null_mut();
1069        // Creates a VM instance for the current process.
1070        let ret = unsafe { hv_vm_create(config) };
1071        assert_eq!(ret, hv_error_t::HV_SUCCESS as i32);
1072        // Retrieves the maximum number of vCPU.
1073        let mut max_vcpu_count = 0;
1074        let ret = unsafe { hv_vm_get_max_vcpu_count(&mut max_vcpu_count) };
1075        assert_eq!(ret, hv_error_t::HV_SUCCESS as i32);
1076        // Creates a vCPU.
1077        let mut vcpu: hv_vcpu_t = 0;
1078        let layout = Layout::new::<hv_vcpu_exit_t>();
1079        let ret = unsafe {
1080            let exit = alloc(layout) as *mut *const hv_vcpu_exit_t;
1081            hv_vcpu_create(&mut vcpu, exit, config)
1082        };
1083        assert_eq!(ret, hv_error_t::HV_SUCCESS as i32);
1084        // Destroys a vCPU.
1085        let ret = unsafe { hv_vcpu_destroy(vcpu) };
1086        assert_eq!(ret, hv_error_t::HV_SUCCESS as i32);
1087        // Destroys the process instance.
1088        let ret = unsafe { hv_vm_destroy() };
1089        assert_eq!(ret, hv_error_t::HV_SUCCESS as i32);
1090    }
1091}