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(u128)]
647pub struct HvHardwareFeatures {
648 pub apic_overlay_assist_in_use: bool,
649 pub msr_bitmaps_in_use: bool,
650 pub architectural_performance_counters_in_use: bool,
651 pub second_level_address_translation_in_use: bool,
652 pub dma_remapping_in_use: bool,
653 pub interrupt_remapping_in_use: bool,
654 pub memory_patrol_scrubber_present: bool,
655 pub dma_protection_in_use: bool,
656 pub hpet_requested: bool,
657 pub synthetic_timers_volatile: bool,
658 #[bits(4)]
659 pub hypervisor_level: u32,
660 pub physical_destination_mode_required: bool,
661 pub use_vmfunc_for_alias_map_switch: bool,
662 pub hv_register_for_memory_zeroing_supported: bool,
663 pub unrestricted_guest_supported: bool,
664 pub rdt_afeatures_supported: bool,
665 pub rdt_mfeatures_supported: bool,
666 pub child_perfmon_pmu_supported: bool,
667 pub child_perfmon_lbr_supported: bool,
668 pub child_perfmon_ipt_supported: bool,
669 pub apic_emulation_supported: bool,
670 pub child_x2_apic_recommended: bool,
671 pub hardware_watchdog_reserved: bool,
672 pub device_access_tracking_supported: bool,
673 pub hardware_gpa_access_tracking_supported: bool,
674 #[bits(4)]
675 _reserved: u32,
676
677 pub device_domain_input_width: u8,
678 #[bits(24)]
679 _reserved1: u32,
680 _reserved2: u32,
681 _reserved3: u32,
682}
683
684#[bitfield(u128)]
685pub struct HvIsolationConfiguration {
686 pub paravisor_present: bool,
687 #[bits(31)]
688 pub _reserved0: u32,
689
690 #[bits(4)]
691 pub isolation_type: u8,
692 _reserved11: bool,
693 pub shared_gpa_boundary_active: bool,
694 #[bits(6)]
695 pub shared_gpa_boundary_bits: u8,
696 #[bits(20)]
697 _reserved12: u32,
698 _reserved2: u32,
699 _reserved3: u32,
700}
701
702open_enum! {
703 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
704 pub enum HypercallCode: u16 {
705 #![expect(non_upper_case_globals)]
706
707 HvCallSwitchVirtualAddressSpace = 0x0001,
708 HvCallFlushVirtualAddressSpace = 0x0002,
709 HvCallFlushVirtualAddressList = 0x0003,
710 HvCallNotifyLongSpinWait = 0x0008,
711 HvCallInvokeHypervisorDebugger = 0x000a,
712 HvCallSendSyntheticClusterIpi = 0x000b,
713 HvCallModifyVtlProtectionMask = 0x000c,
714 HvCallEnablePartitionVtl = 0x000d,
715 HvCallEnableVpVtl = 0x000f,
716 HvCallVtlCall = 0x0011,
717 HvCallVtlReturn = 0x0012,
718 HvCallFlushVirtualAddressSpaceEx = 0x0013,
719 HvCallFlushVirtualAddressListEx = 0x0014,
720 HvCallSendSyntheticClusterIpiEx = 0x0015,
721 HvCallInstallIntercept = 0x004d,
722 HvCallGetVpRegisters = 0x0050,
723 HvCallSetVpRegisters = 0x0051,
724 HvCallTranslateVirtualAddress = 0x0052,
725 HvCallPostMessage = 0x005C,
726 HvCallSignalEvent = 0x005D,
727 HvCallOutputDebugCharacter = 0x0071,
728 HvCallGetSystemProperty = 0x007b,
729 HvCallRetargetDeviceInterrupt = 0x007e,
730 HvCallNotifyPartitionEvent = 0x0087,
731 HvCallRegisterInterceptResult = 0x0091,
732 HvCallAssertVirtualInterrupt = 0x0094,
733 HvCallStartVirtualProcessor = 0x0099,
734 HvCallGetVpIndexFromApicId = 0x009A,
735 HvCallTranslateVirtualAddressEx = 0x00AC,
736 HvCallCheckForIoIntercept = 0x00ad,
737 HvCallFlushGuestPhysicalAddressSpace = 0x00AF,
738 HvCallFlushGuestPhysicalAddressList = 0x00B0,
739 HvCallSignalEventDirect = 0x00C0,
740 HvCallPostMessageDirect = 0x00C1,
741 HvCallCheckSparseGpaPageVtlAccess = 0x00D4,
742 HvCallAcceptGpaPages = 0x00D9,
743 HvCallModifySparseGpaPageHostVisibility = 0x00DB,
744 HvCallGetVpCpuidValues = 0x00F4,
745 HvCallRestorePartitionTime = 0x0103,
746 HvCallMemoryMappedIoRead = 0x0106,
747 HvCallMemoryMappedIoWrite = 0x0107,
748 HvCallPinGpaPageRanges = 0x0112,
749 HvCallUnpinGpaPageRanges = 0x0113,
750 HvCallQuerySparseGpaPageHostVisibility = 0x011C,
751
752 HvExtCallQueryCapabilities = 0x8001,
754
755 HvCallVbsVmCallReport = 0xC001,
757 }
758}
759
760pub const HV_X64_MSR_GUEST_OS_ID: u32 = 0x40000000;
761pub const HV_X64_MSR_HYPERCALL: u32 = 0x40000001;
762pub const HV_X64_MSR_VP_INDEX: u32 = 0x40000002;
763pub const HV_X64_MSR_TIME_REF_COUNT: u32 = 0x40000020;
764pub const HV_X64_MSR_REFERENCE_TSC: u32 = 0x40000021;
765pub const HV_X64_MSR_TSC_FREQUENCY: u32 = 0x40000022;
766pub const HV_X64_MSR_APIC_FREQUENCY: u32 = 0x40000023;
767pub const HV_X64_MSR_EOI: u32 = 0x40000070;
768pub const HV_X64_MSR_ICR: u32 = 0x40000071;
769pub const HV_X64_MSR_TPR: u32 = 0x40000072;
770pub const HV_X64_MSR_VP_ASSIST_PAGE: u32 = 0x40000073;
771pub const HV_X64_MSR_SCONTROL: u32 = 0x40000080;
772pub const HV_X64_MSR_SVERSION: u32 = 0x40000081;
773pub const HV_X64_MSR_SIEFP: u32 = 0x40000082;
774pub const HV_X64_MSR_SIMP: u32 = 0x40000083;
775pub const HV_X64_MSR_EOM: u32 = 0x40000084;
776pub const HV_X64_MSR_SINT0: u32 = 0x40000090;
777pub const HV_X64_MSR_SINT1: u32 = 0x40000091;
778pub const HV_X64_MSR_SINT2: u32 = 0x40000092;
779pub const HV_X64_MSR_SINT3: u32 = 0x40000093;
780pub const HV_X64_MSR_SINT4: u32 = 0x40000094;
781pub const HV_X64_MSR_SINT5: u32 = 0x40000095;
782pub const HV_X64_MSR_SINT6: u32 = 0x40000096;
783pub const HV_X64_MSR_SINT7: u32 = 0x40000097;
784pub const HV_X64_MSR_SINT8: u32 = 0x40000098;
785pub const HV_X64_MSR_SINT9: u32 = 0x40000099;
786pub const HV_X64_MSR_SINT10: u32 = 0x4000009a;
787pub const HV_X64_MSR_SINT11: u32 = 0x4000009b;
788pub const HV_X64_MSR_SINT12: u32 = 0x4000009c;
789pub const HV_X64_MSR_SINT13: u32 = 0x4000009d;
790pub const HV_X64_MSR_SINT14: u32 = 0x4000009e;
791pub const HV_X64_MSR_SINT15: u32 = 0x4000009f;
792pub const HV_X64_MSR_STIMER0_CONFIG: u32 = 0x400000b0;
793pub const HV_X64_MSR_STIMER0_COUNT: u32 = 0x400000b1;
794pub const HV_X64_MSR_STIMER1_CONFIG: u32 = 0x400000b2;
795pub const HV_X64_MSR_STIMER1_COUNT: u32 = 0x400000b3;
796pub const HV_X64_MSR_STIMER2_CONFIG: u32 = 0x400000b4;
797pub const HV_X64_MSR_STIMER2_COUNT: u32 = 0x400000b5;
798pub const HV_X64_MSR_STIMER3_CONFIG: u32 = 0x400000b6;
799pub const HV_X64_MSR_STIMER3_COUNT: u32 = 0x400000b7;
800pub const HV_X64_MSR_GUEST_IDLE: u32 = 0x400000F0;
801pub const HV_X64_MSR_GUEST_CRASH_P0: u32 = 0x40000100;
802pub const HV_X64_MSR_GUEST_CRASH_P1: u32 = 0x40000101;
803pub const HV_X64_MSR_GUEST_CRASH_P2: u32 = 0x40000102;
804pub const HV_X64_MSR_GUEST_CRASH_P3: u32 = 0x40000103;
805pub const HV_X64_MSR_GUEST_CRASH_P4: u32 = 0x40000104;
806pub const HV_X64_MSR_GUEST_CRASH_CTL: u32 = 0x40000105;
807
808pub const HV_X64_GUEST_CRASH_PARAMETER_MSRS: usize = 5;
809
810#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
814#[repr(transparent)]
815pub struct HvStatus(pub u16);
816
817impl HvStatus {
818 pub const SUCCESS: Self = Self(0);
820
821 pub fn result(self) -> HvResult<()> {
824 if let Ok(err) = self.0.try_into() {
825 Err(HvError(err))
826 } else {
827 Ok(())
828 }
829 }
830
831 pub fn is_ok(self) -> bool {
833 self == Self::SUCCESS
834 }
835
836 pub fn is_err(self) -> bool {
838 self != Self::SUCCESS
839 }
840
841 const fn from_bits(bits: u16) -> Self {
842 Self(bits)
843 }
844
845 const fn into_bits(self) -> u16 {
846 self.0
847 }
848}
849
850impl From<Result<(), HvError>> for HvStatus {
851 fn from(err: Result<(), HvError>) -> Self {
852 err.err().map_or(Self::SUCCESS, |err| Self(err.0.get()))
853 }
854}
855
856impl Debug for HvStatus {
857 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
858 match self.result() {
859 Ok(()) => f.write_str("Success"),
860 Err(err) => Debug::fmt(&err, f),
861 }
862 }
863}
864
865#[derive(Copy, Clone, PartialEq, Eq, IntoBytes, Immutable, KnownLayout)]
870#[repr(transparent)]
871pub struct HvError(core::num::NonZeroU16);
872
873impl From<core::num::NonZeroU16> for HvError {
874 fn from(err: core::num::NonZeroU16) -> Self {
875 Self(err)
876 }
877}
878
879impl Debug for HvError {
880 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
881 match self.debug_name() {
882 Some(name) => f.pad(name),
883 None => Debug::fmt(&self.0.get(), f),
884 }
885 }
886}
887
888impl core::fmt::Display for HvError {
889 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
890 match self.doc_str() {
891 Some(s) => f.write_str(s),
892 None => write!(f, "Hypervisor error {:#06x}", self.0),
893 }
894 }
895}
896
897impl core::error::Error for HvError {}
898
899macro_rules! hv_error {
900 ($ty:ty, $(#[doc = $doc:expr] $ident:ident = $val:expr),* $(,)?) => {
901
902 #[expect(non_upper_case_globals)]
903 impl $ty {
904 $(
905 #[doc = $doc]
906 pub const $ident: Self = Self(core::num::NonZeroU16::new($val).unwrap());
907 )*
908
909 fn debug_name(&self) -> Option<&'static str> {
910 Some(match self.0.get() {
911 $(
912 $val => stringify!($ident),
913 )*
914 _ => return None,
915 })
916 }
917
918 fn doc_str(&self) -> Option<&'static str> {
919 Some(match self.0.get() {
920 $(
921 $val => const { $doc.trim_ascii() },
922 )*
923 _ => return None,
924 })
925 }
926 }
927 };
928}
929
930hv_error! {
932 HvError,
933 InvalidHypercallCode = 0x0002,
935 InvalidHypercallInput = 0x0003,
937 InvalidAlignment = 0x0004,
939 InvalidParameter = 0x0005,
941 AccessDenied = 0x0006,
943 InvalidPartitionState = 0x0007,
945 OperationDenied = 0x0008,
947 UnknownProperty = 0x0009,
949 PropertyValueOutOfRange = 0x000A,
951 InsufficientMemory = 0x000B,
953 PartitionTooDeep = 0x000C,
955 InvalidPartitionId = 0x000D,
957 InvalidVpIndex = 0x000E,
959 NotFound = 0x0010,
961 InvalidPortId = 0x0011,
963 InvalidConnectionId = 0x0012,
965 InsufficientBuffers = 0x0013,
967 NotAcknowledged = 0x0014,
969 InvalidVpState = 0x0015,
971 Acknowledged = 0x0016,
973 InvalidSaveRestoreState = 0x0017,
975 InvalidSynicState = 0x0018,
977 ObjectInUse = 0x0019,
979 InvalidProximityDomainInfo = 0x001A,
981 NoData = 0x001B,
983 Inactive = 0x001C,
985 NoResources = 0x001D,
987 FeatureUnavailable = 0x001E,
989 PartialPacket = 0x001F,
991 ProcessorFeatureNotSupported = 0x0020,
993 ProcessorCacheLineFlushSizeIncompatible = 0x0030,
995 InsufficientBuffer = 0x0033,
997 IncompatibleProcessor = 0x0037,
999 InsufficientDeviceDomains = 0x0038,
1001 CpuidFeatureValidationError = 0x003C,
1003 CpuidXsaveFeatureValidationError = 0x003D,
1005 ProcessorStartupTimeout = 0x003E,
1007 SmxEnabled = 0x003F,
1009 InvalidLpIndex = 0x0041,
1011 InvalidRegisterValue = 0x0050,
1013 InvalidVtlState = 0x0051,
1015 NxNotDetected = 0x0055,
1017 InvalidDeviceId = 0x0057,
1019 InvalidDeviceState = 0x0058,
1021 PendingPageRequests = 0x0059,
1023 PageRequestInvalid = 0x0060,
1025 KeyAlreadyExists = 0x0065,
1027 DeviceAlreadyInDomain = 0x0066,
1029 InvalidCpuGroupId = 0x006F,
1031 InvalidCpuGroupState = 0x0070,
1033 OperationFailed = 0x0071,
1035 NotAllowedWithNestedVirtActive = 0x0072,
1037 InsufficientRootMemory = 0x0073,
1039 EventBufferAlreadyFreed = 0x0074,
1041 Timeout = 0x0078,
1043 VtlAlreadyEnabled = 0x0086,
1045 UnknownRegisterName = 0x0087,
1047}
1048
1049pub type HvResult<T> = Result<T, HvError>;
1051
1052#[repr(u8)]
1053#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
1054pub enum Vtl {
1055 Vtl0 = 0,
1056 Vtl1 = 1,
1057 Vtl2 = 2,
1058}
1059
1060impl TryFrom<u8> for Vtl {
1061 type Error = HvError;
1062
1063 fn try_from(value: u8) -> Result<Self, Self::Error> {
1064 Ok(match value {
1065 0 => Self::Vtl0,
1066 1 => Self::Vtl1,
1067 2 => Self::Vtl2,
1068 _ => return Err(HvError::InvalidParameter),
1069 })
1070 }
1071}
1072
1073impl From<Vtl> for u8 {
1074 fn from(value: Vtl) -> Self {
1075 value as u8
1076 }
1077}
1078
1079#[bitfield(u64)]
1081pub struct GuestCrashCtl {
1082 #[bits(58)]
1083 _reserved: u64,
1084 #[bits(3)]
1086 pub pre_os_id: u8,
1087 #[bits(1)]
1089 pub no_crash_dump: bool,
1090 #[bits(1)]
1093 pub crash_message: bool,
1094 #[bits(1)]
1096 pub crash_notify: bool,
1097}
1098
1099#[repr(C, align(16))]
1100#[derive(Copy, Clone, PartialEq, Eq, IntoBytes, Immutable, KnownLayout, FromBytes)]
1101pub struct AlignedU128([u8; 16]);
1102
1103impl AlignedU128 {
1104 pub fn as_ne_bytes(&self) -> [u8; 16] {
1105 self.0
1106 }
1107
1108 pub fn from_ne_bytes(val: [u8; 16]) -> Self {
1109 Self(val)
1110 }
1111}
1112
1113impl Debug for AlignedU128 {
1114 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1115 Debug::fmt(&u128::from_ne_bytes(self.0), f)
1116 }
1117}
1118
1119impl From<u128> for AlignedU128 {
1120 fn from(v: u128) -> Self {
1121 Self(v.to_ne_bytes())
1122 }
1123}
1124
1125impl From<u64> for AlignedU128 {
1126 fn from(v: u64) -> Self {
1127 (v as u128).into()
1128 }
1129}
1130
1131impl From<u32> for AlignedU128 {
1132 fn from(v: u32) -> Self {
1133 (v as u128).into()
1134 }
1135}
1136
1137impl From<u16> for AlignedU128 {
1138 fn from(v: u16) -> Self {
1139 (v as u128).into()
1140 }
1141}
1142
1143impl From<u8> for AlignedU128 {
1144 fn from(v: u8) -> Self {
1145 (v as u128).into()
1146 }
1147}
1148
1149impl From<AlignedU128> for u128 {
1150 fn from(v: AlignedU128) -> Self {
1151 u128::from_ne_bytes(v.0)
1152 }
1153}
1154
1155open_enum! {
1156 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
1157 pub enum HvMessageType: u32 {
1158 #![expect(non_upper_case_globals)]
1159
1160 HvMessageTypeNone = 0x00000000,
1161
1162 HvMessageTypeUnmappedGpa = 0x80000000,
1163 HvMessageTypeGpaIntercept = 0x80000001,
1164 HvMessageTypeUnacceptedGpa = 0x80000003,
1165 HvMessageTypeGpaAttributeIntercept = 0x80000004,
1166 HvMessageTypeEnablePartitionVtlIntercept = 0x80000005,
1167 HvMessageTypeTimerExpired = 0x80000010,
1168 HvMessageTypeInvalidVpRegisterValue = 0x80000020,
1169 HvMessageTypeUnrecoverableException = 0x80000021,
1170 HvMessageTypeUnsupportedFeature = 0x80000022,
1171 HvMessageTypeTlbPageSizeMismatch = 0x80000023,
1172 HvMessageTypeIommuFault = 0x80000024,
1173 HvMessageTypeEventLogBufferComplete = 0x80000040,
1174 HvMessageTypeHypercallIntercept = 0x80000050,
1175 HvMessageTypeSynicEventIntercept = 0x80000060,
1176 HvMessageTypeSynicSintIntercept = 0x80000061,
1177 HvMessageTypeSynicSintDeliverable = 0x80000062,
1178 HvMessageTypeAsyncCallCompletion = 0x80000070,
1179 HvMessageTypeX64IoPortIntercept = 0x80010000,
1180 HvMessageTypeMsrIntercept = 0x80010001,
1181 HvMessageTypeX64CpuidIntercept = 0x80010002,
1182 HvMessageTypeExceptionIntercept = 0x80010003,
1183 HvMessageTypeX64ApicEoi = 0x80010004,
1184 HvMessageTypeX64IommuPrq = 0x80010005,
1185 HvMessageTypeRegisterIntercept = 0x80010006,
1186 HvMessageTypeX64Halt = 0x80010007,
1187 HvMessageTypeX64InterruptionDeliverable = 0x80010008,
1188 HvMessageTypeX64SipiIntercept = 0x80010009,
1189 HvMessageTypeX64RdtscIntercept = 0x8001000a,
1190 HvMessageTypeX64ApicSmiIntercept = 0x8001000b,
1191 HvMessageTypeArm64ResetIntercept = 0x8001000c,
1192 HvMessageTypeX64ApicInitSipiIntercept = 0x8001000d,
1193 HvMessageTypeX64ApicWriteIntercept = 0x8001000e,
1194 HvMessageTypeX64ProxyInterruptIntercept = 0x8001000f,
1195 HvMessageTypeX64IsolationCtrlRegIntercept = 0x80010010,
1196 HvMessageTypeX64SnpGuestRequestIntercept = 0x80010011,
1197 HvMessageTypeX64ExceptionTrapIntercept = 0x80010012,
1198 HvMessageTypeX64SevVmgexitIntercept = 0x80010013,
1199 }
1200}
1201
1202impl Default for HvMessageType {
1203 fn default() -> Self {
1204 HvMessageType::HvMessageTypeNone
1205 }
1206}
1207
1208pub const HV_SYNIC_INTERCEPTION_SINT_INDEX: u8 = 0;
1209
1210pub const NUM_SINTS: usize = 16;
1211pub const NUM_TIMERS: usize = 4;
1212
1213#[repr(C)]
1214#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
1215pub struct HvMessageHeader {
1216 pub typ: HvMessageType,
1217 pub len: u8,
1218 pub flags: HvMessageFlags,
1219 pub rsvd: u16,
1220 pub id: u64,
1221}
1222
1223#[bitfield(u8)]
1224#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
1225pub struct HvMessageFlags {
1226 pub message_pending: bool,
1227 #[bits(7)]
1228 _reserved: u8,
1229}
1230
1231pub const HV_MESSAGE_SIZE: usize = size_of::<HvMessage>();
1232const_assert!(HV_MESSAGE_SIZE == 256);
1233pub const HV_MESSAGE_PAYLOAD_SIZE: usize = 240;
1234
1235#[repr(C, align(16))]
1236#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
1237pub struct HvMessage {
1238 pub header: HvMessageHeader,
1239 pub payload_buffer: [u8; HV_MESSAGE_PAYLOAD_SIZE],
1240}
1241
1242impl Default for HvMessage {
1243 fn default() -> Self {
1244 Self {
1245 header: FromZeros::new_zeroed(),
1246 payload_buffer: [0; 240],
1247 }
1248 }
1249}
1250
1251impl HvMessage {
1252 pub fn new(typ: HvMessageType, id: u64, payload: &[u8]) -> Self {
1255 let mut msg = HvMessage {
1256 header: HvMessageHeader {
1257 typ,
1258 len: payload.len() as u8,
1259 flags: HvMessageFlags::new(),
1260 rsvd: 0,
1261 id,
1262 },
1263 payload_buffer: [0; 240],
1264 };
1265 msg.payload_buffer[..payload.len()].copy_from_slice(payload);
1266 msg
1267 }
1268
1269 pub fn payload(&self) -> &[u8] {
1270 &self.payload_buffer[..self.header.len as usize]
1271 }
1272
1273 pub fn as_message<T: MessagePayload>(&self) -> &T {
1274 let () = T::CHECK;
1276 T::ref_from_prefix(&self.payload_buffer).unwrap().0
1277 }
1278
1279 pub fn as_message_mut<T: MessagePayload>(&mut self) -> &T {
1280 let () = T::CHECK;
1282 T::mut_from_prefix(&mut self.payload_buffer).unwrap().0
1283 }
1284}
1285
1286pub trait MessagePayload: KnownLayout + Immutable + IntoBytes + FromBytes + Sized {
1287 #[doc(hidden)]
1290 const CHECK: () = {
1291 assert!(size_of::<Self>() <= HV_MESSAGE_PAYLOAD_SIZE);
1292 assert!(align_of::<Self>() <= align_of::<HvMessage>());
1293 };
1294}
1295
1296#[repr(C)]
1297#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
1298pub struct TimerMessagePayload {
1299 pub timer_index: u32,
1300 pub reserved: u32,
1301 pub expiration_time: u64,
1302 pub delivery_time: u64,
1303}
1304
1305pub mod hypercall {
1306 use super::*;
1307 use core::ops::RangeInclusive;
1308 use zerocopy::Unalign;
1309
1310 #[bitfield(u64)]
1312 pub struct Control {
1313 pub code: u16,
1315 pub fast: bool,
1317 #[bits(10)]
1319 pub variable_header_size: usize,
1320 #[bits(4)]
1321 _rsvd0: u8,
1322 pub nested: bool,
1324 #[bits(12)]
1326 pub rep_count: usize,
1327 #[bits(4)]
1328 _rsvd1: u8,
1329 #[bits(12)]
1331 pub rep_start: usize,
1332 #[bits(4)]
1333 _rsvd2: u8,
1334 }
1335
1336 #[bitfield(u64)]
1338 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
1339 #[must_use]
1340 pub struct HypercallOutput {
1341 #[bits(16)]
1342 pub call_status: HvStatus,
1343 pub rsvd: u16,
1344 #[bits(12)]
1345 pub elements_processed: usize,
1346 #[bits(20)]
1347 pub rsvd2: u32,
1348 }
1349
1350 impl From<HvError> for HypercallOutput {
1351 fn from(e: HvError) -> Self {
1352 Self::new().with_call_status(Err(e).into())
1353 }
1354 }
1355
1356 impl HypercallOutput {
1357 pub const SUCCESS: Self = Self::new();
1359
1360 pub fn result(&self) -> Result<(), HvError> {
1361 self.call_status().result()
1362 }
1363 }
1364
1365 #[repr(C)]
1366 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
1367 pub struct HvRegisterAssoc {
1368 pub name: HvRegisterName,
1369 pub pad: [u32; 3],
1370 pub value: HvRegisterValue,
1371 }
1372
1373 impl<N: Into<HvRegisterName>, T: Into<HvRegisterValue>> From<(N, T)> for HvRegisterAssoc {
1374 fn from((name, value): (N, T)) -> Self {
1375 Self {
1376 name: name.into(),
1377 pad: [0; 3],
1378 value: value.into(),
1379 }
1380 }
1381 }
1382
1383 impl<N: Copy + Into<HvRegisterName>, T: Copy + Into<HvRegisterValue>> From<&(N, T)>
1384 for HvRegisterAssoc
1385 {
1386 fn from(&(name, value): &(N, T)) -> Self {
1387 Self {
1388 name: name.into(),
1389 pad: [0; 3],
1390 value: value.into(),
1391 }
1392 }
1393 }
1394
1395 #[bitfield(u64)]
1396 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
1397 pub struct MsrHypercallContents {
1398 pub enable: bool,
1399 pub locked: bool,
1400 #[bits(10)]
1401 pub reserved_p: u64,
1402 #[bits(52)]
1403 pub gpn: u64,
1404 }
1405
1406 #[repr(C, align(8))]
1407 #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
1408 pub struct PostMessage {
1409 pub connection_id: u32,
1410 pub padding: u32,
1411 pub message_type: u32,
1412 pub payload_size: u32,
1413 pub payload: [u8; 240],
1414 }
1415
1416 #[repr(C, align(8))]
1417 #[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
1418 pub struct SignalEvent {
1419 pub connection_id: u32,
1420 pub flag_number: u16,
1421 pub rsvd: u16,
1422 }
1423
1424 #[repr(C)]
1425 #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
1426 pub struct PostMessageDirect {
1427 pub partition_id: u64,
1428 pub vp_index: u32,
1429 pub vtl: u8,
1430 pub padding0: [u8; 3],
1431 pub sint: u8,
1432 pub padding1: [u8; 3],
1433 pub message: Unalign<HvMessage>,
1434 pub padding2: u32,
1435 }
1436
1437 #[repr(C)]
1438 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
1439 pub struct SignalEventDirect {
1440 pub target_partition: u64,
1441 pub target_vp: u32,
1442 pub target_vtl: u8,
1443 pub target_sint: u8,
1444 pub flag_number: u16,
1445 }
1446
1447 #[repr(C)]
1448 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
1449 pub struct SignalEventDirectOutput {
1450 pub newly_signaled: u8,
1451 pub rsvd: [u8; 7],
1452 }
1453
1454 #[repr(C)]
1455 #[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
1456 pub struct InterruptEntry {
1457 pub source: HvInterruptSource,
1458 pub rsvd: u32,
1459 pub data: [u32; 2],
1460 }
1461
1462 open_enum! {
1463 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
1464 pub enum HvInterruptSource: u32 {
1465 MSI = 1,
1466 IO_APIC = 2,
1467 }
1468 }
1469
1470 #[repr(C)]
1471 #[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
1472 pub struct InterruptTarget {
1473 pub vector: u32,
1474 pub flags: HvInterruptTargetFlags,
1475 pub mask_or_format: u64,
1476 }
1477
1478 #[bitfield(u32)]
1479 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
1480 pub struct HvInterruptTargetFlags {
1481 pub multicast: bool,
1482 pub processor_set: bool,
1483 pub proxy_redirect: bool,
1484 #[bits(29)]
1485 pub reserved: u32,
1486 }
1487
1488 pub const HV_DEVICE_INTERRUPT_TARGET_MULTICAST: u32 = 1;
1489 pub const HV_DEVICE_INTERRUPT_TARGET_PROCESSOR_SET: u32 = 2;
1490 pub const HV_DEVICE_INTERRUPT_TARGET_PROXY_REDIRECT: u32 = 4;
1491
1492 pub const HV_GENERIC_SET_SPARSE_4K: u64 = 0;
1493 pub const HV_GENERIC_SET_ALL: u64 = 1;
1494
1495 #[repr(C)]
1496 #[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
1497 pub struct RetargetDeviceInterrupt {
1498 pub partition_id: u64,
1499 pub device_id: u64,
1500 pub entry: InterruptEntry,
1501 pub rsvd: u64,
1502 pub target_header: InterruptTarget,
1503 }
1504
1505 #[bitfield(u8)]
1506 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
1507 pub struct HvInputVtl {
1508 #[bits(4)]
1509 pub target_vtl_value: u8,
1510 pub use_target_vtl: bool,
1511 #[bits(3)]
1512 pub reserved: u8,
1513 }
1514
1515 impl From<Vtl> for HvInputVtl {
1516 fn from(value: Vtl) -> Self {
1517 Self::from(Some(value))
1518 }
1519 }
1520
1521 impl From<Option<Vtl>> for HvInputVtl {
1522 fn from(value: Option<Vtl>) -> Self {
1523 Self::new()
1524 .with_use_target_vtl(value.is_some())
1525 .with_target_vtl_value(value.map_or(0, Into::into))
1526 }
1527 }
1528
1529 impl HvInputVtl {
1530 pub fn target_vtl(&self) -> Result<Option<Vtl>, HvError> {
1532 if self.reserved() != 0 {
1533 return Err(HvError::InvalidParameter);
1534 }
1535 if self.use_target_vtl() {
1536 Ok(Some(self.target_vtl_value().try_into()?))
1537 } else {
1538 Ok(None)
1539 }
1540 }
1541
1542 pub const CURRENT_VTL: Self = Self::new();
1543 }
1544
1545 #[repr(C)]
1546 #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
1547 pub struct GetSetVpRegisters {
1548 pub partition_id: u64,
1549 pub vp_index: u32,
1550 pub target_vtl: HvInputVtl,
1551 pub rsvd: [u8; 3],
1552 }
1553
1554 open_enum::open_enum! {
1555 #[derive(Default)]
1556 pub enum HvGuestOsMicrosoftIds: u8 {
1557 UNDEFINED = 0x00,
1558 MSDOS = 0x01,
1559 WINDOWS_3X = 0x02,
1560 WINDOWS_9X = 0x03,
1561 WINDOWS_NT = 0x04,
1562 WINDOWS_CE = 0x05,
1563 }
1564 }
1565
1566 #[bitfield(u64)]
1567 pub struct HvGuestOsMicrosoft {
1568 #[bits(40)]
1569 _rsvd: u64,
1570 #[bits(8)]
1571 pub os_id: u8,
1572 #[bits(16)]
1574 pub vendor_id: u16,
1575 }
1576
1577 open_enum::open_enum! {
1578 #[derive(Default)]
1579 pub enum HvGuestOsOpenSourceType: u8 {
1580 UNDEFINED = 0x00,
1581 LINUX = 0x01,
1582 FREEBSD = 0x02,
1583 XEN = 0x03,
1584 ILLUMOS = 0x04,
1585 }
1586 }
1587
1588 #[bitfield(u64)]
1589 pub struct HvGuestOsOpenSource {
1590 #[bits(16)]
1591 pub build_no: u16,
1592 #[bits(32)]
1593 pub version: u32,
1594 #[bits(8)]
1595 pub os_id: u8,
1596 #[bits(7)]
1597 pub os_type: u8,
1598 #[bits(1)]
1599 pub is_open_source: bool,
1600 }
1601
1602 #[bitfield(u64)]
1603 pub struct HvGuestOsId {
1604 #[bits(63)]
1605 _rsvd: u64,
1606 is_open_source: bool,
1607 }
1608
1609 impl HvGuestOsId {
1610 pub fn microsoft(&self) -> Option<HvGuestOsMicrosoft> {
1611 (!self.is_open_source()).then(|| HvGuestOsMicrosoft::from(u64::from(*self)))
1612 }
1613
1614 pub fn open_source(&self) -> Option<HvGuestOsOpenSource> {
1615 (self.is_open_source()).then(|| HvGuestOsOpenSource::from(u64::from(*self)))
1616 }
1617
1618 pub fn as_u64(&self) -> u64 {
1619 self.0
1620 }
1621 }
1622
1623 pub const HV_INTERCEPT_ACCESS_MASK_NONE: u32 = 0x00;
1624 pub const HV_INTERCEPT_ACCESS_MASK_READ: u32 = 0x01;
1625 pub const HV_INTERCEPT_ACCESS_MASK_WRITE: u32 = 0x02;
1626 pub const HV_INTERCEPT_ACCESS_MASK_READ_WRITE: u32 =
1627 HV_INTERCEPT_ACCESS_MASK_READ | HV_INTERCEPT_ACCESS_MASK_WRITE;
1628 pub const HV_INTERCEPT_ACCESS_MASK_EXECUTE: u32 = 0x04;
1629
1630 open_enum::open_enum! {
1631 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
1632 pub enum HvInterceptType: u32 {
1633 #![expect(non_upper_case_globals)]
1634 HvInterceptTypeX64IoPort = 0x00000000,
1635 HvInterceptTypeX64Msr = 0x00000001,
1636 HvInterceptTypeX64Cpuid = 0x00000002,
1637 HvInterceptTypeException = 0x00000003,
1638 HvInterceptTypeHypercall = 0x00000008,
1639 HvInterceptTypeUnknownSynicConnection = 0x0000000D,
1640 HvInterceptTypeX64ApicEoi = 0x0000000E,
1641 HvInterceptTypeRetargetInterruptWithUnknownDeviceId = 0x0000000F,
1642 HvInterceptTypeX64IoPortRange = 0x00000011,
1643 }
1644 }
1645
1646 #[repr(transparent)]
1647 #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, Debug)]
1648 pub struct HvInterceptParameters(u64);
1649
1650 impl HvInterceptParameters {
1651 pub fn new_io_port(port: u16) -> Self {
1652 Self(port as u64)
1653 }
1654
1655 pub fn new_io_port_range(ports: RangeInclusive<u16>) -> Self {
1656 let base = *ports.start() as u64;
1657 let end = *ports.end() as u64;
1658 Self(base | (end << 16))
1659 }
1660
1661 pub fn new_exception(vector: u16) -> Self {
1662 Self(vector as u64)
1663 }
1664
1665 pub fn io_port(&self) -> u16 {
1666 self.0 as u16
1667 }
1668
1669 pub fn io_port_range(&self) -> RangeInclusive<u16> {
1670 let base = self.0 as u16;
1671 let end = (self.0 >> 16) as u16;
1672 base..=end
1673 }
1674
1675 pub fn cpuid_index(&self) -> u32 {
1676 self.0 as u32
1677 }
1678
1679 pub fn exception(&self) -> u16 {
1680 self.0 as u16
1681 }
1682 }
1683
1684 #[repr(C)]
1685 #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, Debug)]
1686 pub struct InstallIntercept {
1687 pub partition_id: u64,
1688 pub access_type_mask: u32,
1689 pub intercept_type: HvInterceptType,
1690 pub intercept_parameters: HvInterceptParameters,
1691 }
1692
1693 #[repr(C)]
1695 #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, Debug)]
1696 pub struct RegisterInterceptResultCpuid {
1697 pub partition_id: u64,
1698 pub vp_index: u32,
1699 pub intercept_type: HvInterceptType,
1700 pub parameters: HvRegisterX64CpuidResultParameters,
1701 pub _reserved: u32,
1703 }
1704
1705 #[repr(C)]
1707 #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, Debug)]
1708 pub struct HvRegisterX64CpuidResultParameters {
1709 pub input: HvRegisterX64CpuidResultParametersInput,
1710 pub result: HvRegisterX64CpuidResultParametersOutput,
1711 }
1712
1713 #[repr(C)]
1715 #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, Debug)]
1716 pub struct HvRegisterX64CpuidResultParametersInput {
1717 pub eax: u32,
1718 pub ecx: u32,
1719 pub subleaf_specific: u8,
1720 pub always_override: u8,
1721 pub padding: u16,
1722 }
1723
1724 #[repr(C)]
1726 #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, Debug)]
1727 pub struct HvRegisterX64CpuidResultParametersOutput {
1728 pub eax: u32,
1729 pub eax_mask: u32,
1730 pub ebx: u32,
1731 pub ebx_mask: u32,
1732 pub ecx: u32,
1733 pub ecx_mask: u32,
1734 pub edx: u32,
1735 pub edx_mask: u32,
1736 }
1737
1738 #[repr(C)]
1739 #[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes, Debug)]
1740 pub struct AssertVirtualInterrupt {
1741 pub partition_id: u64,
1742 pub interrupt_control: HvInterruptControl,
1743 pub destination_address: u64,
1744 pub requested_vector: u32,
1745 pub target_vtl: u8,
1746 pub rsvd0: u8,
1747 pub rsvd1: u16,
1748 }
1749
1750 #[repr(C)]
1751 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
1752 pub struct StartVirtualProcessorX64 {
1753 pub partition_id: u64,
1754 pub vp_index: u32,
1755 pub target_vtl: u8,
1756 pub rsvd0: u8,
1757 pub rsvd1: u16,
1758 pub vp_context: InitialVpContextX64,
1759 }
1760
1761 #[repr(C)]
1762 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
1763 pub struct InitialVpContextX64 {
1764 pub rip: u64,
1765 pub rsp: u64,
1766 pub rflags: u64,
1767 pub cs: HvX64SegmentRegister,
1768 pub ds: HvX64SegmentRegister,
1769 pub es: HvX64SegmentRegister,
1770 pub fs: HvX64SegmentRegister,
1771 pub gs: HvX64SegmentRegister,
1772 pub ss: HvX64SegmentRegister,
1773 pub tr: HvX64SegmentRegister,
1774 pub ldtr: HvX64SegmentRegister,
1775 pub idtr: HvX64TableRegister,
1776 pub gdtr: HvX64TableRegister,
1777 pub efer: u64,
1778 pub cr0: u64,
1779 pub cr3: u64,
1780 pub cr4: u64,
1781 pub msr_cr_pat: u64,
1782 }
1783
1784 #[repr(C)]
1785 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
1786 pub struct StartVirtualProcessorArm64 {
1787 pub partition_id: u64,
1788 pub vp_index: u32,
1789 pub target_vtl: u8,
1790 pub rsvd0: u8,
1791 pub rsvd1: u16,
1792 pub vp_context: InitialVpContextArm64,
1793 }
1794
1795 #[repr(C)]
1796 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
1797 pub struct InitialVpContextArm64 {
1798 pub pc: u64,
1799 pub sp_elh: u64,
1800 pub sctlr_el1: u64,
1801 pub mair_el1: u64,
1802 pub tcr_el1: u64,
1803 pub vbar_el1: u64,
1804 pub ttbr0_el1: u64,
1805 pub ttbr1_el1: u64,
1806 pub x18: u64,
1807 }
1808
1809 impl InitialVpContextX64 {
1810 pub fn as_hv_register_assocs(&self) -> impl Iterator<Item = HvRegisterAssoc> + '_ {
1811 let regs = [
1812 (HvX64RegisterName::Rip, HvRegisterValue::from(self.rip)).into(),
1813 (HvX64RegisterName::Rsp, HvRegisterValue::from(self.rsp)).into(),
1814 (
1815 HvX64RegisterName::Rflags,
1816 HvRegisterValue::from(self.rflags),
1817 )
1818 .into(),
1819 (HvX64RegisterName::Cs, HvRegisterValue::from(self.cs)).into(),
1820 (HvX64RegisterName::Ds, HvRegisterValue::from(self.ds)).into(),
1821 (HvX64RegisterName::Es, HvRegisterValue::from(self.es)).into(),
1822 (HvX64RegisterName::Fs, HvRegisterValue::from(self.fs)).into(),
1823 (HvX64RegisterName::Gs, HvRegisterValue::from(self.gs)).into(),
1824 (HvX64RegisterName::Ss, HvRegisterValue::from(self.ss)).into(),
1825 (HvX64RegisterName::Tr, HvRegisterValue::from(self.tr)).into(),
1826 (HvX64RegisterName::Ldtr, HvRegisterValue::from(self.ldtr)).into(),
1827 (HvX64RegisterName::Idtr, HvRegisterValue::from(self.idtr)).into(),
1828 (HvX64RegisterName::Gdtr, HvRegisterValue::from(self.gdtr)).into(),
1829 (HvX64RegisterName::Efer, HvRegisterValue::from(self.efer)).into(),
1830 (HvX64RegisterName::Cr0, HvRegisterValue::from(self.cr0)).into(),
1831 (HvX64RegisterName::Cr3, HvRegisterValue::from(self.cr3)).into(),
1832 (HvX64RegisterName::Cr4, HvRegisterValue::from(self.cr4)).into(),
1833 (
1834 HvX64RegisterName::Pat,
1835 HvRegisterValue::from(self.msr_cr_pat),
1836 )
1837 .into(),
1838 ];
1839 regs.into_iter()
1840 }
1841 }
1842
1843 #[bitfield(u64)]
1844 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
1845 pub struct TranslateGvaControlFlagsX64 {
1846 pub validate_read: bool,
1848 pub validate_write: bool,
1850 pub validate_execute: bool,
1852 pub privilege_exempt: bool,
1855 pub set_page_table_bits: bool,
1857 pub tlb_flush_inhibit: bool,
1859 pub supervisor_access: bool,
1861 pub user_access: bool,
1863 pub enforce_smap: bool,
1867 pub override_smap: bool,
1870 pub shadow_stack: bool,
1872 #[bits(45)]
1873 _unused: u64,
1874 input_vtl_value: u8,
1876 }
1877
1878 impl TranslateGvaControlFlagsX64 {
1879 pub fn input_vtl(&self) -> HvInputVtl {
1880 self.input_vtl_value().into()
1881 }
1882
1883 pub fn with_input_vtl(self, input_vtl: HvInputVtl) -> Self {
1884 self.with_input_vtl_value(input_vtl.into())
1885 }
1886
1887 pub fn set_input_vtl(&mut self, input_vtl: HvInputVtl) {
1888 self.set_input_vtl_value(input_vtl.into())
1889 }
1890 }
1891
1892 #[bitfield(u64)]
1893 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
1894 pub struct TranslateGvaControlFlagsArm64 {
1895 pub validate_read: bool,
1897 pub validate_write: bool,
1899 pub validate_execute: bool,
1901 _reserved0: bool,
1902 pub set_page_table_bits: bool,
1904 pub tlb_flush_inhibit: bool,
1906 pub supervisor_access: bool,
1908 pub user_access: bool,
1910 pub pan_set: bool,
1913 pub pan_clear: bool,
1916 #[bits(46)]
1917 _unused: u64,
1918 #[bits(8)]
1920 input_vtl_value: u8,
1921 }
1922
1923 impl TranslateGvaControlFlagsArm64 {
1924 pub fn input_vtl(&self) -> HvInputVtl {
1925 self.input_vtl_value().into()
1926 }
1927
1928 pub fn with_input_vtl(self, input_vtl: HvInputVtl) -> Self {
1929 self.with_input_vtl_value(input_vtl.into())
1930 }
1931
1932 pub fn set_input_vtl(&mut self, input_vtl: HvInputVtl) {
1933 self.set_input_vtl_value(input_vtl.into())
1934 }
1935 }
1936
1937 #[repr(C)]
1938 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
1939 pub struct TranslateVirtualAddressX64 {
1940 pub partition_id: u64,
1941 pub vp_index: u32,
1942 pub reserved: u32,
1944 pub control_flags: TranslateGvaControlFlagsX64,
1945 pub gva_page: u64,
1946 }
1947
1948 #[repr(C)]
1949 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
1950 pub struct TranslateVirtualAddressArm64 {
1951 pub partition_id: u64,
1952 pub vp_index: u32,
1953 pub reserved: u32,
1955 pub control_flags: TranslateGvaControlFlagsArm64,
1956 pub gva_page: u64,
1957 }
1958
1959 open_enum::open_enum! {
1960 pub enum TranslateGvaResultCode: u32 {
1961 SUCCESS = 0,
1962
1963 PAGE_NOT_PRESENT = 1,
1965 PRIVILEGE_VIOLATION = 2,
1966 INVALID_PAGE_TABLE_FLAGS = 3,
1967
1968 GPA_UNMAPPED = 4,
1970 GPA_NO_READ_ACCESS = 5,
1971 GPA_NO_WRITE_ACCESS = 6,
1972 GPA_ILLEGAL_OVERLAY_ACCESS = 7,
1973
1974 INTERCEPT = 8,
1978
1979 GPA_UNACCEPTED = 9,
1980 }
1981 }
1982
1983 #[bitfield(u64)]
1984 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
1985 pub struct TranslateGvaResult {
1986 pub result_code: u32,
1987 pub cache_type: u8,
1988 pub overlay_page: bool,
1989 #[bits(23)]
1990 pub reserved: u32,
1991 }
1992
1993 #[repr(C)]
1994 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
1995 pub struct TranslateVirtualAddressOutput {
1996 pub translation_result: TranslateGvaResult,
1997 pub gpa_page: u64,
1998 }
1999
2000 #[repr(C)]
2001 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2002 pub struct TranslateGvaResultExX64 {
2003 pub result: TranslateGvaResult,
2004 pub reserved: u64,
2005 pub event_info: HvX64PendingEvent,
2006 }
2007
2008 const_assert!(size_of::<TranslateGvaResultExX64>() == 0x30);
2009
2010 #[repr(C)]
2011 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2012 pub struct TranslateGvaResultExArm64 {
2013 pub result: TranslateGvaResult,
2014 }
2015
2016 const_assert!(size_of::<TranslateGvaResultExArm64>() == 0x8);
2017
2018 #[repr(C)]
2019 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2020 pub struct TranslateVirtualAddressExOutputX64 {
2021 pub translation_result: TranslateGvaResultExX64,
2022 pub gpa_page: u64,
2023 pub reserved: u64,
2025 }
2026
2027 const_assert!(size_of::<TranslateVirtualAddressExOutputX64>() == 0x40);
2028
2029 #[repr(C)]
2030 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2031 pub struct TranslateVirtualAddressExOutputArm64 {
2032 pub translation_result: TranslateGvaResultExArm64,
2033 pub gpa_page: u64,
2034 }
2035
2036 const_assert!(size_of::<TranslateVirtualAddressExOutputArm64>() == 0x10);
2037
2038 #[repr(C)]
2039 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2040 pub struct GetVpIndexFromApicId {
2041 pub partition_id: u64,
2042 pub target_vtl: u8,
2043 pub reserved: [u8; 7],
2044 }
2045
2046 #[repr(C)]
2047 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2048 pub struct EnableVpVtlX64 {
2049 pub partition_id: u64,
2050 pub vp_index: u32,
2051 pub target_vtl: u8,
2052 pub reserved: [u8; 3],
2053 pub vp_vtl_context: InitialVpContextX64,
2054 }
2055
2056 #[repr(C)]
2057 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2058 pub struct EnableVpVtlArm64 {
2059 pub partition_id: u64,
2060 pub vp_index: u32,
2061 pub target_vtl: u8,
2062 pub reserved: [u8; 3],
2063 pub vp_vtl_context: InitialVpContextArm64,
2064 }
2065
2066 #[repr(C)]
2067 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2068 pub struct ModifyVtlProtectionMask {
2069 pub partition_id: u64,
2070 pub map_flags: HvMapGpaFlags,
2071 pub target_vtl: HvInputVtl,
2072 pub reserved: [u8; 3],
2073 }
2074
2075 #[repr(C)]
2076 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2077 pub struct CheckSparseGpaPageVtlAccess {
2078 pub partition_id: u64,
2079 pub target_vtl: HvInputVtl,
2080 pub desired_access: u8,
2081 pub reserved0: u16,
2082 pub reserved1: u32,
2083 }
2084 const_assert!(size_of::<CheckSparseGpaPageVtlAccess>() == 0x10);
2085
2086 #[bitfield(u64)]
2087 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2088 pub struct CheckSparseGpaPageVtlAccessOutput {
2089 pub result_code: u8,
2090 pub denied_access: u8,
2091 #[bits(4)]
2092 pub intercepting_vtl: u32,
2093 #[bits(12)]
2094 _reserved0: u32,
2095 _reserved1: u32,
2096 }
2097 const_assert!(size_of::<CheckSparseGpaPageVtlAccessOutput>() == 0x8);
2098
2099 open_enum::open_enum! {
2100 pub enum CheckGpaPageVtlAccessResultCode: u32 {
2101 SUCCESS = 0,
2102 MEMORY_INTERCEPT = 1,
2103 }
2104 }
2105
2106 pub const HV_VTL_PERMISSION_SET_SIZE: usize = 2;
2108
2109 #[repr(C)]
2110 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2111 pub struct VtlPermissionSet {
2112 pub vtl_permission_from_1: [u16; HV_VTL_PERMISSION_SET_SIZE],
2114 }
2115
2116 open_enum::open_enum! {
2117 pub enum AcceptMemoryType: u32 {
2118 ANY = 0,
2119 RAM = 1,
2120 }
2121 }
2122
2123 open_enum! {
2124 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2131 pub enum HostVisibilityType: u8 {
2132 PRIVATE = 0,
2133 SHARED = 3,
2134 }
2135 }
2136
2137 impl HostVisibilityType {
2139 const fn from_bits(value: u8) -> Self {
2140 Self(value)
2141 }
2142
2143 const fn into_bits(value: Self) -> u8 {
2144 value.0
2145 }
2146 }
2147
2148 #[bitfield(u32)]
2150 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2151 pub struct AcceptPagesAttributes {
2152 #[bits(6)]
2153 pub memory_type: u32,
2155 #[bits(2)]
2156 pub host_visibility: HostVisibilityType,
2158 #[bits(3)]
2159 pub vtl_set: u32,
2161 #[bits(21)]
2162 _reserved: u32,
2163 }
2164
2165 #[repr(C)]
2166 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2167 pub struct AcceptGpaPages {
2168 pub partition_id: u64,
2170 pub page_attributes: AcceptPagesAttributes,
2173 pub vtl_permission_set: VtlPermissionSet,
2175 pub gpa_page_base: u64,
2177 }
2178 const_assert!(size_of::<AcceptGpaPages>() == 0x18);
2179
2180 #[bitfield(u32)]
2182 pub struct UnacceptPagesAttributes {
2183 #[bits(3)]
2184 pub vtl_set: u32,
2185 #[bits(29)]
2186 _reserved: u32,
2187 }
2188
2189 #[repr(C)]
2190 pub struct UnacceptGpaPages {
2191 pub partition_id: u64,
2193 pub page_attributes: UnacceptPagesAttributes,
2195 pub vtl_permission_set: VtlPermissionSet,
2197 pub gpa_page_base: u64,
2199 }
2200 const_assert!(size_of::<UnacceptGpaPages>() == 0x18);
2201
2202 #[bitfield(u32)]
2203 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2204 pub struct ModifyHostVisibility {
2205 #[bits(2)]
2206 pub host_visibility: HostVisibilityType,
2207 #[bits(30)]
2208 _reserved: u32,
2209 }
2210
2211 #[repr(C)]
2212 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2213 pub struct ModifySparsePageVisibility {
2214 pub partition_id: u64,
2215 pub host_visibility: ModifyHostVisibility,
2216 pub reserved: u32,
2217 }
2218
2219 #[repr(C)]
2220 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2221 pub struct QuerySparsePageVisibility {
2222 pub partition_id: u64,
2223 }
2224
2225 pub const VBS_VM_REPORT_DATA_SIZE: usize = 64;
2226 pub const VBS_VM_MAX_REPORT_SIZE: usize = 2048;
2227
2228 #[repr(C)]
2229 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2230 pub struct VbsVmCallReport {
2231 pub report_data: [u8; VBS_VM_REPORT_DATA_SIZE],
2232 }
2233
2234 #[repr(C)]
2235 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2236 pub struct VbsVmCallReportOutput {
2237 pub report: [u8; VBS_VM_MAX_REPORT_SIZE],
2238 }
2239
2240 #[bitfield(u8)]
2241 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2242 pub struct EnablePartitionVtlFlags {
2243 pub enable_mbec: bool,
2244 pub enable_supervisor_shadow_stack: bool,
2245 pub enable_hardware_hvpt: bool,
2246 #[bits(5)]
2247 pub reserved: u8,
2248 }
2249
2250 #[repr(C)]
2251 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2252 pub struct EnablePartitionVtl {
2253 pub partition_id: u64,
2254 pub target_vtl: u8,
2255 pub flags: EnablePartitionVtlFlags,
2256 pub reserved_z0: u16,
2257 pub reserved_z1: u32,
2258 }
2259
2260 #[repr(C)]
2261 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2262 pub struct FlushVirtualAddressSpace {
2263 pub address_space: u64,
2264 pub flags: HvFlushFlags,
2265 pub processor_mask: u64,
2266 }
2267
2268 #[repr(C)]
2269 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2270 pub struct FlushVirtualAddressSpaceEx {
2271 pub address_space: u64,
2272 pub flags: HvFlushFlags,
2273 pub vp_set_format: u64,
2274 pub vp_set_valid_banks_mask: u64,
2275 }
2277
2278 #[repr(C)]
2279 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2280 pub struct PinUnpinGpaPageRangesHeader {
2281 pub reserved: u64,
2282 }
2283
2284 #[repr(C)]
2285 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2286 pub struct SendSyntheticClusterIpi {
2287 pub vector: u32,
2288 pub target_vtl: HvInputVtl,
2289 pub flags: u8,
2290 pub reserved: u16,
2291 pub processor_mask: u64,
2292 }
2293
2294 #[repr(C)]
2295 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2296 pub struct SendSyntheticClusterIpiEx {
2297 pub vector: u32,
2298 pub target_vtl: HvInputVtl,
2299 pub flags: u8,
2300 pub reserved: u16,
2301 pub vp_set_format: u64,
2302 pub vp_set_valid_banks_mask: u64,
2303 }
2305
2306 #[bitfield(u64)]
2307 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2308 pub struct HvFlushFlags {
2309 pub all_processors: bool,
2310 pub all_virtual_address_spaces: bool,
2311 pub non_global_mappings_only: bool,
2312 pub use_extended_range_format: bool,
2313 pub use_target_vtl: bool,
2314
2315 #[bits(3)]
2316 _reserved: u8,
2317
2318 pub target_vtl0: bool,
2319 pub target_vtl1: bool,
2320
2321 #[bits(54)]
2322 _reserved2: u64,
2323 }
2324
2325 #[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
2326 #[repr(transparent)]
2327 pub struct HvGvaRange(pub u64);
2328
2329 impl From<u64> for HvGvaRange {
2330 fn from(value: u64) -> Self {
2331 Self(value)
2332 }
2333 }
2334
2335 impl From<HvGvaRange> for u64 {
2336 fn from(value: HvGvaRange) -> Self {
2337 value.0
2338 }
2339 }
2340
2341 impl HvGvaRange {
2342 pub fn as_simple(self) -> HvGvaRangeSimple {
2343 HvGvaRangeSimple(self.0)
2344 }
2345
2346 pub fn as_extended(self) -> HvGvaRangeExtended {
2347 HvGvaRangeExtended(self.0)
2348 }
2349
2350 pub fn as_extended_large_page(self) -> HvGvaRangeExtendedLargePage {
2351 HvGvaRangeExtendedLargePage(self.0)
2352 }
2353 }
2354
2355 #[bitfield(u64)]
2356 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2357 pub struct HvGvaRangeSimple {
2358 #[bits(12)]
2360 pub additional_pages: u64,
2361 #[bits(52)]
2363 pub gva_page_number: u64,
2364 }
2365
2366 #[bitfield(u64)]
2367 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2368 pub struct HvGvaRangeExtended {
2369 #[bits(11)]
2371 pub additional_pages: u64,
2372 pub large_page: bool,
2374 #[bits(52)]
2376 pub gva_page_number: u64,
2377 }
2378
2379 #[bitfield(u64)]
2380 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2381 pub struct HvGvaRangeExtendedLargePage {
2382 #[bits(11)]
2384 pub additional_pages: u64,
2385 pub large_page: bool,
2387 pub page_size: bool,
2391 #[bits(8)]
2392 _reserved: u64,
2393 #[bits(43)]
2395 pub gva_large_page_number: u64,
2396 }
2397
2398 #[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
2399 #[repr(transparent)]
2400 pub struct HvGpaRange(pub u64);
2401
2402 impl HvGpaRange {
2403 pub fn as_simple(self) -> HvGpaRangeSimple {
2404 HvGpaRangeSimple(self.0)
2405 }
2406
2407 pub fn as_extended(self) -> HvGpaRangeExtended {
2408 HvGpaRangeExtended(self.0)
2409 }
2410
2411 pub fn as_extended_large_page(self) -> HvGpaRangeExtendedLargePage {
2412 HvGpaRangeExtendedLargePage(self.0)
2413 }
2414 }
2415
2416 #[bitfield(u64)]
2417 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2418 pub struct HvGpaRangeSimple {
2419 #[bits(12)]
2421 pub additional_pages: u64,
2422 #[bits(52)]
2424 pub gpa_page_number: u64,
2425 }
2426
2427 #[bitfield(u64)]
2428 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2429 pub struct HvGpaRangeExtended {
2430 #[bits(11)]
2432 pub additional_pages: u64,
2433 pub large_page: bool,
2435 #[bits(52)]
2437 pub gpa_page_number: u64,
2438 }
2439
2440 #[bitfield(u64)]
2441 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2442 pub struct HvGpaRangeExtendedLargePage {
2443 #[bits(11)]
2445 pub additional_pages: u64,
2446 pub large_page: bool,
2448 pub page_size: bool,
2452 #[bits(8)]
2453 _reserved: u64,
2454 #[bits(43)]
2456 pub gpa_large_page_number: u64,
2457 }
2458
2459 pub const HV_HYPERCALL_MMIO_MAX_DATA_LENGTH: usize = 64;
2460
2461 #[repr(C)]
2462 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2463 pub struct MemoryMappedIoRead {
2464 pub gpa: u64,
2465 pub access_width: u32,
2466 pub reserved_z0: u32,
2467 }
2468
2469 #[repr(C)]
2470 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2471 pub struct MemoryMappedIoReadOutput {
2472 pub data: [u8; HV_HYPERCALL_MMIO_MAX_DATA_LENGTH],
2473 }
2474
2475 #[repr(C)]
2476 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2477 pub struct MemoryMappedIoWrite {
2478 pub gpa: u64,
2479 pub access_width: u32,
2480 pub reserved_z0: u32,
2481 pub data: [u8; HV_HYPERCALL_MMIO_MAX_DATA_LENGTH],
2482 }
2483
2484 #[repr(C)]
2485 #[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
2486 pub struct RestorePartitionTime {
2487 pub partition_id: u64,
2488 pub tsc_sequence: u32,
2489 pub reserved: u32,
2490 pub reference_time_in_100_ns: u64,
2491 pub tsc: u64,
2492 }
2493}
2494
2495macro_rules! registers {
2496 ($name:ident {
2497 $(
2498 $(#[$vattr:meta])*
2499 $variant:ident = $value:expr
2500 ),*
2501 $(,)?
2502 }) => {
2503 open_enum! {
2504 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
2505 pub enum $name: u32 {
2506 #![expect(non_upper_case_globals)]
2507 $($variant = $value,)*
2508 InstructionEmulationHints = 0x00000002,
2509 InternalActivityState = 0x00000004,
2510
2511 GuestCrashP0 = 0x00000210,
2513 GuestCrashP1 = 0x00000211,
2514 GuestCrashP2 = 0x00000212,
2515 GuestCrashP3 = 0x00000213,
2516 GuestCrashP4 = 0x00000214,
2517 GuestCrashCtl = 0x00000215,
2518
2519 PendingInterruption = 0x00010002,
2520 InterruptState = 0x00010003,
2521 PendingEvent0 = 0x00010004,
2522 PendingEvent1 = 0x00010005,
2523 DeliverabilityNotifications = 0x00010006,
2524
2525 GicrBaseGpa = 0x00063000,
2526
2527 VpRuntime = 0x00090000,
2528 GuestOsId = 0x00090002,
2529 VpIndex = 0x00090003,
2530 TimeRefCount = 0x00090004,
2531 CpuManagementVersion = 0x00090007,
2532 VpAssistPage = 0x00090013,
2533 VpRootSignalCount = 0x00090014,
2534 ReferenceTsc = 0x00090017,
2535 VpConfig = 0x00090018,
2536 Ghcb = 0x00090019,
2537 ReferenceTscSequence = 0x0009001A,
2538 GuestSchedulerEvent = 0x0009001B,
2539
2540 Sint0 = 0x000A0000,
2541 Sint1 = 0x000A0001,
2542 Sint2 = 0x000A0002,
2543 Sint3 = 0x000A0003,
2544 Sint4 = 0x000A0004,
2545 Sint5 = 0x000A0005,
2546 Sint6 = 0x000A0006,
2547 Sint7 = 0x000A0007,
2548 Sint8 = 0x000A0008,
2549 Sint9 = 0x000A0009,
2550 Sint10 = 0x000A000A,
2551 Sint11 = 0x000A000B,
2552 Sint12 = 0x000A000C,
2553 Sint13 = 0x000A000D,
2554 Sint14 = 0x000A000E,
2555 Sint15 = 0x000A000F,
2556 Scontrol = 0x000A0010,
2557 Sversion = 0x000A0011,
2558 Sifp = 0x000A0012,
2559 Sipp = 0x000A0013,
2560 Eom = 0x000A0014,
2561 Sirbp = 0x000A0015,
2562
2563 Stimer0Config = 0x000B0000,
2564 Stimer0Count = 0x000B0001,
2565 Stimer1Config = 0x000B0002,
2566 Stimer1Count = 0x000B0003,
2567 Stimer2Config = 0x000B0004,
2568 Stimer2Count = 0x000B0005,
2569 Stimer3Config = 0x000B0006,
2570 Stimer3Count = 0x000B0007,
2571 StimeUnhaltedTimerConfig = 0x000B0100,
2572 StimeUnhaltedTimerCount = 0x000B0101,
2573
2574 VsmCodePageOffsets = 0x000D0002,
2575 VsmVpStatus = 0x000D0003,
2576 VsmPartitionStatus = 0x000D0004,
2577 VsmVina = 0x000D0005,
2578 VsmCapabilities = 0x000D0006,
2579 VsmPartitionConfig = 0x000D0007,
2580 GuestVsmPartitionConfig = 0x000D0008,
2581 VsmVpSecureConfigVtl0 = 0x000D0010,
2582 VsmVpSecureConfigVtl1 = 0x000D0011,
2583 VsmVpSecureConfigVtl2 = 0x000D0012,
2584 VsmVpSecureConfigVtl3 = 0x000D0013,
2585 VsmVpSecureConfigVtl4 = 0x000D0014,
2586 VsmVpSecureConfigVtl5 = 0x000D0015,
2587 VsmVpSecureConfigVtl6 = 0x000D0016,
2588 VsmVpSecureConfigVtl7 = 0x000D0017,
2589 VsmVpSecureConfigVtl8 = 0x000D0018,
2590 VsmVpSecureConfigVtl9 = 0x000D0019,
2591 VsmVpSecureConfigVtl10 = 0x000D001A,
2592 VsmVpSecureConfigVtl11 = 0x000D001B,
2593 VsmVpSecureConfigVtl12 = 0x000D001C,
2594 VsmVpSecureConfigVtl13 = 0x000D001D,
2595 VsmVpSecureConfigVtl14 = 0x000D001E,
2596 VsmVpWaitForTlbLock = 0x000D0020,
2597 }
2598 }
2599
2600 impl From<HvRegisterName> for $name {
2601 fn from(name: HvRegisterName) -> Self {
2602 Self(name.0)
2603 }
2604 }
2605
2606 impl From<$name> for HvRegisterName {
2607 fn from(name: $name) -> Self {
2608 Self(name.0)
2609 }
2610 }
2611 };
2612}
2613
2614#[repr(C)]
2619#[derive(Debug, Copy, Clone, PartialEq, Eq, IntoBytes, Immutable, KnownLayout, FromBytes)]
2620pub struct HvRegisterName(pub u32);
2621
2622registers! {
2623 HvAllArchRegisterName {}
2625}
2626
2627impl From<HvAllArchRegisterName> for HvX64RegisterName {
2628 fn from(name: HvAllArchRegisterName) -> Self {
2629 Self(name.0)
2630 }
2631}
2632
2633impl From<HvAllArchRegisterName> for HvArm64RegisterName {
2634 fn from(name: HvAllArchRegisterName) -> Self {
2635 Self(name.0)
2636 }
2637}
2638
2639registers! {
2640 HvX64RegisterName {
2641 Rax = 0x00020000,
2643 Rcx = 0x00020001,
2644 Rdx = 0x00020002,
2645 Rbx = 0x00020003,
2646 Rsp = 0x00020004,
2647 Rbp = 0x00020005,
2648 Rsi = 0x00020006,
2649 Rdi = 0x00020007,
2650 R8 = 0x00020008,
2651 R9 = 0x00020009,
2652 R10 = 0x0002000a,
2653 R11 = 0x0002000b,
2654 R12 = 0x0002000c,
2655 R13 = 0x0002000d,
2656 R14 = 0x0002000e,
2657 R15 = 0x0002000f,
2658 Rip = 0x00020010,
2659 Rflags = 0x00020011,
2660
2661 Xmm0 = 0x00030000,
2663 Xmm1 = 0x00030001,
2664 Xmm2 = 0x00030002,
2665 Xmm3 = 0x00030003,
2666 Xmm4 = 0x00030004,
2667 Xmm5 = 0x00030005,
2668 Xmm6 = 0x00030006,
2669 Xmm7 = 0x00030007,
2670 Xmm8 = 0x00030008,
2671 Xmm9 = 0x00030009,
2672 Xmm10 = 0x0003000A,
2673 Xmm11 = 0x0003000B,
2674 Xmm12 = 0x0003000C,
2675 Xmm13 = 0x0003000D,
2676 Xmm14 = 0x0003000E,
2677 Xmm15 = 0x0003000F,
2678 FpMmx0 = 0x00030010,
2679 FpMmx1 = 0x00030011,
2680 FpMmx2 = 0x00030012,
2681 FpMmx3 = 0x00030013,
2682 FpMmx4 = 0x00030014,
2683 FpMmx5 = 0x00030015,
2684 FpMmx6 = 0x00030016,
2685 FpMmx7 = 0x00030017,
2686 FpControlStatus = 0x00030018,
2687 XmmControlStatus = 0x00030019,
2688
2689 Cr0 = 0x00040000,
2691 Cr2 = 0x00040001,
2692 Cr3 = 0x00040002,
2693 Cr4 = 0x00040003,
2694 Cr8 = 0x00040004,
2695 Xfem = 0x00040005,
2696 IntermediateCr0 = 0x00041000,
2698 IntermediateCr3 = 0x00041002,
2699 IntermediateCr4 = 0x00041003,
2700 IntermediateCr8 = 0x00041004,
2701 Dr0 = 0x00050000,
2703 Dr1 = 0x00050001,
2704 Dr2 = 0x00050002,
2705 Dr3 = 0x00050003,
2706 Dr6 = 0x00050004,
2707 Dr7 = 0x00050005,
2708 Es = 0x00060000,
2710 Cs = 0x00060001,
2711 Ss = 0x00060002,
2712 Ds = 0x00060003,
2713 Fs = 0x00060004,
2714 Gs = 0x00060005,
2715 Ldtr = 0x00060006,
2716 Tr = 0x00060007,
2717 Idtr = 0x00070000,
2719 Gdtr = 0x00070001,
2720 Tsc = 0x00080000,
2722 Efer = 0x00080001,
2723 KernelGsBase = 0x00080002,
2724 ApicBase = 0x00080003,
2725 Pat = 0x00080004,
2726 SysenterCs = 0x00080005,
2727 SysenterEip = 0x00080006,
2728 SysenterEsp = 0x00080007,
2729 Star = 0x00080008,
2730 Lstar = 0x00080009,
2731 Cstar = 0x0008000a,
2732 Sfmask = 0x0008000b,
2733 InitialApicId = 0x0008000c,
2734 MsrMtrrCap = 0x0008000d,
2736 MsrMtrrDefType = 0x0008000e,
2737 MsrMtrrPhysBase0 = 0x00080010,
2738 MsrMtrrPhysBase1 = 0x00080011,
2739 MsrMtrrPhysBase2 = 0x00080012,
2740 MsrMtrrPhysBase3 = 0x00080013,
2741 MsrMtrrPhysBase4 = 0x00080014,
2742 MsrMtrrPhysBase5 = 0x00080015,
2743 MsrMtrrPhysBase6 = 0x00080016,
2744 MsrMtrrPhysBase7 = 0x00080017,
2745 MsrMtrrPhysBase8 = 0x00080018,
2746 MsrMtrrPhysBase9 = 0x00080019,
2747 MsrMtrrPhysBaseA = 0x0008001a,
2748 MsrMtrrPhysBaseB = 0x0008001b,
2749 MsrMtrrPhysBaseC = 0x0008001c,
2750 MsrMtrrPhysBaseD = 0x0008001d,
2751 MsrMtrrPhysBaseE = 0x0008001e,
2752 MsrMtrrPhysBaseF = 0x0008001f,
2753 MsrMtrrPhysMask0 = 0x00080040,
2754 MsrMtrrPhysMask1 = 0x00080041,
2755 MsrMtrrPhysMask2 = 0x00080042,
2756 MsrMtrrPhysMask3 = 0x00080043,
2757 MsrMtrrPhysMask4 = 0x00080044,
2758 MsrMtrrPhysMask5 = 0x00080045,
2759 MsrMtrrPhysMask6 = 0x00080046,
2760 MsrMtrrPhysMask7 = 0x00080047,
2761 MsrMtrrPhysMask8 = 0x00080048,
2762 MsrMtrrPhysMask9 = 0x00080049,
2763 MsrMtrrPhysMaskA = 0x0008004a,
2764 MsrMtrrPhysMaskB = 0x0008004b,
2765 MsrMtrrPhysMaskC = 0x0008004c,
2766 MsrMtrrPhysMaskD = 0x0008004d,
2767 MsrMtrrPhysMaskE = 0x0008004e,
2768 MsrMtrrPhysMaskF = 0x0008004f,
2769 MsrMtrrFix64k00000 = 0x00080070,
2770 MsrMtrrFix16k80000 = 0x00080071,
2771 MsrMtrrFix16kA0000 = 0x00080072,
2772 MsrMtrrFix4kC0000 = 0x00080073,
2773 MsrMtrrFix4kC8000 = 0x00080074,
2774 MsrMtrrFix4kD0000 = 0x00080075,
2775 MsrMtrrFix4kD8000 = 0x00080076,
2776 MsrMtrrFix4kE0000 = 0x00080077,
2777 MsrMtrrFix4kE8000 = 0x00080078,
2778 MsrMtrrFix4kF0000 = 0x00080079,
2779 MsrMtrrFix4kF8000 = 0x0008007a,
2780
2781 TscAux = 0x0008007B,
2782 Bndcfgs = 0x0008007C,
2783 DebugCtl = 0x0008007D,
2784 MCount = 0x0008007E,
2785 ACount = 0x0008007F,
2786
2787 SgxLaunchControl0 = 0x00080080,
2788 SgxLaunchControl1 = 0x00080081,
2789 SgxLaunchControl2 = 0x00080082,
2790 SgxLaunchControl3 = 0x00080083,
2791 SpecCtrl = 0x00080084,
2792 PredCmd = 0x00080085,
2793 VirtSpecCtrl = 0x00080086,
2794 TscVirtualOffset = 0x00080087,
2795 TsxCtrl = 0x00080088,
2796 MsrMcUpdatePatchLevel = 0x00080089,
2797 Available1 = 0x0008008A,
2798 Xss = 0x0008008B,
2799 UCet = 0x0008008C,
2800 SCet = 0x0008008D,
2801 Ssp = 0x0008008E,
2802 Pl0Ssp = 0x0008008F,
2803 Pl1Ssp = 0x00080090,
2804 Pl2Ssp = 0x00080091,
2805 Pl3Ssp = 0x00080092,
2806 InterruptSspTableAddr = 0x00080093,
2807 TscVirtualMultiplier = 0x00080094,
2808 TscDeadline = 0x00080095,
2809 TscAdjust = 0x00080096,
2810 Pasid = 0x00080097,
2811 UmwaitControl = 0x00080098,
2812 Xfd = 0x00080099,
2813 XfdErr = 0x0008009A,
2814
2815 ApicId = 0x00084802,
2817 ApicVersion = 0x00084803,
2818 ApicTpr = 0x00084808,
2819 ApicPpr = 0x0008480a,
2820 ApicEoi = 0x0008480b,
2821 ApicLdr = 0x0008480d,
2822 ApicSpurious = 0x0008480f,
2823 ApicIsr0 = 0x00084810,
2824 ApicIsr1 = 0x00084811,
2825 ApicIsr2 = 0x00084812,
2826 ApicIsr3 = 0x00084813,
2827 ApicIsr4 = 0x00084814,
2828 ApicIsr5 = 0x00084815,
2829 ApicIsr6 = 0x00084816,
2830 ApicIsr7 = 0x00084817,
2831 ApicTmr0 = 0x00084818,
2832 ApicTmr1 = 0x00084819,
2833 ApicTmr2 = 0x0008481a,
2834 ApicTmr3 = 0x0008481b,
2835 ApicTmr4 = 0x0008481c,
2836 ApicTmr5 = 0x0008481d,
2837 ApicTmr6 = 0x0008481e,
2838 ApicTmr7 = 0x0008481f,
2839 ApicIrr0 = 0x00084820,
2840 ApicIrr1 = 0x00084821,
2841 ApicIrr2 = 0x00084822,
2842 ApicIrr3 = 0x00084823,
2843 ApicIrr4 = 0x00084824,
2844 ApicIrr5 = 0x00084825,
2845 ApicIrr6 = 0x00084826,
2846 ApicIrr7 = 0x00084827,
2847 ApicEse = 0x00084828,
2848 ApicIcr = 0x00084830,
2849 ApicLvtTimer = 0x00084832,
2850 ApicLvtThermal = 0x00084833,
2851 ApicLvtPerfmon = 0x00084834,
2852 ApicLvtLint0 = 0x00084835,
2853 ApicLvtLint1 = 0x00084836,
2854 ApicLvtError = 0x00084837,
2855 ApicInitCount = 0x00084838,
2856 ApicCurrentCount = 0x00084839,
2857 ApicDivide = 0x0008483e,
2858 ApicSelfIpi = 0x0008483f,
2859
2860 Hypercall = 0x00090001,
2861 RegisterPage = 0x0009001C,
2862
2863 EmulatedTimerPeriod = 0x00090030,
2865 EmulatedTimerControl = 0x00090031,
2866 PmTimerAssist = 0x00090032,
2867
2868 SevControl = 0x00090040,
2870 SevGhcbGpa = 0x00090041,
2871 SevAvicGpa = 0x00090043,
2872
2873 CrInterceptControl = 0x000E0000,
2874 CrInterceptCr0Mask = 0x000E0001,
2875 CrInterceptCr4Mask = 0x000E0002,
2876 CrInterceptIa32MiscEnableMask = 0x000E0003,
2877 }
2878}
2879
2880registers! {
2881 HvArm64RegisterName {
2882 HypervisorVersion = 0x00000100,
2883 PrivilegesAndFeaturesInfo = 0x00000200,
2884 FeaturesInfo = 0x00000201,
2885 ImplementationLimitsInfo = 0x00000202,
2886 HardwareFeaturesInfo = 0x00000203,
2887 CpuManagementFeaturesInfo = 0x00000204,
2888 PasidFeaturesInfo = 0x00000205,
2889 SkipLevelFeaturesInfo = 0x00000206,
2890 NestedVirtFeaturesInfo = 0x00000207,
2891 IptFeaturesInfo = 0x00000208,
2892 IsolationConfiguration = 0x00000209,
2893
2894 X0 = 0x00020000,
2895 X1 = 0x00020001,
2896 X2 = 0x00020002,
2897 X3 = 0x00020003,
2898 X4 = 0x00020004,
2899 X5 = 0x00020005,
2900 X6 = 0x00020006,
2901 X7 = 0x00020007,
2902 X8 = 0x00020008,
2903 X9 = 0x00020009,
2904 X10 = 0x0002000A,
2905 X11 = 0x0002000B,
2906 X12 = 0x0002000C,
2907 X13 = 0x0002000D,
2908 X14 = 0x0002000E,
2909 X15 = 0x0002000F,
2910 X16 = 0x00020010,
2911 X17 = 0x00020011,
2912 X18 = 0x00020012,
2913 X19 = 0x00020013,
2914 X20 = 0x00020014,
2915 X21 = 0x00020015,
2916 X22 = 0x00020016,
2917 X23 = 0x00020017,
2918 X24 = 0x00020018,
2919 X25 = 0x00020019,
2920 X26 = 0x0002001A,
2921 X27 = 0x0002001B,
2922 X28 = 0x0002001C,
2923 XFp = 0x0002001D,
2924 XLr = 0x0002001E,
2925 XSp = 0x0002001F, XSpEl0 = 0x00020020,
2927 XSpElx = 0x00020021,
2928 XPc = 0x00020022,
2929 Cpsr = 0x00020023,
2930 SpsrEl2 = 0x00021002,
2931
2932 SctlrEl1 = 0x00040002,
2933 Ttbr0El1 = 0x00040005,
2934 Ttbr1El1 = 0x00040006,
2935 TcrEl1 = 0x00040007,
2936 EsrEl1 = 0x00040008,
2937 FarEl1 = 0x00040009,
2938 MairEl1 = 0x0004000b,
2939 VbarEl1 = 0x0004000c,
2940 ElrEl1 = 0x00040015,
2941 }
2942}
2943
2944#[repr(C)]
2945#[derive(Clone, Copy, Debug, Eq, PartialEq, IntoBytes, Immutable, KnownLayout, FromBytes)]
2946pub struct HvRegisterValue(pub AlignedU128);
2947
2948impl HvRegisterValue {
2949 pub fn as_u128(&self) -> u128 {
2950 self.0.into()
2951 }
2952
2953 pub fn as_u64(&self) -> u64 {
2954 self.as_u128() as u64
2955 }
2956
2957 pub fn as_u32(&self) -> u32 {
2958 self.as_u128() as u32
2959 }
2960
2961 pub fn as_u16(&self) -> u16 {
2962 self.as_u128() as u16
2963 }
2964
2965 pub fn as_u8(&self) -> u8 {
2966 self.as_u128() as u8
2967 }
2968
2969 pub fn as_table(&self) -> HvX64TableRegister {
2970 HvX64TableRegister::read_from_prefix(self.as_bytes())
2971 .unwrap()
2972 .0 }
2974
2975 pub fn as_segment(&self) -> HvX64SegmentRegister {
2976 HvX64SegmentRegister::read_from_prefix(self.as_bytes())
2977 .unwrap()
2978 .0 }
2980}
2981
2982impl From<u8> for HvRegisterValue {
2983 fn from(val: u8) -> Self {
2984 (val as u128).into()
2985 }
2986}
2987
2988impl From<u16> for HvRegisterValue {
2989 fn from(val: u16) -> Self {
2990 (val as u128).into()
2991 }
2992}
2993
2994impl From<u32> for HvRegisterValue {
2995 fn from(val: u32) -> Self {
2996 (val as u128).into()
2997 }
2998}
2999
3000impl From<u64> for HvRegisterValue {
3001 fn from(val: u64) -> Self {
3002 (val as u128).into()
3003 }
3004}
3005
3006impl From<u128> for HvRegisterValue {
3007 fn from(val: u128) -> Self {
3008 Self(val.into())
3009 }
3010}
3011
3012#[repr(C)]
3013#[derive(Clone, Copy, Debug, Eq, PartialEq, IntoBytes, Immutable, KnownLayout, FromBytes)]
3014pub struct HvX64TableRegister {
3015 pub pad: [u16; 3],
3016 pub limit: u16,
3017 pub base: u64,
3018}
3019
3020impl From<HvX64TableRegister> for HvRegisterValue {
3021 fn from(val: HvX64TableRegister) -> Self {
3022 Self::read_from_prefix(val.as_bytes()).unwrap().0 }
3024}
3025
3026impl From<HvRegisterValue> for HvX64TableRegister {
3027 fn from(val: HvRegisterValue) -> Self {
3028 Self::read_from_prefix(val.as_bytes()).unwrap().0 }
3030}
3031
3032#[repr(C)]
3033#[derive(Clone, Copy, Debug, Eq, PartialEq, IntoBytes, Immutable, KnownLayout, FromBytes)]
3034pub struct HvX64SegmentRegister {
3035 pub base: u64,
3036 pub limit: u32,
3037 pub selector: u16,
3038 pub attributes: u16,
3039}
3040
3041impl From<HvX64SegmentRegister> for HvRegisterValue {
3042 fn from(val: HvX64SegmentRegister) -> Self {
3043 Self::read_from_prefix(val.as_bytes()).unwrap().0 }
3045}
3046
3047impl From<HvRegisterValue> for HvX64SegmentRegister {
3048 fn from(val: HvRegisterValue) -> Self {
3049 Self::read_from_prefix(val.as_bytes()).unwrap().0 }
3051}
3052
3053#[bitfield(u64)]
3054#[derive(IntoBytes, Immutable, KnownLayout, FromBytes, PartialEq, Eq)]
3055pub struct HvDeliverabilityNotificationsRegister {
3056 pub nmi_notification: bool,
3058 pub interrupt_notification: bool,
3060 #[bits(4)]
3062 pub interrupt_priority: u8,
3064 #[bits(42)]
3065 pub reserved: u64,
3066 pub sints: u16,
3067}
3068
3069open_enum! {
3070 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3071 pub enum HvVtlEntryReason: u32 {
3072 RESERVED = 0,
3074
3075 VTL_CALL = 1,
3077
3078 INTERRUPT = 2,
3080
3081 INTERCEPT = 3,
3083 }
3084}
3085
3086#[repr(C)]
3087#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3088pub struct HvVpVtlControl {
3089 pub entry_reason: HvVtlEntryReason,
3094
3095 pub vina_status: u8,
3097 pub reserved_z0: u8,
3098 pub reserved_z1: u16,
3099
3100 pub registers: [u64; 2],
3105}
3106
3107#[bitfield(u64)]
3108#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3109pub struct HvRegisterVsmVina {
3110 pub vector: u8,
3111 pub enabled: bool,
3112 pub auto_reset: bool,
3113 pub auto_eoi: bool,
3114 #[bits(53)]
3115 pub reserved: u64,
3116}
3117
3118#[repr(C)]
3119#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3120pub struct HvVpAssistPage {
3121 pub apic_assist: u32,
3123 pub reserved_z0: u32,
3124
3125 pub vtl_control: HvVpVtlControl,
3127
3128 pub nested_enlightenments_control: u64,
3129 pub enlighten_vm_entry: u8,
3130 pub reserved_z1: [u8; 7],
3131 pub current_nested_vmcs: u64,
3132 pub synthetic_time_unhalted_timer_expired: u8,
3133 pub reserved_z2: [u8; 7],
3134 pub virtualization_fault_information: [u8; 40],
3135 pub reserved_z3: u64,
3136 pub intercept_message: HvMessage,
3137 pub vtl_return_actions: [u8; 256],
3138}
3139
3140#[repr(C)]
3141#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3142pub struct HvVpAssistPageActionSignalEvent {
3143 pub action_type: u64,
3144 pub target_vp: u32,
3145 pub target_vtl: u8,
3146 pub target_sint: u8,
3147 pub flag_number: u16,
3148}
3149
3150open_enum! {
3151 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3152 pub enum HvInterceptAccessType: u8 {
3153 READ = 0,
3154 WRITE = 1,
3155 EXECUTE = 2,
3156 }
3157}
3158
3159#[bitfield(u16)]
3160#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3161pub struct HvX64VpExecutionState {
3162 #[bits(2)]
3163 pub cpl: u8,
3164 pub cr0_pe: bool,
3165 pub cr0_am: bool,
3166 pub efer_lma: bool,
3167 pub debug_active: bool,
3168 pub interruption_pending: bool,
3169 #[bits(4)]
3170 pub vtl: u8,
3171 pub enclave_mode: bool,
3172 pub interrupt_shadow: bool,
3173 pub virtualization_fault_active: bool,
3174 #[bits(2)]
3175 pub reserved: u8,
3176}
3177
3178#[bitfield(u16)]
3179#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3180pub struct HvArm64VpExecutionState {
3181 #[bits(2)]
3182 pub cpl: u8,
3183 pub debug_active: bool,
3184 pub interruption_pending: bool,
3185 #[bits(4)]
3186 pub vtl: u8,
3187 pub virtualization_fault_active: bool,
3188 #[bits(7)]
3189 pub reserved: u8,
3190}
3191
3192#[repr(C)]
3193#[derive(Debug, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
3194pub struct HvX64InterceptMessageHeader {
3195 pub vp_index: u32,
3196 pub instruction_length_and_cr8: u8,
3197 pub intercept_access_type: HvInterceptAccessType,
3198 pub execution_state: HvX64VpExecutionState,
3199 pub cs_segment: HvX64SegmentRegister,
3200 pub rip: u64,
3201 pub rflags: u64,
3202}
3203
3204impl MessagePayload for HvX64InterceptMessageHeader {}
3205
3206impl HvX64InterceptMessageHeader {
3207 pub fn instruction_len(&self) -> u8 {
3208 self.instruction_length_and_cr8 & 0xf
3209 }
3210
3211 pub fn cr8(&self) -> u8 {
3212 self.instruction_length_and_cr8 >> 4
3213 }
3214}
3215
3216#[repr(C)]
3217#[derive(Debug, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
3218pub struct HvArm64InterceptMessageHeader {
3219 pub vp_index: u32,
3220 pub instruction_length: u8,
3221 pub intercept_access_type: HvInterceptAccessType,
3222 pub execution_state: HvArm64VpExecutionState,
3223 pub pc: u64,
3224 pub cspr: u64,
3225}
3226const_assert!(size_of::<HvArm64InterceptMessageHeader>() == 0x18);
3227
3228impl MessagePayload for HvArm64InterceptMessageHeader {}
3229
3230#[repr(transparent)]
3231#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
3232pub struct HvX64IoPortAccessInfo(pub u8);
3233
3234impl HvX64IoPortAccessInfo {
3235 pub fn new(access_size: u8, string_op: bool, rep_prefix: bool) -> Self {
3236 let mut info = access_size & 0x7;
3237
3238 if string_op {
3239 info |= 0x8;
3240 }
3241
3242 if rep_prefix {
3243 info |= 0x10;
3244 }
3245
3246 Self(info)
3247 }
3248
3249 pub fn access_size(&self) -> u8 {
3250 self.0 & 0x7
3251 }
3252
3253 pub fn string_op(&self) -> bool {
3254 self.0 & 0x8 != 0
3255 }
3256
3257 pub fn rep_prefix(&self) -> bool {
3258 self.0 & 0x10 != 0
3259 }
3260}
3261
3262#[repr(C)]
3263#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3264pub struct HvX64IoPortInterceptMessage {
3265 pub header: HvX64InterceptMessageHeader,
3266 pub port_number: u16,
3267 pub access_info: HvX64IoPortAccessInfo,
3268 pub instruction_byte_count: u8,
3269 pub reserved: u32,
3270 pub rax: u64,
3271 pub instruction_bytes: [u8; 16],
3272 pub ds_segment: HvX64SegmentRegister,
3273 pub es_segment: HvX64SegmentRegister,
3274 pub rcx: u64,
3275 pub rsi: u64,
3276 pub rdi: u64,
3277}
3278
3279impl MessagePayload for HvX64IoPortInterceptMessage {}
3280
3281#[bitfield(u8)]
3282#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3283pub struct HvX64MemoryAccessInfo {
3284 pub gva_valid: bool,
3285 pub gva_gpa_valid: bool,
3286 pub hypercall_output_pending: bool,
3287 pub tlb_locked: bool,
3288 pub supervisor_shadow_stack: bool,
3289 #[bits(3)]
3290 pub reserved1: u8,
3291}
3292
3293#[bitfield(u8)]
3294#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3295pub struct HvArm64MemoryAccessInfo {
3296 pub gva_valid: bool,
3297 pub gva_gpa_valid: bool,
3298 pub hypercall_output_pending: bool,
3299 #[bits(5)]
3300 pub reserved1: u8,
3301}
3302
3303open_enum! {
3304 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3305 pub enum HvCacheType: u32 {
3306 #![expect(non_upper_case_globals)]
3307 HvCacheTypeUncached = 0,
3308 HvCacheTypeWriteCombining = 1,
3309 HvCacheTypeWriteThrough = 4,
3310 HvCacheTypeWriteProtected = 5,
3311 HvCacheTypeWriteBack = 6,
3312 }
3313}
3314
3315#[repr(C)]
3316#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3317pub struct HvX64MemoryInterceptMessage {
3318 pub header: HvX64InterceptMessageHeader,
3319 pub cache_type: HvCacheType,
3320 pub instruction_byte_count: u8,
3321 pub memory_access_info: HvX64MemoryAccessInfo,
3322 pub tpr_priority: u8,
3323 pub reserved: u8,
3324 pub guest_virtual_address: u64,
3325 pub guest_physical_address: u64,
3326 pub instruction_bytes: [u8; 16],
3327}
3328
3329impl MessagePayload for HvX64MemoryInterceptMessage {}
3330const_assert!(size_of::<HvX64MemoryInterceptMessage>() == 0x50);
3331
3332#[repr(C)]
3333#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3334pub struct HvArm64MemoryInterceptMessage {
3335 pub header: HvArm64InterceptMessageHeader,
3336 pub cache_type: HvCacheType,
3337 pub instruction_byte_count: u8,
3338 pub memory_access_info: HvArm64MemoryAccessInfo,
3339 pub reserved1: u16,
3340 pub instruction_bytes: [u8; 4],
3341 pub reserved2: u32,
3342 pub guest_virtual_address: u64,
3343 pub guest_physical_address: u64,
3344 pub syndrome: u64,
3345}
3346
3347impl MessagePayload for HvArm64MemoryInterceptMessage {}
3348const_assert!(size_of::<HvArm64MemoryInterceptMessage>() == 0x40);
3349
3350#[repr(C)]
3351#[derive(Debug, FromBytes, IntoBytes, Immutable, KnownLayout)]
3352pub struct HvArm64MmioInterceptMessage {
3353 pub header: HvArm64InterceptMessageHeader,
3354 pub guest_physical_address: u64,
3355 pub access_size: u32,
3356 pub data: [u8; 32],
3357 pub padding: u32,
3358}
3359
3360impl MessagePayload for HvArm64MmioInterceptMessage {}
3361const_assert!(size_of::<HvArm64MmioInterceptMessage>() == 0x48);
3362
3363#[repr(C)]
3364#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3365pub struct HvX64MsrInterceptMessage {
3366 pub header: HvX64InterceptMessageHeader,
3367 pub msr_number: u32,
3368 pub reserved: u32,
3369 pub rdx: u64,
3370 pub rax: u64,
3371}
3372
3373impl MessagePayload for HvX64MsrInterceptMessage {}
3374
3375#[repr(C)]
3376#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3377pub struct HvX64SipiInterceptMessage {
3378 pub header: HvX64InterceptMessageHeader,
3379 pub target_vp_index: u32,
3380 pub vector: u32,
3381}
3382
3383impl MessagePayload for HvX64SipiInterceptMessage {}
3384
3385#[repr(C)]
3386#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3387pub struct HvX64SynicSintDeliverableMessage {
3388 pub header: HvX64InterceptMessageHeader,
3389 pub deliverable_sints: u16,
3390 pub rsvd1: u16,
3391 pub rsvd2: u32,
3392}
3393
3394impl MessagePayload for HvX64SynicSintDeliverableMessage {}
3395
3396#[repr(C)]
3397#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3398pub struct HvArm64SynicSintDeliverableMessage {
3399 pub header: HvArm64InterceptMessageHeader,
3400 pub deliverable_sints: u16,
3401 pub rsvd1: u16,
3402 pub rsvd2: u32,
3403}
3404
3405impl MessagePayload for HvArm64SynicSintDeliverableMessage {}
3406
3407#[repr(C)]
3408#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3409pub struct HvX64InterruptionDeliverableMessage {
3410 pub header: HvX64InterceptMessageHeader,
3411 pub deliverable_type: HvX64PendingInterruptionType,
3412 pub rsvd: [u8; 3],
3413 pub rsvd2: u32,
3414}
3415
3416impl MessagePayload for HvX64InterruptionDeliverableMessage {}
3417
3418open_enum! {
3419 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3420 pub enum HvX64PendingInterruptionType: u8 {
3421 HV_X64_PENDING_INTERRUPT = 0,
3422 HV_X64_PENDING_NMI = 2,
3423 HV_X64_PENDING_EXCEPTION = 3,
3424 HV_X64_PENDING_SOFTWARE_INTERRUPT = 4,
3425 HV_X64_PENDING_PRIVILEGED_SOFTWARE_EXCEPTION = 5,
3426 HV_X64_PENDING_SOFTWARE_EXCEPTION = 6,
3427 }
3428}
3429
3430#[repr(C)]
3431#[derive(Debug, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
3432pub struct HvX64HypercallInterceptMessage {
3433 pub header: HvX64InterceptMessageHeader,
3434 pub rax: u64,
3435 pub rbx: u64,
3436 pub rcx: u64,
3437 pub rdx: u64,
3438 pub r8: u64,
3439 pub rsi: u64,
3440 pub rdi: u64,
3441 pub xmm_registers: [AlignedU128; 6],
3442 pub flags: HvHypercallInterceptMessageFlags,
3443 pub rsvd2: [u32; 3],
3444}
3445
3446impl MessagePayload for HvX64HypercallInterceptMessage {}
3447
3448#[repr(C)]
3449#[derive(Debug, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
3450pub struct HvArm64HypercallInterceptMessage {
3451 pub header: HvArm64InterceptMessageHeader,
3452 pub immediate: u16,
3453 pub reserved: u16,
3454 pub flags: HvHypercallInterceptMessageFlags,
3455 pub x: [u64; 18],
3456}
3457
3458impl MessagePayload for HvArm64HypercallInterceptMessage {}
3459
3460#[bitfield(u32)]
3461#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3462pub struct HvHypercallInterceptMessageFlags {
3463 pub is_isolated: bool,
3464 #[bits(31)]
3465 _reserved: u32,
3466}
3467
3468#[repr(C)]
3469#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3470pub struct HvX64CpuidInterceptMessage {
3471 pub header: HvX64InterceptMessageHeader,
3472 pub rax: u64,
3473 pub rcx: u64,
3474 pub rdx: u64,
3475 pub rbx: u64,
3476 pub default_result_rax: u64,
3477 pub default_result_rcx: u64,
3478 pub default_result_rdx: u64,
3479 pub default_result_rbx: u64,
3480}
3481
3482impl MessagePayload for HvX64CpuidInterceptMessage {}
3483
3484#[bitfield(u8)]
3485#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3486pub struct HvX64ExceptionInfo {
3487 pub error_code_valid: bool,
3488 pub software_exception: bool,
3489 #[bits(6)]
3490 reserved: u8,
3491}
3492
3493#[repr(C)]
3494#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3495pub struct HvX64ExceptionInterceptMessage {
3496 pub header: HvX64InterceptMessageHeader,
3497 pub vector: u16,
3498 pub exception_info: HvX64ExceptionInfo,
3499 pub instruction_byte_count: u8,
3500 pub error_code: u32,
3501 pub exception_parameter: u64,
3502 pub reserved: u64,
3503 pub instruction_bytes: [u8; 16],
3504 pub ds_segment: HvX64SegmentRegister,
3505 pub ss_segment: HvX64SegmentRegister,
3506 pub rax: u64,
3507 pub rcx: u64,
3508 pub rdx: u64,
3509 pub rbx: u64,
3510 pub rsp: u64,
3511 pub rbp: u64,
3512 pub rsi: u64,
3513 pub rdi: u64,
3514 pub r8: u64,
3515 pub r9: u64,
3516 pub r10: u64,
3517 pub r11: u64,
3518 pub r12: u64,
3519 pub r13: u64,
3520 pub r14: u64,
3521 pub r15: u64,
3522}
3523
3524impl MessagePayload for HvX64ExceptionInterceptMessage {}
3525
3526#[repr(C)]
3527#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3528pub struct HvInvalidVpRegisterMessage {
3529 pub vp_index: u32,
3530 pub reserved: u32,
3531}
3532
3533impl MessagePayload for HvInvalidVpRegisterMessage {}
3534
3535#[repr(C)]
3536#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3537pub struct HvX64ApicEoiMessage {
3538 pub vp_index: u32,
3539 pub interrupt_vector: u32,
3540}
3541
3542impl MessagePayload for HvX64ApicEoiMessage {}
3543
3544#[repr(C)]
3545#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3546pub struct HvX64UnrecoverableExceptionMessage {
3547 pub header: HvX64InterceptMessageHeader,
3548}
3549
3550impl MessagePayload for HvX64UnrecoverableExceptionMessage {}
3551
3552#[repr(C)]
3553#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3554pub struct HvX64HaltMessage {
3555 pub header: HvX64InterceptMessageHeader,
3556}
3557
3558impl MessagePayload for HvX64HaltMessage {}
3559
3560#[repr(C)]
3561#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
3562pub struct HvArm64ResetInterceptMessage {
3563 pub header: HvArm64InterceptMessageHeader,
3564 pub reset_type: HvArm64ResetType,
3565 pub reset_code: u32,
3566}
3567
3568impl MessagePayload for HvArm64ResetInterceptMessage {}
3569
3570open_enum! {
3571 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3572 pub enum HvArm64ResetType: u32 {
3573 POWER_OFF = 0,
3574 REBOOT = 1,
3575 SYSTEM_RESET = 2,
3576 HIBERNATE = 3,
3577 }
3578}
3579
3580#[bitfield(u8)]
3581#[derive(IntoBytes, Immutable, FromBytes)]
3582pub struct HvX64RegisterInterceptMessageFlags {
3583 pub is_memory_op: bool,
3584 #[bits(7)]
3585 _rsvd: u8,
3586}
3587
3588#[repr(C)]
3589#[derive(IntoBytes, Immutable, FromBytes)]
3590pub struct HvX64RegisterInterceptMessage {
3591 pub header: HvX64InterceptMessageHeader,
3592 pub flags: HvX64RegisterInterceptMessageFlags,
3593 pub rsvd: u8,
3594 pub rsvd2: u16,
3595 pub register_name: HvX64RegisterName,
3596 pub access_info: HvX64RegisterAccessInfo,
3597}
3598
3599#[repr(transparent)]
3600#[derive(IntoBytes, Immutable, FromBytes)]
3601pub struct HvX64RegisterAccessInfo(u128);
3602
3603impl HvX64RegisterAccessInfo {
3604 pub fn new_source_value(source_value: HvRegisterValue) -> Self {
3605 Self(source_value.as_u128())
3606 }
3607}
3608
3609open_enum! {
3610 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3611 pub enum HvInterruptType : u32 {
3612 #![expect(non_upper_case_globals)]
3613 HvArm64InterruptTypeFixed = 0x0000,
3614 HvX64InterruptTypeFixed = 0x0000,
3615 HvX64InterruptTypeLowestPriority = 0x0001,
3616 HvX64InterruptTypeSmi = 0x0002,
3617 HvX64InterruptTypeRemoteRead = 0x0003,
3618 HvX64InterruptTypeNmi = 0x0004,
3619 HvX64InterruptTypeInit = 0x0005,
3620 HvX64InterruptTypeSipi = 0x0006,
3621 HvX64InterruptTypeExtInt = 0x0007,
3622 HvX64InterruptTypeLocalInt0 = 0x0008,
3623 HvX64InterruptTypeLocalInt1 = 0x0009,
3624 }
3625}
3626
3627#[bitfield(u64)]
3634#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3635pub struct HvInterruptControl {
3636 interrupt_type_value: u32,
3637 pub x86_level_triggered: bool,
3638 pub x86_logical_destination_mode: bool,
3639 pub arm64_asserted: bool,
3640 #[bits(29)]
3641 pub unused: u32,
3642}
3643
3644impl HvInterruptControl {
3645 pub fn interrupt_type(&self) -> HvInterruptType {
3646 HvInterruptType(self.interrupt_type_value())
3647 }
3648
3649 pub fn set_interrupt_type(&mut self, ty: HvInterruptType) {
3650 self.set_interrupt_type_value(ty.0)
3651 }
3652
3653 pub fn with_interrupt_type(self, ty: HvInterruptType) -> Self {
3654 self.with_interrupt_type_value(ty.0)
3655 }
3656}
3657
3658#[bitfield(u64)]
3659pub struct HvRegisterVsmCapabilities {
3660 pub dr6_shared: bool,
3661 pub mbec_vtl_mask: u16,
3662 pub deny_lower_vtl_startup: bool,
3663 pub supervisor_shadow_stack: bool,
3664 pub hardware_hvpt_available: bool,
3665 pub software_hvpt_available: bool,
3666 #[bits(6)]
3667 pub hardware_hvpt_range_bits: u8,
3668 pub intercept_page_available: bool,
3669 pub return_action_available: bool,
3670 pub vtl0_alias_map_available: bool,
3675 pub intercept_not_present_available: bool,
3680 pub install_intercept_ex: bool,
3681 pub intercept_system_reset_available: bool,
3683 #[bits(1)]
3684 pub reserved1: u8,
3685 pub proxy_interrupt_redirect_available: bool,
3686 #[bits(29)]
3687 pub reserved2: u64,
3688}
3689
3690#[bitfield(u64)]
3691pub struct HvRegisterVsmPartitionConfig {
3692 pub enable_vtl_protection: bool,
3693 #[bits(4)]
3694 pub default_vtl_protection_mask: u8,
3695 pub zero_memory_on_reset: bool,
3696 pub deny_lower_vtl_startup: bool,
3697 pub intercept_acceptance: bool,
3698 pub intercept_enable_vtl_protection: bool,
3699 pub intercept_vp_startup: bool,
3700 pub intercept_cpuid_unimplemented: bool,
3701 pub intercept_unrecoverable_exception: bool,
3702 pub intercept_page: bool,
3703 pub intercept_restore_partition_time: bool,
3704 pub intercept_not_present: bool,
3707 pub intercept_system_reset: bool,
3708 #[bits(48)]
3709 pub reserved: u64,
3710}
3711
3712#[bitfield(u64)]
3713pub struct HvRegisterVsmPartitionStatus {
3714 #[bits(16)]
3715 pub enabled_vtl_set: u16,
3716 #[bits(4)]
3717 pub maximum_vtl: u8,
3718 #[bits(16)]
3719 pub mbec_enabled_vtl_set: u16,
3720 #[bits(4)]
3721 pub supervisor_shadow_stack_enabled_vtl_set: u8,
3722 #[bits(24)]
3723 pub reserved: u64,
3724}
3725
3726open_enum! {
3727 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3728 pub enum HvSnpInterruptInjection : u8 {
3729 #![allow(non_upper_case_globals)]
3730 HvSnpRestricted = 0x0,
3731 HvSnpNormal = 0x1,
3732 HvSnpAlternate = 0x2,
3733 HvSnpSecureAvic = 0x3,
3734 }
3735}
3736
3737impl HvSnpInterruptInjection {
3739 const fn from_bits(val: u8) -> Self {
3740 HvSnpInterruptInjection(val)
3741 }
3742
3743 const fn into_bits(self) -> u8 {
3744 self.0
3745 }
3746}
3747
3748#[bitfield(u64)]
3749pub struct HvRegisterGuestVsmPartitionConfig {
3750 #[bits(4)]
3751 pub maximum_vtl: u8,
3752 #[bits(2)]
3753 pub vtl0_interrupt_injection: HvSnpInterruptInjection,
3754 #[bits(2)]
3755 pub vtl1_interrupt_injection: HvSnpInterruptInjection,
3756 #[bits(56)]
3757 pub reserved: u64,
3758}
3759
3760#[bitfield(u64)]
3761pub struct HvRegisterVsmVpStatus {
3762 #[bits(4)]
3763 pub active_vtl: u8,
3764 pub active_mbec_enabled: bool,
3765 #[bits(11)]
3766 pub reserved_mbz0: u16,
3767 #[bits(16)]
3768 pub enabled_vtl_set: u16,
3769 #[bits(32)]
3770 pub reserved_mbz1: u32,
3771}
3772
3773#[bitfield(u64)]
3774pub struct HvRegisterVsmCodePageOffsets {
3775 #[bits(12)]
3776 pub call_offset: u16,
3777 #[bits(12)]
3778 pub return_offset: u16,
3779 #[bits(40)]
3780 pub reserved: u64,
3781}
3782
3783#[repr(C)]
3784#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3785pub struct HvStimerState {
3786 pub undelivered_message_pending: u32,
3787 pub reserved: u32,
3788 pub config: u64,
3789 pub count: u64,
3790 pub adjustment: u64,
3791 pub undelivered_expiration_time: u64,
3792}
3793
3794#[repr(C)]
3795#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3796pub struct HvSyntheticTimersState {
3797 pub timers: [HvStimerState; 4],
3798 pub reserved: [u64; 5],
3799}
3800
3801#[bitfield(u64)]
3802pub struct HvInternalActivityRegister {
3803 pub startup_suspend: bool,
3804 pub halt_suspend: bool,
3805 pub idle_suspend: bool,
3806 #[bits(61)]
3807 pub reserved: u64,
3808}
3809
3810#[bitfield(u64)]
3811pub struct HvSynicSint {
3812 pub vector: u8,
3813 _reserved: u8,
3814 pub masked: bool,
3815 pub auto_eoi: bool,
3816 pub polling: bool,
3817 _reserved2: bool,
3818 pub proxy: bool,
3819 #[bits(43)]
3820 _reserved2: u64,
3821}
3822
3823#[bitfield(u64)]
3824pub struct HvSynicScontrol {
3825 pub enabled: bool,
3826 #[bits(63)]
3827 _reserved: u64,
3828}
3829
3830#[bitfield(u64)]
3831pub struct HvSynicSimpSiefp {
3832 pub enabled: bool,
3833 #[bits(11)]
3834 _reserved: u64,
3835 #[bits(52)]
3836 pub base_gpn: u64,
3837}
3838
3839#[bitfield(u64)]
3840pub struct HvSynicStimerConfig {
3841 pub enabled: bool,
3842 pub periodic: bool,
3843 pub lazy: bool,
3844 pub auto_enable: bool,
3845 pub apic_vector: u8,
3847 pub direct_mode: bool,
3848 #[bits(3)]
3849 pub _reserved1: u8,
3850 #[bits(4)]
3851 pub sint: u8,
3852 #[bits(44)]
3853 pub _reserved2: u64,
3854}
3855
3856pub const HV_X64_PENDING_EVENT_EXCEPTION: u8 = 0;
3857pub const HV_X64_PENDING_EVENT_MEMORY_INTERCEPT: u8 = 1;
3858pub const HV_X64_PENDING_EVENT_NESTED_MEMORY_INTERCEPT: u8 = 2;
3859pub const HV_X64_PENDING_EVENT_VIRTUALIZATION_FAULT: u8 = 3;
3860pub const HV_X64_PENDING_EVENT_HYPERCALL_OUTPUT: u8 = 4;
3861pub const HV_X64_PENDING_EVENT_EXT_INT: u8 = 5;
3862pub const HV_X64_PENDING_EVENT_SHADOW_IPT: u8 = 6;
3863
3864#[bitfield(u128)]
3866pub struct HvX64PendingExceptionEvent {
3867 pub event_pending: bool,
3868 #[bits(3)]
3869 pub event_type: u8,
3870 #[bits(4)]
3871 pub reserved0: u8,
3872
3873 pub deliver_error_code: bool,
3874 #[bits(7)]
3875 pub reserved1: u8,
3876 pub vector: u16,
3877 pub error_code: u32,
3878 pub exception_parameter: u64,
3879}
3880
3881#[bitfield(u128)]
3883pub struct HvX64PendingVirtualizationFaultEvent {
3884 pub event_pending: bool,
3885 #[bits(3)]
3886 pub event_type: u8,
3887 #[bits(4)]
3888 pub reserved0: u8,
3889
3890 pub reserved1: u8,
3891 pub parameter0: u16,
3892 pub code: u32,
3893 pub parameter1: u64,
3894}
3895
3896#[bitfield(u8)]
3898#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3899pub struct HvX64PendingEventMemoryInterceptPendingEventHeader {
3900 pub event_pending: bool,
3901 #[bits(3)]
3902 pub event_type: u8,
3903 #[bits(4)]
3904 _reserved0: u8,
3905}
3906
3907#[bitfield(u8)]
3909#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3910pub struct HvX64PendingEventMemoryInterceptAccessFlags {
3911 pub guest_linear_address_valid: bool,
3913 pub caused_by_gpa_access: bool,
3916 #[bits(6)]
3917 _reserved1: u8,
3918}
3919
3920#[repr(C)]
3922#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3923pub struct HvX64PendingEventMemoryIntercept {
3924 pub event_header: HvX64PendingEventMemoryInterceptPendingEventHeader,
3925 pub target_vtl: u8,
3928 pub access_type: HvInterceptAccessType,
3930 pub access_flags: HvX64PendingEventMemoryInterceptAccessFlags,
3931 pub _reserved2: u32,
3932 pub guest_linear_address: u64,
3934 pub guest_physical_address: u64,
3936 pub _reserved3: u64,
3937}
3938const_assert!(size_of::<HvX64PendingEventMemoryIntercept>() == 0x20);
3939
3940#[bitfield(u128)]
3944pub struct HvX64PendingHypercallOutputEvent {
3945 pub event_pending: bool,
3946 #[bits(3)]
3947 pub event_type: u8,
3948 #[bits(4)]
3949 pub reserved0: u8,
3950
3951 pub retired: bool,
3953
3954 #[bits(23)]
3955 pub reserved1: u32,
3956
3957 pub output_size: u32,
3959
3960 pub output_gpa: u64,
3962}
3963
3964#[bitfield(u128)]
3966pub struct HvX64PendingExtIntEvent {
3967 pub event_pending: bool,
3968 #[bits(3)]
3969 pub event_type: u8,
3970 #[bits(4)]
3971 pub reserved0: u8,
3972 pub vector: u8,
3973 #[bits(48)]
3974 pub reserved1: u64,
3975 pub reserved2: u64,
3976}
3977
3978#[bitfield(u128)]
3980pub struct HvX64PendingShadowIptEvent {
3981 pub event_pending: bool,
3982 #[bits(4)]
3983 pub event_type: u8,
3984 #[bits(59)]
3985 pub reserved0: u64,
3986
3987 pub reserved1: u64,
3988}
3989
3990#[bitfield(u128)]
3991#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
3992pub struct HvX64PendingEventReg0 {
3993 pub event_pending: bool,
3994 #[bits(3)]
3995 pub event_type: u8,
3996 #[bits(4)]
3997 pub reserved: u8,
3998 #[bits(120)]
3999 pub data: u128,
4000}
4001
4002#[repr(C)]
4003#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
4004pub struct HvX64PendingEvent {
4005 pub reg_0: HvX64PendingEventReg0,
4006 pub reg_1: AlignedU128,
4007}
4008const_assert!(size_of::<HvX64PendingEvent>() == 0x20);
4009
4010impl From<HvX64PendingExceptionEvent> for HvX64PendingEvent {
4011 fn from(exception_event: HvX64PendingExceptionEvent) -> Self {
4012 HvX64PendingEvent {
4013 reg_0: HvX64PendingEventReg0::from(u128::from(exception_event)),
4014 reg_1: 0u128.into(),
4015 }
4016 }
4017}
4018
4019#[bitfield(u64)]
4020#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4021pub struct HvX64PendingInterruptionRegister {
4022 pub interruption_pending: bool,
4023 #[bits(3)]
4024 pub interruption_type: u8,
4025 pub deliver_error_code: bool,
4026 #[bits(4)]
4027 pub instruction_length: u8,
4028 pub nested_event: bool,
4029 #[bits(6)]
4030 pub reserved: u8,
4031 pub interruption_vector: u16,
4032 pub error_code: u32,
4033}
4034
4035#[bitfield(u64)]
4036#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4037pub struct HvX64InterruptStateRegister {
4038 pub interrupt_shadow: bool,
4039 pub nmi_masked: bool,
4040 #[bits(62)]
4041 pub reserved: u64,
4042}
4043
4044#[bitfield(u64)]
4045#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4046pub struct HvInstructionEmulatorHintsRegister {
4047 pub partition_secure_vtl_enabled: bool,
4049 pub mbec_user_execute_control: bool,
4052 #[bits(62)]
4053 pub _padding: u64,
4054}
4055
4056open_enum! {
4057 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4058 pub enum HvAarch64PendingEventType: u8 {
4059 EXCEPTION = 0,
4060 SYNTHETIC_EXCEPTION = 1,
4061 HYPERCALL_OUTPUT = 2,
4062 }
4063}
4064
4065impl HvAarch64PendingEventType {
4067 const fn from_bits(val: u8) -> Self {
4068 HvAarch64PendingEventType(val)
4069 }
4070
4071 const fn into_bits(self) -> u8 {
4072 self.0
4073 }
4074}
4075
4076#[bitfield[u8]]
4077#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4078pub struct HvAarch64PendingEventHeader {
4079 #[bits(1)]
4080 pub event_pending: bool,
4081 #[bits(3)]
4082 pub event_type: HvAarch64PendingEventType,
4083 #[bits(4)]
4084 pub reserved: u8,
4085}
4086
4087#[repr(C)]
4088#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
4089pub struct HvAarch64PendingExceptionEvent {
4090 pub header: HvAarch64PendingEventHeader,
4091 pub _padding: [u8; 7],
4092 pub syndrome: u64,
4093 pub fault_address: u64,
4094}
4095
4096#[bitfield[u8]]
4097#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4098pub struct HvAarch64PendingHypercallOutputEventFlags {
4099 #[bits(1)]
4100 pub retired: u8,
4101 #[bits(7)]
4102 pub reserved: u8,
4103}
4104
4105#[repr(C)]
4106#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
4107pub struct HvAarch64PendingHypercallOutputEvent {
4108 pub header: HvAarch64PendingEventHeader,
4109 pub flags: HvAarch64PendingHypercallOutputEventFlags,
4110 pub reserved: u16,
4111 pub output_size: u32,
4112 pub output_gpa: u64,
4113}
4114
4115#[repr(C)]
4116#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
4117pub struct HvAarch64PendingEvent {
4118 pub header: HvAarch64PendingEventHeader,
4119 pub event_data: [u8; 15],
4120 pub _padding: [u64; 2],
4121}
4122
4123#[bitfield(u32)]
4124#[derive(PartialEq, Eq, IntoBytes, Immutable, KnownLayout, FromBytes)]
4125pub struct HvMapGpaFlags {
4126 pub readable: bool,
4127 pub writable: bool,
4128 pub kernel_executable: bool,
4129 pub user_executable: bool,
4130 pub supervisor_shadow_stack: bool,
4131 pub paging_writability: bool,
4132 pub verify_paging_writability: bool,
4133 #[bits(8)]
4134 _padding0: u32,
4135 pub adjustable: bool,
4136 #[bits(16)]
4137 _padding1: u32,
4138}
4139
4140pub const HV_MAP_GPA_PERMISSIONS_NONE: HvMapGpaFlags = HvMapGpaFlags::new();
4142pub const HV_MAP_GPA_PERMISSIONS_ALL: HvMapGpaFlags = HvMapGpaFlags::new()
4143 .with_readable(true)
4144 .with_writable(true)
4145 .with_kernel_executable(true)
4146 .with_user_executable(true);
4147
4148#[repr(C)]
4149#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4150pub struct HvMonitorPage {
4151 pub trigger_state: HvMonitorTriggerState,
4152 pub reserved1: u32,
4153 pub trigger_group: [HvMonitorTriggerGroup; 4],
4154 pub reserved2: [u64; 3],
4155 pub next_check_time: [[u32; 32]; 4],
4156 pub latency: [[u16; 32]; 4],
4157 pub reserved3: [u64; 32],
4158 pub parameter: [[HvMonitorParameter; 32]; 4],
4159 pub reserved4: [u8; 1984],
4160}
4161
4162#[repr(C)]
4163#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4164pub struct HvMonitorPageSmall {
4165 pub trigger_state: HvMonitorTriggerState,
4166 pub reserved1: u32,
4167 pub trigger_group: [HvMonitorTriggerGroup; 4],
4168}
4169
4170#[repr(C)]
4171#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4172pub struct HvMonitorTriggerGroup {
4173 pub pending: u32,
4174 pub armed: u32,
4175}
4176
4177#[repr(C)]
4178#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4179pub struct HvMonitorParameter {
4180 pub connection_id: u32,
4181 pub flag_number: u16,
4182 pub reserved: u16,
4183}
4184
4185#[bitfield(u32)]
4186#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4187pub struct HvMonitorTriggerState {
4188 #[bits(4)]
4189 pub group_enable: u32,
4190 #[bits(28)]
4191 pub reserved: u32,
4192}
4193
4194#[bitfield(u64)]
4195#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4196pub struct HvPmTimerInfo {
4197 #[bits(16)]
4198 pub port: u16,
4199 #[bits(1)]
4200 pub width_24: bool,
4201 #[bits(1)]
4202 pub enabled: bool,
4203 #[bits(14)]
4204 pub reserved1: u32,
4205 #[bits(32)]
4206 pub reserved2: u32,
4207}
4208
4209#[bitfield(u64)]
4210#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4211pub struct HvX64RegisterSevControl {
4212 pub enable_encrypted_state: bool,
4213 #[bits(11)]
4214 _rsvd1: u64,
4215 #[bits(52)]
4216 pub vmsa_gpa_page_number: u64,
4217}
4218
4219#[bitfield(u64)]
4220#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4221pub struct HvX64RegisterSevAvic {
4222 pub enable_secure_apic: bool,
4223 #[bits(11)]
4224 _rsvd1: u64,
4225 #[bits(52)]
4226 pub avic_gpa_page_number: u64,
4227}
4228
4229#[bitfield(u64)]
4230#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4231pub struct HvRegisterReferenceTsc {
4232 pub enable: bool,
4233 #[bits(11)]
4234 pub reserved_p: u64,
4235 #[bits(52)]
4236 pub gpn: u64,
4237}
4238
4239#[repr(C)]
4240#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4241pub struct HvReferenceTscPage {
4242 pub tsc_sequence: u32,
4243 pub reserved1: u32,
4244 pub tsc_scale: u64,
4245 pub tsc_offset: i64,
4246 pub timeline_bias: u64,
4247 pub tsc_multiplier: u64,
4248 pub reserved2: [u64; 507],
4249}
4250
4251pub const HV_REFERENCE_TSC_SEQUENCE_INVALID: u32 = 0;
4252
4253#[bitfield(u64)]
4254#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4255pub struct HvX64VmgexitInterceptMessageFlags {
4256 pub ghcb_page_valid: bool,
4257 pub ghcb_request_error: bool,
4258 #[bits(62)]
4259 _reserved: u64,
4260}
4261
4262#[repr(C)]
4263#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
4264pub struct HvX64VmgexitInterceptMessageGhcbPageStandard {
4265 pub ghcb_protocol_version: u16,
4266 _reserved: [u16; 3],
4267 pub sw_exit_code: u64,
4268 pub sw_exit_info1: u64,
4269 pub sw_exit_info2: u64,
4270 pub sw_scratch: u64,
4271}
4272
4273#[repr(C)]
4274#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
4275pub struct HvX64VmgexitInterceptMessageGhcbPage {
4276 pub ghcb_usage: u32,
4277 _reserved: u32,
4278 pub standard: HvX64VmgexitInterceptMessageGhcbPageStandard,
4279}
4280
4281#[repr(C)]
4282#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
4283pub struct HvX64VmgexitInterceptMessage {
4284 pub header: HvX64InterceptMessageHeader,
4285 pub ghcb_msr: u64,
4286 pub flags: HvX64VmgexitInterceptMessageFlags,
4287 pub ghcb_page: HvX64VmgexitInterceptMessageGhcbPage,
4288}
4289
4290impl MessagePayload for HvX64VmgexitInterceptMessage {}
4291
4292#[bitfield(u64)]
4293pub struct HvRegisterVpAssistPage {
4294 pub enabled: bool,
4295 #[bits(11)]
4296 _reserved: u64,
4297 #[bits(52)]
4298 pub gpa_page_number: u64,
4299}
4300
4301#[bitfield(u32)]
4302#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4303pub struct HvX64RegisterPageDirtyFlags {
4304 pub general_purpose: bool,
4305 pub instruction_pointer: bool,
4306 pub xmm: bool,
4307 pub segments: bool,
4308 pub flags: bool,
4309 #[bits(27)]
4310 reserved: u32,
4311}
4312
4313#[repr(C)]
4314#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
4315pub struct HvX64RegisterPage {
4316 pub version: u16,
4317 pub is_valid: u8,
4318 pub vtl: u8,
4319 pub dirty: HvX64RegisterPageDirtyFlags,
4320 pub gp_registers: [u64; 16],
4323 pub rip: u64,
4324 pub rflags: u64,
4325 pub reserved: u64,
4326 pub xmm: [u128; 6],
4327 pub segment: [HvX64SegmentRegister; 6],
4328 pub cr0: u64,
4330 pub cr3: u64,
4331 pub cr4: u64,
4332 pub cr8: u64,
4333 pub efer: u64,
4334 pub dr7: u64,
4335 pub pending_interruption: HvX64PendingInterruptionRegister,
4336 pub interrupt_state: HvX64InterruptStateRegister,
4337 pub instruction_emulation_hints: HvInstructionEmulatorHintsRegister,
4338 pub reserved_end: [u8; 3672],
4339}
4340
4341const _: () = assert!(size_of::<HvX64RegisterPage>() == HV_PAGE_SIZE_USIZE);
4342
4343#[bitfield(u32)]
4344#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
4345pub struct HvAarch64RegisterPageDirtyFlags {
4346 _unused: bool,
4347 pub instruction_pointer: bool,
4348 pub processor_state: bool,
4349 pub control_registers: bool,
4350 #[bits(28)]
4351 reserved: u32,
4352}
4353
4354#[repr(C)]
4355#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
4356pub struct HvAarch64RegisterPage {
4357 pub version: u16,
4358 pub is_valid: u8,
4359 pub vtl: u8,
4360 pub dirty: HvAarch64RegisterPageDirtyFlags,
4361 pub _rsvd: [u64; 33],
4363 pub pc: u64,
4365 pub cpsr: u64,
4367 pub sctlr_el1: u64,
4369 pub tcr_el1: u64,
4370 pub reserved_end: [u8; 3792],
4372}
4373
4374const _: () = assert!(size_of::<HvAarch64RegisterPage>() == HV_PAGE_SIZE_USIZE);
4375
4376#[bitfield(u64)]
4377pub struct HvRegisterVsmWpWaitForTlbLock {
4378 pub wait: bool,
4379 #[bits(63)]
4380 _reserved: u64,
4381}
4382
4383#[bitfield(u64)]
4384pub struct HvRegisterVsmVpSecureVtlConfig {
4385 pub mbec_enabled: bool,
4386 pub tlb_locked: bool,
4387 pub supervisor_shadow_stack_enabled: bool,
4388 pub hardware_hvpt_enabled: bool,
4389 #[bits(60)]
4390 _reserved: u64,
4391}
4392
4393#[bitfield(u64)]
4394pub struct HvRegisterCrInterceptControl {
4395 pub cr0_write: bool,
4396 pub cr4_write: bool,
4397 pub xcr0_write: bool,
4398 pub ia32_misc_enable_read: bool,
4399 pub ia32_misc_enable_write: bool,
4400 pub msr_lstar_read: bool,
4401 pub msr_lstar_write: bool,
4402 pub msr_star_read: bool,
4403 pub msr_star_write: bool,
4404 pub msr_cstar_read: bool,
4405 pub msr_cstar_write: bool,
4406 pub apic_base_msr_read: bool,
4407 pub apic_base_msr_write: bool,
4408 pub msr_efer_read: bool,
4409 pub msr_efer_write: bool,
4410 pub gdtr_write: bool,
4411 pub idtr_write: bool,
4412 pub ldtr_write: bool,
4413 pub tr_write: bool,
4414 pub msr_sysenter_cs_write: bool,
4415 pub msr_sysenter_eip_write: bool,
4416 pub msr_sysenter_esp_write: bool,
4417 pub msr_sfmask_write: bool,
4418 pub msr_tsc_aux_write: bool,
4419 pub msr_sgx_launch_control_write: bool,
4420 pub msr_xss_write: bool,
4421 pub msr_scet_write: bool,
4422 pub msr_pls_ssp_write: bool,
4423 pub msr_interrupt_ssp_table_addr_write: bool,
4424 #[bits(35)]
4425 _rsvd_z: u64,
4426}
4427
4428#[repr(C)]
4429#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
4430pub struct HvX64InterruptControllerState {
4431 pub apic_id: u32,
4432 pub apic_version: u32,
4433 pub apic_ldr: u32,
4434 pub apic_dfr: u32,
4435 pub apic_spurious: u32,
4436 pub apic_isr: [u32; 8],
4437 pub apic_tmr: [u32; 8],
4438 pub apic_irr: [u32; 8],
4439 pub apic_esr: u32,
4440 pub apic_icr_high: u32,
4441 pub apic_icr_low: u32,
4442 pub apic_lvt_timer: u32,
4443 pub apic_lvt_thermal: u32,
4444 pub apic_lvt_perfmon: u32,
4445 pub apic_lvt_lint0: u32,
4446 pub apic_lvt_lint1: u32,
4447 pub apic_lvt_error: u32,
4448 pub apic_lvt_cmci: u32,
4449 pub apic_error_status: u32,
4450 pub apic_initial_count: u32,
4451 pub apic_counter_value: u32,
4452 pub apic_divide_configuration: u32,
4453 pub apic_remote_read: u32,
4454}