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}