whp/
abi.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4#![expect(non_camel_case_types, non_snake_case, non_upper_case_globals)]
5
6mod arm64;
7mod x64;
8
9#[cfg(target_arch = "aarch64")]
10pub use arm64::*;
11#[cfg(target_arch = "x86_64")]
12pub use x64::*;
13
14use std::ffi::c_void;
15use std::fmt::Debug;
16use std::fmt::Display;
17use winapi::shared::ntdef::LUID;
18
19macro_rules! bitops_base {
20    ($t:ty) => {
21        impl std::ops::BitOr for $t {
22            type Output = Self;
23            fn bitor(mut self, rhs: Self) -> Self {
24                self |= rhs;
25                self
26            }
27        }
28
29        impl std::ops::BitAnd for $t {
30            type Output = Self;
31            fn bitand(mut self, rhs: Self) -> Self {
32                self &= rhs;
33                self
34            }
35        }
36    };
37}
38
39pub(crate) use bitops_base;
40
41macro_rules! bitops {
42    ($t:ty) => {
43        bitops_base!($t);
44        impl $t {
45            pub fn is_empty(&self) -> bool {
46                self.0 == 0
47            }
48            pub fn is_set(&self, v: Self) -> bool {
49                self.0 & v.0 == v.0
50            }
51        }
52        impl std::ops::BitOrAssign for $t {
53            fn bitor_assign(&mut self, rhs: Self) {
54                self.0 |= rhs.0;
55            }
56        }
57        impl std::ops::BitAndAssign for $t {
58            fn bitand_assign(&mut self, rhs: Self) {
59                self.0 &= rhs.0;
60            }
61        }
62        impl std::ops::Not for $t {
63            type Output = Self;
64
65            fn not(self) -> Self {
66                Self(!self.0)
67            }
68        }
69    };
70}
71
72pub(crate) use bitops;
73
74#[repr(C)]
75#[derive(Copy, Clone, Debug, PartialEq, Eq)]
76pub struct WHV_CAPABILITY_CODE(pub u32);
77
78// Capabilities of the API implementation
79pub const WHvCapabilityCodeHypervisorPresent: WHV_CAPABILITY_CODE = WHV_CAPABILITY_CODE(0x00000000);
80pub const WHvCapabilityCodeFeatures: WHV_CAPABILITY_CODE = WHV_CAPABILITY_CODE(0x00000001);
81pub const WHvCapabilityCodeExtendedVmExits: WHV_CAPABILITY_CODE = WHV_CAPABILITY_CODE(0x00000002);
82#[cfg(target_arch = "x86_64")]
83pub const WHvCapabilityCodeExceptionExitBitmap: WHV_CAPABILITY_CODE =
84    WHV_CAPABILITY_CODE(0x00000003);
85#[cfg(target_arch = "x86_64")]
86pub const WHvCapabilityCodeX64MsrExitBitmap: WHV_CAPABILITY_CODE = WHV_CAPABILITY_CODE(0x00000004);
87pub const WHvCapabilityCodeGpaRangePopulateFlags: WHV_CAPABILITY_CODE =
88    WHV_CAPABILITY_CODE(0x00000005);
89pub const WHvCapabilityCodeSchedulerFeatures: WHV_CAPABILITY_CODE = WHV_CAPABILITY_CODE(0x00000006);
90
91// Capabilities of the system's processor
92pub const WHvCapabilityCodeProcessorVendor: WHV_CAPABILITY_CODE = WHV_CAPABILITY_CODE(0x00001000);
93pub const WHvCapabilityCodeProcessorFeatures: WHV_CAPABILITY_CODE = WHV_CAPABILITY_CODE(0x00001001);
94pub const WHvCapabilityCodeProcessorClFlushSize: WHV_CAPABILITY_CODE =
95    WHV_CAPABILITY_CODE(0x00001002);
96#[cfg(target_arch = "x86_64")]
97pub const WHvCapabilityCodeProcessorXsaveFeatures: WHV_CAPABILITY_CODE =
98    WHV_CAPABILITY_CODE(0x00001003);
99pub const WHvCapabilityCodeProcessorClockFrequency: WHV_CAPABILITY_CODE =
100    WHV_CAPABILITY_CODE(0x00001004);
101#[cfg(target_arch = "x86_64")]
102pub const WHvCapabilityCodeInterruptClockFrequency: WHV_CAPABILITY_CODE =
103    WHV_CAPABILITY_CODE(0x00001005);
104pub const WHvCapabilityCodeProcessorFeaturesBanks: WHV_CAPABILITY_CODE =
105    WHV_CAPABILITY_CODE(0x00001006);
106pub const WHvCapabilityCodeProcessorFrequencyCap: WHV_CAPABILITY_CODE =
107    WHV_CAPABILITY_CODE(0x00001007);
108pub const WHvCapabilityCodeSyntheticProcessorFeaturesBanks: WHV_CAPABILITY_CODE =
109    WHV_CAPABILITY_CODE(0x00001008);
110#[cfg(target_arch = "x86_64")]
111pub const WHvCapabilityCodePerfmonFeatures: WHV_CAPABILITY_CODE = WHV_CAPABILITY_CODE(0x00001009);
112
113pub struct WHV_CAPABILITY_FEATURES(pub u64);
114bitops!(WHV_CAPABILITY_FEATURES);
115
116impl WHV_CAPABILITY_FEATURES {
117    pub const PartialUnmap: Self = Self(1 << 0);
118    #[cfg(target_arch = "x86_64")]
119    pub const LocalApicEmulation: Self = Self(1 << 1);
120    #[cfg(target_arch = "x86_64")]
121    pub const Xsave: Self = Self(1 << 2);
122    pub const DirtyPageTracking: Self = Self(1 << 3);
123    pub const SpeculationControl: Self = Self(1 << 4);
124    #[cfg(target_arch = "x86_64")]
125    pub const ApicRemoteRead: Self = Self(1 << 5);
126    pub const IdleSuspend: Self = Self(1 << 6);
127    pub const VirtualPciDeviceSupport: Self = Self(1 << 7);
128    pub const IommuSupport: Self = Self(1 << 8);
129    pub const VpHotAddSupport: Self = Self(1 << 9);
130}
131
132#[repr(C)]
133#[derive(Clone, Copy, Debug, PartialEq, Eq)]
134pub struct WHV_PROCESSOR_VENDOR(pub u32);
135
136pub const WHvProcessorVendorAmd: WHV_PROCESSOR_VENDOR = WHV_PROCESSOR_VENDOR(0x0000);
137pub const WHvProcessorVendorIntel: WHV_PROCESSOR_VENDOR = WHV_PROCESSOR_VENDOR(0x0001);
138pub const WHvProcessorVendorHygon: WHV_PROCESSOR_VENDOR = WHV_PROCESSOR_VENDOR(0x0002);
139pub const WHvProcessorVendorArm: WHV_PROCESSOR_VENDOR = WHV_PROCESSOR_VENDOR(0x0010);
140
141#[repr(C)]
142#[derive(Debug, Copy, Clone)]
143pub struct WHV_CAPABILITY_PROCESSOR_FREQUENCY_CAP {
144    pub Flags: u32,
145    pub HighestFrequencyMhz: u32,
146    pub NominalFrequencyMhz: u32,
147    pub LowestFrequencyMhz: u32,
148    pub FrequencyStepMhz: u32,
149}
150
151impl WHV_CAPABILITY_PROCESSOR_FREQUENCY_CAP {
152    pub fn IsSupported(&self) -> bool {
153        (self.Flags & 1) != 0
154    }
155}
156
157#[repr(C)]
158#[derive(Clone, Copy)]
159pub struct WHV_PARTITION_HANDLE(pub isize);
160
161impl Debug for WHV_PARTITION_HANDLE {
162    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
163        f.debug_struct("WHV_PARTITION_HANDLE").finish()
164    }
165}
166
167#[repr(C)]
168#[derive(Debug, Copy, Clone)]
169pub struct WHV_MAP_GPA_RANGE_FLAGS(pub u32);
170bitops!(WHV_MAP_GPA_RANGE_FLAGS);
171
172pub const WHvMapGpaRangeFlagNone: WHV_MAP_GPA_RANGE_FLAGS = WHV_MAP_GPA_RANGE_FLAGS(0x00000000);
173pub const WHvMapGpaRangeFlagRead: WHV_MAP_GPA_RANGE_FLAGS = WHV_MAP_GPA_RANGE_FLAGS(0x00000001);
174pub const WHvMapGpaRangeFlagWrite: WHV_MAP_GPA_RANGE_FLAGS = WHV_MAP_GPA_RANGE_FLAGS(0x00000002);
175pub const WHvMapGpaRangeFlagExecute: WHV_MAP_GPA_RANGE_FLAGS = WHV_MAP_GPA_RANGE_FLAGS(0x00000004);
176pub const WHvMapGpaRangeFlagTrackDirtyPages: WHV_MAP_GPA_RANGE_FLAGS =
177    WHV_MAP_GPA_RANGE_FLAGS(0x00000008);
178
179#[repr(transparent)]
180#[derive(Debug, Copy, Clone)]
181pub struct WHV_PARTITION_PROPERTY_CODE(u32);
182
183pub const WHvPartitionPropertyCodeExtendedVmExits: WHV_PARTITION_PROPERTY_CODE =
184    WHV_PARTITION_PROPERTY_CODE(0x00000001);
185#[cfg(target_arch = "x86_64")]
186pub const WHvPartitionPropertyCodeExceptionExitBitmap: WHV_PARTITION_PROPERTY_CODE =
187    WHV_PARTITION_PROPERTY_CODE(0x00000002);
188pub const WHvPartitionPropertyCodeSeparateSecurityDomain: WHV_PARTITION_PROPERTY_CODE =
189    WHV_PARTITION_PROPERTY_CODE(0x00000003);
190#[cfg(target_arch = "x86_64")]
191pub const WHvPartitionPropertyCodeX64MsrExitBitmap: WHV_PARTITION_PROPERTY_CODE =
192    WHV_PARTITION_PROPERTY_CODE(0x00000005);
193pub const WHvPartitionPropertyCodePrimaryNumaNode: WHV_PARTITION_PROPERTY_CODE =
194    WHV_PARTITION_PROPERTY_CODE(0x00000006);
195pub const WHvPartitionPropertyCodeCpuReserve: WHV_PARTITION_PROPERTY_CODE =
196    WHV_PARTITION_PROPERTY_CODE(0x00000007);
197pub const WHvPartitionPropertyCodeCpuCap: WHV_PARTITION_PROPERTY_CODE =
198    WHV_PARTITION_PROPERTY_CODE(0x00000008);
199pub const WHvPartitionPropertyCodeCpuWeight: WHV_PARTITION_PROPERTY_CODE =
200    WHV_PARTITION_PROPERTY_CODE(0x00000009);
201pub const WHvPartitionPropertyCodeCpuGroupId: WHV_PARTITION_PROPERTY_CODE =
202    WHV_PARTITION_PROPERTY_CODE(0x0000000a);
203pub const WHvPartitionPropertyCodeProcessorFrequencyCap: WHV_PARTITION_PROPERTY_CODE =
204    WHV_PARTITION_PROPERTY_CODE(0x0000000b);
205pub const WHvPartitionPropertyCodeAllowDeviceAssignment: WHV_PARTITION_PROPERTY_CODE =
206    WHV_PARTITION_PROPERTY_CODE(0x0000000c);
207pub const WHvPartitionPropertyCodeDisableSmt: WHV_PARTITION_PROPERTY_CODE =
208    WHV_PARTITION_PROPERTY_CODE(0x0000000d);
209
210pub const WHvPartitionPropertyCodeProcessorFeatures: WHV_PARTITION_PROPERTY_CODE =
211    WHV_PARTITION_PROPERTY_CODE(0x00001001);
212pub const WHvPartitionPropertyCodeProcessorClFlushSize: WHV_PARTITION_PROPERTY_CODE =
213    WHV_PARTITION_PROPERTY_CODE(0x00001002);
214#[cfg(target_arch = "x86_64")]
215pub const WHvPartitionPropertyCodeCpuidExitList: WHV_PARTITION_PROPERTY_CODE =
216    WHV_PARTITION_PROPERTY_CODE(0x00001003);
217#[cfg(target_arch = "x86_64")]
218pub const WHvPartitionPropertyCodeCpuidResultList: WHV_PARTITION_PROPERTY_CODE =
219    WHV_PARTITION_PROPERTY_CODE(0x00001004);
220#[cfg(target_arch = "x86_64")]
221pub const WHvPartitionPropertyCodeLocalApicEmulationMode: WHV_PARTITION_PROPERTY_CODE =
222    WHV_PARTITION_PROPERTY_CODE(0x00001005);
223#[cfg(target_arch = "x86_64")]
224pub const WHvPartitionPropertyCodeProcessorXsaveFeatures: WHV_PARTITION_PROPERTY_CODE =
225    WHV_PARTITION_PROPERTY_CODE(0x00001006);
226pub const WHvPartitionPropertyCodeProcessorClockFrequency: WHV_PARTITION_PROPERTY_CODE =
227    WHV_PARTITION_PROPERTY_CODE(0x00001007);
228#[cfg(target_arch = "x86_64")]
229pub const WHvPartitionPropertyCodeInterruptClockFrequency: WHV_PARTITION_PROPERTY_CODE =
230    WHV_PARTITION_PROPERTY_CODE(0x00001008);
231#[cfg(target_arch = "x86_64")]
232pub const WHvPartitionPropertyCodeApicRemoteReadSupport: WHV_PARTITION_PROPERTY_CODE =
233    WHV_PARTITION_PROPERTY_CODE(0x00001009);
234pub const WHvPartitionPropertyCodeProcessorFeaturesBanks: WHV_PARTITION_PROPERTY_CODE =
235    WHV_PARTITION_PROPERTY_CODE(0x0000100A);
236pub const WHvPartitionPropertyCodeReferenceTime: WHV_PARTITION_PROPERTY_CODE =
237    WHV_PARTITION_PROPERTY_CODE(0x0000100B);
238pub const WHvPartitionPropertyCodeSyntheticProcessorFeaturesBanks: WHV_PARTITION_PROPERTY_CODE =
239    WHV_PARTITION_PROPERTY_CODE(0x0000100C);
240#[cfg(target_arch = "x86_64")]
241pub const WHvPartitionPropertyCodeCpuidResultList2: WHV_PARTITION_PROPERTY_CODE =
242    WHV_PARTITION_PROPERTY_CODE(0x0000100D);
243#[cfg(target_arch = "x86_64")]
244pub const WHvPartitionPropertyCodeProcessorPerfmonFeatures: WHV_PARTITION_PROPERTY_CODE =
245    WHV_PARTITION_PROPERTY_CODE(0x0000100E);
246#[cfg(target_arch = "x86_64")]
247pub const WHvPartitionPropertyCodeMsrActionList: WHV_PARTITION_PROPERTY_CODE =
248    WHV_PARTITION_PROPERTY_CODE(0x0000100F);
249#[cfg(target_arch = "x86_64")]
250pub const WHvPartitionPropertyCodeUnimplementedMsrAction: WHV_PARTITION_PROPERTY_CODE =
251    WHV_PARTITION_PROPERTY_CODE(0x00001010);
252pub const WHvPartitionPropertyCodePhysicalAddressWidth: WHV_PARTITION_PROPERTY_CODE =
253    WHV_PARTITION_PROPERTY_CODE(0x00001011);
254pub const WHvPartitionPropertyCodeArm64IcParameters: WHV_PARTITION_PROPERTY_CODE =
255    WHV_PARTITION_PROPERTY_CODE(0x00001012);
256pub const WHvPartitionPropertyCodeProcessorCount: WHV_PARTITION_PROPERTY_CODE =
257    WHV_PARTITION_PROPERTY_CODE(0x00001fff);
258
259#[repr(transparent)]
260#[derive(Clone, Copy, Debug, Eq, PartialEq)]
261pub struct WHV_REGISTER_NAME(pub u32);
262
263#[repr(C)]
264#[derive(Clone, Copy, Debug, Eq, PartialEq, Default)]
265pub struct WHV_REGISTER_VALUE(pub WHV_UINT128);
266
267#[repr(transparent)]
268#[derive(Debug, Copy, Clone)]
269pub struct WHV_ADVISE_GPA_RANGE_CODE(u32);
270
271pub const WHvAdviseGpaRangeCodePopulate: WHV_ADVISE_GPA_RANGE_CODE =
272    WHV_ADVISE_GPA_RANGE_CODE(0x00000000);
273pub const WHvAdviseGpaRangeCodePin: WHV_ADVISE_GPA_RANGE_CODE =
274    WHV_ADVISE_GPA_RANGE_CODE(0x00000001);
275pub const WHvAdviseGpaRangeCodeUnpin: WHV_ADVISE_GPA_RANGE_CODE =
276    WHV_ADVISE_GPA_RANGE_CODE(0x00000002);
277
278#[repr(C)]
279#[derive(Copy, Clone)]
280pub struct WHV_RUN_VP_EXIT_CONTEXT {
281    pub ExitReason: WHV_RUN_VP_EXIT_REASON,
282    pub Reserved: u32,
283    #[cfg(target_arch = "x86_64")]
284    pub VpContext: WHV_VP_EXIT_CONTEXT,
285    #[cfg(all(target_arch = "aarch64", feature = "unstable_whp"))]
286    pub Reserved1: u64,
287    pub u: WHV_RUN_VP_EXIT_CONTEXT_u,
288}
289
290#[repr(C)]
291#[derive(Debug, Copy, Clone, Default)]
292pub struct WHV_ADVISE_GPA_RANGE_POPULATE_FLAGS(pub u32);
293bitops!(WHV_ADVISE_GPA_RANGE_POPULATE_FLAGS);
294
295impl WHV_ADVISE_GPA_RANGE_POPULATE_FLAGS {
296    pub const Prefetch: Self = Self(0x1);
297    pub const AvoidHardFaults: Self = Self(0x2);
298}
299
300#[repr(C)]
301#[derive(Debug, Copy, Clone)]
302pub struct WHV_ADVISE_GPA_RANGE_POPULATE {
303    pub Flags: WHV_ADVISE_GPA_RANGE_POPULATE_FLAGS,
304    pub AccessType: WHV_MEMORY_ACCESS_TYPE,
305}
306
307#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)]
308pub struct WHV_EXTENDED_VM_EXITS(pub u64);
309bitops!(WHV_EXTENDED_VM_EXITS);
310
311impl WHV_EXTENDED_VM_EXITS {
312    #[cfg(target_arch = "x86_64")]
313    pub const X64CpuidExit: Self = Self(1 << 0);
314    #[cfg(target_arch = "x86_64")]
315    pub const X64MsrExit: Self = Self(1 << 1);
316    #[cfg(target_arch = "x86_64")]
317    pub const ExceptionExit: Self = Self(1 << 2);
318    #[cfg(target_arch = "x86_64")]
319    pub const X64RdtscExit: Self = Self(1 << 3);
320    #[cfg(target_arch = "x86_64")]
321    pub const X64ApicSmiExitTrap: Self = Self(1 << 4);
322    pub const HypercallExit: Self = Self(1 << 5);
323    #[cfg(target_arch = "x86_64")]
324    pub const X64ApicInitSipiExitTrap: Self = Self(1 << 6);
325    #[cfg(target_arch = "x86_64")]
326    pub const X64ApicWriteLint0ExitTrap: Self = Self(1 << 7);
327    #[cfg(target_arch = "x86_64")]
328    pub const X64ApicWriteLint1ExitTrap: Self = Self(1 << 8);
329    #[cfg(target_arch = "x86_64")]
330    pub const X64ApicWriteSvrExitTrap: Self = Self(1 << 9);
331    pub const UnknownSynicConnection: Self = Self(1 << 10);
332    pub const RetargetUnknownVpciDevice: Self = Self(1 << 11);
333    #[cfg(target_arch = "x86_64")]
334    pub const X64ApicWriteLdrExitTrap: Self = Self(1 << 12);
335    #[cfg(target_arch = "x86_64")]
336    pub const X64ApicWriteDfrExitTrap: Self = Self(1 << 13);
337    pub const GpaAccessFaultExit: Self = Self(1 << 14);
338}
339
340#[repr(C)]
341#[derive(Debug, Copy, Clone)]
342pub struct WHV_PROCESSOR_FEATURES_BANKS {
343    pub BanksCount: u32,
344    pub Reserved0: u32,
345    pub Banks: [u64; 2],
346}
347
348#[derive(Debug, Copy, Clone, Default, Eq, PartialEq)]
349pub struct WHV_PROCESSOR_FEATURES(pub u64);
350bitops!(WHV_PROCESSOR_FEATURES);
351
352#[repr(C)]
353#[derive(Debug, Copy, Clone, Default, Eq, PartialEq)]
354pub struct WHV_PROCESSOR_FEATURES1(pub u64);
355bitops!(WHV_PROCESSOR_FEATURES1);
356
357#[derive(Debug, Copy, Clone)]
358pub struct WHV_PROCESSOR_XSAVE_FEATURES(pub u64);
359bitops!(WHV_PROCESSOR_XSAVE_FEATURES);
360
361impl WHV_PROCESSOR_XSAVE_FEATURES {
362    pub const XsaveSupport: Self = Self(1 << 0);
363    pub const XsaveoptSupport: Self = Self(1 << 1);
364    pub const AvxSupport: Self = Self(1 << 2);
365    pub const Avx2Support: Self = Self(1 << 3);
366    pub const FmaSupport: Self = Self(1 << 4);
367    pub const MpxSupport: Self = Self(1 << 5);
368    pub const Avx512Support: Self = Self(1 << 6);
369    pub const Avx512DqSupport: Self = Self(1 << 7);
370    pub const Avx512CdSupport: Self = Self(1 << 8);
371    pub const Avx512BwSupport: Self = Self(1 << 9);
372    pub const Avx512VlSupport: Self = Self(1 << 10);
373    pub const XsaveCompSupport: Self = Self(1 << 11);
374    pub const XsaveSupervisorSupport: Self = Self(1 << 12);
375    pub const Xcr1Support: Self = Self(1 << 13);
376    pub const Avx512BitalgSupport: Self = Self(1 << 14);
377    pub const Avx512IfmaSupport: Self = Self(1 << 15);
378    pub const Avx512VBmiSupport: Self = Self(1 << 16);
379    pub const Avx512VBmi2Support: Self = Self(1 << 17);
380    pub const Avx512VnniSupport: Self = Self(1 << 18);
381    pub const GfniSupport: Self = Self(1 << 19);
382    pub const VaesSupport: Self = Self(1 << 20);
383    pub const Avx512VPopcntdqSupport: Self = Self(1 << 21);
384    pub const VpclmulqdqSupport: Self = Self(1 << 22);
385    pub const Avx512Bf16Support: Self = Self(1 << 23);
386    pub const Avx512Vp2IntersectSupport: Self = Self(1 << 24);
387    pub const Avx512Fp16Support: Self = Self(1 << 25);
388    pub const XfdSupport: Self = Self(1 << 26);
389    pub const AmxTileSupport: Self = Self(1 << 27);
390    pub const AmxBf16Support: Self = Self(1 << 28);
391    pub const AmxInt8Support: Self = Self(1 << 29);
392    pub const AvxVnniSupport: Self = Self(1 << 30);
393}
394
395#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
396pub struct WHV_SYNTHETIC_PROCESSOR_FEATURES(pub u64);
397bitops!(WHV_SYNTHETIC_PROCESSOR_FEATURES);
398
399impl WHV_SYNTHETIC_PROCESSOR_FEATURES {
400    /// Report a hypervisor is present. CPUID leaves
401    /// 0x40000000 and 0x40000001 are supported.
402    pub const HypervisorPresent: Self = Self(1 << 0);
403
404    /// Report support for Hv1 (CPUID leaves 0x40000000 - 0x40000006).
405    pub const Hv1: Self = Self(1 << 1);
406
407    /// Access to HV_X64_MSR_VP_RUNTIME.
408    /// Corresponds to AccessVpRunTimeReg privilege.
409    pub const AccessVpRunTimeReg: Self = Self(1 << 2);
410
411    /// Access to HV_X64_MSR_TIME_REF_COUNT.
412    /// Corresponds to AccessPartitionReferenceCounter privilege.
413    pub const AccessPartitionReferenceCounter: Self = Self(1 << 3);
414
415    /// Access to SINT-related registers (HV_X64_MSR_SCONTROL through
416    /// HV_X64_MSR_EOM and HV_X64_MSR_SINT0 through HV_X64_MSR_SINT15).
417    /// Corresponds to AccessSynicRegs privilege.
418    pub const AccessSynicRegs: Self = Self(1 << 4);
419
420    /// Access to synthetic timers and associated MSRs
421    /// (HV_X64_MSR_STIMER0_CONFIG through HV_X64_MSR_STIMER3_COUNT).
422    /// Corresponds to AccessSyntheticTimerRegs privilege.
423    pub const AccessSyntheticTimerRegs: Self = Self(1 << 5);
424
425    /// Access to APIC MSRs (HV_X64_MSR_EOI, HV_X64_MSR_ICR and HV_X64_MSR_TPR)
426    /// as well as the VP assist page.
427    /// Corresponds to AccessIntrCtrlRegs privilege.
428    pub const AccessIntrCtrlRegs: Self = Self(1 << 6);
429
430    /// Access to registers associated with hypercalls (HV_X64_MSR_GUEST_OS_ID
431    /// and HV_X64_MSR_HYPERCALL).
432    /// Corresponds to AccessHypercallMsrs privilege.
433    pub const AccessHypercallRegs: Self = Self(1 << 7);
434
435    /// VP index can be queried. Corresponds to AccessVpIndex privilege.
436    pub const AccessVpIndex: Self = Self(1 << 8);
437
438    /// Access to the reference TSC. Corresponds to AccessPartitionReferenceTsc
439    /// privilege.
440    pub const AccessPartitionReferenceTsc: Self = Self(1 << 9);
441
442    /// Partition has access to the guest idle reg. Corresponds to
443    /// AccessGuestIdleReg privilege.
444    ///
445    #[cfg(target_arch = "x86_64")]
446    pub const AccessGuestIdleReg: Self = Self(1 << 10);
447
448    /// Partition has access to frequency regs. Corresponds to AccessFrequencyRegs
449    /// privilege.
450    #[cfg(target_arch = "x86_64")]
451    pub const AccessFrequencyRegs: Self = Self(1 << 11);
452
453    // pub const ReservedZ12: Self = Self(1 << 12);
454    // pub const ReservedZ13: Self = Self(1 << 13);
455    // pub const ReservedZ14: Self = Self(1 << 14);
456
457    /// Extended GVA ranges for HvCallFlushVirtualAddressList hypercall.
458    /// Corresponds to privilege.
459    #[cfg(target_arch = "x86_64")]
460    pub const EnableExtendedGvaRangesForFlushVirtualAddressList: Self = Self(1 << 15);
461
462    // pub const ReservedZ16: Self = Self(1 << 16);
463    // pub const ReservedZ17: Self = Self(1 << 17);
464
465    /// Use fast hypercall output. Corresponds to privilege.
466    pub const FastHypercallOutput: Self = Self(1 << 18);
467
468    // pub const ReservedZ19: Self = Self(1 << 19);
469
470    // pub const ReservedZ20: Self = Self(1 << 20);
471
472    // pub const ReservedZ21: Self = Self(1 << 21);
473
474    /// Synthetic timers in direct mode.
475    pub const DirectSyntheticTimers: Self = Self(1 << 22);
476
477    // pub const ReservedZ23: Self = Self(1 << 23);
478
479    /// Use extended processor masks.
480    pub const ExtendedProcessorMasks: Self = Self(1 << 24);
481
482    // On AMD64, HvCallFlushVirtualAddressSpace / HvCallFlushVirtualAddressList are supported, on
483    // ARM64 HvCallFlushVirtualAddressSpace / HvCallFlushTlb are supported.
484    pub const TbFlushHypercalls: Self = Self(1 << 25);
485
486    /// HvCallSendSyntheticClusterIpi is supported.
487    pub const SyntheticClusterIpi: Self = Self(1 << 26);
488
489    /// HvCallNotifyLongSpinWait is supported.
490    pub const NotifyLongSpinWait: Self = Self(1 << 27);
491
492    /// HvCallQueryNumaDistance is supported.
493    pub const QueryNumaDistance: Self = Self(1 << 28);
494
495    /// HvCallSignalEvent is supported. Corresponds to privilege.
496    pub const SignalEvents: Self = Self(1 << 29);
497
498    /// HvCallRetargetDeviceInterrupt is supported.
499    pub const RetargetDeviceInterrupt: Self = Self(1 << 30);
500
501    /// HvCallRestorePartitionTime is supported.
502    #[cfg(target_arch = "x86_64")]
503    pub const RestoreTime: Self = Self(1 << 31);
504
505    /// EnlightenedVmcs nested enlightenment is supported.
506    #[cfg(target_arch = "x86_64")]
507    pub const EnlightenedVmcs: Self = Self(1 << 32);
508
509    /// Non-zero values can be written to DEBUG_CTL.
510    #[cfg(target_arch = "x86_64")]
511    pub const NestedDebugCtl: Self = Self(1 << 33);
512
513    /// Synthetic time-unhalted timer MSRs are supported.
514    #[cfg(target_arch = "x86_64")]
515    pub const SyntheticTimeUnhaltedTimer: Self = Self(1 << 34);
516
517    /// SPEC_CTRL MSR behavior when the VP is idle
518    #[cfg(target_arch = "x86_64")]
519    pub const IdleSpecCtrl: Self = Self(1 << 35);
520
521    /// Register intercepts supported in V1. As more registers are supported in the future
522    /// releases, new bits will be added here to prevent migration between incompatible hosts.
523    ///
524    /// List of registers supported in V1.
525    /// 1. TPIDRRO_EL0
526    /// 2. TPIDR_EL1
527    /// 3. SCTLR_EL1 - Supports write intercept mask.
528    /// 4. VBAR_EL1
529    /// 5. TCR_EL1 - Supports write intercept mask.
530    /// 6. MAIR_EL1 - Supports write intercept mask.
531    /// 7. CPACR_EL1 - Supports write intercept mask.
532    /// 8. CONTEXTIDR_EL1
533    /// 9. PAuth keys(total 10 registers)
534    /// 10. HvArm64RegisterSyntheticException
535    #[cfg(target_arch = "aarch64")]
536    pub const RegisterInterceptsV1: Self = Self(1 << 36);
537
538    /// HvCallWakeVps is supported.
539    pub const WakeVps: Self = Self(1 << 37);
540
541    /// HvCallGet/SetVpRegisters is supported.
542    /// Corresponds to the AccessVpRegisters privilege.
543    /// This feature only affects exo partitions.
544    pub const AccessVpRegs: Self = Self(1 << 38);
545
546    /// HvCallSyncContext/Ex is supported.
547    #[cfg(target_arch = "aarch64")]
548    pub const SyncContext: Self = Self(1 << 39);
549
550    /// Management VTL synic support is allowed.
551    /// Corresponds to the ManagementVtlSynicSupport privilege.
552    pub const ManagementVtlSynicSupport: Self = Self(1 << 40);
553
554    /// Hypervisor supports guest mechanism to signal pending interrupts to paravisor.
555    #[cfg(target_arch = "x86_64")]
556    pub const ProxyInterruptDoorbellSupport: Self = Self(1 << 41);
557
558    /// InterceptSystemResetAvailable is exposed.
559    #[cfg(target_arch = "aarch64")]
560    pub const InterceptSystemReset: Self = Self(1 << 42);
561
562    /// Hypercalls for host MMIO operations are available.
563    pub const MmioHypercalls: Self = Self(1 << 43);
564
565    /// SPIs are advertised to VTL2.
566    #[cfg(target_arch = "aarch64")]
567    pub const ManagementVtlSpiSupport: Self = Self(1 << 44);
568}
569
570#[repr(C)]
571#[derive(Debug, Copy, Clone)]
572pub struct WHV_SYNTHETIC_PROCESSOR_FEATURES_BANKS {
573    pub BanksCount: u32,
574    pub Reserved0: u32,
575    pub Banks: [u64; 1],
576}
577
578#[repr(C)]
579#[derive(Debug, Copy, Clone)]
580pub struct WHV_TRANSLATE_GVA_RESULT {
581    pub ResultCode: WHV_TRANSLATE_GVA_RESULT_CODE,
582    pub Reserved: u32,
583}
584
585#[repr(transparent)]
586#[derive(Debug, Copy, Clone, PartialEq, Eq)]
587pub struct WHV_TRANSLATE_GVA_FLAGS(pub u32);
588bitops!(WHV_TRANSLATE_GVA_FLAGS);
589
590pub const WHvTranslateGvaFlagNone: WHV_TRANSLATE_GVA_FLAGS = WHV_TRANSLATE_GVA_FLAGS(0x00000000);
591pub const WHvTranslateGvaFlagValidateRead: WHV_TRANSLATE_GVA_FLAGS =
592    WHV_TRANSLATE_GVA_FLAGS(0x00000001);
593pub const WHvTranslateGvaFlagValidateWrite: WHV_TRANSLATE_GVA_FLAGS =
594    WHV_TRANSLATE_GVA_FLAGS(0x00000002);
595pub const WHvTranslateGvaFlagValidateExecute: WHV_TRANSLATE_GVA_FLAGS =
596    WHV_TRANSLATE_GVA_FLAGS(0x00000004);
597#[cfg(target_arch = "x86_64")]
598pub const WHvTranslateGvaFlagPrivilegeExempt: WHV_TRANSLATE_GVA_FLAGS =
599    WHV_TRANSLATE_GVA_FLAGS(0x00000008);
600pub const WHvTranslateGvaFlagSetPageTableBits: WHV_TRANSLATE_GVA_FLAGS =
601    WHV_TRANSLATE_GVA_FLAGS(0x00000010);
602
603#[repr(C)]
604#[derive(Debug, Copy, Clone, PartialEq, Eq)]
605pub struct WHV_TRANSLATE_GVA_RESULT_CODE(pub u32);
606
607pub const WHvTranslateGvaResultSuccess: WHV_TRANSLATE_GVA_RESULT_CODE =
608    WHV_TRANSLATE_GVA_RESULT_CODE(0);
609
610// Translation failures
611pub const WHvTranslateGvaResultPageNotPresent: WHV_TRANSLATE_GVA_RESULT_CODE =
612    WHV_TRANSLATE_GVA_RESULT_CODE(1);
613pub const WHvTranslateGvaResultPrivilegeViolation: WHV_TRANSLATE_GVA_RESULT_CODE =
614    WHV_TRANSLATE_GVA_RESULT_CODE(2);
615pub const WHvTranslateGvaResultInvalidPageTableFlags: WHV_TRANSLATE_GVA_RESULT_CODE =
616    WHV_TRANSLATE_GVA_RESULT_CODE(3);
617
618// GPA access failures
619pub const WHvTranslateGvaResultGpaUnmapped: WHV_TRANSLATE_GVA_RESULT_CODE =
620    WHV_TRANSLATE_GVA_RESULT_CODE(4);
621pub const WHvTranslateGvaResultGpaNoReadAccess: WHV_TRANSLATE_GVA_RESULT_CODE =
622    WHV_TRANSLATE_GVA_RESULT_CODE(5);
623pub const WHvTranslateGvaResultGpaNoWriteAccess: WHV_TRANSLATE_GVA_RESULT_CODE =
624    WHV_TRANSLATE_GVA_RESULT_CODE(6);
625pub const WHvTranslateGvaResultGpaIllegalOverlayAccess: WHV_TRANSLATE_GVA_RESULT_CODE =
626    WHV_TRANSLATE_GVA_RESULT_CODE(7);
627pub const WHvTranslateGvaResultIntercept: WHV_TRANSLATE_GVA_RESULT_CODE =
628    WHV_TRANSLATE_GVA_RESULT_CODE(8);
629
630#[repr(C)]
631#[derive(Debug, Copy, Clone)]
632pub struct WHV_DOORBELL_MATCH_DATA {
633    pub GuestAddress: u64,
634    pub Value: u64,
635    pub Length: u32,
636    pub Flags: u32,
637}
638
639#[repr(C)]
640#[derive(Debug, Copy, Clone)]
641pub struct WHV_MEMORY_RANGE_ENTRY {
642    pub GuestAddress: u64,
643    pub SizeInBytes: u64,
644}
645
646#[repr(C)]
647#[derive(Debug, Copy, Clone)]
648pub struct WHV_SYNIC_EVENT_PARAMETERS {
649    pub VpIndex: u32,
650    pub TargetSint: u8,
651    pub Reserved: u8,
652    pub FlagNumber: u16,
653}
654
655#[repr(C)]
656#[derive(Debug, Copy, Clone, PartialEq, Eq)]
657pub struct WHV_RUN_VP_EXIT_REASON(pub u32);
658
659#[repr(transparent)]
660#[derive(Debug, Copy, Clone, PartialEq, Eq)]
661pub struct WHV_MEMORY_ACCESS_TYPE(pub u32);
662
663pub const WHvMemoryAccessRead: WHV_MEMORY_ACCESS_TYPE = WHV_MEMORY_ACCESS_TYPE(0);
664pub const WHvMemoryAccessWrite: WHV_MEMORY_ACCESS_TYPE = WHV_MEMORY_ACCESS_TYPE(1);
665pub const WHvMemoryAccessExecute: WHV_MEMORY_ACCESS_TYPE = WHV_MEMORY_ACCESS_TYPE(2);
666
667impl Display for WHV_MEMORY_ACCESS_TYPE {
668    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
669        let string = match *self {
670            WHvMemoryAccessRead => "read",
671            WHvMemoryAccessWrite => "write",
672            WHvMemoryAccessExecute => "execute",
673            _ => "unknown",
674        };
675
676        f.write_str(string)
677    }
678}
679
680#[repr(C, align(16))]
681#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
682pub struct WHV_UINT128([u8; 16]);
683
684impl From<u128> for WHV_UINT128 {
685    fn from(v: u128) -> Self {
686        Self(v.to_ne_bytes())
687    }
688}
689
690impl From<u64> for WHV_UINT128 {
691    fn from(v: u64) -> Self {
692        (v as u128).into()
693    }
694}
695
696impl From<u32> for WHV_UINT128 {
697    fn from(v: u32) -> Self {
698        (v as u128).into()
699    }
700}
701
702impl From<u16> for WHV_UINT128 {
703    fn from(v: u16) -> Self {
704        (v as u128).into()
705    }
706}
707
708impl From<u8> for WHV_UINT128 {
709    fn from(v: u8) -> Self {
710        (v as u128).into()
711    }
712}
713
714impl From<WHV_UINT128> for u128 {
715    fn from(v: WHV_UINT128) -> Self {
716        u128::from_ne_bytes(v.0)
717    }
718}
719
720#[repr(C)]
721#[derive(Debug, Copy, Clone)]
722pub struct WHV_NOTIFICATION_PORT_HANDLE(pub isize);
723
724#[repr(C)]
725#[derive(Debug, Copy, Clone)]
726pub struct WHV_NOTIFICATION_PORT_PROPERTY_CODE(pub u32);
727
728pub const WHvNotificationPortPropertyPreferredTargetVp: WHV_NOTIFICATION_PORT_PROPERTY_CODE =
729    WHV_NOTIFICATION_PORT_PROPERTY_CODE(1);
730pub const WHvNotificationPortPropertyPreferredTargetDuration: WHV_NOTIFICATION_PORT_PROPERTY_CODE =
731    WHV_NOTIFICATION_PORT_PROPERTY_CODE(5);
732
733#[repr(C)]
734#[derive(Debug, Copy, Clone)]
735pub struct WHV_NOTIFICATION_PORT_TYPE(pub u32);
736
737pub const WHvNotificationPortTypeEvent: WHV_NOTIFICATION_PORT_TYPE = WHV_NOTIFICATION_PORT_TYPE(2);
738pub const WHvNotificationPortTypeDoorbell: WHV_NOTIFICATION_PORT_TYPE =
739    WHV_NOTIFICATION_PORT_TYPE(4);
740
741#[repr(C)]
742#[derive(Copy, Clone)]
743pub struct WHV_NOTIFICATION_PORT_PARAMETERS {
744    pub NotificationPortType: WHV_NOTIFICATION_PORT_TYPE,
745    pub Reserved: u32,
746    pub u: WHV_NOTIFICATION_PORT_PARAMETERS_u,
747}
748
749#[repr(C)]
750#[derive(Copy, Clone)]
751pub union WHV_NOTIFICATION_PORT_PARAMETERS_u {
752    pub Doorbell: WHV_DOORBELL_MATCH_DATA,
753    pub Event: WHV_NOTIFICATION_PORT_PARAMETERS_u_Event,
754}
755
756#[repr(C)]
757#[derive(Copy, Clone)]
758pub struct WHV_NOTIFICATION_PORT_PARAMETERS_u_Event {
759    pub ConnectionId: u32,
760}
761
762#[repr(C)]
763#[derive(Debug, Copy, Clone)]
764pub struct WHV_CPUID_OUTPUT {
765    pub Eax: u32,
766    pub Ebx: u32,
767    pub Ecx: u32,
768    pub Edx: u32,
769}
770
771#[repr(C)]
772#[derive(Debug, Copy, Clone)]
773pub struct WHV_VIRTUAL_PROCESSOR_PROPERTY_CODE(u32);
774
775pub const WHvVirtualProcessorPropertyCodeNumaNode: WHV_VIRTUAL_PROCESSOR_PROPERTY_CODE =
776    WHV_VIRTUAL_PROCESSOR_PROPERTY_CODE(0x00000000);
777
778#[repr(C)]
779#[derive(Copy, Clone)]
780pub struct WHV_VIRTUAL_PROCESSOR_PROPERTY {
781    pub PropertyCode: WHV_VIRTUAL_PROCESSOR_PROPERTY_CODE,
782    pub Reserved: u32,
783    pub u: WHV_VIRTUAL_PROCESSOR_PROPERTY_u,
784}
785
786#[repr(C)]
787#[derive(Copy, Clone)]
788pub union WHV_VIRTUAL_PROCESSOR_PROPERTY_u {
789    pub NumaNode: u16,
790    pub Padding: u64,
791}
792
793#[repr(C)]
794#[derive(Debug, Copy, Clone)]
795pub struct WHV_MSR_ACTION_ENTRY {
796    pub Index: u32,
797    pub ReadAction: u8,  // WHV_MSR_ACTION
798    pub WriteAction: u8, // WHV_MSR_ACTION
799    pub Reserved: u16,
800}
801
802#[repr(C)]
803#[derive(Debug, Copy, Clone)]
804pub struct WHV_MSR_ACTION(pub u32);
805
806pub const WHvMsrActionArchitectureDefault: WHV_MSR_ACTION = WHV_MSR_ACTION(0);
807pub const WHvMsrActionIgnoreWriteReadZero: WHV_MSR_ACTION = WHV_MSR_ACTION(1);
808pub const WHvMsrActionExit: WHV_MSR_ACTION = WHV_MSR_ACTION(2);
809
810#[repr(C)]
811#[derive(Debug, Copy, Clone)]
812pub struct WHV_SCHEDULER_FEATURES(pub u32);
813bitops!(WHV_SCHEDULER_FEATURES);
814
815impl WHV_SCHEDULER_FEATURES {
816    pub const CpuReserve: Self = Self(1 << 0);
817    pub const CpuCap: Self = Self(1 << 1);
818    pub const CpuWeight: Self = Self(1 << 2);
819    pub const CpuGroupId: Self = Self(1 << 3);
820    pub const DisableSmt: Self = Self(1 << 4);
821}
822
823#[repr(C)]
824#[derive(Debug, Clone, Copy, Default)]
825pub struct WHV_ALLOCATE_VPCI_RESOURCE_FLAGS(pub u32);
826bitops!(WHV_ALLOCATE_VPCI_RESOURCE_FLAGS);
827
828pub const WHvAllocateVpciResourceFlagAllowDirectP2P: WHV_ALLOCATE_VPCI_RESOURCE_FLAGS =
829    WHV_ALLOCATE_VPCI_RESOURCE_FLAGS(0x00000001);
830
831pub const WHV_MAX_DEVICE_ID_SIZE_IN_CHARS: usize = 200;
832
833#[repr(C)]
834#[derive(Clone, Copy)]
835pub struct WHV_SRIOV_RESOURCE_DESCRIPTOR {
836    pub PnpInstanceId: [u16; WHV_MAX_DEVICE_ID_SIZE_IN_CHARS],
837    pub VirtualFunctionId: LUID,
838    pub VirtualFunctionIndex: u16,
839    pub Reserved: u16,
840}
841
842#[repr(C)]
843#[derive(Debug, Clone, Copy, PartialEq, Eq)]
844pub struct WHV_VPCI_DEVICE_NOTIFICATION_TYPE(pub u32);
845
846pub const WHvVpciDeviceNotificationUndefined: WHV_VPCI_DEVICE_NOTIFICATION_TYPE =
847    WHV_VPCI_DEVICE_NOTIFICATION_TYPE(0);
848pub const WHvVpciDeviceNotificationMmioRemapping: WHV_VPCI_DEVICE_NOTIFICATION_TYPE =
849    WHV_VPCI_DEVICE_NOTIFICATION_TYPE(1);
850pub const WHvVpciDeviceNotificationSurpriseRemoval: WHV_VPCI_DEVICE_NOTIFICATION_TYPE =
851    WHV_VPCI_DEVICE_NOTIFICATION_TYPE(2);
852
853#[repr(C)]
854#[derive(Debug, Clone, Copy)]
855pub struct WHV_VPCI_DEVICE_NOTIFICATION {
856    pub NotificationType: WHV_VPCI_DEVICE_NOTIFICATION_TYPE,
857    pub Reserved1: u32,
858    pub Reserved2: u64,
859}
860
861#[repr(C)]
862#[derive(Debug, Clone, Copy, Default)]
863pub struct WHV_CREATE_VPCI_DEVICE_FLAGS(u32);
864bitops!(WHV_CREATE_VPCI_DEVICE_FLAGS);
865
866pub const WHvCreateVpciDeviceFlagNone: WHV_CREATE_VPCI_DEVICE_FLAGS =
867    WHV_CREATE_VPCI_DEVICE_FLAGS(0x00000000);
868pub const WHvCreateVpciDeviceFlagPhysicallyBacked: WHV_CREATE_VPCI_DEVICE_FLAGS =
869    WHV_CREATE_VPCI_DEVICE_FLAGS(0x00000001);
870pub const WHvCreateVpciDeviceFlagUseLogicalInterrupts: WHV_CREATE_VPCI_DEVICE_FLAGS =
871    WHV_CREATE_VPCI_DEVICE_FLAGS(0x00000002);
872
873#[repr(C)]
874#[derive(Debug, Clone, Copy)]
875pub struct WHV_VPCI_DEVICE_PROPERTY_CODE(u32);
876
877pub const WHvVpciDevicePropertyCodeUndefined: WHV_VPCI_DEVICE_PROPERTY_CODE =
878    WHV_VPCI_DEVICE_PROPERTY_CODE(0);
879pub const WHvVpciDevicePropertyCodeHardwareIDs: WHV_VPCI_DEVICE_PROPERTY_CODE =
880    WHV_VPCI_DEVICE_PROPERTY_CODE(1);
881pub const WHvVpciDevicePropertyCodeProbedBARs: WHV_VPCI_DEVICE_PROPERTY_CODE =
882    WHV_VPCI_DEVICE_PROPERTY_CODE(2);
883
884#[repr(C)]
885#[derive(Debug, Clone, Copy, Default)]
886pub struct WHV_VPCI_HARDWARE_IDS {
887    pub VendorID: u16,
888    pub DeviceID: u16,
889    pub RevisionID: u8,
890    pub ProgIf: u8,
891    pub SubClass: u8,
892    pub BaseClass: u8,
893    pub SubVendorID: u16,
894    pub SubSystemID: u16,
895}
896
897#[repr(C)]
898#[derive(Debug, Clone, Copy, Default)]
899pub struct WHV_VPCI_PROBED_BARS {
900    pub Value: [u32; 6],
901}
902
903#[repr(C)]
904#[derive(Debug, Clone, Copy, Default)]
905pub struct WHV_VPCI_MMIO_RANGE_FLAGS(pub u32);
906bitops!(WHV_VPCI_MMIO_RANGE_FLAGS);
907
908pub const WHvVpciMmioRangeFlagReadAccess: WHV_VPCI_MMIO_RANGE_FLAGS =
909    WHV_VPCI_MMIO_RANGE_FLAGS(0x00000001);
910pub const WHvVpciMmioRangeFlagWriteAccess: WHV_VPCI_MMIO_RANGE_FLAGS =
911    WHV_VPCI_MMIO_RANGE_FLAGS(0x00000002);
912
913#[repr(C)]
914#[derive(Debug, Clone, Copy)]
915pub struct WHV_VPCI_DEVICE_REGISTER_SPACE(pub i32);
916
917pub const WHvVpciConfigSpace: WHV_VPCI_DEVICE_REGISTER_SPACE = WHV_VPCI_DEVICE_REGISTER_SPACE(-1);
918pub const WHvVpciBar0: WHV_VPCI_DEVICE_REGISTER_SPACE = WHV_VPCI_DEVICE_REGISTER_SPACE(0);
919pub const WHvVpciBar1: WHV_VPCI_DEVICE_REGISTER_SPACE = WHV_VPCI_DEVICE_REGISTER_SPACE(1);
920pub const WHvVpciBar2: WHV_VPCI_DEVICE_REGISTER_SPACE = WHV_VPCI_DEVICE_REGISTER_SPACE(2);
921pub const WHvVpciBar3: WHV_VPCI_DEVICE_REGISTER_SPACE = WHV_VPCI_DEVICE_REGISTER_SPACE(3);
922pub const WHvVpciBar4: WHV_VPCI_DEVICE_REGISTER_SPACE = WHV_VPCI_DEVICE_REGISTER_SPACE(4);
923pub const WHvVpciBar5: WHV_VPCI_DEVICE_REGISTER_SPACE = WHV_VPCI_DEVICE_REGISTER_SPACE(5);
924
925#[repr(C)]
926#[derive(Debug, Clone, Copy)]
927pub struct WHV_VPCI_MMIO_MAPPING {
928    pub Location: WHV_VPCI_DEVICE_REGISTER_SPACE,
929    pub Flags: WHV_VPCI_MMIO_RANGE_FLAGS,
930    pub SizeInBytes: u64,
931    pub OffsetInBytes: u64,
932    pub VirtualAddress: *mut c_void,
933}
934
935#[repr(C)]
936#[derive(Debug, Clone, Copy)]
937pub struct WHV_VPCI_DEVICE_REGISTER {
938    pub Location: WHV_VPCI_DEVICE_REGISTER_SPACE,
939    pub SizeInBytes: u32,
940    pub OffsetInBytes: u64,
941}
942
943#[repr(C)]
944#[derive(Debug, Clone, Copy)]
945pub struct WHV_VPCI_INTERRUPT_TARGET {
946    pub Vector: u32,
947    pub Flags: WHV_VPCI_INTERRUPT_TARGET_FLAGS,
948    pub ProcessorCount: u32,
949    pub Processors: [u32; 0],
950}
951
952#[repr(C)]
953#[derive(Debug, Copy, Clone, Default)]
954pub struct WHV_VPCI_INTERRUPT_TARGET_FLAGS(pub u32);
955bitops!(WHV_VPCI_INTERRUPT_TARGET_FLAGS);
956
957pub const WHvVpciInterruptTargetFlagMulticast: WHV_VPCI_INTERRUPT_TARGET_FLAGS =
958    WHV_VPCI_INTERRUPT_TARGET_FLAGS(1);
959
960#[repr(C)]
961#[derive(Copy, Clone, Debug)]
962pub struct WHV_TRIGGER_TYPE(u32);
963
964pub const WHvTriggerTypeInterrupt: WHV_TRIGGER_TYPE = WHV_TRIGGER_TYPE(0);
965pub const WHvTriggerTypeSynicEvent: WHV_TRIGGER_TYPE = WHV_TRIGGER_TYPE(1);
966pub const WHvTriggerTypeDeviceInterrupt: WHV_TRIGGER_TYPE = WHV_TRIGGER_TYPE(2);
967
968#[repr(C)]
969#[derive(Copy, Clone)]
970pub struct WHV_TRIGGER_PARAMETERS {
971    pub TriggerType: WHV_TRIGGER_TYPE,
972    pub Reserved: u32,
973    pub u: WHV_TRIGGER_PARAMETERS_u,
974}
975
976#[repr(C)]
977#[derive(Copy, Clone)]
978pub union WHV_TRIGGER_PARAMETERS_u {
979    #[cfg(target_arch = "x86_64")]
980    pub Interrupt: WHV_INTERRUPT_CONTROL,
981    pub SynicEvent: WHV_SYNIC_EVENT_PARAMETERS,
982    pub DeviceInterrupt: WHV_TRIGGER_PARAMETERS_u_DeviceInterrupt,
983}
984
985#[repr(C)]
986#[derive(Debug, Copy, Clone)]
987pub struct WHV_TRIGGER_PARAMETERS_u_DeviceInterrupt {
988    pub LogicalDeviceId: u64,
989    pub MsiAddress: u64,
990    pub MsiData: u32,
991    pub Reserved: u32,
992}
993
994#[repr(C)]
995#[derive(Debug, Copy, Clone)]
996pub struct WHV_TRIGGER_HANDLE(isize);
997
998#[repr(transparent)]
999#[derive(Debug, Copy, Clone)]
1000pub struct WHV_VIRTUAL_PROCESSOR_STATE_TYPE(u32);
1001
1002pub const WHvVirtualProcessorStateTypeSynicMessagePage: WHV_VIRTUAL_PROCESSOR_STATE_TYPE =
1003    WHV_VIRTUAL_PROCESSOR_STATE_TYPE(0x00000000);
1004pub const WHvVirtualProcessorStateTypeSynicEventFlagPage: WHV_VIRTUAL_PROCESSOR_STATE_TYPE =
1005    WHV_VIRTUAL_PROCESSOR_STATE_TYPE(0x00000001);
1006pub const WHvVirtualProcessorStateTypeSynicTimerState: WHV_VIRTUAL_PROCESSOR_STATE_TYPE =
1007    WHV_VIRTUAL_PROCESSOR_STATE_TYPE(0x00000002);
1008pub const WHvVirtualProcessorStateTypeInterruptControllerState2: WHV_VIRTUAL_PROCESSOR_STATE_TYPE =
1009    WHV_VIRTUAL_PROCESSOR_STATE_TYPE(0x00001000);
1010pub const WHvVirtualProcessorStateTypeXsaveState: WHV_VIRTUAL_PROCESSOR_STATE_TYPE =
1011    WHV_VIRTUAL_PROCESSOR_STATE_TYPE(0x00001001);
1012
1013#[repr(u32)]
1014#[derive(Debug, Copy, Clone)]
1015pub enum WHV_ARM64_IC_EMULATION_MODE {
1016    None = 0,
1017    GicV3 = 1,
1018}
1019
1020#[repr(C, packed)]
1021#[derive(Debug, Copy, Clone)]
1022pub struct WHV_ARM64_IC_GIC_V3_PARAMETERS {
1023    pub GicdBaseAddress: u64,
1024    pub GitsTranslatorBaseAddress: u64,
1025    pub Reserved: u32,
1026    pub GicLpiIntIdBits: u32,
1027    pub GicPpiOverflowInterruptFromCntv: u32,
1028    pub GicPpiPerformanceMonitorsInterrupt: u32,
1029    pub Reserved1: [u32; 6],
1030}
1031
1032// Legacy Hyper-V defaults
1033pub const DEFAULT_GITS_TRANSLATER_BASE_ADDRESS: u64 = 0;
1034pub const DEFAULT_GIC_LPI_INT_ID_BITS: u32 = 1;
1035pub const DEFAULT_GIC_PPI_OVERFLOW_INTERRUPT_FROM_CNTV: u32 = 0x14;
1036
1037#[repr(C, packed)]
1038#[derive(Debug, Copy, Clone)]
1039pub struct WHV_ARM64_IC_PARAMETERS {
1040    pub EmulationMode: WHV_ARM64_IC_EMULATION_MODE,
1041    pub Reserved: u32,
1042    pub GicV3Parameters: WHV_ARM64_IC_GIC_V3_PARAMETERS,
1043}