1#![expect(missing_docs)]
7#![forbid(unsafe_code)]
8#![no_std]
9
10pub mod save_restore;
11pub mod vbs;
12
13use bitfield_struct::bitfield;
14use core::fmt::Debug;
15use core::mem::size_of;
16use open_enum::open_enum;
17use static_assertions::const_assert;
18use zerocopy::FromBytes;
19use zerocopy::FromZeros;
20use zerocopy::Immutable;
21use zerocopy::IntoBytes;
22use zerocopy::KnownLayout;
23
24pub const HV_PAGE_SIZE: u64 = 4096;
25pub const HV_PAGE_SIZE_USIZE: usize = 4096;
26pub const HV_PAGE_SHIFT: u64 = 12;
27
28pub const HV_PARTITION_ID_SELF: u64 = u64::MAX;
29pub const HV_VP_INDEX_SELF: u32 = 0xfffffffe;
30pub const HV_ANY_VP: u32 = 0xffffffff;
31
32pub const HV_CPUID_FUNCTION_VERSION_AND_FEATURES: u32 = 0x00000001;
33pub const HV_CPUID_FUNCTION_HV_VENDOR_AND_MAX_FUNCTION: u32 = 0x40000000;
34pub const HV_CPUID_FUNCTION_HV_INTERFACE: u32 = 0x40000001;
35pub const HV_CPUID_FUNCTION_MS_HV_VERSION: u32 = 0x40000002;
36pub const HV_CPUID_FUNCTION_MS_HV_FEATURES: u32 = 0x40000003;
37pub const HV_CPUID_FUNCTION_MS_HV_ENLIGHTENMENT_INFORMATION: u32 = 0x40000004;
38pub const HV_CPUID_FUNCTION_MS_HV_IMPLEMENTATION_LIMITS: u32 = 0x40000005;
39pub const HV_CPUID_FUNCTION_MS_HV_HARDWARE_FEATURES: u32 = 0x40000006;
40pub const HV_CPUID_FUNCTION_MS_HV_NESTED_FEATURES: u32 = 0x4000000A;
41pub const HV_CPUID_FUNCTION_MS_HV_ISOLATION_CONFIGURATION: u32 = 0x4000000C;
42
43pub const VIRTUALIZATION_STACK_CPUID_VENDOR: u32 = 0x40000080;
44pub const VIRTUALIZATION_STACK_CPUID_INTERFACE: u32 = 0x40000081;
45pub const VIRTUALIZATION_STACK_CPUID_PROPERTIES: u32 = 0x40000082;
46
47pub const VS1_PARTITION_PROPERTIES_EAX_IS_PORTABLE: u32 = 0x000000001;
52pub const VS1_PARTITION_PROPERTIES_EAX_DEBUG_DEVICE_PRESENT: u32 = 0x000000002;
54pub const VS1_PARTITION_PROPERTIES_EAX_EXTENDED_IOAPIC_RTE: u32 = 0x000000004;
56pub const VS1_PARTITION_PROPERTIES_EAX_CONFIDENTIAL_VMBUS_AVAILABLE: u32 = 0x000000008;
58
59pub const VENDOR_HYP_UID_MS_HYPERVISOR: [u32; 4] = [0x4d32ba58, 0xcd244764, 0x8eef6c75, 0x16597024];
61
62#[bitfield(u64)]
63pub struct HvPartitionPrivilege {
64 pub access_vp_runtime_msr: bool,
66 pub access_partition_reference_counter: bool,
67 pub access_synic_msrs: bool,
68 pub access_synthetic_timer_msrs: bool,
69 pub access_apic_msrs: bool,
70 pub access_hypercall_msrs: bool,
71 pub access_vp_index: bool,
72 pub access_reset_msr: bool,
73 pub access_stats_msr: bool,
74 pub access_partition_reference_tsc: bool,
75 pub access_guest_idle_msr: bool,
76 pub access_frequency_msrs: bool,
77 pub access_debug_msrs: bool,
78 pub access_reenlightenment_ctrls: bool,
79 pub access_root_scheduler_msr: bool,
80 pub access_tsc_invariant_controls: bool,
81 _reserved1: u16,
82
83 pub create_partitions: bool,
85 pub access_partition_id: bool,
86 pub access_memory_pool: bool,
87 pub adjust_message_buffers: bool,
88 pub post_messages: bool,
89 pub signal_events: bool,
90 pub create_port: bool,
91 pub connect_port: bool,
92 pub access_stats: bool,
93 #[bits(2)]
94 _reserved2: u64,
95 pub debugging: bool,
96 pub cpu_management: bool,
97 pub configure_profiler: bool,
98 pub access_vp_exit_tracing: bool,
99 pub enable_extended_gva_ranges_flush_va_list: bool,
100 pub access_vsm: bool,
101 pub access_vp_registers: bool,
102 _unused_bit: bool,
103 pub fast_hypercall_output: bool,
104 pub enable_extended_hypercalls: bool,
105 pub start_virtual_processor: bool,
106 pub isolation: bool,
107 #[bits(9)]
108 _reserved3: u64,
109}
110
111#[bitfield(u64)]
117pub struct HvX64PartitionProcessorFeatures {
118 pub sse3_support: bool,
119 pub lahf_sahf_support: bool,
120 pub ssse3_support: bool,
121 pub sse4_1_support: bool,
122 pub sse4_2_support: bool,
123 pub sse4a_support: bool,
124 pub xop_support: bool,
125 pub pop_cnt_support: bool,
126 pub cmpxchg16b_support: bool,
127 pub altmovcr8_support: bool,
128 pub lzcnt_support: bool,
129 pub mis_align_sse_support: bool,
130 pub mmx_ext_support: bool,
131 pub amd3d_now_support: bool,
132 pub extended_amd3d_now_support: bool,
133 pub page_1gb_support: bool,
134 pub aes_support: bool,
135 pub pclmulqdq_support: bool,
136 pub pcid_support: bool,
137 pub fma4_support: bool,
138 pub f16c_support: bool,
139 pub rd_rand_support: bool,
140 pub rd_wr_fs_gs_support: bool,
141 pub smep_support: bool,
142 pub enhanced_fast_string_support: bool,
143 pub bmi1_support: bool,
144 pub bmi2_support: bool,
145 pub hle_support_deprecated: bool,
146 pub rtm_support_deprecated: bool,
147 pub movbe_support: bool,
148 pub npiep1_support: bool,
149 pub dep_x87_fpu_save_support: bool,
150 pub rd_seed_support: bool,
151 pub adx_support: bool,
152 pub intel_prefetch_support: bool,
153 pub smap_support: bool,
154 pub hle_support: bool,
155 pub rtm_support: bool,
156 pub rdtscp_support: bool,
157 pub clflushopt_support: bool,
158 pub clwb_support: bool,
159 pub sha_support: bool,
160 pub x87_pointers_saved_support: bool,
161 pub invpcid_support: bool,
162 pub ibrs_support: bool,
163 pub stibp_support: bool,
164 pub ibpb_support: bool,
165 pub unrestricted_guest_support: bool,
166 pub mdd_support: bool,
167 pub fast_short_rep_mov_support: bool,
168 pub l1d_cache_flush_support: bool,
169 pub rdcl_no_support: bool,
170 pub ibrs_all_support: bool,
171 pub skip_l1df_support: bool,
172 pub ssb_no_support: bool,
173 pub rsb_a_no_support: bool,
174 pub virt_spec_ctrl_support: bool,
175 pub rd_pid_support: bool,
176 pub umip_support: bool,
177 pub mbs_no_support: bool,
178 pub mb_clear_support: bool,
179 pub taa_no_support: bool,
180 pub tsx_ctrl_support: bool,
181 _reserved_bank0: bool,
182}
183
184#[bitfield(u64)]
186pub struct HvX64PartitionProcessorFeatures1 {
187 pub a_count_m_count_support: bool,
188 pub tsc_invariant_support: bool,
189 pub cl_zero_support: bool,
190 pub rdpru_support: bool,
191 pub la57_support: bool,
192 pub mbec_support: bool,
193 pub nested_virt_support: bool,
194 pub psfd_support: bool,
195 pub cet_ss_support: bool,
196 pub cet_ibt_support: bool,
197 pub vmx_exception_inject_support: bool,
198 pub enqcmd_support: bool,
199 pub umwait_tpause_support: bool,
200 pub movdiri_support: bool,
201 pub movdir64b_support: bool,
202 pub cldemote_support: bool,
203 pub serialize_support: bool,
204 pub tsc_deadline_tmr_support: bool,
205 pub tsc_adjust_support: bool,
206 pub fz_l_rep_movsb: bool,
207 pub fs_rep_stosb: bool,
208 pub fs_rep_cmpsb: bool,
209 pub tsx_ld_trk_support: bool,
210 pub vmx_ins_outs_exit_info_support: bool,
211 pub hlat_support: bool,
212 pub sbdr_ssdp_no_support: bool,
213 pub fbsdp_no_support: bool,
214 pub psdp_no_support: bool,
215 pub fb_clear_support: bool,
216 pub btc_no_support: bool,
217 pub ibpb_rsb_flush_support: bool,
218 pub stibp_always_on_support: bool,
219 pub perf_global_ctrl_support: bool,
220 pub npt_execute_only_support: bool,
221 pub npt_ad_flags_support: bool,
222 pub npt_1gb_page_support: bool,
223 pub amd_processor_topology_node_id_support: bool,
224 pub local_machine_check_support: bool,
225 pub extended_topology_leaf_fp256_amd_support: bool,
226 pub gds_no_support: bool,
227 pub cmpccxadd_support: bool,
228 pub tsc_aux_virtualization_support: bool,
229 pub rmp_query_support: bool,
230 pub bhi_no_support: bool,
231 pub bhi_dis_support: bool,
232 pub prefetch_i_support: bool,
233 pub sha512_support: bool,
234 pub mitigation_ctrl_support: bool,
235 pub rfds_no_support: bool,
236 pub rfds_clear_support: bool,
237 pub sm3_support: bool,
238 pub sm4_support: bool,
239 pub secure_avic_support: bool,
240 pub guest_intercept_ctrl_support: bool,
241 pub sbpb_support: bool,
242 pub ibpb_br_type_support: bool,
243 pub srso_no_support: bool,
244 pub srso_user_kernel_no_support: bool,
245 pub vrew_clear_support: bool,
246 pub tsa_l1_no_support: bool,
247 pub tsa_sq_no_support: bool,
248 pub lass_support: bool,
249 #[bits(2)]
250 _reserved_bank1: u8,
251}
252
253#[bitfield(u64)]
255pub struct HvX64PartitionProcessorXsaveFeatures {
256 pub xsave_support: bool,
257 pub xsaveopt_support: bool,
258 pub avx_support: bool,
259 pub avx2_support: bool,
260 pub fma_support: bool,
261 pub mpx_support: bool,
262 pub avx512_support: bool,
263 pub avx512_dq_support: bool,
264 pub avx512_cd_support: bool,
265 pub avx512_bw_support: bool,
266 pub avx512_vl_support: bool,
267 pub xsave_comp_support: bool,
268 pub xsave_supervisor_support: bool,
269 pub xcr1_support: bool,
270 pub avx512_bitalg_support: bool,
271 pub avx512_ifma_support: bool,
272 pub avx512_vbmi_support: bool,
273 pub avx512_vbmi2_support: bool,
274 pub avx512_vnni_support: bool,
275 pub gfni_support: bool,
276 pub vaes_support: bool,
277 pub avx512_vpopcntdq_support: bool,
278 pub vpclmulqdq_support: bool,
279 pub avx512_bf16_support: bool,
280 pub avx512_vp2_intersect_support: bool,
281 pub avx512_fp16_support: bool,
282 pub xfd_support: bool,
283 pub amx_tile_support: bool,
284 pub amx_bf16_support: bool,
285 pub amx_int8_support: bool,
286 pub avx_vnni_support: bool,
287 pub avx_ifma_support: bool,
288 pub avx_ne_convert_support: bool,
289 pub avx_vnni_int8_support: bool,
290 pub avx_vnni_int16_support: bool,
291 pub avx10_1_256_support: bool,
292 pub avx10_1_512_support: bool,
293 pub amx_fp16_support: bool,
294 #[bits(26)]
295 _reserved: u64,
296}
297
298#[bitfield(u64)]
301pub struct HvPartitionSyntheticProcessorFeatures {
302 pub hypervisor_present: bool,
303 pub hv1: bool,
304 pub access_vp_run_time_reg: bool,
305 pub access_partition_reference_counter: bool,
306 pub access_synic_regs: bool,
307 pub access_synthetic_timer_regs: bool,
308 pub access_intr_ctrl_regs: bool,
309 pub access_hypercall_regs: bool,
310 pub access_vp_index: bool,
311 pub access_partition_reference_tsc: bool,
312 pub access_guest_idle_reg: bool,
313 pub access_frequency_regs: bool,
314 _reserved_z12: bool,
315 _reserved_z13: bool,
316 _reserved_z14: bool,
317 pub enable_extended_gva_ranges_for_flush_virtual_address_list: bool,
318 _reserved_z16: bool,
319 _reserved_z17: bool,
320 pub fast_hypercall_output: bool,
321 _reserved_z19: bool,
322 pub start_virtual_processor: bool,
323 _reserved_z21: bool,
324 pub direct_synthetic_timers: bool,
325 _reserved_z23: bool,
326 pub extended_processor_masks: bool,
327 pub tb_flush_hypercalls: bool,
328 pub synthetic_cluster_ipi: bool,
329 pub notify_long_spin_wait: bool,
330 pub query_numa_distance: bool,
331 pub signal_events: bool,
332 pub retarget_device_interrupt: bool,
333 pub restore_time: bool,
334 pub enlightened_vmcs: bool,
335 pub nested_debug_ctl: bool,
336 pub synthetic_time_unhalted_timer: bool,
337 pub idle_spec_ctrl: bool,
338 _reserved_z36: bool,
339 pub wake_vps: bool,
340 pub access_vp_regs: bool,
341 pub sync_context: bool,
342 pub management_vtl_synic_support: bool,
343 pub proxy_interrupt_doorbell_support: bool,
344 _reserved_z42: bool,
345 pub mmio_hypercalls: bool,
346 #[bits(20)]
347 _reserved: u64,
348}
349
350open_enum! {
351 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
352 pub enum HvPartitionIsolationType: u8 {
353 NONE = 0,
354 VBS = 1,
355 SNP = 2,
356 TDX = 3,
357 CCA = 4,
358 }
359}
360
361open_enum! {
362 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
364 pub enum HvPartitionPropertyCode: u32 {
365 #![expect(non_upper_case_globals)]
366
367 PrivilegeFlags = 0x00010000,
369 SyntheticProcFeatures = 0x00010001,
370 AllowedParentUserModeHypercalls = 0x00010002,
371
372 Suspend = 0x00020000,
374 CpuReserve = 0x00020001,
375 CpuCap = 0x00020002,
376 CpuWeight = 0x00020003,
377 CpuGroupId = 0x00020004,
378 HierarchicalIntegratedSchedulerEnabled = 0x00020005,
379
380 TimeFreeze = 0x00030003,
382 ApicFrequency = 0x00030004,
383 ReferenceTime = 0x00030005,
384
385 DebugChannelId = 0x00040000,
387 DebugChannelId0 = 0x00040001,
388 DebugChannelId1 = 0x00040002,
389 DebugChannelId2 = 0x00040003,
390
391 VirtualTlbPageCount = 0x00050000,
393 VsmConfig = 0x00050001,
394 ZeroMemoryOnReset = 0x00050002,
395 ProcessorsPerSocket = 0x00050003,
396 NestedTlbSize = 0x00050004,
397 GpaPageAccessTracking = 0x00050005,
398 VsmPermissionsDirtySinceLastQuery = 0x00050006,
399 SgxLaunchControlConfig = 0x00050007,
400 DefaultSgxLaunchControl0 = 0x00050008,
401 DefaultSgxLaunchControl1 = 0x00050009,
402 DefaultSgxLaunchControl2 = 0x0005000A,
403 DefaultSgxLaunchControl3 = 0x0005000B,
404 IsolationState = 0x0005000C,
405 IsolationControl = 0x0005000D,
406 AllocationId = 0x0005000E,
407 MonitoringId = 0x0005000F,
408 ImplementedPhysicalAddressBits = 0x00050010,
409 NonArchitecturalCoreSharing = 0x00050011,
410 HypercallDoorbellPage = 0x00050012,
411 CppcRequestValue = 0x00050013,
412 IsolationPolicy = 0x00050014,
413 DmaCapableDevices = 0x00050015,
414 ProcessorsPerL3 = 0x00050016,
415 UnimplementedMsrAction = 0x00050017,
416 AmdNodesPerSocket = 0x00050018,
417 ReferenceTscPageActive = 0x00050019,
418 AutoEoiEnabled = 0x0005001A,
419 L3CacheWays = 0x0005001B,
420 IsolationType = 0x0005001C,
421 PerfmonMode = 0x0005001D,
422 DepositStatus = 0x0005001E,
423 Mirroring = 0x0005001F,
424 MirrorState = 0x00050020,
425 MgmtVtlMaxMemorySections = 0x00050021,
426 SevVmgexitOffloads = 0x00050022,
427 PenalizeBusLock = 0x00050023,
428 TopologyApicIdOptIn = 0x00050024,
429 CppcResourcePrioritiesValue = 0x00050025,
430 PartitionDiagBufferConfig = 0x00050026,
431 GicdBaseAddress = 0x00050028,
432 GitsTranslaterBaseAddress = 0x00050029,
433 GicLpiIntIdBits = 0x0005002A,
434 GicPpiOverflowInterruptFromCntv = 0x0005002B,
435 GicPpiOverflowInterruptFromCntp = 0x0005002C,
436 GicPpiPerformanceMonitorsInterrupt = 0x0005002D,
437 GicPpiPmbirq = 0x0005002E,
438 TdMigrationStreamCount = 0x0005002F,
439 AutoSuspend = 0x00050030,
440 SintReservedInterruptId = 0x00050031,
441 GpaPinningEnabled = 0x00050032,
442 TdMigrationMaxStreamCount = 0x00050033,
443 TdMigrationNumMemScanContext = 0x00050034,
444 TdMigrationMaxMemScanRanges = 0x00050035,
445
446 ProcessorVendor = 0x00060000,
448 ProcessorFeaturesDeprecated = 0x00060001,
449 ProcessorXsaveFeatures = 0x00060002,
450 ProcessorCLFlushSize = 0x00060003,
451 EnlightenmentModifications = 0x00060004,
452 CompatibilityVersion = 0x00060005,
453 PhysicalAddressWidth = 0x00060006,
454 XsaveStates = 0x00060007,
455 MaxXsaveDataSize = 0x00060008,
456 ProcessorClockFrequency = 0x00060009,
457 ProcessorFeatures0 = 0x0006000A,
458 ProcessorFeatures1 = 0x0006000B,
459 ProcessorCtrEl0 = 0x0006000C,
460 ProcessorDczidEl0 = 0x0006000D,
461 ProcessorIchVtrEl2 = 0x0006000E,
462 ProcessorIdAa64Dfr0El1 = 0x0006000F,
463 RootProcessorFeatures0 = 0x00060010,
464 RootProcessorFeatures1 = 0x00060011,
465 RootProcessorXsaveFeatures = 0x00060012,
466 RootSyntheticProcFeatures = 0x00060013,
467 PhysicalAddressSize = 0x00060014,
468 FeatureBankCount = 0x00060015,
469 ProcessorIdAa64Dfr1El1 = 0x00060016,
470 ProcessorCntfrqEl0 = 0x00060017,
471 MaxSveVectorLength = 0x00060018,
472 MaxSmeStreamingVectorLength = 0x00060019,
473
474 GuestOsId = 0x00070000,
476
477 ProcessorVirtualizationFeatures = 0x00080000,
479 MaxHardwareIsolatedGuests = 0x00080001,
480 SnpEnabled = 0x00080002,
481 NestedVmxBasic = 0x00080003,
482 NestedVmxPinbasedCtls = 0x00080004,
483 NestedVmxProcbasedCtls = 0x00080005,
484 NestedVmxExitCtls = 0x00080006,
485 NestedVmxEntryCtls = 0x00080007,
486 NestedVmxMisc = 0x00080008,
487 NestedVmxCr0Fixed0 = 0x00080009,
488 NestedVmxCr0Fixed1 = 0x0008000A,
489 NestedVmxCr4Fixed0 = 0x0008000B,
490 NestedVmxCr4Fixed1 = 0x0008000C,
491 NestedVmxVmcsEnum = 0x0008000D,
492 NestedVmxProcbasedCtls2 = 0x0008000E,
493 NestedVmxEptVpidCap = 0x0008000F,
494 NestedVmxTruePinbasedCtls = 0x00080010,
495 NestedVmxTrueProcbasedCtls = 0x00080011,
496 NestedVmxTrueExitCtls = 0x00080012,
497 NestedVmxTrueEntryCtls = 0x00080013,
498 NestedVmxProcbasedCtls3 = 0x00080014,
499 NestedVmxExitCtls2 = 0x00080015,
500 VhState = 0x00080100,
501 MaxHierarchicalPartitionCount = 0x00080101,
502 MaxHierarchicalVpCount = 0x00080102,
503 StateTransferMode = 0x00080103,
504 MigrationAbortCleanupCount = 0x00080104,
505 TdComprehensiveReset = 0x00080105,
506
507 InheritedDeviceDomainReservedRegions = 0x00090000,
509 TdMrConfigId = 0x00090001,
510 TdMrOwner = 0x00090002,
511 TdMrOwnerConfig = 0x00090003,
512 VNUMATopologyConfig = 0x00090004,
513 RootVpSharedPages = 0x00090005,
514 VmmCapabilities = 0x00090007,
515 CompletePartitionIntercept = 0x00090008,
516 AssignableSyntheticProcFeatures = 0x00090009,
517 HwIsolationTdxSupported = 0x0009000A,
518 HwIsolationSevSupported = 0x0009000B,
519 MigrationTdInfoHash = 0x0009000C,
520 MigrationTdBindingSlot = 0x0009000D,
521 DisabledProcessorFeaturesEx = 0x0009000E,
522 RootProcessorFeaturesEx = 0x0009000F,
523 EnabledProcessorFeaturesEx = 0x00090010,
524 PmuEventTypes = 0x00090011,
525 TdComprehensiveConfigure = 0x00090012,
526 }
527}
528
529open_enum! {
530 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
532 pub enum HvProcessorVendor: u32 {
533 AMD = 0x0000,
534 INTEL = 0x0001,
535 HYGON = 0x0002,
536 ARM = 0x0010,
537 }
538}
539
540#[bitfield(u128)]
541#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
542pub struct HvFeatures {
543 #[bits(64)]
544 pub privileges: HvPartitionPrivilege,
545
546 #[bits(4)]
547 pub max_supported_cstate: u32,
548 pub hpet_needed_for_c3_power_state_deprecated: bool,
549 pub invariant_mperf_available: bool,
550 pub supervisor_shadow_stack_available: bool,
551 pub arch_pmu_available: bool,
552 pub exception_trap_intercept_available: bool,
553 #[bits(23)]
554 reserved: u32,
555
556 pub mwait_available_deprecated: bool,
557 pub guest_debugging_available: bool,
558 pub performance_monitors_available: bool,
559 pub cpu_dynamic_partitioning_available: bool,
560 pub xmm_registers_for_fast_hypercall_available: bool,
561 pub guest_idle_available: bool,
562 pub hypervisor_sleep_state_support_available: bool,
563 pub numa_distance_query_available: bool,
564 pub frequency_regs_available: bool,
565 pub synthetic_machine_check_available: bool,
566 pub guest_crash_regs_available: bool,
567 pub debug_regs_available: bool,
568 pub npiep1_available: bool,
569 pub disable_hypervisor_available: bool,
570 pub extended_gva_ranges_for_flush_virtual_address_list_available: bool,
571 pub fast_hypercall_output_available: bool,
572 pub svm_features_available: bool,
573 pub sint_polling_mode_available: bool,
574 pub hypercall_msr_lock_available: bool,
575 pub direct_synthetic_timers: bool,
576 pub register_pat_available: bool,
577 pub register_bndcfgs_available: bool,
578 pub watchdog_timer_available: bool,
579 pub synthetic_time_unhalted_timer_available: bool,
580 pub device_domains_available: bool, pub s1_device_domains_available: bool, pub lbr_available: bool,
583 pub ipt_available: bool,
584 pub cross_vtl_flush_available: bool,
585 pub idle_spec_ctrl_available: bool,
586 pub translate_gva_flags_available: bool,
587 pub apic_eoi_intercept_available: bool,
588}
589
590impl HvFeatures {
591 pub fn from_cpuid(cpuid: [u32; 4]) -> Self {
592 zerocopy::transmute!(cpuid)
593 }
594
595 pub fn into_cpuid(self) -> [u32; 4] {
596 zerocopy::transmute!(self)
597 }
598}
599
600#[bitfield(u128)]
601#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
602pub struct HvEnlightenmentInformation {
603 pub use_hypercall_for_address_space_switch: bool,
604 pub use_hypercall_for_local_flush: bool,
605 pub use_hypercall_for_remote_flush_and_local_flush_entire: bool,
606 pub use_apic_msrs: bool,
607 pub use_hv_register_for_reset: bool,
608 pub use_relaxed_timing: bool,
609 pub use_dma_remapping_deprecated: bool,
610 pub use_interrupt_remapping_deprecated: bool,
611 pub use_x2_apic_msrs: bool,
612 pub deprecate_auto_eoi: bool,
613 pub use_synthetic_cluster_ipi: bool,
614 pub use_ex_processor_masks: bool,
615 pub nested: bool,
616 pub use_int_for_mbec_system_calls: bool,
617 pub use_vmcs_enlightenments: bool,
618 pub use_synced_timeline: bool,
619 pub core_scheduler_requested: bool,
620 pub use_direct_local_flush_entire: bool,
621 pub no_non_architectural_core_sharing: bool,
622 pub use_x2_apic: bool,
623 pub restore_time_on_resume: bool,
624 pub use_hypercall_for_mmio_access: bool,
625 pub use_gpa_pinning_hypercall: bool,
626 pub wake_vps: bool,
627 _reserved: u8,
628 pub long_spin_wait_count: u32,
629 #[bits(7)]
630 pub implemented_physical_address_bits: u32,
631 #[bits(25)]
632 _reserved1: u32,
633 _reserved2: u32,
634}
635
636impl HvEnlightenmentInformation {
637 pub fn from_cpuid(cpuid: [u32; 4]) -> Self {
638 zerocopy::transmute!(cpuid)
639 }
640
641 pub fn into_cpuid(self) -> [u32; 4] {
642 zerocopy::transmute!(self)
643 }
644}
645
646#[bitfield(u32)]
650#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
651pub struct HvNestedVirtFeaturesEax {
652 pub enlightened_vmcs_version_low: u8,
653 pub enlightened_vmcs_version_high: u8,
654 _reserved16: bool,
655 pub nested_flush_virtual_hypercall: bool,
656 pub flush_guest_physical_hypercall: bool,
657 pub msr_bitmap: bool,
658 pub virtualization_exception: bool,
659 pub debug_ctl: bool,
660 pub enlightened_npt_tlb: bool,
661 #[bits(9)]
662 _reserved23: u32,
663}
664
665#[bitfield(u128)]
666pub struct HvHardwareFeatures {
667 pub apic_overlay_assist_in_use: bool,
668 pub msr_bitmaps_in_use: bool,
669 pub architectural_performance_counters_in_use: bool,
670 pub second_level_address_translation_in_use: bool,
671 pub dma_remapping_in_use: bool,
672 pub interrupt_remapping_in_use: bool,
673 pub memory_patrol_scrubber_present: bool,
674 pub dma_protection_in_use: bool,
675 pub hpet_requested: bool,
676 pub synthetic_timers_volatile: bool,
677 #[bits(4)]
678 pub hypervisor_level: u32,
679 pub physical_destination_mode_required: bool,
680 pub use_vmfunc_for_alias_map_switch: bool,
681 pub hv_register_for_memory_zeroing_supported: bool,
682 pub unrestricted_guest_supported: bool,
683 pub rdt_afeatures_supported: bool,
684 pub rdt_mfeatures_supported: bool,
685 pub child_perfmon_pmu_supported: bool,
686 pub child_perfmon_lbr_supported: bool,
687 pub child_perfmon_ipt_supported: bool,
688 pub apic_emulation_supported: bool,
689 pub child_x2_apic_recommended: bool,
690 pub hardware_watchdog_reserved: bool,
691 pub device_access_tracking_supported: bool,
692 pub hardware_gpa_access_tracking_supported: bool,
693 #[bits(4)]
694 _reserved: u32,
695
696 pub device_domain_input_width: u8,
697 #[bits(24)]
698 _reserved1: u32,
699 _reserved2: u32,
700 _reserved3: u32,
701}
702
703#[bitfield(u128)]
704pub struct HvIsolationConfiguration {
705 pub paravisor_present: bool,
706 #[bits(31)]
707 pub _reserved0: u32,
708
709 #[bits(4)]
710 pub isolation_type: u8,
711 _reserved11: bool,
712 pub shared_gpa_boundary_active: bool,
713 #[bits(6)]
714 pub shared_gpa_boundary_bits: u8,
715 #[bits(20)]
716 _reserved12: u32,
717 _reserved2: u32,
718 _reserved3: u32,
719}
720
721open_enum! {
722 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
723 pub enum HypercallCode: u16 {
724 #![expect(non_upper_case_globals)]
725
726 HvCallSwitchVirtualAddressSpace = 0x0001,
727 HvCallFlushVirtualAddressSpace = 0x0002,
728 HvCallFlushVirtualAddressList = 0x0003,
729 HvCallNotifyLongSpinWait = 0x0008,
730 HvCallInvokeHypervisorDebugger = 0x000a,
731 HvCallSendSyntheticClusterIpi = 0x000b,
732 HvCallModifyVtlProtectionMask = 0x000c,
733 HvCallEnablePartitionVtl = 0x000d,
734 HvCallEnableVpVtl = 0x000f,
735 HvCallVtlCall = 0x0011,
736 HvCallVtlReturn = 0x0012,
737 HvCallFlushVirtualAddressSpaceEx = 0x0013,
738 HvCallFlushVirtualAddressListEx = 0x0014,
739 HvCallSendSyntheticClusterIpiEx = 0x0015,
740 HvCallInstallIntercept = 0x004d,
741 HvCallGetVpRegisters = 0x0050,
742 HvCallSetVpRegisters = 0x0051,
743 HvCallTranslateVirtualAddress = 0x0052,
744 HvCallPostMessage = 0x005C,
745 HvCallSignalEvent = 0x005D,
746 HvCallOutputDebugCharacter = 0x0071,
747 HvCallGetSystemProperty = 0x007b,
748 HvCallRetargetDeviceInterrupt = 0x007e,
749 HvCallNotifyPartitionEvent = 0x0087,
750 HvCallRegisterInterceptResult = 0x0091,
751 HvCallAssertVirtualInterrupt = 0x0094,
752 HvCallStartVirtualProcessor = 0x0099,
753 HvCallGetVpIndexFromApicId = 0x009A,
754 HvCallTranslateVirtualAddressEx = 0x00AC,
755 HvCallCheckForIoIntercept = 0x00ad,
756 HvCallFlushGuestPhysicalAddressSpace = 0x00AF,
757 HvCallFlushGuestPhysicalAddressList = 0x00B0,
758 HvCallSignalEventDirect = 0x00C0,
759 HvCallPostMessageDirect = 0x00C1,
760 HvCallCheckSparseGpaPageVtlAccess = 0x00D4,
761 HvCallAcceptGpaPages = 0x00D9,
762 HvCallModifySparseGpaPageHostVisibility = 0x00DB,
763 HvCallGetVpCpuidValues = 0x00F4,
764 HvCallRestorePartitionTime = 0x0103,
765 HvCallMemoryMappedIoRead = 0x0106,
766 HvCallMemoryMappedIoWrite = 0x0107,
767 HvCallPinGpaPageRanges = 0x0112,
768 HvCallUnpinGpaPageRanges = 0x0113,
769 HvCallQuerySparseGpaPageHostVisibility = 0x011C,
770
771 HvExtCallQueryCapabilities = 0x8001,
773
774 HvCallVbsVmCallReport = 0xC001,
776 }
777}
778
779pub const HV_X64_MSR_GUEST_OS_ID: u32 = 0x40000000;
780pub const HV_X64_MSR_HYPERCALL: u32 = 0x40000001;
781pub const HV_X64_MSR_VP_INDEX: u32 = 0x40000002;
782pub const HV_X64_MSR_TIME_REF_COUNT: u32 = 0x40000020;
783pub const HV_X64_MSR_REFERENCE_TSC: u32 = 0x40000021;
784pub const HV_X64_MSR_TSC_FREQUENCY: u32 = 0x40000022;
785pub const HV_X64_MSR_APIC_FREQUENCY: u32 = 0x40000023;
786pub const HV_X64_MSR_EOI: u32 = 0x40000070;
787pub const HV_X64_MSR_ICR: u32 = 0x40000071;
788pub const HV_X64_MSR_TPR: u32 = 0x40000072;
789pub const HV_X64_MSR_VP_ASSIST_PAGE: u32 = 0x40000073;
790pub const HV_X64_MSR_SCONTROL: u32 = 0x40000080;
791pub const HV_X64_MSR_SVERSION: u32 = 0x40000081;
792pub const HV_X64_MSR_SIEFP: u32 = 0x40000082;
793pub const HV_X64_MSR_SIMP: u32 = 0x40000083;
794pub const HV_X64_MSR_EOM: u32 = 0x40000084;
795pub const HV_X64_MSR_SINT0: u32 = 0x40000090;
796pub const HV_X64_MSR_SINT1: u32 = 0x40000091;
797pub const HV_X64_MSR_SINT2: u32 = 0x40000092;
798pub const HV_X64_MSR_SINT3: u32 = 0x40000093;
799pub const HV_X64_MSR_SINT4: u32 = 0x40000094;
800pub const HV_X64_MSR_SINT5: u32 = 0x40000095;
801pub const HV_X64_MSR_SINT6: u32 = 0x40000096;
802pub const HV_X64_MSR_SINT7: u32 = 0x40000097;
803pub const HV_X64_MSR_SINT8: u32 = 0x40000098;
804pub const HV_X64_MSR_SINT9: u32 = 0x40000099;
805pub const HV_X64_MSR_SINT10: u32 = 0x4000009a;
806pub const HV_X64_MSR_SINT11: u32 = 0x4000009b;
807pub const HV_X64_MSR_SINT12: u32 = 0x4000009c;
808pub const HV_X64_MSR_SINT13: u32 = 0x4000009d;
809pub const HV_X64_MSR_SINT14: u32 = 0x4000009e;
810pub const HV_X64_MSR_SINT15: u32 = 0x4000009f;
811pub const HV_X64_MSR_STIMER0_CONFIG: u32 = 0x400000b0;
812pub const HV_X64_MSR_STIMER0_COUNT: u32 = 0x400000b1;
813pub const HV_X64_MSR_STIMER1_CONFIG: u32 = 0x400000b2;
814pub const HV_X64_MSR_STIMER1_COUNT: u32 = 0x400000b3;
815pub const HV_X64_MSR_STIMER2_CONFIG: u32 = 0x400000b4;
816pub const HV_X64_MSR_STIMER2_COUNT: u32 = 0x400000b5;
817pub const HV_X64_MSR_STIMER3_CONFIG: u32 = 0x400000b6;
818pub const HV_X64_MSR_STIMER3_COUNT: u32 = 0x400000b7;
819pub const HV_X64_MSR_GUEST_IDLE: u32 = 0x400000F0;
820pub const HV_X64_MSR_GUEST_CRASH_P0: u32 = 0x40000100;
821pub const HV_X64_MSR_GUEST_CRASH_P1: u32 = 0x40000101;
822pub const HV_X64_MSR_GUEST_CRASH_P2: u32 = 0x40000102;
823pub const HV_X64_MSR_GUEST_CRASH_P3: u32 = 0x40000103;
824pub const HV_X64_MSR_GUEST_CRASH_P4: u32 = 0x40000104;
825pub const HV_X64_MSR_GUEST_CRASH_CTL: u32 = 0x40000105;
826
827pub const HV_X64_GUEST_CRASH_PARAMETER_MSRS: usize = 5;
828
829#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
833#[repr(transparent)]
834pub struct HvStatus(pub u16);
835
836impl HvStatus {
837 pub const SUCCESS: Self = Self(0);
839
840 pub fn result(self) -> HvResult<()> {
843 if let Ok(err) = self.0.try_into() {
844 Err(HvError(err))
845 } else {
846 Ok(())
847 }
848 }
849
850 pub fn is_ok(self) -> bool {
852 self == Self::SUCCESS
853 }
854
855 pub fn is_err(self) -> bool {
857 self != Self::SUCCESS
858 }
859
860 const fn from_bits(bits: u16) -> Self {
861 Self(bits)
862 }
863
864 const fn into_bits(self) -> u16 {
865 self.0
866 }
867}
868
869impl From<Result<(), HvError>> for HvStatus {
870 fn from(err: Result<(), HvError>) -> Self {
871 err.err().map_or(Self::SUCCESS, |err| Self(err.0.get()))
872 }
873}
874
875impl Debug for HvStatus {
876 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
877 match self.result() {
878 Ok(()) => f.write_str("Success"),
879 Err(err) => Debug::fmt(&err, f),
880 }
881 }
882}
883
884#[derive(Copy, Clone, PartialEq, Eq, IntoBytes, Immutable, KnownLayout)]
889#[repr(transparent)]
890pub struct HvError(core::num::NonZeroU16);
891
892impl From<core::num::NonZeroU16> for HvError {
893 fn from(err: core::num::NonZeroU16) -> Self {
894 Self(err)
895 }
896}
897
898impl Debug for HvError {
899 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
900 match self.debug_name() {
901 Some(name) => f.pad(name),
902 None => Debug::fmt(&self.0.get(), f),
903 }
904 }
905}
906
907impl core::fmt::Display for HvError {
908 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
909 match self.doc_str() {
910 Some(s) => f.write_str(s),
911 None => write!(f, "Hypervisor error {:#06x}", self.0),
912 }
913 }
914}
915
916impl core::error::Error for HvError {}
917
918macro_rules! hv_error {
919 ($ty:ty, $(#[doc = $doc:expr] $ident:ident = $val:expr),* $(,)?) => {
920
921 #[expect(non_upper_case_globals)]
922 impl $ty {
923 $(
924 #[doc = $doc]
925 pub const $ident: Self = Self(core::num::NonZeroU16::new($val).unwrap());
926 )*
927
928 fn debug_name(&self) -> Option<&'static str> {
929 Some(match self.0.get() {
930 $(
931 $val => stringify!($ident),
932 )*
933 _ => return None,
934 })
935 }
936
937 fn doc_str(&self) -> Option<&'static str> {
938 Some(match self.0.get() {
939 $(
940 $val => const { $doc.trim_ascii() },
941 )*
942 _ => return None,
943 })
944 }
945 }
946 };
947}
948
949hv_error! {
951 HvError,
952 InvalidHypercallCode = 0x0002,
954 InvalidHypercallInput = 0x0003,
956 InvalidAlignment = 0x0004,
958 InvalidParameter = 0x0005,
960 AccessDenied = 0x0006,
962 InvalidPartitionState = 0x0007,
964 OperationDenied = 0x0008,
966 UnknownProperty = 0x0009,
968 PropertyValueOutOfRange = 0x000A,
970 InsufficientMemory = 0x000B,
972 PartitionTooDeep = 0x000C,
974 InvalidPartitionId = 0x000D,
976 InvalidVpIndex = 0x000E,
978 NotFound = 0x0010,
980 InvalidPortId = 0x0011,
982 InvalidConnectionId = 0x0012,
984 InsufficientBuffers = 0x0013,
986 NotAcknowledged = 0x0014,
988 InvalidVpState = 0x0015,
990 Acknowledged = 0x0016,
992 InvalidSaveRestoreState = 0x0017,
994 InvalidSynicState = 0x0018,
996 ObjectInUse = 0x0019,
998 InvalidProximityDomainInfo = 0x001A,
1000 NoData = 0x001B,
1002 Inactive = 0x001C,
1004 NoResources = 0x001D,
1006 FeatureUnavailable = 0x001E,
1008 PartialPacket = 0x001F,
1010 ProcessorFeatureNotSupported = 0x0020,
1012 ProcessorCacheLineFlushSizeIncompatible = 0x0030,
1014 InsufficientBuffer = 0x0033,
1016 IncompatibleProcessor = 0x0037,
1018 InsufficientDeviceDomains = 0x0038,
1020 CpuidFeatureValidationError = 0x003C,
1022 CpuidXsaveFeatureValidationError = 0x003D,
1024 ProcessorStartupTimeout = 0x003E,
1026 SmxEnabled = 0x003F,
1028 InvalidLpIndex = 0x0041,
1030 InvalidRegisterValue = 0x0050,
1032 InvalidVtlState = 0x0051,
1034 NxNotDetected = 0x0055,
1036 InvalidDeviceId = 0x0057,
1038 InvalidDeviceState = 0x0058,
1040 PendingPageRequests = 0x0059,
1042 PageRequestInvalid = 0x0060,
1044 KeyAlreadyExists = 0x0065,
1046 DeviceAlreadyInDomain = 0x0066,
1048 InvalidCpuGroupId = 0x006F,
1050 InvalidCpuGroupState = 0x0070,
1052 OperationFailed = 0x0071,
1054 NotAllowedWithNestedVirtActive = 0x0072,
1056 InsufficientRootMemory = 0x0073,
1058 EventBufferAlreadyFreed = 0x0074,
1060 Timeout = 0x0078,
1062 VtlAlreadyEnabled = 0x0086,
1064 UnknownRegisterName = 0x0087,
1066}
1067
1068pub type HvResult<T> = Result<T, HvError>;
1070
1071#[repr(u8)]
1072#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
1073pub enum Vtl {
1074 Vtl0 = 0,
1075 Vtl1 = 1,
1076 Vtl2 = 2,
1077}
1078
1079impl TryFrom<u8> for Vtl {
1080 type Error = HvError;
1081
1082 fn try_from(value: u8) -> Result<Self, Self::Error> {
1083 Ok(match value {
1084 0 => Self::Vtl0,
1085 1 => Self::Vtl1,
1086 2 => Self::Vtl2,
1087 _ => return Err(HvError::InvalidParameter),
1088 })
1089 }
1090}
1091
1092impl From<Vtl> for u8 {
1093 fn from(value: Vtl) -> Self {
1094 value as u8
1095 }
1096}
1097
1098#[bitfield(u64)]
1100pub struct GuestCrashCtl {
1101 #[bits(58)]
1102 _reserved: u64,
1103 #[bits(3)]
1105 pub pre_os_id: u8,
1106 #[bits(1)]
1108 pub no_crash_dump: bool,
1109 #[bits(1)]
1112 pub crash_message: bool,
1113 #[bits(1)]
1115 pub crash_notify: bool,
1116}
1117
1118#[repr(C, align(16))]
1119#[derive(Copy, Clone, PartialEq, Eq, IntoBytes, Immutable, KnownLayout, FromBytes)]
1120pub struct AlignedU128([u8; 16]);
1121
1122impl AlignedU128 {
1123 pub fn as_ne_bytes(&self) -> [u8; 16] {
1124 self.0
1125 }
1126
1127 pub fn from_ne_bytes(val: [u8; 16]) -> Self {
1128 Self(val)
1129 }
1130}
1131
1132impl Debug for AlignedU128 {
1133 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1134 Debug::fmt(&u128::from_ne_bytes(self.0), f)
1135 }
1136}
1137
1138impl From<u128> for AlignedU128 {
1139 fn from(v: u128) -> Self {
1140 Self(v.to_ne_bytes())
1141 }
1142}
1143
1144impl From<u64> for AlignedU128 {
1145 fn from(v: u64) -> Self {
1146 (v as u128).into()
1147 }
1148}
1149
1150impl From<u32> for AlignedU128 {
1151 fn from(v: u32) -> Self {
1152 (v as u128).into()
1153 }
1154}
1155
1156impl From<u16> for AlignedU128 {
1157 fn from(v: u16) -> Self {
1158 (v as u128).into()
1159 }
1160}
1161
1162impl From<u8> for AlignedU128 {
1163 fn from(v: u8) -> Self {
1164 (v as u128).into()
1165 }
1166}
1167
1168impl From<AlignedU128> for u128 {
1169 fn from(v: AlignedU128) -> Self {
1170 u128::from_ne_bytes(v.0)
1171 }
1172}
1173
1174open_enum! {
1175 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
1176 pub enum HvMessageType: u32 {
1177 #![expect(non_upper_case_globals)]
1178
1179 HvMessageTypeNone = 0x00000000,
1180
1181 HvMessageTypeUnmappedGpa = 0x80000000,
1182 HvMessageTypeGpaIntercept = 0x80000001,
1183 HvMessageTypeUnacceptedGpa = 0x80000003,
1184 HvMessageTypeGpaAttributeIntercept = 0x80000004,
1185 HvMessageTypeEnablePartitionVtlIntercept = 0x80000005,
1186 HvMessageTypeTimerExpired = 0x80000010,
1187 HvMessageTypeInvalidVpRegisterValue = 0x80000020,
1188 HvMessageTypeUnrecoverableException = 0x80000021,
1189 HvMessageTypeUnsupportedFeature = 0x80000022,
1190 HvMessageTypeTlbPageSizeMismatch = 0x80000023,
1191 HvMessageTypeIommuFault = 0x80000024,
1192 HvMessageTypeEventLogBufferComplete = 0x80000040,
1193 HvMessageTypeHypercallIntercept = 0x80000050,
1194 HvMessageTypeSynicEventIntercept = 0x80000060,
1195 HvMessageTypeSynicSintIntercept = 0x80000061,
1196 HvMessageTypeSynicSintDeliverable = 0x80000062,
1197 HvMessageTypeAsyncCallCompletion = 0x80000070,
1198 HvMessageTypeX64IoPortIntercept = 0x80010000,
1199 HvMessageTypeMsrIntercept = 0x80010001,
1200 HvMessageTypeX64CpuidIntercept = 0x80010002,
1201 HvMessageTypeExceptionIntercept = 0x80010003,
1202 HvMessageTypeX64ApicEoi = 0x80010004,
1203 HvMessageTypeX64IommuPrq = 0x80010005,
1204 HvMessageTypeRegisterIntercept = 0x80010006,
1205 HvMessageTypeX64Halt = 0x80010007,
1206 HvMessageTypeX64InterruptionDeliverable = 0x80010008,
1207 HvMessageTypeX64SipiIntercept = 0x80010009,
1208 HvMessageTypeX64RdtscIntercept = 0x8001000a,
1209 HvMessageTypeX64ApicSmiIntercept = 0x8001000b,
1210 HvMessageTypeArm64ResetIntercept = 0x8001000c,
1211 HvMessageTypeX64ApicInitSipiIntercept = 0x8001000d,
1212 HvMessageTypeX64ApicWriteIntercept = 0x8001000e,
1213 HvMessageTypeX64ProxyInterruptIntercept = 0x8001000f,
1214 HvMessageTypeX64IsolationCtrlRegIntercept = 0x80010010,
1215 HvMessageTypeX64SnpGuestRequestIntercept = 0x80010011,
1216 HvMessageTypeX64ExceptionTrapIntercept = 0x80010012,
1217 HvMessageTypeX64SevVmgexitIntercept = 0x80010013,
1218 }
1219}
1220
1221impl Default for HvMessageType {
1222 fn default() -> Self {
1223 HvMessageType::HvMessageTypeNone
1224 }
1225}
1226
1227pub const HV_SYNIC_INTERCEPTION_SINT_INDEX: u8 = 0;
1228
1229pub const NUM_SINTS: usize = 16;
1230pub const NUM_TIMERS: usize = 4;
1231
1232#[repr(C)]
1233#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
1234pub struct HvMessageHeader {
1235 pub typ: HvMessageType,
1236 pub len: u8,
1237 pub flags: HvMessageFlags,
1238 pub rsvd: u16,
1239 pub id: u64,
1240}
1241
1242#[bitfield(u8)]
1243#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
1244pub struct HvMessageFlags {
1245 pub message_pending: bool,
1246 #[bits(7)]
1247 _reserved: u8,
1248}
1249
1250pub const HV_MESSAGE_SIZE: usize = size_of::<HvMessage>();
1251const_assert!(HV_MESSAGE_SIZE == 256);
1252pub const HV_MESSAGE_PAYLOAD_SIZE: usize = 240;
1253
1254#[repr(C, align(16))]
1255#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
1256pub struct HvMessage {
1257 pub header: HvMessageHeader,
1258 pub payload_buffer: [u8; HV_MESSAGE_PAYLOAD_SIZE],
1259}
1260
1261impl Default for HvMessage {
1262 fn default() -> Self {
1263 Self {
1264 header: FromZeros::new_zeroed(),
1265 payload_buffer: [0; 240],
1266 }
1267 }
1268}
1269
1270impl HvMessage {
1271 pub fn new(typ: HvMessageType, id: u64, payload: &[u8]) -> Self {
1274 let mut msg = HvMessage {
1275 header: HvMessageHeader {
1276 typ,
1277 len: payload.len() as u8,
1278 flags: HvMessageFlags::new(),
1279 rsvd: 0,
1280 id,
1281 },
1282 payload_buffer: [0; 240],
1283 };
1284 msg.payload_buffer[..payload.len()].copy_from_slice(payload);
1285 msg
1286 }
1287
1288 pub fn payload(&self) -> &[u8] {
1289 &self.payload_buffer[..self.header.len as usize]
1290 }
1291
1292 pub fn as_message<T: MessagePayload>(&self) -> &T {
1293 let () = T::CHECK;
1295 T::ref_from_prefix(&self.payload_buffer).unwrap().0
1296 }
1297
1298 pub fn as_message_mut<T: MessagePayload>(&mut self) -> &T {
1299 let () = T::CHECK;
1301 T::mut_from_prefix(&mut self.payload_buffer).unwrap().0
1302 }
1303}
1304
1305pub trait MessagePayload: KnownLayout + Immutable + IntoBytes + FromBytes + Sized {
1306 #[doc(hidden)]
1309 const CHECK: () = {
1310 assert!(size_of::<Self>() <= HV_MESSAGE_PAYLOAD_SIZE);
1311 assert!(align_of::<Self>() <= align_of::<HvMessage>());
1312 };
1313}
1314
1315#[repr(C)]
1316#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
1317pub struct TimerMessagePayload {
1318 pub timer_index: u32,
1319 pub reserved: u32,
1320 pub expiration_time: u64,
1321 pub delivery_time: u64,
1322}
1323
1324pub mod hypercall {
1325 use super::*;
1326 use core::ops::RangeInclusive;
1327 use zerocopy::Unalign;
1328
1329 #[bitfield(u64)]
1331 pub struct Control {
1332 pub code: u16,
1334 pub fast: bool,
1336 #[bits(10)]
1338 pub variable_header_size: usize,
1339 #[bits(4)]
1340 _rsvd0: u8,
1341 pub nested: bool,
1343 #[bits(12)]
1345 pub rep_count: usize,
1346 #[bits(4)]
1347 _rsvd1: u8,
1348 #[bits(12)]
1350 pub rep_start: usize,
1351 #[bits(4)]
1352 _rsvd2: u8,
1353 }
1354
1355 #[bitfield(u64)]
1357 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
1358 #[must_use]
1359 pub struct HypercallOutput {
1360 #[bits(16)]
1361 pub call_status: HvStatus,
1362 pub rsvd: u16,
1363 #[bits(12)]
1364 pub elements_processed: usize,
1365 #[bits(20)]
1366 pub rsvd2: u32,
1367 }
1368
1369 impl From<HvError> for HypercallOutput {
1370 fn from(e: HvError) -> Self {
1371 Self::new().with_call_status(Err(e).into())
1372 }
1373 }
1374
1375 impl HypercallOutput {
1376 pub const SUCCESS: Self = Self::new();
1378
1379 pub fn result(&self) -> Result<(), HvError> {
1380 self.call_status().result()
1381 }
1382 }
1383
1384 #[repr(C)]
1385 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
1386 pub struct HvRegisterAssoc {
1387 pub name: HvRegisterName,
1388 pub pad: [u32; 3],
1389 pub value: HvRegisterValue,
1390 }
1391
1392 impl<N: Into<HvRegisterName>, T: Into<HvRegisterValue>> From<(N, T)> for HvRegisterAssoc {
1393 fn from((name, value): (N, T)) -> Self {
1394 Self {
1395 name: name.into(),
1396 pad: [0; 3],
1397 value: value.into(),
1398 }
1399 }
1400 }
1401
1402 impl<N: Copy + Into<HvRegisterName>, T: Copy + Into<HvRegisterValue>> From<&(N, T)>
1403 for HvRegisterAssoc
1404 {
1405 fn from(&(name, value): &(N, T)) -> Self {
1406 Self {
1407 name: name.into(),
1408 pad: [0; 3],
1409 value: value.into(),
1410 }
1411 }
1412 }
1413
1414 #[bitfield(u64)]
1415 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
1416 pub struct MsrHypercallContents {
1417 pub enable: bool,
1418 pub locked: bool,
1419 #[bits(10)]
1420 pub reserved_p: u64,
1421 #[bits(52)]
1422 pub gpn: u64,
1423 }
1424
1425 #[repr(C, align(8))]
1426 #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
1427 pub struct PostMessage {
1428 pub connection_id: u32,
1429 pub padding: u32,
1430 pub message_type: u32,
1431 pub payload_size: u32,
1432 pub payload: [u8; 240],
1433 }
1434
1435 #[repr(C, align(8))]
1436 #[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
1437 pub struct SignalEvent {
1438 pub connection_id: u32,
1439 pub flag_number: u16,
1440 pub rsvd: u16,
1441 }
1442
1443 #[repr(C)]
1444 #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
1445 pub struct PostMessageDirect {
1446 pub partition_id: u64,
1447 pub vp_index: u32,
1448 pub vtl: u8,
1449 pub padding0: [u8; 3],
1450 pub sint: u8,
1451 pub padding1: [u8; 3],
1452 pub message: Unalign<HvMessage>,
1453 pub padding2: u32,
1454 }
1455
1456 #[repr(C)]
1457 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
1458 pub struct SignalEventDirect {
1459 pub target_partition: u64,
1460 pub target_vp: u32,
1461 pub target_vtl: u8,
1462 pub target_sint: u8,
1463 pub flag_number: u16,
1464 }
1465
1466 #[repr(C)]
1467 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
1468 pub struct SignalEventDirectOutput {
1469 pub newly_signaled: u8,
1470 pub rsvd: [u8; 7],
1471 }
1472
1473 #[repr(C)]
1474 #[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
1475 pub struct InterruptEntry {
1476 pub source: HvInterruptSource,
1477 pub rsvd: u32,
1478 pub data: [u32; 2],
1479 }
1480
1481 open_enum! {
1482 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
1483 pub enum HvInterruptSource: u32 {
1484 MSI = 1,
1485 IO_APIC = 2,
1486 }
1487 }
1488
1489 #[repr(C)]
1490 #[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
1491 pub struct InterruptTarget {
1492 pub vector: u32,
1493 pub flags: HvInterruptTargetFlags,
1494 pub mask_or_format: u64,
1495 }
1496
1497 #[bitfield(u32)]
1498 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
1499 pub struct HvInterruptTargetFlags {
1500 pub multicast: bool,
1501 pub processor_set: bool,
1502 pub proxy_redirect: bool,
1503 #[bits(29)]
1504 pub reserved: u32,
1505 }
1506
1507 pub const HV_DEVICE_INTERRUPT_TARGET_MULTICAST: u32 = 1;
1508 pub const HV_DEVICE_INTERRUPT_TARGET_PROCESSOR_SET: u32 = 2;
1509 pub const HV_DEVICE_INTERRUPT_TARGET_PROXY_REDIRECT: u32 = 4;
1510
1511 pub const HV_GENERIC_SET_SPARSE_4K: u64 = 0;
1512 pub const HV_GENERIC_SET_ALL: u64 = 1;
1513
1514 #[repr(C)]
1515 #[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
1516 pub struct RetargetDeviceInterrupt {
1517 pub partition_id: u64,
1518 pub device_id: u64,
1519 pub entry: InterruptEntry,
1520 pub rsvd: u64,
1521 pub target_header: InterruptTarget,
1522 }
1523
1524 #[bitfield(u8)]
1525 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
1526 pub struct HvInputVtl {
1527 #[bits(4)]
1528 pub target_vtl_value: u8,
1529 pub use_target_vtl: bool,
1530 #[bits(3)]
1531 pub reserved: u8,
1532 }
1533
1534 impl From<Vtl> for HvInputVtl {
1535 fn from(value: Vtl) -> Self {
1536 Self::from(Some(value))
1537 }
1538 }
1539
1540 impl From<Option<Vtl>> for HvInputVtl {
1541 fn from(value: Option<Vtl>) -> Self {
1542 Self::new()
1543 .with_use_target_vtl(value.is_some())
1544 .with_target_vtl_value(value.map_or(0, Into::into))
1545 }
1546 }
1547
1548 impl HvInputVtl {
1549 pub fn target_vtl(&self) -> Result<Option<Vtl>, HvError> {
1551 if self.reserved() != 0 {
1552 return Err(HvError::InvalidParameter);
1553 }
1554 if self.use_target_vtl() {
1555 Ok(Some(self.target_vtl_value().try_into()?))
1556 } else {
1557 Ok(None)
1558 }
1559 }
1560
1561 pub const CURRENT_VTL: Self = Self::new();
1562 }
1563
1564 #[repr(C)]
1565 #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
1566 pub struct GetSetVpRegisters {
1567 pub partition_id: u64,
1568 pub vp_index: u32,
1569 pub target_vtl: HvInputVtl,
1570 pub rsvd: [u8; 3],
1571 }
1572
1573 open_enum::open_enum! {
1574 #[derive(Default)]
1575 pub enum HvGuestOsMicrosoftIds: u8 {
1576 UNDEFINED = 0x00,
1577 MSDOS = 0x01,
1578 WINDOWS_3X = 0x02,
1579 WINDOWS_9X = 0x03,
1580 WINDOWS_NT = 0x04,
1581 WINDOWS_CE = 0x05,
1582 }
1583 }
1584
1585 #[bitfield(u64)]
1586 pub struct HvGuestOsMicrosoft {
1587 #[bits(40)]
1588 _rsvd: u64,
1589 #[bits(8)]
1590 pub os_id: u8,
1591 #[bits(16)]
1593 pub vendor_id: u16,
1594 }
1595
1596 open_enum::open_enum! {
1597 #[derive(Default)]
1598 pub enum HvGuestOsOpenSourceType: u8 {
1599 UNDEFINED = 0x00,
1600 LINUX = 0x01,
1601 FREEBSD = 0x02,
1602 XEN = 0x03,
1603 ILLUMOS = 0x04,
1604 }
1605 }
1606
1607 #[bitfield(u64)]
1608 pub struct HvGuestOsOpenSource {
1609 #[bits(16)]
1610 pub build_no: u16,
1611 #[bits(32)]
1612 pub version: u32,
1613 #[bits(8)]
1614 pub os_id: u8,
1615 #[bits(7)]
1616 pub os_type: u8,
1617 #[bits(1)]
1618 pub is_open_source: bool,
1619 }
1620
1621 #[bitfield(u64)]
1622 pub struct HvGuestOsId {
1623 #[bits(63)]
1624 _rsvd: u64,
1625 is_open_source: bool,
1626 }
1627
1628 impl HvGuestOsId {
1629 pub fn microsoft(&self) -> Option<HvGuestOsMicrosoft> {
1630 (!self.is_open_source()).then(|| HvGuestOsMicrosoft::from(u64::from(*self)))
1631 }
1632
1633 pub fn open_source(&self) -> Option<HvGuestOsOpenSource> {
1634 (self.is_open_source()).then(|| HvGuestOsOpenSource::from(u64::from(*self)))
1635 }
1636
1637 pub fn as_u64(&self) -> u64 {
1638 self.0
1639 }
1640 }
1641
1642 pub const HV_INTERCEPT_ACCESS_MASK_NONE: u32 = 0x00;
1643 pub const HV_INTERCEPT_ACCESS_MASK_READ: u32 = 0x01;
1644 pub const HV_INTERCEPT_ACCESS_MASK_WRITE: u32 = 0x02;
1645 pub const HV_INTERCEPT_ACCESS_MASK_READ_WRITE: u32 =
1646 HV_INTERCEPT_ACCESS_MASK_READ | HV_INTERCEPT_ACCESS_MASK_WRITE;
1647 pub const HV_INTERCEPT_ACCESS_MASK_EXECUTE: u32 = 0x04;
1648
1649 open_enum::open_enum! {
1650 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
1651 pub enum HvInterceptType: u32 {
1652 #![expect(non_upper_case_globals)]
1653 HvInterceptTypeX64IoPort = 0x00000000,
1654 HvInterceptTypeX64Msr = 0x00000001,
1655 HvInterceptTypeX64Cpuid = 0x00000002,
1656 HvInterceptTypeException = 0x00000003,
1657 HvInterceptTypeHypercall = 0x00000008,
1658 HvInterceptTypeUnknownSynicConnection = 0x0000000D,
1659 HvInterceptTypeX64ApicEoi = 0x0000000E,
1660 HvInterceptTypeRetargetInterruptWithUnknownDeviceId = 0x0000000F,
1661 HvInterceptTypeX64IoPortRange = 0x00000011,
1662 }
1663 }
1664
1665 #[repr(transparent)]
1666 #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, Debug)]
1667 pub struct HvInterceptParameters(u64);
1668
1669 impl HvInterceptParameters {
1670 pub fn new_io_port(port: u16) -> Self {
1671 Self(port as u64)
1672 }
1673
1674 pub fn new_io_port_range(ports: RangeInclusive<u16>) -> Self {
1675 let base = *ports.start() as u64;
1676 let end = *ports.end() as u64;
1677 Self(base | (end << 16))
1678 }
1679
1680 pub fn new_exception(vector: u16) -> Self {
1681 Self(vector as u64)
1682 }
1683
1684 pub fn io_port(&self) -> u16 {
1685 self.0 as u16
1686 }
1687
1688 pub fn io_port_range(&self) -> RangeInclusive<u16> {
1689 let base = self.0 as u16;
1690 let end = (self.0 >> 16) as u16;
1691 base..=end
1692 }
1693
1694 pub fn cpuid_index(&self) -> u32 {
1695 self.0 as u32
1696 }
1697
1698 pub fn exception(&self) -> u16 {
1699 self.0 as u16
1700 }
1701 }
1702
1703 #[repr(C)]
1704 #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, Debug)]
1705 pub struct InstallIntercept {
1706 pub partition_id: u64,
1707 pub access_type_mask: u32,
1708 pub intercept_type: HvInterceptType,
1709 pub intercept_parameters: HvInterceptParameters,
1710 }
1711
1712 #[repr(C)]
1714 #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, Debug)]
1715 pub struct RegisterInterceptResultCpuid {
1716 pub partition_id: u64,
1717 pub vp_index: u32,
1718 pub intercept_type: HvInterceptType,
1719 pub parameters: HvRegisterX64CpuidResultParameters,
1720 pub _reserved: u32,
1722 }
1723
1724 #[repr(C)]
1726 #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, Debug)]
1727 pub struct HvRegisterX64CpuidResultParameters {
1728 pub input: HvRegisterX64CpuidResultParametersInput,
1729 pub result: HvRegisterX64CpuidResultParametersOutput,
1730 }
1731
1732 #[repr(C)]
1734 #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, Debug)]
1735 pub struct HvRegisterX64CpuidResultParametersInput {
1736 pub eax: u32,
1737 pub ecx: u32,
1738 pub subleaf_specific: u8,
1739 pub always_override: u8,
1740 pub padding: u16,
1741 }
1742
1743 #[repr(C)]
1745 #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, Debug)]
1746 pub struct HvRegisterX64CpuidResultParametersOutput {
1747 pub eax: u32,
1748 pub eax_mask: u32,
1749 pub ebx: u32,
1750 pub ebx_mask: u32,
1751 pub ecx: u32,
1752 pub ecx_mask: u32,
1753 pub edx: u32,
1754 pub edx_mask: u32,
1755 }
1756
1757 #[repr(C)]
1758 #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, Debug)]
1759 pub struct AssertVirtualInterrupt {
1760 pub partition_id: u64,
1761 pub interrupt_control: HvInterruptControl,
1762 pub destination_address: u64,
1763 pub requested_vector: u32,
1764 pub target_vtl: u8,
1765 pub rsvd0: u8,
1766 pub rsvd1: u16,
1767 }
1768
1769 #[repr(C)]
1770 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
1771 pub struct StartVirtualProcessorX64 {
1772 pub partition_id: u64,
1773 pub vp_index: u32,
1774 pub target_vtl: u8,
1775 pub rsvd0: u8,
1776 pub rsvd1: u16,
1777 pub vp_context: InitialVpContextX64,
1778 }
1779
1780 #[repr(C)]
1781 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
1782 pub struct InitialVpContextX64 {
1783 pub rip: u64,
1784 pub rsp: u64,
1785 pub rflags: u64,
1786 pub cs: HvX64SegmentRegister,
1787 pub ds: HvX64SegmentRegister,
1788 pub es: HvX64SegmentRegister,
1789 pub fs: HvX64SegmentRegister,
1790 pub gs: HvX64SegmentRegister,
1791 pub ss: HvX64SegmentRegister,
1792 pub tr: HvX64SegmentRegister,
1793 pub ldtr: HvX64SegmentRegister,
1794 pub idtr: HvX64TableRegister,
1795 pub gdtr: HvX64TableRegister,
1796 pub efer: u64,
1797 pub cr0: u64,
1798 pub cr3: u64,
1799 pub cr4: u64,
1800 pub msr_cr_pat: u64,
1801 }
1802
1803 #[repr(C)]
1804 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
1805 pub struct StartVirtualProcessorArm64 {
1806 pub partition_id: u64,
1807 pub vp_index: u32,
1808 pub target_vtl: u8,
1809 pub rsvd0: u8,
1810 pub rsvd1: u16,
1811 pub vp_context: InitialVpContextArm64,
1812 }
1813
1814 #[repr(C)]
1815 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
1816 pub struct InitialVpContextArm64 {
1817 pub pc: u64,
1818 pub sp_elh: u64,
1819 pub sctlr_el1: u64,
1820 pub mair_el1: u64,
1821 pub tcr_el1: u64,
1822 pub vbar_el1: u64,
1823 pub ttbr0_el1: u64,
1824 pub ttbr1_el1: u64,
1825 pub x18: u64,
1826 }
1827
1828 impl InitialVpContextX64 {
1829 pub fn as_hv_register_assocs(&self) -> impl Iterator<Item = HvRegisterAssoc> + '_ {
1830 let regs = [
1831 (HvX64RegisterName::Rip, HvRegisterValue::from(self.rip)).into(),
1832 (HvX64RegisterName::Rsp, HvRegisterValue::from(self.rsp)).into(),
1833 (
1834 HvX64RegisterName::Rflags,
1835 HvRegisterValue::from(self.rflags),
1836 )
1837 .into(),
1838 (HvX64RegisterName::Cs, HvRegisterValue::from(self.cs)).into(),
1839 (HvX64RegisterName::Ds, HvRegisterValue::from(self.ds)).into(),
1840 (HvX64RegisterName::Es, HvRegisterValue::from(self.es)).into(),
1841 (HvX64RegisterName::Fs, HvRegisterValue::from(self.fs)).into(),
1842 (HvX64RegisterName::Gs, HvRegisterValue::from(self.gs)).into(),
1843 (HvX64RegisterName::Ss, HvRegisterValue::from(self.ss)).into(),
1844 (HvX64RegisterName::Tr, HvRegisterValue::from(self.tr)).into(),
1845 (HvX64RegisterName::Ldtr, HvRegisterValue::from(self.ldtr)).into(),
1846 (HvX64RegisterName::Idtr, HvRegisterValue::from(self.idtr)).into(),
1847 (HvX64RegisterName::Gdtr, HvRegisterValue::from(self.gdtr)).into(),
1848 (HvX64RegisterName::Efer, HvRegisterValue::from(self.efer)).into(),
1849 (HvX64RegisterName::Cr0, HvRegisterValue::from(self.cr0)).into(),
1850 (HvX64RegisterName::Cr3, HvRegisterValue::from(self.cr3)).into(),
1851 (HvX64RegisterName::Cr4, HvRegisterValue::from(self.cr4)).into(),
1852 (
1853 HvX64RegisterName::Pat,
1854 HvRegisterValue::from(self.msr_cr_pat),
1855 )
1856 .into(),
1857 ];
1858 regs.into_iter()
1859 }
1860 }
1861
1862 #[bitfield(u64)]
1863 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
1864 pub struct TranslateGvaControlFlagsX64 {
1865 pub validate_read: bool,
1867 pub validate_write: bool,
1869 pub validate_execute: bool,
1871 pub privilege_exempt: bool,
1874 pub set_page_table_bits: bool,
1876 pub tlb_flush_inhibit: bool,
1878 pub supervisor_access: bool,
1880 pub user_access: bool,
1882 pub enforce_smap: bool,
1886 pub override_smap: bool,
1889 pub shadow_stack: bool,
1891 #[bits(45)]
1892 _unused: u64,
1893 input_vtl_value: u8,
1895 }
1896
1897 impl TranslateGvaControlFlagsX64 {
1898 pub fn input_vtl(&self) -> HvInputVtl {
1899 self.input_vtl_value().into()
1900 }
1901
1902 pub fn with_input_vtl(self, input_vtl: HvInputVtl) -> Self {
1903 self.with_input_vtl_value(input_vtl.into())
1904 }
1905
1906 pub fn set_input_vtl(&mut self, input_vtl: HvInputVtl) {
1907 self.set_input_vtl_value(input_vtl.into())
1908 }
1909 }
1910
1911 #[bitfield(u64)]
1912 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
1913 pub struct TranslateGvaControlFlagsArm64 {
1914 pub validate_read: bool,
1916 pub validate_write: bool,
1918 pub validate_execute: bool,
1920 _reserved0: bool,
1921 pub set_page_table_bits: bool,
1923 pub tlb_flush_inhibit: bool,
1925 pub supervisor_access: bool,
1927 pub user_access: bool,
1929 pub pan_set: bool,
1932 pub pan_clear: bool,
1935 #[bits(46)]
1936 _unused: u64,
1937 #[bits(8)]
1939 input_vtl_value: u8,
1940 }
1941
1942 impl TranslateGvaControlFlagsArm64 {
1943 pub fn input_vtl(&self) -> HvInputVtl {
1944 self.input_vtl_value().into()
1945 }
1946
1947 pub fn with_input_vtl(self, input_vtl: HvInputVtl) -> Self {
1948 self.with_input_vtl_value(input_vtl.into())
1949 }
1950
1951 pub fn set_input_vtl(&mut self, input_vtl: HvInputVtl) {
1952 self.set_input_vtl_value(input_vtl.into())
1953 }
1954 }
1955
1956 #[repr(C)]
1957 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
1958 pub struct TranslateVirtualAddressX64 {
1959 pub partition_id: u64,
1960 pub vp_index: u32,
1961 pub reserved: u32,
1963 pub control_flags: TranslateGvaControlFlagsX64,
1964 pub gva_page: u64,
1965 }
1966
1967 #[repr(C)]
1968 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
1969 pub struct TranslateVirtualAddressArm64 {
1970 pub partition_id: u64,
1971 pub vp_index: u32,
1972 pub reserved: u32,
1974 pub control_flags: TranslateGvaControlFlagsArm64,
1975 pub gva_page: u64,
1976 }
1977
1978 open_enum::open_enum! {
1979 pub enum TranslateGvaResultCode: u32 {
1980 SUCCESS = 0,
1981
1982 PAGE_NOT_PRESENT = 1,
1984 PRIVILEGE_VIOLATION = 2,
1985 INVALID_PAGE_TABLE_FLAGS = 3,
1986
1987 GPA_UNMAPPED = 4,
1989 GPA_NO_READ_ACCESS = 5,
1990 GPA_NO_WRITE_ACCESS = 6,
1991 GPA_ILLEGAL_OVERLAY_ACCESS = 7,
1992
1993 INTERCEPT = 8,
1997
1998 GPA_UNACCEPTED = 9,
1999 }
2000 }
2001
2002 #[bitfield(u64)]
2003 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2004 pub struct TranslateGvaResult {
2005 pub result_code: u32,
2006 pub cache_type: u8,
2007 pub overlay_page: bool,
2008 #[bits(23)]
2009 pub reserved: u32,
2010 }
2011
2012 #[repr(C)]
2013 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2014 pub struct TranslateVirtualAddressOutput {
2015 pub translation_result: TranslateGvaResult,
2016 pub gpa_page: u64,
2017 }
2018
2019 #[repr(C)]
2020 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2021 pub struct TranslateGvaResultExX64 {
2022 pub result: TranslateGvaResult,
2023 pub reserved: u64,
2024 pub event_info: HvX64PendingEvent,
2025 }
2026
2027 const_assert!(size_of::<TranslateGvaResultExX64>() == 0x30);
2028
2029 #[repr(C)]
2030 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2031 pub struct TranslateGvaResultExArm64 {
2032 pub result: TranslateGvaResult,
2033 }
2034
2035 const_assert!(size_of::<TranslateGvaResultExArm64>() == 0x8);
2036
2037 #[repr(C)]
2038 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2039 pub struct TranslateVirtualAddressExOutputX64 {
2040 pub translation_result: TranslateGvaResultExX64,
2041 pub gpa_page: u64,
2042 pub reserved: u64,
2044 }
2045
2046 const_assert!(size_of::<TranslateVirtualAddressExOutputX64>() == 0x40);
2047
2048 #[repr(C)]
2049 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2050 pub struct TranslateVirtualAddressExOutputArm64 {
2051 pub translation_result: TranslateGvaResultExArm64,
2052 pub gpa_page: u64,
2053 }
2054
2055 const_assert!(size_of::<TranslateVirtualAddressExOutputArm64>() == 0x10);
2056
2057 #[repr(C)]
2058 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2059 pub struct GetVpIndexFromApicId {
2060 pub partition_id: u64,
2061 pub target_vtl: u8,
2062 pub reserved: [u8; 7],
2063 }
2064
2065 #[repr(C)]
2066 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2067 pub struct EnableVpVtlX64 {
2068 pub partition_id: u64,
2069 pub vp_index: u32,
2070 pub target_vtl: u8,
2071 pub reserved: [u8; 3],
2072 pub vp_vtl_context: InitialVpContextX64,
2073 }
2074
2075 #[repr(C)]
2076 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2077 pub struct EnableVpVtlArm64 {
2078 pub partition_id: u64,
2079 pub vp_index: u32,
2080 pub target_vtl: u8,
2081 pub reserved: [u8; 3],
2082 pub vp_vtl_context: InitialVpContextArm64,
2083 }
2084
2085 #[repr(C)]
2086 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2087 pub struct ModifyVtlProtectionMask {
2088 pub partition_id: u64,
2089 pub map_flags: HvMapGpaFlags,
2090 pub target_vtl: HvInputVtl,
2091 pub reserved: [u8; 3],
2092 }
2093
2094 #[repr(C)]
2095 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2096 pub struct CheckSparseGpaPageVtlAccess {
2097 pub partition_id: u64,
2098 pub target_vtl: HvInputVtl,
2099 pub desired_access: u8,
2100 pub reserved0: u16,
2101 pub reserved1: u32,
2102 }
2103 const_assert!(size_of::<CheckSparseGpaPageVtlAccess>() == 0x10);
2104
2105 #[bitfield(u64)]
2106 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2107 pub struct CheckSparseGpaPageVtlAccessOutput {
2108 pub result_code: u8,
2109 pub denied_access: u8,
2110 #[bits(4)]
2111 pub intercepting_vtl: u32,
2112 #[bits(12)]
2113 _reserved0: u32,
2114 _reserved1: u32,
2115 }
2116 const_assert!(size_of::<CheckSparseGpaPageVtlAccessOutput>() == 0x8);
2117
2118 open_enum::open_enum! {
2119 pub enum CheckGpaPageVtlAccessResultCode: u32 {
2120 SUCCESS = 0,
2121 MEMORY_INTERCEPT = 1,
2122 }
2123 }
2124
2125 pub const HV_VTL_PERMISSION_SET_SIZE: usize = 2;
2127
2128 #[repr(C)]
2129 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2130 pub struct VtlPermissionSet {
2131 pub vtl_permission_from_1: [u16; HV_VTL_PERMISSION_SET_SIZE],
2133 }
2134
2135 open_enum::open_enum! {
2136 pub enum AcceptMemoryType: u32 {
2137 ANY = 0,
2138 RAM = 1,
2139 }
2140 }
2141
2142 open_enum! {
2143 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2150 pub enum HostVisibilityType: u8 {
2151 PRIVATE = 0,
2152 SHARED = 3,
2153 }
2154 }
2155
2156 impl HostVisibilityType {
2158 const fn from_bits(value: u8) -> Self {
2159 Self(value)
2160 }
2161
2162 const fn into_bits(value: Self) -> u8 {
2163 value.0
2164 }
2165 }
2166
2167 #[bitfield(u32)]
2169 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2170 pub struct AcceptPagesAttributes {
2171 #[bits(6)]
2172 pub memory_type: u32,
2174 #[bits(2)]
2175 pub host_visibility: HostVisibilityType,
2177 #[bits(3)]
2178 pub vtl_set: u32,
2180 #[bits(21)]
2181 _reserved: u32,
2182 }
2183
2184 #[repr(C)]
2185 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2186 pub struct AcceptGpaPages {
2187 pub partition_id: u64,
2189 pub page_attributes: AcceptPagesAttributes,
2192 pub vtl_permission_set: VtlPermissionSet,
2194 pub gpa_page_base: u64,
2196 }
2197 const_assert!(size_of::<AcceptGpaPages>() == 0x18);
2198
2199 #[bitfield(u32)]
2201 pub struct UnacceptPagesAttributes {
2202 #[bits(3)]
2203 pub vtl_set: u32,
2204 #[bits(29)]
2205 _reserved: u32,
2206 }
2207
2208 #[repr(C)]
2209 pub struct UnacceptGpaPages {
2210 pub partition_id: u64,
2212 pub page_attributes: UnacceptPagesAttributes,
2214 pub vtl_permission_set: VtlPermissionSet,
2216 pub gpa_page_base: u64,
2218 }
2219 const_assert!(size_of::<UnacceptGpaPages>() == 0x18);
2220
2221 #[bitfield(u32)]
2222 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2223 pub struct ModifyHostVisibility {
2224 #[bits(2)]
2225 pub host_visibility: HostVisibilityType,
2226 #[bits(30)]
2227 _reserved: u32,
2228 }
2229
2230 #[repr(C)]
2231 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2232 pub struct ModifySparsePageVisibility {
2233 pub partition_id: u64,
2234 pub host_visibility: ModifyHostVisibility,
2235 pub reserved: u32,
2236 }
2237
2238 #[bitfield(u32)]
2241 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2242 pub struct ModifyHostVisibilityWithImmutability {
2243 #[bits(2)]
2244 pub host_visibility: HostVisibilityType,
2245 pub immutability: bool,
2246 #[bits(29)]
2247 _reserved: u32,
2248 }
2249
2250 #[repr(C)]
2253 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2254 pub struct ModifySparsePageVisibilityWithImmutability {
2255 pub partition_id: u64,
2256 pub host_visibility: ModifyHostVisibilityWithImmutability,
2257 pub reserved: u32,
2258 }
2259
2260 #[repr(C)]
2261 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2262 pub struct QuerySparsePageVisibility {
2263 pub partition_id: u64,
2264 }
2265
2266 pub const VBS_VM_REPORT_DATA_SIZE: usize = 64;
2267 pub const VBS_VM_MAX_REPORT_SIZE: usize = 2048;
2268
2269 #[repr(C)]
2270 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2271 pub struct VbsVmCallReport {
2272 pub report_data: [u8; VBS_VM_REPORT_DATA_SIZE],
2273 }
2274
2275 #[repr(C)]
2276 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2277 pub struct VbsVmCallReportOutput {
2278 pub report: [u8; VBS_VM_MAX_REPORT_SIZE],
2279 }
2280
2281 #[bitfield(u8)]
2282 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2283 pub struct EnablePartitionVtlFlags {
2284 pub enable_mbec: bool,
2285 pub enable_supervisor_shadow_stack: bool,
2286 pub enable_hardware_hvpt: bool,
2287 #[bits(5)]
2288 pub reserved: u8,
2289 }
2290
2291 #[repr(C)]
2292 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2293 pub struct EnablePartitionVtl {
2294 pub partition_id: u64,
2295 pub target_vtl: u8,
2296 pub flags: EnablePartitionVtlFlags,
2297 pub reserved_z0: u16,
2298 pub reserved_z1: u32,
2299 }
2300
2301 #[repr(C)]
2302 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2303 pub struct FlushVirtualAddressSpace {
2304 pub address_space: u64,
2305 pub flags: HvFlushFlags,
2306 pub processor_mask: u64,
2307 }
2308
2309 #[repr(C)]
2310 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2311 pub struct FlushVirtualAddressSpaceEx {
2312 pub address_space: u64,
2313 pub flags: HvFlushFlags,
2314 pub vp_set_format: u64,
2315 pub vp_set_valid_banks_mask: u64,
2316 }
2318
2319 #[repr(C)]
2320 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2321 pub struct PinUnpinGpaPageRangesHeader {
2322 pub reserved: u64,
2323 }
2324
2325 #[repr(C)]
2326 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2327 pub struct SendSyntheticClusterIpi {
2328 pub vector: u32,
2329 pub target_vtl: HvInputVtl,
2330 pub flags: u8,
2331 pub reserved: u16,
2332 pub processor_mask: u64,
2333 }
2334
2335 #[repr(C)]
2336 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2337 pub struct SendSyntheticClusterIpiEx {
2338 pub vector: u32,
2339 pub target_vtl: HvInputVtl,
2340 pub flags: u8,
2341 pub reserved: u16,
2342 pub vp_set_format: u64,
2343 pub vp_set_valid_banks_mask: u64,
2344 }
2346
2347 #[bitfield(u64)]
2348 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2349 pub struct HvFlushFlags {
2350 pub all_processors: bool,
2351 pub all_virtual_address_spaces: bool,
2352 pub non_global_mappings_only: bool,
2353 pub use_extended_range_format: bool,
2354 pub use_target_vtl: bool,
2355
2356 #[bits(3)]
2357 _reserved: u8,
2358
2359 pub target_vtl0: bool,
2360 pub target_vtl1: bool,
2361
2362 #[bits(54)]
2363 _reserved2: u64,
2364 }
2365
2366 #[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
2367 #[repr(transparent)]
2368 pub struct HvGvaRange(pub u64);
2369
2370 impl From<u64> for HvGvaRange {
2371 fn from(value: u64) -> Self {
2372 Self(value)
2373 }
2374 }
2375
2376 impl From<HvGvaRange> for u64 {
2377 fn from(value: HvGvaRange) -> Self {
2378 value.0
2379 }
2380 }
2381
2382 impl HvGvaRange {
2383 pub fn as_simple(self) -> HvGvaRangeSimple {
2384 HvGvaRangeSimple(self.0)
2385 }
2386
2387 pub fn as_extended(self) -> HvGvaRangeExtended {
2388 HvGvaRangeExtended(self.0)
2389 }
2390
2391 pub fn as_extended_large_page(self) -> HvGvaRangeExtendedLargePage {
2392 HvGvaRangeExtendedLargePage(self.0)
2393 }
2394 }
2395
2396 #[bitfield(u64)]
2397 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2398 pub struct HvGvaRangeSimple {
2399 #[bits(12)]
2401 pub additional_pages: u64,
2402 #[bits(52)]
2404 pub gva_page_number: u64,
2405 }
2406
2407 #[bitfield(u64)]
2408 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2409 pub struct HvGvaRangeExtended {
2410 #[bits(11)]
2412 pub additional_pages: u64,
2413 pub large_page: bool,
2415 #[bits(52)]
2417 pub gva_page_number: u64,
2418 }
2419
2420 #[bitfield(u64)]
2421 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2422 pub struct HvGvaRangeExtendedLargePage {
2423 #[bits(11)]
2425 pub additional_pages: u64,
2426 pub large_page: bool,
2428 pub page_size: bool,
2432 #[bits(8)]
2433 _reserved: u64,
2434 #[bits(43)]
2436 pub gva_large_page_number: u64,
2437 }
2438
2439 #[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
2440 #[repr(transparent)]
2441 pub struct HvGpaRange(pub u64);
2442
2443 impl HvGpaRange {
2444 pub fn as_simple(self) -> HvGpaRangeSimple {
2445 HvGpaRangeSimple(self.0)
2446 }
2447
2448 pub fn as_extended(self) -> HvGpaRangeExtended {
2449 HvGpaRangeExtended(self.0)
2450 }
2451
2452 pub fn as_extended_large_page(self) -> HvGpaRangeExtendedLargePage {
2453 HvGpaRangeExtendedLargePage(self.0)
2454 }
2455 }
2456
2457 #[bitfield(u64)]
2458 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2459 pub struct HvGpaRangeSimple {
2460 #[bits(12)]
2462 pub additional_pages: u64,
2463 #[bits(52)]
2465 pub gpa_page_number: u64,
2466 }
2467
2468 #[bitfield(u64)]
2469 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2470 pub struct HvGpaRangeExtended {
2471 #[bits(11)]
2473 pub additional_pages: u64,
2474 pub large_page: bool,
2476 #[bits(52)]
2478 pub gpa_page_number: u64,
2479 }
2480
2481 #[bitfield(u64)]
2482 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2483 pub struct HvGpaRangeExtendedLargePage {
2484 #[bits(11)]
2486 pub additional_pages: u64,
2487 pub large_page: bool,
2489 pub page_size: bool,
2493 #[bits(8)]
2494 _reserved: u64,
2495 #[bits(43)]
2497 pub gpa_large_page_number: u64,
2498 }
2499
2500 pub const HV_HYPERCALL_MMIO_MAX_DATA_LENGTH: usize = 64;
2501
2502 #[repr(C)]
2503 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2504 pub struct MemoryMappedIoRead {
2505 pub gpa: u64,
2506 pub access_width: u32,
2507 pub reserved_z0: u32,
2508 }
2509
2510 #[repr(C)]
2511 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2512 pub struct MemoryMappedIoReadOutput {
2513 pub data: [u8; HV_HYPERCALL_MMIO_MAX_DATA_LENGTH],
2514 }
2515
2516 #[repr(C)]
2517 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2518 pub struct MemoryMappedIoWrite {
2519 pub gpa: u64,
2520 pub access_width: u32,
2521 pub reserved_z0: u32,
2522 pub data: [u8; HV_HYPERCALL_MMIO_MAX_DATA_LENGTH],
2523 }
2524
2525 #[repr(C)]
2526 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2527 pub struct RestorePartitionTime {
2528 pub partition_id: u64,
2529 pub tsc_sequence: u32,
2530 pub reserved: u32,
2531 pub reference_time_in_100_ns: u64,
2532 pub tsc: u64,
2533 }
2534}
2535
2536macro_rules! registers {
2537 ($name:ident {
2538 $(
2539 $(#[$vattr:meta])*
2540 $variant:ident = $value:expr
2541 ),*
2542 $(,)?
2543 }) => {
2544 open_enum! {
2545 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2546 pub enum $name: u32 {
2547 #![expect(non_upper_case_globals)]
2548 $($variant = $value,)*
2549 InstructionEmulationHints = 0x00000002,
2550 InternalActivityState = 0x00000004,
2551
2552 GuestCrashP0 = 0x00000210,
2554 GuestCrashP1 = 0x00000211,
2555 GuestCrashP2 = 0x00000212,
2556 GuestCrashP3 = 0x00000213,
2557 GuestCrashP4 = 0x00000214,
2558 GuestCrashCtl = 0x00000215,
2559
2560 PendingInterruption = 0x00010002,
2561 InterruptState = 0x00010003,
2562 PendingEvent0 = 0x00010004,
2563 PendingEvent1 = 0x00010005,
2564 DeliverabilityNotifications = 0x00010006,
2565
2566 GicrBaseGpa = 0x00063000,
2567
2568 VpRuntime = 0x00090000,
2569 GuestOsId = 0x00090002,
2570 VpIndex = 0x00090003,
2571 TimeRefCount = 0x00090004,
2572 CpuManagementVersion = 0x00090007,
2573 VpAssistPage = 0x00090013,
2574 VpRootSignalCount = 0x00090014,
2575 ReferenceTsc = 0x00090017,
2576 VpConfig = 0x00090018,
2577 Ghcb = 0x00090019,
2578 ReferenceTscSequence = 0x0009001A,
2579 GuestSchedulerEvent = 0x0009001B,
2580
2581 Sint0 = 0x000A0000,
2582 Sint1 = 0x000A0001,
2583 Sint2 = 0x000A0002,
2584 Sint3 = 0x000A0003,
2585 Sint4 = 0x000A0004,
2586 Sint5 = 0x000A0005,
2587 Sint6 = 0x000A0006,
2588 Sint7 = 0x000A0007,
2589 Sint8 = 0x000A0008,
2590 Sint9 = 0x000A0009,
2591 Sint10 = 0x000A000A,
2592 Sint11 = 0x000A000B,
2593 Sint12 = 0x000A000C,
2594 Sint13 = 0x000A000D,
2595 Sint14 = 0x000A000E,
2596 Sint15 = 0x000A000F,
2597 Scontrol = 0x000A0010,
2598 Sversion = 0x000A0011,
2599 Sifp = 0x000A0012,
2600 Sipp = 0x000A0013,
2601 Eom = 0x000A0014,
2602 Sirbp = 0x000A0015,
2603
2604 Stimer0Config = 0x000B0000,
2605 Stimer0Count = 0x000B0001,
2606 Stimer1Config = 0x000B0002,
2607 Stimer1Count = 0x000B0003,
2608 Stimer2Config = 0x000B0004,
2609 Stimer2Count = 0x000B0005,
2610 Stimer3Config = 0x000B0006,
2611 Stimer3Count = 0x000B0007,
2612 StimeUnhaltedTimerConfig = 0x000B0100,
2613 StimeUnhaltedTimerCount = 0x000B0101,
2614
2615 VsmCodePageOffsets = 0x000D0002,
2616 VsmVpStatus = 0x000D0003,
2617 VsmPartitionStatus = 0x000D0004,
2618 VsmVina = 0x000D0005,
2619 VsmCapabilities = 0x000D0006,
2620 VsmPartitionConfig = 0x000D0007,
2621 GuestVsmPartitionConfig = 0x000D0008,
2622 VsmVpSecureConfigVtl0 = 0x000D0010,
2623 VsmVpSecureConfigVtl1 = 0x000D0011,
2624 VsmVpSecureConfigVtl2 = 0x000D0012,
2625 VsmVpSecureConfigVtl3 = 0x000D0013,
2626 VsmVpSecureConfigVtl4 = 0x000D0014,
2627 VsmVpSecureConfigVtl5 = 0x000D0015,
2628 VsmVpSecureConfigVtl6 = 0x000D0016,
2629 VsmVpSecureConfigVtl7 = 0x000D0017,
2630 VsmVpSecureConfigVtl8 = 0x000D0018,
2631 VsmVpSecureConfigVtl9 = 0x000D0019,
2632 VsmVpSecureConfigVtl10 = 0x000D001A,
2633 VsmVpSecureConfigVtl11 = 0x000D001B,
2634 VsmVpSecureConfigVtl12 = 0x000D001C,
2635 VsmVpSecureConfigVtl13 = 0x000D001D,
2636 VsmVpSecureConfigVtl14 = 0x000D001E,
2637 VsmVpWaitForTlbLock = 0x000D0020,
2638 }
2639 }
2640
2641 impl From<HvRegisterName> for $name {
2642 fn from(name: HvRegisterName) -> Self {
2643 Self(name.0)
2644 }
2645 }
2646
2647 impl From<$name> for HvRegisterName {
2648 fn from(name: $name) -> Self {
2649 Self(name.0)
2650 }
2651 }
2652 };
2653}
2654
2655#[repr(C)]
2660#[derive(Debug, Copy, Clone, PartialEq, Eq, IntoBytes, Immutable, KnownLayout, FromBytes)]
2661pub struct HvRegisterName(pub u32);
2662
2663registers! {
2664 HvAllArchRegisterName {}
2666}
2667
2668impl From<HvAllArchRegisterName> for HvX64RegisterName {
2669 fn from(name: HvAllArchRegisterName) -> Self {
2670 Self(name.0)
2671 }
2672}
2673
2674impl From<HvAllArchRegisterName> for HvArm64RegisterName {
2675 fn from(name: HvAllArchRegisterName) -> Self {
2676 Self(name.0)
2677 }
2678}
2679
2680registers! {
2681 HvX64RegisterName {
2682 Rax = 0x00020000,
2684 Rcx = 0x00020001,
2685 Rdx = 0x00020002,
2686 Rbx = 0x00020003,
2687 Rsp = 0x00020004,
2688 Rbp = 0x00020005,
2689 Rsi = 0x00020006,
2690 Rdi = 0x00020007,
2691 R8 = 0x00020008,
2692 R9 = 0x00020009,
2693 R10 = 0x0002000a,
2694 R11 = 0x0002000b,
2695 R12 = 0x0002000c,
2696 R13 = 0x0002000d,
2697 R14 = 0x0002000e,
2698 R15 = 0x0002000f,
2699 Rip = 0x00020010,
2700 Rflags = 0x00020011,
2701
2702 Xmm0 = 0x00030000,
2704 Xmm1 = 0x00030001,
2705 Xmm2 = 0x00030002,
2706 Xmm3 = 0x00030003,
2707 Xmm4 = 0x00030004,
2708 Xmm5 = 0x00030005,
2709 Xmm6 = 0x00030006,
2710 Xmm7 = 0x00030007,
2711 Xmm8 = 0x00030008,
2712 Xmm9 = 0x00030009,
2713 Xmm10 = 0x0003000A,
2714 Xmm11 = 0x0003000B,
2715 Xmm12 = 0x0003000C,
2716 Xmm13 = 0x0003000D,
2717 Xmm14 = 0x0003000E,
2718 Xmm15 = 0x0003000F,
2719 FpMmx0 = 0x00030010,
2720 FpMmx1 = 0x00030011,
2721 FpMmx2 = 0x00030012,
2722 FpMmx3 = 0x00030013,
2723 FpMmx4 = 0x00030014,
2724 FpMmx5 = 0x00030015,
2725 FpMmx6 = 0x00030016,
2726 FpMmx7 = 0x00030017,
2727 FpControlStatus = 0x00030018,
2728 XmmControlStatus = 0x00030019,
2729
2730 Cr0 = 0x00040000,
2732 Cr2 = 0x00040001,
2733 Cr3 = 0x00040002,
2734 Cr4 = 0x00040003,
2735 Cr8 = 0x00040004,
2736 Xfem = 0x00040005,
2737 IntermediateCr0 = 0x00041000,
2739 IntermediateCr3 = 0x00041002,
2740 IntermediateCr4 = 0x00041003,
2741 IntermediateCr8 = 0x00041004,
2742 Dr0 = 0x00050000,
2744 Dr1 = 0x00050001,
2745 Dr2 = 0x00050002,
2746 Dr3 = 0x00050003,
2747 Dr6 = 0x00050004,
2748 Dr7 = 0x00050005,
2749 Es = 0x00060000,
2751 Cs = 0x00060001,
2752 Ss = 0x00060002,
2753 Ds = 0x00060003,
2754 Fs = 0x00060004,
2755 Gs = 0x00060005,
2756 Ldtr = 0x00060006,
2757 Tr = 0x00060007,
2758 Idtr = 0x00070000,
2760 Gdtr = 0x00070001,
2761 Tsc = 0x00080000,
2763 Efer = 0x00080001,
2764 KernelGsBase = 0x00080002,
2765 ApicBase = 0x00080003,
2766 Pat = 0x00080004,
2767 SysenterCs = 0x00080005,
2768 SysenterEip = 0x00080006,
2769 SysenterEsp = 0x00080007,
2770 Star = 0x00080008,
2771 Lstar = 0x00080009,
2772 Cstar = 0x0008000a,
2773 Sfmask = 0x0008000b,
2774 InitialApicId = 0x0008000c,
2775 MsrMtrrCap = 0x0008000d,
2777 MsrMtrrDefType = 0x0008000e,
2778 MsrMtrrPhysBase0 = 0x00080010,
2779 MsrMtrrPhysBase1 = 0x00080011,
2780 MsrMtrrPhysBase2 = 0x00080012,
2781 MsrMtrrPhysBase3 = 0x00080013,
2782 MsrMtrrPhysBase4 = 0x00080014,
2783 MsrMtrrPhysBase5 = 0x00080015,
2784 MsrMtrrPhysBase6 = 0x00080016,
2785 MsrMtrrPhysBase7 = 0x00080017,
2786 MsrMtrrPhysBase8 = 0x00080018,
2787 MsrMtrrPhysBase9 = 0x00080019,
2788 MsrMtrrPhysBaseA = 0x0008001a,
2789 MsrMtrrPhysBaseB = 0x0008001b,
2790 MsrMtrrPhysBaseC = 0x0008001c,
2791 MsrMtrrPhysBaseD = 0x0008001d,
2792 MsrMtrrPhysBaseE = 0x0008001e,
2793 MsrMtrrPhysBaseF = 0x0008001f,
2794 MsrMtrrPhysMask0 = 0x00080040,
2795 MsrMtrrPhysMask1 = 0x00080041,
2796 MsrMtrrPhysMask2 = 0x00080042,
2797 MsrMtrrPhysMask3 = 0x00080043,
2798 MsrMtrrPhysMask4 = 0x00080044,
2799 MsrMtrrPhysMask5 = 0x00080045,
2800 MsrMtrrPhysMask6 = 0x00080046,
2801 MsrMtrrPhysMask7 = 0x00080047,
2802 MsrMtrrPhysMask8 = 0x00080048,
2803 MsrMtrrPhysMask9 = 0x00080049,
2804 MsrMtrrPhysMaskA = 0x0008004a,
2805 MsrMtrrPhysMaskB = 0x0008004b,
2806 MsrMtrrPhysMaskC = 0x0008004c,
2807 MsrMtrrPhysMaskD = 0x0008004d,
2808 MsrMtrrPhysMaskE = 0x0008004e,
2809 MsrMtrrPhysMaskF = 0x0008004f,
2810 MsrMtrrFix64k00000 = 0x00080070,
2811 MsrMtrrFix16k80000 = 0x00080071,
2812 MsrMtrrFix16kA0000 = 0x00080072,
2813 MsrMtrrFix4kC0000 = 0x00080073,
2814 MsrMtrrFix4kC8000 = 0x00080074,
2815 MsrMtrrFix4kD0000 = 0x00080075,
2816 MsrMtrrFix4kD8000 = 0x00080076,
2817 MsrMtrrFix4kE0000 = 0x00080077,
2818 MsrMtrrFix4kE8000 = 0x00080078,
2819 MsrMtrrFix4kF0000 = 0x00080079,
2820 MsrMtrrFix4kF8000 = 0x0008007a,
2821
2822 TscAux = 0x0008007B,
2823 Bndcfgs = 0x0008007C,
2824 DebugCtl = 0x0008007D,
2825 MCount = 0x0008007E,
2826 ACount = 0x0008007F,
2827
2828 SgxLaunchControl0 = 0x00080080,
2829 SgxLaunchControl1 = 0x00080081,
2830 SgxLaunchControl2 = 0x00080082,
2831 SgxLaunchControl3 = 0x00080083,
2832 SpecCtrl = 0x00080084,
2833 PredCmd = 0x00080085,
2834 VirtSpecCtrl = 0x00080086,
2835 TscVirtualOffset = 0x00080087,
2836 TsxCtrl = 0x00080088,
2837 MsrMcUpdatePatchLevel = 0x00080089,
2838 Available1 = 0x0008008A,
2839 Xss = 0x0008008B,
2840 UCet = 0x0008008C,
2841 SCet = 0x0008008D,
2842 Ssp = 0x0008008E,
2843 Pl0Ssp = 0x0008008F,
2844 Pl1Ssp = 0x00080090,
2845 Pl2Ssp = 0x00080091,
2846 Pl3Ssp = 0x00080092,
2847 InterruptSspTableAddr = 0x00080093,
2848 TscVirtualMultiplier = 0x00080094,
2849 TscDeadline = 0x00080095,
2850 TscAdjust = 0x00080096,
2851 Pasid = 0x00080097,
2852 UmwaitControl = 0x00080098,
2853 Xfd = 0x00080099,
2854 XfdErr = 0x0008009A,
2855
2856 ApicId = 0x00084802,
2858 ApicVersion = 0x00084803,
2859 ApicTpr = 0x00084808,
2860 ApicPpr = 0x0008480a,
2861 ApicEoi = 0x0008480b,
2862 ApicLdr = 0x0008480d,
2863 ApicSpurious = 0x0008480f,
2864 ApicIsr0 = 0x00084810,
2865 ApicIsr1 = 0x00084811,
2866 ApicIsr2 = 0x00084812,
2867 ApicIsr3 = 0x00084813,
2868 ApicIsr4 = 0x00084814,
2869 ApicIsr5 = 0x00084815,
2870 ApicIsr6 = 0x00084816,
2871 ApicIsr7 = 0x00084817,
2872 ApicTmr0 = 0x00084818,
2873 ApicTmr1 = 0x00084819,
2874 ApicTmr2 = 0x0008481a,
2875 ApicTmr3 = 0x0008481b,
2876 ApicTmr4 = 0x0008481c,
2877 ApicTmr5 = 0x0008481d,
2878 ApicTmr6 = 0x0008481e,
2879 ApicTmr7 = 0x0008481f,
2880 ApicIrr0 = 0x00084820,
2881 ApicIrr1 = 0x00084821,
2882 ApicIrr2 = 0x00084822,
2883 ApicIrr3 = 0x00084823,
2884 ApicIrr4 = 0x00084824,
2885 ApicIrr5 = 0x00084825,
2886 ApicIrr6 = 0x00084826,
2887 ApicIrr7 = 0x00084827,
2888 ApicEse = 0x00084828,
2889 ApicIcr = 0x00084830,
2890 ApicLvtTimer = 0x00084832,
2891 ApicLvtThermal = 0x00084833,
2892 ApicLvtPerfmon = 0x00084834,
2893 ApicLvtLint0 = 0x00084835,
2894 ApicLvtLint1 = 0x00084836,
2895 ApicLvtError = 0x00084837,
2896 ApicInitCount = 0x00084838,
2897 ApicCurrentCount = 0x00084839,
2898 ApicDivide = 0x0008483e,
2899 ApicSelfIpi = 0x0008483f,
2900
2901 Hypercall = 0x00090001,
2902 RegisterPage = 0x0009001C,
2903
2904 EmulatedTimerPeriod = 0x00090030,
2906 EmulatedTimerControl = 0x00090031,
2907 PmTimerAssist = 0x00090032,
2908
2909 SevControl = 0x00090040,
2911 SevGhcbGpa = 0x00090041,
2912 SevDoorbellGpa = 0x00090042,
2913 SevAvicGpa = 0x00090043,
2914
2915 CrInterceptControl = 0x000E0000,
2916 CrInterceptCr0Mask = 0x000E0001,
2917 CrInterceptCr4Mask = 0x000E0002,
2918 CrInterceptIa32MiscEnableMask = 0x000E0003,
2919 }
2920}
2921
2922registers! {
2923 HvArm64RegisterName {
2924 HypervisorVersion = 0x00000100,
2925 PrivilegesAndFeaturesInfo = 0x00000200,
2926 FeaturesInfo = 0x00000201,
2927 ImplementationLimitsInfo = 0x00000202,
2928 HardwareFeaturesInfo = 0x00000203,
2929 CpuManagementFeaturesInfo = 0x00000204,
2930 PasidFeaturesInfo = 0x00000205,
2931 SkipLevelFeaturesInfo = 0x00000206,
2932 NestedVirtFeaturesInfo = 0x00000207,
2933 IptFeaturesInfo = 0x00000208,
2934 IsolationConfiguration = 0x00000209,
2935
2936 X0 = 0x00020000,
2937 X1 = 0x00020001,
2938 X2 = 0x00020002,
2939 X3 = 0x00020003,
2940 X4 = 0x00020004,
2941 X5 = 0x00020005,
2942 X6 = 0x00020006,
2943 X7 = 0x00020007,
2944 X8 = 0x00020008,
2945 X9 = 0x00020009,
2946 X10 = 0x0002000A,
2947 X11 = 0x0002000B,
2948 X12 = 0x0002000C,
2949 X13 = 0x0002000D,
2950 X14 = 0x0002000E,
2951 X15 = 0x0002000F,
2952 X16 = 0x00020010,
2953 X17 = 0x00020011,
2954 X18 = 0x00020012,
2955 X19 = 0x00020013,
2956 X20 = 0x00020014,
2957 X21 = 0x00020015,
2958 X22 = 0x00020016,
2959 X23 = 0x00020017,
2960 X24 = 0x00020018,
2961 X25 = 0x00020019,
2962 X26 = 0x0002001A,
2963 X27 = 0x0002001B,
2964 X28 = 0x0002001C,
2965 XFp = 0x0002001D,
2966 XLr = 0x0002001E,
2967 XSp = 0x0002001F, XSpEl0 = 0x00020020,
2969 XSpElx = 0x00020021,
2970 XPc = 0x00020022,
2971 Cpsr = 0x00020023,
2972 SpsrEl2 = 0x00021002,
2973
2974 MpidrEl1 = 0x00040001,
2975 SctlrEl1 = 0x00040002,
2976 Ttbr0El1 = 0x00040005,
2977 Ttbr1El1 = 0x00040006,
2978 TcrEl1 = 0x00040007,
2979 EsrEl1 = 0x00040008,
2980 FarEl1 = 0x00040009,
2981 MairEl1 = 0x0004000b,
2982 VbarEl1 = 0x0004000c,
2983 ElrEl1 = 0x00040015,
2984 }
2985}
2986
2987#[repr(C)]
2988#[derive(Clone, Copy, Debug, Eq, PartialEq, IntoBytes, Immutable, KnownLayout, FromBytes)]
2989pub struct HvRegisterValue(pub AlignedU128);
2990
2991impl HvRegisterValue {
2992 pub fn as_u128(&self) -> u128 {
2993 self.0.into()
2994 }
2995
2996 pub fn as_u64(&self) -> u64 {
2997 self.as_u128() as u64
2998 }
2999
3000 pub fn as_u32(&self) -> u32 {
3001 self.as_u128() as u32
3002 }
3003
3004 pub fn as_u16(&self) -> u16 {
3005 self.as_u128() as u16
3006 }
3007
3008 pub fn as_u8(&self) -> u8 {
3009 self.as_u128() as u8
3010 }
3011
3012 pub fn as_table(&self) -> HvX64TableRegister {
3013 HvX64TableRegister::read_from_prefix(self.as_bytes())
3014 .unwrap()
3015 .0 }
3017
3018 pub fn as_segment(&self) -> HvX64SegmentRegister {
3019 HvX64SegmentRegister::read_from_prefix(self.as_bytes())
3020 .unwrap()
3021 .0 }
3023}
3024
3025impl From<u8> for HvRegisterValue {
3026 fn from(val: u8) -> Self {
3027 (val as u128).into()
3028 }
3029}
3030
3031impl From<u16> for HvRegisterValue {
3032 fn from(val: u16) -> Self {
3033 (val as u128).into()
3034 }
3035}
3036
3037impl From<u32> for HvRegisterValue {
3038 fn from(val: u32) -> Self {
3039 (val as u128).into()
3040 }
3041}
3042
3043impl From<u64> for HvRegisterValue {
3044 fn from(val: u64) -> Self {
3045 (val as u128).into()
3046 }
3047}
3048
3049impl From<u128> for HvRegisterValue {
3050 fn from(val: u128) -> Self {
3051 Self(val.into())
3052 }
3053}
3054
3055#[repr(C)]
3056#[derive(Clone, Copy, Debug, Eq, PartialEq, IntoBytes, Immutable, KnownLayout, FromBytes)]
3057pub struct HvX64TableRegister {
3058 pub pad: [u16; 3],
3059 pub limit: u16,
3060 pub base: u64,
3061}
3062
3063impl From<HvX64TableRegister> for HvRegisterValue {
3064 fn from(val: HvX64TableRegister) -> Self {
3065 Self::read_from_prefix(val.as_bytes()).unwrap().0 }
3067}
3068
3069impl From<HvRegisterValue> for HvX64TableRegister {
3070 fn from(val: HvRegisterValue) -> Self {
3071 Self::read_from_prefix(val.as_bytes()).unwrap().0 }
3073}
3074
3075#[repr(C)]
3076#[derive(Clone, Copy, Debug, Eq, PartialEq, IntoBytes, Immutable, KnownLayout, FromBytes)]
3077pub struct HvX64SegmentRegister {
3078 pub base: u64,
3079 pub limit: u32,
3080 pub selector: u16,
3081 pub attributes: u16,
3082}
3083
3084impl From<HvX64SegmentRegister> for HvRegisterValue {
3085 fn from(val: HvX64SegmentRegister) -> Self {
3086 Self::read_from_prefix(val.as_bytes()).unwrap().0 }
3088}
3089
3090impl From<HvRegisterValue> for HvX64SegmentRegister {
3091 fn from(val: HvRegisterValue) -> Self {
3092 Self::read_from_prefix(val.as_bytes()).unwrap().0 }
3094}
3095
3096#[bitfield(u64)]
3097#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
3098pub struct HvDeliverabilityNotificationsRegister {
3099 pub nmi_notification: bool,
3101 pub interrupt_notification: bool,
3103 #[bits(4)]
3105 pub interrupt_priority: u8,
3107 #[bits(42)]
3108 pub reserved: u64,
3109 pub sints: u16,
3110}
3111
3112open_enum! {
3113 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3114 pub enum HvVtlEntryReason: u32 {
3115 RESERVED = 0,
3117
3118 VTL_CALL = 1,
3120
3121 INTERRUPT = 2,
3123
3124 INTERCEPT = 3,
3126 }
3127}
3128
3129#[repr(C)]
3130#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3131pub struct HvVpVtlControl {
3132 pub entry_reason: HvVtlEntryReason,
3137
3138 pub vina_status: u8,
3140 pub reserved_z0: u8,
3141 pub reserved_z1: u16,
3142
3143 pub registers: [u64; 2],
3148}
3149
3150#[bitfield(u64)]
3151#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3152pub struct HvRegisterVsmVina {
3153 pub vector: u8,
3154 pub enabled: bool,
3155 pub auto_reset: bool,
3156 pub auto_eoi: bool,
3157 #[bits(53)]
3158 pub reserved: u64,
3159}
3160
3161#[repr(C)]
3162#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3163pub struct HvVpAssistPage {
3164 pub apic_assist: u32,
3166 pub reserved_z0: u32,
3167
3168 pub vtl_control: HvVpVtlControl,
3170
3171 pub nested_enlightenments_control: u64,
3172 pub enlighten_vm_entry: u8,
3173 pub reserved_z1: [u8; 7],
3174 pub current_nested_vmcs: u64,
3175 pub synthetic_time_unhalted_timer_expired: u8,
3176 pub reserved_z2: [u8; 7],
3177 pub virtualization_fault_information: [u8; 40],
3178 pub reserved_z3: u64,
3179 pub intercept_message: HvMessage,
3180 pub vtl_return_actions: [u8; 256],
3181}
3182
3183#[repr(C)]
3184#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3185pub struct HvVpAssistPageActionSignalEvent {
3186 pub action_type: u64,
3187 pub target_vp: u32,
3188 pub target_vtl: u8,
3189 pub target_sint: u8,
3190 pub flag_number: u16,
3191}
3192
3193open_enum! {
3194 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3195 pub enum HvInterceptAccessType: u8 {
3196 READ = 0,
3197 WRITE = 1,
3198 EXECUTE = 2,
3199 }
3200}
3201
3202#[bitfield(u16)]
3203#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3204pub struct HvX64VpExecutionState {
3205 #[bits(2)]
3206 pub cpl: u8,
3207 pub cr0_pe: bool,
3208 pub cr0_am: bool,
3209 pub efer_lma: bool,
3210 pub debug_active: bool,
3211 pub interruption_pending: bool,
3212 #[bits(4)]
3213 pub vtl: u8,
3214 pub enclave_mode: bool,
3215 pub interrupt_shadow: bool,
3216 pub virtualization_fault_active: bool,
3217 #[bits(2)]
3218 pub reserved: u8,
3219}
3220
3221#[bitfield(u16)]
3222#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3223pub struct HvArm64VpExecutionState {
3224 #[bits(2)]
3225 pub cpl: u8,
3226 pub debug_active: bool,
3227 pub interruption_pending: bool,
3228 #[bits(4)]
3229 pub vtl: u8,
3230 pub virtualization_fault_active: bool,
3231 #[bits(7)]
3232 pub reserved: u8,
3233}
3234
3235#[repr(C)]
3236#[derive(Debug, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
3237pub struct HvX64InterceptMessageHeader {
3238 pub vp_index: u32,
3239 pub instruction_length_and_cr8: u8,
3240 pub intercept_access_type: HvInterceptAccessType,
3241 pub execution_state: HvX64VpExecutionState,
3242 pub cs_segment: HvX64SegmentRegister,
3243 pub rip: u64,
3244 pub rflags: u64,
3245}
3246
3247impl MessagePayload for HvX64InterceptMessageHeader {}
3248
3249impl HvX64InterceptMessageHeader {
3250 pub fn instruction_len(&self) -> u8 {
3251 self.instruction_length_and_cr8 & 0xf
3252 }
3253
3254 pub fn cr8(&self) -> u8 {
3255 self.instruction_length_and_cr8 >> 4
3256 }
3257}
3258
3259#[repr(C)]
3260#[derive(Debug, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
3261pub struct HvArm64InterceptMessageHeader {
3262 pub vp_index: u32,
3263 pub instruction_length: u8,
3264 pub intercept_access_type: HvInterceptAccessType,
3265 pub execution_state: HvArm64VpExecutionState,
3266 pub pc: u64,
3267 pub cspr: u64,
3268}
3269const_assert!(size_of::<HvArm64InterceptMessageHeader>() == 0x18);
3270
3271impl MessagePayload for HvArm64InterceptMessageHeader {}
3272
3273#[repr(transparent)]
3274#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
3275pub struct HvX64IoPortAccessInfo(pub u8);
3276
3277impl HvX64IoPortAccessInfo {
3278 pub fn new(access_size: u8, string_op: bool, rep_prefix: bool) -> Self {
3279 let mut info = access_size & 0x7;
3280
3281 if string_op {
3282 info |= 0x8;
3283 }
3284
3285 if rep_prefix {
3286 info |= 0x10;
3287 }
3288
3289 Self(info)
3290 }
3291
3292 pub fn access_size(&self) -> u8 {
3293 self.0 & 0x7
3294 }
3295
3296 pub fn string_op(&self) -> bool {
3297 self.0 & 0x8 != 0
3298 }
3299
3300 pub fn rep_prefix(&self) -> bool {
3301 self.0 & 0x10 != 0
3302 }
3303}
3304
3305#[repr(C)]
3306#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3307pub struct HvX64IoPortInterceptMessage {
3308 pub header: HvX64InterceptMessageHeader,
3309 pub port_number: u16,
3310 pub access_info: HvX64IoPortAccessInfo,
3311 pub instruction_byte_count: u8,
3312 pub reserved: u32,
3313 pub rax: u64,
3314 pub instruction_bytes: [u8; 16],
3315 pub ds_segment: HvX64SegmentRegister,
3316 pub es_segment: HvX64SegmentRegister,
3317 pub rcx: u64,
3318 pub rsi: u64,
3319 pub rdi: u64,
3320}
3321
3322impl MessagePayload for HvX64IoPortInterceptMessage {}
3323
3324#[bitfield(u8)]
3325#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3326pub struct HvX64MemoryAccessInfo {
3327 pub gva_valid: bool,
3328 pub gva_gpa_valid: bool,
3329 pub hypercall_output_pending: bool,
3330 pub tlb_locked: bool,
3331 pub supervisor_shadow_stack: bool,
3332 #[bits(3)]
3333 pub reserved1: u8,
3334}
3335
3336#[bitfield(u8)]
3337#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3338pub struct HvArm64MemoryAccessInfo {
3339 pub gva_valid: bool,
3340 pub gva_gpa_valid: bool,
3341 pub hypercall_output_pending: bool,
3342 #[bits(5)]
3343 pub reserved1: u8,
3344}
3345
3346open_enum! {
3347 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3348 pub enum HvCacheType: u32 {
3349 #![expect(non_upper_case_globals)]
3350 HvCacheTypeUncached = 0,
3351 HvCacheTypeWriteCombining = 1,
3352 HvCacheTypeWriteThrough = 4,
3353 HvCacheTypeWriteProtected = 5,
3354 HvCacheTypeWriteBack = 6,
3355 }
3356}
3357
3358#[repr(C)]
3359#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3360pub struct HvX64MemoryInterceptMessage {
3361 pub header: HvX64InterceptMessageHeader,
3362 pub cache_type: HvCacheType,
3363 pub instruction_byte_count: u8,
3364 pub memory_access_info: HvX64MemoryAccessInfo,
3365 pub tpr_priority: u8,
3366 pub reserved: u8,
3367 pub guest_virtual_address: u64,
3368 pub guest_physical_address: u64,
3369 pub instruction_bytes: [u8; 16],
3370}
3371
3372impl MessagePayload for HvX64MemoryInterceptMessage {}
3373const_assert!(size_of::<HvX64MemoryInterceptMessage>() == 0x50);
3374
3375#[repr(C)]
3376#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3377pub struct HvArm64MemoryInterceptMessage {
3378 pub header: HvArm64InterceptMessageHeader,
3379 pub cache_type: HvCacheType,
3380 pub instruction_byte_count: u8,
3381 pub memory_access_info: HvArm64MemoryAccessInfo,
3382 pub reserved1: u16,
3383 pub instruction_bytes: [u8; 4],
3384 pub reserved2: u32,
3385 pub guest_virtual_address: u64,
3386 pub guest_physical_address: u64,
3387 pub syndrome: u64,
3388}
3389
3390impl MessagePayload for HvArm64MemoryInterceptMessage {}
3391const_assert!(size_of::<HvArm64MemoryInterceptMessage>() == 0x40);
3392
3393#[repr(C)]
3394#[derive(Debug, FromBytes, IntoBytes, Immutable, KnownLayout)]
3395pub struct HvArm64MmioInterceptMessage {
3396 pub header: HvArm64InterceptMessageHeader,
3397 pub guest_physical_address: u64,
3398 pub access_size: u32,
3399 pub data: [u8; 32],
3400 pub padding: u32,
3401}
3402
3403impl MessagePayload for HvArm64MmioInterceptMessage {}
3404const_assert!(size_of::<HvArm64MmioInterceptMessage>() == 0x48);
3405
3406#[repr(C)]
3407#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3408pub struct HvX64MsrInterceptMessage {
3409 pub header: HvX64InterceptMessageHeader,
3410 pub msr_number: u32,
3411 pub reserved: u32,
3412 pub rdx: u64,
3413 pub rax: u64,
3414}
3415
3416impl MessagePayload for HvX64MsrInterceptMessage {}
3417
3418#[repr(C)]
3419#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3420pub struct HvX64SipiInterceptMessage {
3421 pub header: HvX64InterceptMessageHeader,
3422 pub target_vp_index: u32,
3423 pub vector: u32,
3424}
3425
3426impl MessagePayload for HvX64SipiInterceptMessage {}
3427
3428#[repr(C)]
3429#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3430pub struct HvX64SynicSintDeliverableMessage {
3431 pub header: HvX64InterceptMessageHeader,
3432 pub deliverable_sints: u16,
3433 pub rsvd1: u16,
3434 pub rsvd2: u32,
3435}
3436
3437impl MessagePayload for HvX64SynicSintDeliverableMessage {}
3438
3439#[repr(C)]
3440#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3441pub struct HvArm64SynicSintDeliverableMessage {
3442 pub header: HvArm64InterceptMessageHeader,
3443 pub deliverable_sints: u16,
3444 pub rsvd1: u16,
3445 pub rsvd2: u32,
3446}
3447
3448impl MessagePayload for HvArm64SynicSintDeliverableMessage {}
3449
3450#[repr(C)]
3451#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3452pub struct HvX64InterruptionDeliverableMessage {
3453 pub header: HvX64InterceptMessageHeader,
3454 pub deliverable_type: HvX64PendingInterruptionType,
3455 pub rsvd: [u8; 3],
3456 pub rsvd2: u32,
3457}
3458
3459impl MessagePayload for HvX64InterruptionDeliverableMessage {}
3460
3461open_enum! {
3462 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3463 pub enum HvX64PendingInterruptionType: u8 {
3464 HV_X64_PENDING_INTERRUPT = 0,
3465 HV_X64_PENDING_NMI = 2,
3466 HV_X64_PENDING_EXCEPTION = 3,
3467 HV_X64_PENDING_SOFTWARE_INTERRUPT = 4,
3468 HV_X64_PENDING_PRIVILEGED_SOFTWARE_EXCEPTION = 5,
3469 HV_X64_PENDING_SOFTWARE_EXCEPTION = 6,
3470 }
3471}
3472
3473#[repr(C)]
3474#[derive(Debug, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
3475pub struct HvX64HypercallInterceptMessage {
3476 pub header: HvX64InterceptMessageHeader,
3477 pub rax: u64,
3478 pub rbx: u64,
3479 pub rcx: u64,
3480 pub rdx: u64,
3481 pub r8: u64,
3482 pub rsi: u64,
3483 pub rdi: u64,
3484 pub xmm_registers: [AlignedU128; 6],
3485 pub flags: HvHypercallInterceptMessageFlags,
3486 pub rsvd2: [u32; 3],
3487}
3488
3489impl MessagePayload for HvX64HypercallInterceptMessage {}
3490
3491#[repr(C)]
3492#[derive(Debug, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
3493pub struct HvArm64HypercallInterceptMessage {
3494 pub header: HvArm64InterceptMessageHeader,
3495 pub immediate: u16,
3496 pub reserved: u16,
3497 pub flags: HvHypercallInterceptMessageFlags,
3498 pub x: [u64; 18],
3499}
3500
3501impl MessagePayload for HvArm64HypercallInterceptMessage {}
3502
3503#[bitfield(u32)]
3504#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3505pub struct HvHypercallInterceptMessageFlags {
3506 pub is_isolated: bool,
3507 #[bits(31)]
3508 _reserved: u32,
3509}
3510
3511#[repr(C)]
3512#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3513pub struct HvX64CpuidInterceptMessage {
3514 pub header: HvX64InterceptMessageHeader,
3515 pub rax: u64,
3516 pub rcx: u64,
3517 pub rdx: u64,
3518 pub rbx: u64,
3519 pub default_result_rax: u64,
3520 pub default_result_rcx: u64,
3521 pub default_result_rdx: u64,
3522 pub default_result_rbx: u64,
3523}
3524
3525impl MessagePayload for HvX64CpuidInterceptMessage {}
3526
3527#[bitfield(u8)]
3528#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3529pub struct HvX64ExceptionInfo {
3530 pub error_code_valid: bool,
3531 pub software_exception: bool,
3532 #[bits(6)]
3533 reserved: u8,
3534}
3535
3536#[repr(C)]
3537#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3538pub struct HvX64ExceptionInterceptMessage {
3539 pub header: HvX64InterceptMessageHeader,
3540 pub vector: u16,
3541 pub exception_info: HvX64ExceptionInfo,
3542 pub instruction_byte_count: u8,
3543 pub error_code: u32,
3544 pub exception_parameter: u64,
3545 pub reserved: u64,
3546 pub instruction_bytes: [u8; 16],
3547 pub ds_segment: HvX64SegmentRegister,
3548 pub ss_segment: HvX64SegmentRegister,
3549 pub rax: u64,
3550 pub rcx: u64,
3551 pub rdx: u64,
3552 pub rbx: u64,
3553 pub rsp: u64,
3554 pub rbp: u64,
3555 pub rsi: u64,
3556 pub rdi: u64,
3557 pub r8: u64,
3558 pub r9: u64,
3559 pub r10: u64,
3560 pub r11: u64,
3561 pub r12: u64,
3562 pub r13: u64,
3563 pub r14: u64,
3564 pub r15: u64,
3565}
3566
3567impl MessagePayload for HvX64ExceptionInterceptMessage {}
3568
3569#[repr(C)]
3570#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3571pub struct HvInvalidVpRegisterMessage {
3572 pub vp_index: u32,
3573 pub reserved: u32,
3574}
3575
3576impl MessagePayload for HvInvalidVpRegisterMessage {}
3577
3578#[repr(C)]
3579#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3580pub struct HvX64ApicEoiMessage {
3581 pub vp_index: u32,
3582 pub interrupt_vector: u32,
3583}
3584
3585impl MessagePayload for HvX64ApicEoiMessage {}
3586
3587#[repr(C)]
3588#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3589pub struct HvX64UnrecoverableExceptionMessage {
3590 pub header: HvX64InterceptMessageHeader,
3591}
3592
3593impl MessagePayload for HvX64UnrecoverableExceptionMessage {}
3594
3595#[repr(C)]
3596#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3597pub struct HvX64HaltMessage {
3598 pub header: HvX64InterceptMessageHeader,
3599}
3600
3601impl MessagePayload for HvX64HaltMessage {}
3602
3603#[repr(C)]
3604#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3605pub struct HvArm64ResetInterceptMessage {
3606 pub header: HvArm64InterceptMessageHeader,
3607 pub reset_type: HvArm64ResetType,
3608 pub reset_code: u32,
3609}
3610
3611impl MessagePayload for HvArm64ResetInterceptMessage {}
3612
3613open_enum! {
3614 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3615 pub enum HvArm64ResetType: u32 {
3616 POWER_OFF = 0,
3617 REBOOT = 1,
3618 SYSTEM_RESET = 2,
3619 HIBERNATE = 3,
3620 }
3621}
3622
3623#[bitfield(u8)]
3624#[derive(IntoBytes, Immutable, FromBytes)]
3625pub struct HvX64RegisterInterceptMessageFlags {
3626 pub is_memory_op: bool,
3627 #[bits(7)]
3628 _rsvd: u8,
3629}
3630
3631#[repr(C)]
3632#[derive(IntoBytes, Immutable, FromBytes)]
3633pub struct HvX64RegisterInterceptMessage {
3634 pub header: HvX64InterceptMessageHeader,
3635 pub flags: HvX64RegisterInterceptMessageFlags,
3636 pub rsvd: u8,
3637 pub rsvd2: u16,
3638 pub register_name: HvX64RegisterName,
3639 pub access_info: HvX64RegisterAccessInfo,
3640}
3641
3642#[repr(transparent)]
3643#[derive(IntoBytes, Immutable, FromBytes)]
3644pub struct HvX64RegisterAccessInfo(u128);
3645
3646impl HvX64RegisterAccessInfo {
3647 pub fn new_source_value(source_value: HvRegisterValue) -> Self {
3648 Self(source_value.as_u128())
3649 }
3650}
3651
3652open_enum! {
3653 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3654 pub enum HvInterruptType : u32 {
3655 #![expect(non_upper_case_globals)]
3656 HvArm64InterruptTypeFixed = 0x0000,
3657 HvX64InterruptTypeFixed = 0x0000,
3658 HvX64InterruptTypeLowestPriority = 0x0001,
3659 HvX64InterruptTypeSmi = 0x0002,
3660 HvX64InterruptTypeRemoteRead = 0x0003,
3661 HvX64InterruptTypeNmi = 0x0004,
3662 HvX64InterruptTypeInit = 0x0005,
3663 HvX64InterruptTypeSipi = 0x0006,
3664 HvX64InterruptTypeExtInt = 0x0007,
3665 HvX64InterruptTypeLocalInt0 = 0x0008,
3666 HvX64InterruptTypeLocalInt1 = 0x0009,
3667 }
3668}
3669
3670#[bitfield(u64)]
3677#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3678pub struct HvInterruptControl {
3679 interrupt_type_value: u32,
3680 pub x86_level_triggered: bool,
3681 pub x86_logical_destination_mode: bool,
3682 pub arm64_asserted: bool,
3683 #[bits(29)]
3684 pub unused: u32,
3685}
3686
3687impl HvInterruptControl {
3688 pub fn interrupt_type(&self) -> HvInterruptType {
3689 HvInterruptType(self.interrupt_type_value())
3690 }
3691
3692 pub fn set_interrupt_type(&mut self, ty: HvInterruptType) {
3693 self.set_interrupt_type_value(ty.0)
3694 }
3695
3696 pub fn with_interrupt_type(self, ty: HvInterruptType) -> Self {
3697 self.with_interrupt_type_value(ty.0)
3698 }
3699}
3700
3701#[bitfield(u64)]
3702pub struct HvRegisterVsmCapabilities {
3703 pub dr6_shared: bool,
3704 pub mbec_vtl_mask: u16,
3705 pub deny_lower_vtl_startup: bool,
3706 pub supervisor_shadow_stack: bool,
3707 pub hardware_hvpt_available: bool,
3708 pub software_hvpt_available: bool,
3709 #[bits(6)]
3710 pub hardware_hvpt_range_bits: u8,
3711 pub intercept_page_available: bool,
3712 pub return_action_available: bool,
3713 pub vtl0_alias_map_available: bool,
3718 pub intercept_not_present_available: bool,
3723 pub install_intercept_ex: bool,
3724 pub intercept_system_reset_available: bool,
3726 #[bits(1)]
3727 pub reserved1: u8,
3728 pub proxy_interrupt_redirect_available: bool,
3729 #[bits(29)]
3730 pub reserved2: u64,
3731}
3732
3733#[bitfield(u64)]
3734pub struct HvRegisterVsmPartitionConfig {
3735 pub enable_vtl_protection: bool,
3736 #[bits(4)]
3737 pub default_vtl_protection_mask: u8,
3738 pub zero_memory_on_reset: bool,
3739 pub deny_lower_vtl_startup: bool,
3740 pub intercept_acceptance: bool,
3741 pub intercept_enable_vtl_protection: bool,
3742 pub intercept_vp_startup: bool,
3743 pub intercept_cpuid_unimplemented: bool,
3744 pub intercept_unrecoverable_exception: bool,
3745 pub intercept_page: bool,
3746 pub intercept_restore_partition_time: bool,
3747 pub intercept_not_present: bool,
3750 pub intercept_system_reset: bool,
3751 #[bits(48)]
3752 pub reserved: u64,
3753}
3754
3755#[bitfield(u64)]
3756pub struct HvRegisterVsmPartitionStatus {
3757 #[bits(16)]
3758 pub enabled_vtl_set: u16,
3759 #[bits(4)]
3760 pub maximum_vtl: u8,
3761 #[bits(16)]
3762 pub mbec_enabled_vtl_set: u16,
3763 #[bits(4)]
3764 pub supervisor_shadow_stack_enabled_vtl_set: u8,
3765 #[bits(24)]
3766 pub reserved: u64,
3767}
3768
3769open_enum! {
3770 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3771 pub enum HvSnpInterruptInjection : u8 {
3772 #![allow(non_upper_case_globals)]
3773 HvSnpRestricted = 0x0,
3774 HvSnpNormal = 0x1,
3775 HvSnpAlternate = 0x2,
3776 HvSnpSecureAvic = 0x3,
3777 }
3778}
3779
3780impl HvSnpInterruptInjection {
3782 const fn from_bits(val: u8) -> Self {
3783 HvSnpInterruptInjection(val)
3784 }
3785
3786 const fn into_bits(self) -> u8 {
3787 self.0
3788 }
3789}
3790
3791#[bitfield(u64)]
3792pub struct HvRegisterGuestVsmPartitionConfig {
3793 #[bits(4)]
3794 pub maximum_vtl: u8,
3795 #[bits(2)]
3796 pub vtl0_interrupt_injection: HvSnpInterruptInjection,
3797 #[bits(2)]
3798 pub vtl1_interrupt_injection: HvSnpInterruptInjection,
3799 #[bits(56)]
3800 pub reserved: u64,
3801}
3802
3803#[bitfield(u64)]
3804pub struct HvRegisterVsmVpStatus {
3805 #[bits(4)]
3806 pub active_vtl: u8,
3807 pub active_mbec_enabled: bool,
3808 #[bits(11)]
3809 pub reserved_mbz0: u16,
3810 #[bits(16)]
3811 pub enabled_vtl_set: u16,
3812 #[bits(32)]
3813 pub reserved_mbz1: u32,
3814}
3815
3816#[bitfield(u64)]
3817pub struct HvRegisterVsmCodePageOffsets {
3818 #[bits(12)]
3819 pub call_offset: u16,
3820 #[bits(12)]
3821 pub return_offset: u16,
3822 #[bits(40)]
3823 pub reserved: u64,
3824}
3825
3826#[repr(C)]
3827#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3828pub struct HvStimerState {
3829 pub undelivered_message_pending: u32,
3830 pub reserved: u32,
3831 pub config: u64,
3832 pub count: u64,
3833 pub adjustment: u64,
3834 pub undelivered_expiration_time: u64,
3835}
3836
3837#[repr(C)]
3838#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3839pub struct HvSyntheticTimersState {
3840 pub timers: [HvStimerState; 4],
3841 pub reserved: [u64; 5],
3842}
3843
3844#[bitfield(u64)]
3845pub struct HvInternalActivityRegister {
3846 pub startup_suspend: bool,
3847 pub halt_suspend: bool,
3848 pub idle_suspend: bool,
3849 #[bits(61)]
3850 pub reserved: u64,
3851}
3852
3853#[bitfield(u64)]
3854pub struct HvSynicSint {
3855 pub vector: u8,
3856 _reserved: u8,
3857 pub masked: bool,
3858 pub auto_eoi: bool,
3859 pub polling: bool,
3860 _reserved2: bool,
3861 pub proxy: bool,
3862 #[bits(43)]
3863 _reserved2: u64,
3864}
3865
3866#[bitfield(u64)]
3867pub struct HvSynicScontrol {
3868 pub enabled: bool,
3869 #[bits(63)]
3870 _reserved: u64,
3871}
3872
3873#[bitfield(u64)]
3874pub struct HvSynicSimpSiefp {
3875 pub enabled: bool,
3876 #[bits(11)]
3877 _reserved: u64,
3878 #[bits(52)]
3879 pub base_gpn: u64,
3880}
3881
3882#[bitfield(u64)]
3883pub struct HvSynicStimerConfig {
3884 pub enabled: bool,
3885 pub periodic: bool,
3886 pub lazy: bool,
3887 pub auto_enable: bool,
3888 pub apic_vector: u8,
3890 pub direct_mode: bool,
3891 #[bits(3)]
3892 pub _reserved1: u8,
3893 #[bits(4)]
3894 pub sint: u8,
3895 #[bits(44)]
3896 pub _reserved2: u64,
3897}
3898
3899pub const HV_X64_PENDING_EVENT_EXCEPTION: u8 = 0;
3900pub const HV_X64_PENDING_EVENT_MEMORY_INTERCEPT: u8 = 1;
3901pub const HV_X64_PENDING_EVENT_NESTED_MEMORY_INTERCEPT: u8 = 2;
3902pub const HV_X64_PENDING_EVENT_VIRTUALIZATION_FAULT: u8 = 3;
3903pub const HV_X64_PENDING_EVENT_HYPERCALL_OUTPUT: u8 = 4;
3904pub const HV_X64_PENDING_EVENT_EXT_INT: u8 = 5;
3905pub const HV_X64_PENDING_EVENT_SHADOW_IPT: u8 = 6;
3906
3907#[bitfield(u128)]
3909pub struct HvX64PendingExceptionEvent {
3910 pub event_pending: bool,
3911 #[bits(3)]
3912 pub event_type: u8,
3913 #[bits(4)]
3914 pub reserved0: u8,
3915
3916 pub deliver_error_code: bool,
3917 #[bits(7)]
3918 pub reserved1: u8,
3919 pub vector: u16,
3920 pub error_code: u32,
3921 pub exception_parameter: u64,
3922}
3923
3924#[bitfield(u128)]
3926pub struct HvX64PendingVirtualizationFaultEvent {
3927 pub event_pending: bool,
3928 #[bits(3)]
3929 pub event_type: u8,
3930 #[bits(4)]
3931 pub reserved0: u8,
3932
3933 pub reserved1: u8,
3934 pub parameter0: u16,
3935 pub code: u32,
3936 pub parameter1: u64,
3937}
3938
3939#[bitfield(u8)]
3941#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3942pub struct HvX64PendingEventMemoryInterceptPendingEventHeader {
3943 pub event_pending: bool,
3944 #[bits(3)]
3945 pub event_type: u8,
3946 #[bits(4)]
3947 _reserved0: u8,
3948}
3949
3950#[bitfield(u8)]
3952#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3953pub struct HvX64PendingEventMemoryInterceptAccessFlags {
3954 pub guest_linear_address_valid: bool,
3956 pub caused_by_gpa_access: bool,
3959 #[bits(6)]
3960 _reserved1: u8,
3961}
3962
3963#[repr(C)]
3965#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3966pub struct HvX64PendingEventMemoryIntercept {
3967 pub event_header: HvX64PendingEventMemoryInterceptPendingEventHeader,
3968 pub target_vtl: u8,
3971 pub access_type: HvInterceptAccessType,
3973 pub access_flags: HvX64PendingEventMemoryInterceptAccessFlags,
3974 pub _reserved2: u32,
3975 pub guest_linear_address: u64,
3977 pub guest_physical_address: u64,
3979 pub _reserved3: u64,
3980}
3981const_assert!(size_of::<HvX64PendingEventMemoryIntercept>() == 0x20);
3982
3983#[bitfield(u128)]
3987pub struct HvX64PendingHypercallOutputEvent {
3988 pub event_pending: bool,
3989 #[bits(3)]
3990 pub event_type: u8,
3991 #[bits(4)]
3992 pub reserved0: u8,
3993
3994 pub retired: bool,
3996
3997 #[bits(23)]
3998 pub reserved1: u32,
3999
4000 pub output_size: u32,
4002
4003 pub output_gpa: u64,
4005}
4006
4007#[bitfield(u128)]
4009pub struct HvX64PendingExtIntEvent {
4010 pub event_pending: bool,
4011 #[bits(3)]
4012 pub event_type: u8,
4013 #[bits(4)]
4014 pub reserved0: u8,
4015 pub vector: u8,
4016 #[bits(48)]
4017 pub reserved1: u64,
4018 pub reserved2: u64,
4019}
4020
4021#[bitfield(u128)]
4023pub struct HvX64PendingShadowIptEvent {
4024 pub event_pending: bool,
4025 #[bits(4)]
4026 pub event_type: u8,
4027 #[bits(59)]
4028 pub reserved0: u64,
4029
4030 pub reserved1: u64,
4031}
4032
4033#[bitfield(u128)]
4034#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4035pub struct HvX64PendingEventReg0 {
4036 pub event_pending: bool,
4037 #[bits(3)]
4038 pub event_type: u8,
4039 #[bits(4)]
4040 pub reserved: u8,
4041 #[bits(120)]
4042 pub data: u128,
4043}
4044
4045#[repr(C)]
4046#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
4047pub struct HvX64PendingEvent {
4048 pub reg_0: HvX64PendingEventReg0,
4049 pub reg_1: AlignedU128,
4050}
4051const_assert!(size_of::<HvX64PendingEvent>() == 0x20);
4052
4053impl From<HvX64PendingExceptionEvent> for HvX64PendingEvent {
4054 fn from(exception_event: HvX64PendingExceptionEvent) -> Self {
4055 HvX64PendingEvent {
4056 reg_0: HvX64PendingEventReg0::from(u128::from(exception_event)),
4057 reg_1: 0u128.into(),
4058 }
4059 }
4060}
4061
4062#[bitfield(u64)]
4063#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4064pub struct HvX64PendingInterruptionRegister {
4065 pub interruption_pending: bool,
4066 #[bits(3)]
4067 pub interruption_type: u8,
4068 pub deliver_error_code: bool,
4069 #[bits(4)]
4070 pub instruction_length: u8,
4071 pub nested_event: bool,
4072 #[bits(6)]
4073 pub reserved: u8,
4074 pub interruption_vector: u16,
4075 pub error_code: u32,
4076}
4077
4078#[bitfield(u64)]
4079#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4080pub struct HvX64InterruptStateRegister {
4081 pub interrupt_shadow: bool,
4082 pub nmi_masked: bool,
4083 #[bits(62)]
4084 pub reserved: u64,
4085}
4086
4087#[bitfield(u64)]
4088#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4089pub struct HvInstructionEmulatorHintsRegister {
4090 pub partition_secure_vtl_enabled: bool,
4092 pub mbec_user_execute_control: bool,
4095 #[bits(62)]
4096 pub _padding: u64,
4097}
4098
4099open_enum! {
4100 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4101 pub enum HvAarch64PendingEventType: u8 {
4102 EXCEPTION = 0,
4103 SYNTHETIC_EXCEPTION = 1,
4104 HYPERCALL_OUTPUT = 2,
4105 }
4106}
4107
4108impl HvAarch64PendingEventType {
4110 const fn from_bits(val: u8) -> Self {
4111 HvAarch64PendingEventType(val)
4112 }
4113
4114 const fn into_bits(self) -> u8 {
4115 self.0
4116 }
4117}
4118
4119#[bitfield[u8]]
4120#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4121pub struct HvAarch64PendingEventHeader {
4122 #[bits(1)]
4123 pub event_pending: bool,
4124 #[bits(3)]
4125 pub event_type: HvAarch64PendingEventType,
4126 #[bits(4)]
4127 pub reserved: u8,
4128}
4129
4130#[repr(C)]
4131#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
4132pub struct HvAarch64PendingExceptionEvent {
4133 pub header: HvAarch64PendingEventHeader,
4134 pub _padding: [u8; 7],
4135 pub syndrome: u64,
4136 pub fault_address: u64,
4137}
4138
4139#[bitfield[u8]]
4140#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4141pub struct HvAarch64PendingHypercallOutputEventFlags {
4142 #[bits(1)]
4143 pub retired: u8,
4144 #[bits(7)]
4145 pub reserved: u8,
4146}
4147
4148#[repr(C)]
4149#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
4150pub struct HvAarch64PendingHypercallOutputEvent {
4151 pub header: HvAarch64PendingEventHeader,
4152 pub flags: HvAarch64PendingHypercallOutputEventFlags,
4153 pub reserved: u16,
4154 pub output_size: u32,
4155 pub output_gpa: u64,
4156}
4157
4158#[repr(C)]
4159#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
4160pub struct HvAarch64PendingEvent {
4161 pub header: HvAarch64PendingEventHeader,
4162 pub event_data: [u8; 15],
4163 pub _padding: [u64; 2],
4164}
4165
4166#[bitfield(u32)]
4167#[derive(PartialEq, Eq, IntoBytes, Immutable, KnownLayout, FromBytes)]
4168pub struct HvMapGpaFlags {
4169 pub readable: bool,
4170 pub writable: bool,
4171 pub kernel_executable: bool,
4172 pub user_executable: bool,
4173 pub supervisor_shadow_stack: bool,
4174 pub paging_writability: bool,
4175 pub verify_paging_writability: bool,
4176 #[bits(8)]
4177 _padding0: u32,
4178 pub adjustable: bool,
4179 #[bits(16)]
4180 _padding1: u32,
4181}
4182
4183pub const HV_MAP_GPA_PERMISSIONS_NONE: HvMapGpaFlags = HvMapGpaFlags::new();
4185pub const HV_MAP_GPA_PERMISSIONS_ALL: HvMapGpaFlags = HvMapGpaFlags::new()
4186 .with_readable(true)
4187 .with_writable(true)
4188 .with_kernel_executable(true)
4189 .with_user_executable(true);
4190
4191#[repr(C)]
4192#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4193pub struct HvMonitorPage {
4194 pub trigger_state: HvMonitorTriggerState,
4195 pub reserved1: u32,
4196 pub trigger_group: [HvMonitorTriggerGroup; 4],
4197 pub reserved2: [u64; 3],
4198 pub next_check_time: [[u32; 32]; 4],
4199 pub latency: [[u16; 32]; 4],
4200 pub reserved3: [u64; 32],
4201 pub parameter: [[HvMonitorParameter; 32]; 4],
4202 pub reserved4: [u8; 1984],
4203}
4204
4205#[repr(C)]
4206#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4207pub struct HvMonitorPageSmall {
4208 pub trigger_state: HvMonitorTriggerState,
4209 pub reserved1: u32,
4210 pub trigger_group: [HvMonitorTriggerGroup; 4],
4211}
4212
4213#[repr(C)]
4214#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4215pub struct HvMonitorTriggerGroup {
4216 pub pending: u32,
4217 pub armed: u32,
4218}
4219
4220#[repr(C)]
4221#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4222pub struct HvMonitorParameter {
4223 pub connection_id: u32,
4224 pub flag_number: u16,
4225 pub reserved: u16,
4226}
4227
4228#[bitfield(u32)]
4229#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4230pub struct HvMonitorTriggerState {
4231 #[bits(4)]
4232 pub group_enable: u32,
4233 #[bits(28)]
4234 pub reserved: u32,
4235}
4236
4237#[bitfield(u64)]
4238#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4239pub struct HvPmTimerInfo {
4240 #[bits(16)]
4241 pub port: u16,
4242 #[bits(1)]
4243 pub width_24: bool,
4244 #[bits(1)]
4245 pub enabled: bool,
4246 #[bits(14)]
4247 pub reserved1: u32,
4248 #[bits(32)]
4249 pub reserved2: u32,
4250}
4251
4252#[bitfield(u64)]
4253#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4254pub struct HvX64RegisterSevControl {
4255 pub enable_encrypted_state: bool,
4256 #[bits(11)]
4257 _rsvd1: u64,
4258 #[bits(52)]
4259 pub vmsa_gpa_page_number: u64,
4260}
4261
4262#[bitfield(u64)]
4263#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4264pub struct HvX64RegisterSevAvic {
4265 pub enable_secure_apic: bool,
4266 #[bits(11)]
4267 _rsvd1: u64,
4268 #[bits(52)]
4269 pub avic_gpa_page_number: u64,
4270}
4271
4272#[bitfield(u64)]
4273#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4274pub struct HvRegisterReferenceTsc {
4275 pub enable: bool,
4276 #[bits(11)]
4277 pub reserved_p: u64,
4278 #[bits(52)]
4279 pub gpn: u64,
4280}
4281
4282#[repr(C)]
4283#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4284pub struct HvReferenceTscPage {
4285 pub tsc_sequence: u32,
4286 pub reserved1: u32,
4287 pub tsc_scale: u64,
4288 pub tsc_offset: i64,
4289 pub timeline_bias: u64,
4290 pub tsc_multiplier: u64,
4291 pub reserved2: [u64; 507],
4292}
4293
4294pub const HV_REFERENCE_TSC_SEQUENCE_INVALID: u32 = 0;
4295
4296#[bitfield(u64)]
4297#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4298pub struct HvX64VmgexitInterceptMessageFlags {
4299 pub ghcb_page_valid: bool,
4300 pub ghcb_request_error: bool,
4301 #[bits(62)]
4302 _reserved: u64,
4303}
4304
4305#[repr(C)]
4306#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
4307pub struct HvX64VmgexitInterceptMessageGhcbPageStandard {
4308 pub ghcb_protocol_version: u16,
4309 _reserved: [u16; 3],
4310 pub sw_exit_code: u64,
4311 pub sw_exit_info1: u64,
4312 pub sw_exit_info2: u64,
4313 pub sw_scratch: u64,
4314}
4315
4316#[repr(C)]
4317#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
4318pub struct HvX64VmgexitInterceptMessageGhcbPage {
4319 pub ghcb_usage: u32,
4320 _reserved: u32,
4321 pub standard: HvX64VmgexitInterceptMessageGhcbPageStandard,
4322}
4323
4324#[repr(C)]
4325#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
4326pub struct HvX64VmgexitInterceptMessage {
4327 pub header: HvX64InterceptMessageHeader,
4328 pub ghcb_msr: u64,
4329 pub flags: HvX64VmgexitInterceptMessageFlags,
4330 pub ghcb_page: HvX64VmgexitInterceptMessageGhcbPage,
4331}
4332
4333impl MessagePayload for HvX64VmgexitInterceptMessage {}
4334
4335#[bitfield(u32)]
4336#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4337pub struct HvX64GpaAttributeInterceptMessageFlags {
4338 #[bits(5)]
4339 pub range_count: u32,
4340 pub adjust: bool,
4341 #[bits(2)]
4342 pub host_visibility: u32,
4343 #[bits(6)]
4344 pub memory_type: u32,
4345 #[bits(18)]
4346 _reserved: u32,
4347}
4348
4349#[repr(C)]
4350#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
4351pub struct HvX64GpaAttributeInterceptMessage {
4352 pub vp_index: u32,
4353 pub flags: HvX64GpaAttributeInterceptMessageFlags,
4354 pub ranges: [hypercall::HvGpaRange; 29],
4355}
4356
4357impl MessagePayload for HvX64GpaAttributeInterceptMessage {}
4358const_assert!(size_of::<HvX64GpaAttributeInterceptMessage>() == HV_MESSAGE_PAYLOAD_SIZE);
4359
4360#[bitfield(u64)]
4361pub struct HvRegisterVpAssistPage {
4362 pub enabled: bool,
4363 #[bits(11)]
4364 _reserved: u64,
4365 #[bits(52)]
4366 pub gpa_page_number: u64,
4367}
4368
4369#[bitfield(u32)]
4370#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4371pub struct HvX64RegisterPageDirtyFlags {
4372 pub general_purpose: bool,
4373 pub instruction_pointer: bool,
4374 pub xmm: bool,
4375 pub segments: bool,
4376 pub flags: bool,
4377 #[bits(27)]
4378 reserved: u32,
4379}
4380
4381#[repr(C)]
4382#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
4383pub struct HvX64RegisterPage {
4384 pub version: u16,
4385 pub is_valid: u8,
4386 pub vtl: u8,
4387 pub dirty: HvX64RegisterPageDirtyFlags,
4388 pub gp_registers: [u64; 16],
4391 pub rip: u64,
4392 pub rflags: u64,
4393 pub reserved: u64,
4394 pub xmm: [u128; 6],
4395 pub segment: [HvX64SegmentRegister; 6],
4396 pub cr0: u64,
4398 pub cr3: u64,
4399 pub cr4: u64,
4400 pub cr8: u64,
4401 pub efer: u64,
4402 pub dr7: u64,
4403 pub pending_interruption: HvX64PendingInterruptionRegister,
4404 pub interrupt_state: HvX64InterruptStateRegister,
4405 pub instruction_emulation_hints: HvInstructionEmulatorHintsRegister,
4406 pub reserved_end: [u8; 3672],
4407}
4408
4409const _: () = assert!(size_of::<HvX64RegisterPage>() == HV_PAGE_SIZE_USIZE);
4410
4411#[bitfield(u32)]
4412#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4413pub struct HvAarch64RegisterPageDirtyFlags {
4414 _unused: bool,
4415 pub instruction_pointer: bool,
4416 pub processor_state: bool,
4417 pub control_registers: bool,
4418 #[bits(28)]
4419 reserved: u32,
4420}
4421
4422#[repr(C)]
4423#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
4424pub struct HvAarch64RegisterPage {
4425 pub version: u16,
4426 pub is_valid: u8,
4427 pub vtl: u8,
4428 pub dirty: HvAarch64RegisterPageDirtyFlags,
4429 pub _rsvd: [u64; 33],
4431 pub pc: u64,
4433 pub cpsr: u64,
4435 pub sctlr_el1: u64,
4437 pub tcr_el1: u64,
4438 pub reserved_end: [u8; 3792],
4440}
4441
4442const _: () = assert!(size_of::<HvAarch64RegisterPage>() == HV_PAGE_SIZE_USIZE);
4443
4444#[bitfield(u64)]
4445pub struct HvRegisterVsmWpWaitForTlbLock {
4446 pub wait: bool,
4447 #[bits(63)]
4448 _reserved: u64,
4449}
4450
4451#[bitfield(u64)]
4452pub struct HvRegisterVsmVpSecureVtlConfig {
4453 pub mbec_enabled: bool,
4454 pub tlb_locked: bool,
4455 pub supervisor_shadow_stack_enabled: bool,
4456 pub hardware_hvpt_enabled: bool,
4457 #[bits(60)]
4458 _reserved: u64,
4459}
4460
4461#[bitfield(u64)]
4462pub struct HvRegisterCrInterceptControl {
4463 pub cr0_write: bool,
4464 pub cr4_write: bool,
4465 pub xcr0_write: bool,
4466 pub ia32_misc_enable_read: bool,
4467 pub ia32_misc_enable_write: bool,
4468 pub msr_lstar_read: bool,
4469 pub msr_lstar_write: bool,
4470 pub msr_star_read: bool,
4471 pub msr_star_write: bool,
4472 pub msr_cstar_read: bool,
4473 pub msr_cstar_write: bool,
4474 pub apic_base_msr_read: bool,
4475 pub apic_base_msr_write: bool,
4476 pub msr_efer_read: bool,
4477 pub msr_efer_write: bool,
4478 pub gdtr_write: bool,
4479 pub idtr_write: bool,
4480 pub ldtr_write: bool,
4481 pub tr_write: bool,
4482 pub msr_sysenter_cs_write: bool,
4483 pub msr_sysenter_eip_write: bool,
4484 pub msr_sysenter_esp_write: bool,
4485 pub msr_sfmask_write: bool,
4486 pub msr_tsc_aux_write: bool,
4487 pub msr_sgx_launch_control_write: bool,
4488 pub msr_xss_write: bool,
4489 pub msr_scet_write: bool,
4490 pub msr_pls_ssp_write: bool,
4491 pub msr_interrupt_ssp_table_addr_write: bool,
4492 #[bits(35)]
4493 _rsvd_z: u64,
4494}
4495
4496#[repr(C)]
4497#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
4498pub struct HvX64InterruptControllerState {
4499 pub apic_id: u32,
4500 pub apic_version: u32,
4501 pub apic_ldr: u32,
4502 pub apic_dfr: u32,
4503 pub apic_spurious: u32,
4504 pub apic_isr: [u32; 8],
4505 pub apic_tmr: [u32; 8],
4506 pub apic_irr: [u32; 8],
4507 pub apic_esr: u32,
4508 pub apic_icr_high: u32,
4509 pub apic_icr_low: u32,
4510 pub apic_lvt_timer: u32,
4511 pub apic_lvt_thermal: u32,
4512 pub apic_lvt_perfmon: u32,
4513 pub apic_lvt_lint0: u32,
4514 pub apic_lvt_lint1: u32,
4515 pub apic_lvt_error: u32,
4516 pub apic_lvt_cmci: u32,
4517 pub apic_error_status: u32,
4518 pub apic_initial_count: u32,
4519 pub apic_counter_value: u32,
4520 pub apic_divide_configuration: u32,
4521 pub apic_remote_read: u32,
4522}