#ifndef VMCB_LAYOUT_H #define VMCB_LAYOUT_H #include struct InterceptVector0 { u32 read_cr0 : 1; u32 read_cr1 : 1; u32 read_cr2 : 1; u32 read_cr3 : 1; u32 read_cr4 : 1; u32 read_cr5 : 1; u32 read_cr6 : 1; u32 read_cr7 : 1; u32 read_cr8 : 1; u32 read_cr9 : 1; u32 read_cr10 : 1; u32 read_cr11 : 1; u32 read_cr12 : 1; u32 read_cr13 : 1; u32 read_cr14 : 1; u32 read_cr15 : 1; u32 write_cr0 : 1; u32 write_cr1 : 1; u32 write_cr2 : 1; u32 write_cr3 : 1; u32 write_cr4 : 1; u32 write_cr5 : 1; u32 write_cr6 : 1; u32 write_cr7 : 1; u32 write_cr8 : 1; u32 write_cr9 : 1; u32 write_cr10 : 1; u32 write_cr11 : 1; u32 write_cr12 : 1; u32 write_cr13 : 1; u32 write_cr14 : 1; u32 write_cr15 : 1; } __attribute__((packed)); static_assert(sizeof(struct InterceptVector0) == 4); struct InterceptVector1 { u32 read_dr0 : 1; u32 read_dr1 : 1; u32 read_dr2 : 1; u32 read_dr3 : 1; u32 read_dr4 : 1; u32 read_dr5 : 1; u32 read_dr6 : 1; u32 read_dr7 : 1; u32 read_dr8 : 1; u32 read_dr9 : 1; u32 read_dr10 : 1; u32 read_dr11 : 1; u32 read_dr12 : 1; u32 read_dr13 : 1; u32 read_dr14 : 1; u32 read_dr15 : 1; u32 write_dr0 : 1; u32 write_dr1 : 1; u32 write_dr2 : 1; u32 write_dr3 : 1; u32 write_dr4 : 1; u32 write_dr5 : 1; u32 write_dr6 : 1; u32 write_dr7 : 1; u32 write_dr8 : 1; u32 write_dr9 : 1; u32 write_dr10 : 1; u32 write_dr11 : 1; u32 write_dr12 : 1; u32 write_dr13 : 1; u32 write_dr14 : 1; u32 write_dr15 : 1; } __attribute__((packed)); static_assert(sizeof(struct InterceptVector1) == 4); struct InterceptVector2 { u32 exception_vector0 : 1; u32 exception_vector1 : 1; u32 exception_vector2 : 1; u32 exception_vector3 : 1; u32 exception_vector4 : 1; u32 exception_vector5 : 1; u32 exception_vector6 : 1; u32 exception_vector7 : 1; u32 exception_vector8 : 1; u32 exception_vector9 : 1; u32 exception_vector10 : 1; u32 exception_vector11 : 1; u32 exception_vector12 : 1; u32 exception_vector13 : 1; u32 exception_vector14 : 1; u32 exception_vector15 : 1; u32 exception_vector16 : 1; u32 exception_vector17 : 1; u32 exception_vector18 : 1; u32 exception_vector19 : 1; u32 exception_vector20 : 1; u32 exception_vector21 : 1; u32 exception_vector22 : 1; u32 exception_vector23 : 1; u32 exception_vector24 : 1; u32 exception_vector25 : 1; u32 exception_vector26 : 1; u32 exception_vector27 : 1; u32 exception_vector28 : 1; u32 exception_vector29 : 1; u32 exception_vector30 : 1; u32 exception_vector31 : 1; } __attribute__((packed)); static_assert(sizeof(struct InterceptVector2) == 4); struct InterceptVector3 { u32 intr : 1; u32 nmi : 1; u32 smi : 1; u32 init : 1; u32 vintr : 1; u32 cr0_writes : 1; u32 idtr_read : 1; u32 gdtr_read : 1; u32 ldtr_read : 1; u32 tr_read : 1; u32 idtr_write : 1; u32 gdtr_write : 1; u32 ldtr_write : 1; u32 tr_write : 1; u32 rdtsc_inst : 1; u32 rdpmc_inst : 1; u32 pushf_inst : 1; u32 popf_inst : 1; u32 cpuid_inst : 1; u32 rsm_inst : 1; u32 iret_inst : 1; u32 intn_inst : 1; u32 invd_inst : 1; u32 pause_inst : 1; u32 hlt_inst : 1; u32 invlpg_inst : 1; u32 invlpga_inst : 1; u32 ioio_prot : 1; u32 msr_prot : 1; u32 task_switches : 1; u32 ferr_freeze : 1; u32 shutdown : 1; } __attribute__((packed)); static_assert(sizeof(struct InterceptVector3) == 4); struct InterceptVector4 { u32 vmrun_inst : 1; u32 vmcall_inst : 1; u32 vmload_inst : 1; u32 vmsave_inst : 1; u32 stgi_inst : 1; u32 clgi_inst : 1; u32 skinit_inst : 1; u32 rdtscp_inst : 1; u32 icebp_inst : 1; u32 wbinvd_inst : 1; u32 monitor_inst : 1; u32 mwait_inst_uncond : 1; u32 mwait_inst_armed : 1; u32 xsetbv_inst : 1; u32 rdpru_inst : 1; u32 efer_write : 1; u32 write_cr0_after : 1; u32 write_cr1_after : 1; u32 write_cr2_after : 1; u32 write_cr3_after : 1; u32 write_cr4_after : 1; u32 write_cr5_after : 1; u32 write_cr6_after : 1; u32 write_cr7_after : 1; u32 write_cr8_after : 1; u32 write_cr9_after : 1; u32 write_cr10_after : 1; u32 write_cr11_after : 1; u32 write_cr12_after : 1; u32 write_cr13_after : 1; u32 write_cr14_after : 1; u32 write_cr15_after : 1; } __attribute__((packed)); static_assert(sizeof(struct InterceptVector4) == 4); struct InterceptVector5 { u32 invlpgb_inst_all : 1; u32 invlpgb_inst_ill : 1; u32 invpcid_inst : 1; u32 mcommit_inst : 1; u32 tlbsync_inst : 1; u32 bus_lock_op : 1; u32 hlt_inst_npen : 1; u32 reserved : 25; } __attribute__((packed)); static_assert(sizeof(struct InterceptVector5) == 4); struct TLBControl { u32 tlb_control : 8; u32 allow_larger_rap : 1; u32 clear_rap : 1; u32 reserved : 22; } __attribute__((packed)); static_assert(sizeof(struct TLBControl) == 4); struct VirtualInterruptControl { u64 v_tpr : 4; u64 v_tpr_mbz : 4; u64 v_irq : 1; u64 v_gif : 1; u64 reserved_0 : 1; u64 v_nmi : 1; u64 v_nmi_mask : 1; u64 reserved_1 : 3; u64 v_intr_prio : 4; u64 v_ign_tpr : 1; u64 reserved_2 : 3; u64 v_intr_masking : 1; u64 v_gif_enable : 1; u64 v_nmi_enable : 1; u64 reserved_3 : 3; u64 x2avic_enable : 1; u64 avic_enable : 1; u64 v_intr_vector : 8; u64 reserved_4 : 24; } __attribute__((packed)); static_assert(sizeof(struct VirtualInterruptControl) == 8); struct InterruptShadow { u64 interrupt_shadow : 1; u64 guest_interrupt_mask : 1; u64 reserved : 62; } __attribute__((packed)); static_assert(sizeof(struct InterruptShadow) == 8); struct VirtualizationControl0 { u64 np_enable : 1; u64 sev_enable : 1; u64 sev_es : 1; u64 guest_mode_execute_trap : 1; u64 ssscheck_en : 1; u64 virtual_transparent_encryption : 1; u64 read_only_guest_page_tables : 1; u64 invlpg_tlbsync_enable : 1; u64 reserved : 56; } __attribute__((packed)); static_assert(sizeof(struct VirtualizationControl0) == 8); struct AVICAPICBar { u64 avic_apic_bar : 52; u64 reserved : 12; } __attribute__((packed)); static_assert(sizeof(struct AVICAPICBar) == 8); struct VirtualizationControl1 { u64 lbr_virtualization_enable : 1; u64 vmsave_vmload_virtualization_enable : 1; u64 ibs_virtualization_enable : 1; u64 pmc_virtualization_enable : 1; u64 ignored : 60; } __attribute__((packed)); static_assert(sizeof(struct VirtualizationControl1) == 8); struct GuestInstruction { u8 bytes_fetched; u8 guest_instruction[0xF]; } __attribute__((packed)); static_assert(sizeof(struct GuestInstruction) == 0x10); struct AVICAPICBackingPage { u64 avic_apic_backing_page_pointer : 52; u64 reserved : 12; } __attribute__((packed)); static_assert(sizeof(struct AVICAPICBackingPage) == 8); struct AVICLogicalTablePointer { u64 reserved_0 : 12; u64 avic_logical_table_pointer : 40; u64 reserved_1 : 12; } __attribute__((packed)); static_assert(sizeof(struct AVICLogicalTablePointer) == 8); struct AVICPhysicalTablePointer { u64 avic_physical_max_index : 12; u64 avic_physical_table_pointer : 40; u64 reserved_0 : 12; } __attribute__((packed)); static_assert(sizeof(struct AVICPhysicalTablePointer) == 8); struct VMSAPointer { u64 reserved_0 : 12; u64 vmsa_pointer : 40; u64 reserved_1 : 12; } __attribute__((packed)); static_assert(sizeof(struct VMSAPointer) == 8); struct AllowedSEVFeatures { u64 allowed_sev_features_mask : 62; u64 reserved_0 : 1; u64 allowed_sev_features_en : 1; } __attribute__((packed)); static_assert(sizeof(struct AllowedSEVFeatures) == 8); struct RequestedIRR { u64 irr[4]; } __attribute__((packed)); static_assert(sizeof(struct RequestedIRR) == 0x20); struct VMCBControlArea { struct InterceptVector0 intercept_vector0; struct InterceptVector1 intercept_vector1; struct InterceptVector2 intercept_vector2; struct InterceptVector3 intercept_vector3; struct InterceptVector4 intercept_vector4; struct InterceptVector5 intercept_vector5; u8 reserved_0[0x24]; u16 pause_filter_threshold; u16 pause_filter_count; u64 iopm_base_pa; u64 msrpm_base_pa; u64 tsc_offset; u32 guest_asid; struct TLBControl tlb_control; struct VirtualInterruptControl v_intr; struct InterruptShadow interrupt_shadow; u64 exitcode; u64 exitinfo1; u64 exitinfo2; u64 exitintinfo; struct VirtualizationControl0 virtualization_control0; struct AVICAPICBar avic_apic_bar; u64 guest_ghcb_pa; u64 eventinj; u64 h_cr3; struct VirtualizationControl1 virtualization_control1; u32 vmcb_clean_bits; u8 reserved_1[0x4]; u64 nrip; struct GuestInstruction guest_instruction; struct AVICAPICBackingPage avicapic_backing_page; u8 reserved_2[0x8]; struct AVICLogicalTablePointer avic_logical_table; struct AVICPhysicalTablePointer avic_physical_table; u8 reserved_3[0x08]; struct VMSAPointer vmsa_pointer; u64 vmgexit_rax; u8 vmgexit_cpl; u8 reserved_4[0x07]; u16 bus_lock_threshold_counter; u8 reserved_5[0x12]; u32 update_irr; struct AllowedSEVFeatures allowed_sev_features; u64 guest_sev_features; u8 reserved_6[0x8]; struct RequestedIRR requested_irr; u8 reserved_7[0x270]; u8 host_reserved[0x20]; } __attribute__((packed)); static_assert(offsetof(struct VMCBControlArea, intercept_vector0) == 0x000); static_assert(offsetof(struct VMCBControlArea, intercept_vector1) == 0x004); static_assert(offsetof(struct VMCBControlArea, intercept_vector2) == 0x008); static_assert(offsetof(struct VMCBControlArea, intercept_vector3) == 0x00C); static_assert(offsetof(struct VMCBControlArea, intercept_vector4) == 0x010); static_assert(offsetof(struct VMCBControlArea, intercept_vector5) == 0x014); static_assert(offsetof(struct VMCBControlArea, pause_filter_threshold) == 0x03C); static_assert(offsetof(struct VMCBControlArea, pause_filter_count) == 0x03E); static_assert(offsetof(struct VMCBControlArea, intercept_vector5) == 0x014); static_assert(offsetof(struct VMCBControlArea, iopm_base_pa) == 0x040); static_assert(offsetof(struct VMCBControlArea, msrpm_base_pa) == 0x048); static_assert(offsetof(struct VMCBControlArea, tsc_offset) == 0x050); static_assert(offsetof(struct VMCBControlArea, guest_asid) == 0x058); static_assert(offsetof(struct VMCBControlArea, tlb_control) == 0x05C); static_assert(offsetof(struct VMCBControlArea, v_intr) == 0x060); static_assert(offsetof(struct VMCBControlArea, interrupt_shadow) == 0x068); static_assert(offsetof(struct VMCBControlArea, exitcode) == 0x070); static_assert(offsetof(struct VMCBControlArea, exitinfo1) == 0x078); static_assert(offsetof(struct VMCBControlArea, exitinfo2) == 0x080); static_assert(offsetof(struct VMCBControlArea, exitintinfo) == 0x088); static_assert(offsetof(struct VMCBControlArea, virtualization_control0) == 0x090); static_assert(offsetof(struct VMCBControlArea, avic_apic_bar) == 0x098); static_assert(offsetof(struct VMCBControlArea, guest_ghcb_pa) == 0x0A0); static_assert(offsetof(struct VMCBControlArea, eventinj) == 0x0A8); static_assert(offsetof(struct VMCBControlArea, h_cr3) == 0x0B0); static_assert(offsetof(struct VMCBControlArea, virtualization_control1) == 0x0B8); static_assert(offsetof(struct VMCBControlArea, vmcb_clean_bits) == 0x0C0); static_assert(offsetof(struct VMCBControlArea, nrip) == 0x0C8); static_assert(offsetof(struct VMCBControlArea, guest_instruction) == 0x0D0); static_assert(offsetof(struct VMCBControlArea, avicapic_backing_page) == 0x0E0); static_assert(offsetof(struct VMCBControlArea, avic_logical_table) == 0x0F0); static_assert(offsetof(struct VMCBControlArea, avic_physical_table) == 0x0F8); static_assert(offsetof(struct VMCBControlArea, vmsa_pointer) == 0x108); static_assert(offsetof(struct VMCBControlArea, vmgexit_rax) == 0x110); static_assert(offsetof(struct VMCBControlArea, vmgexit_cpl) == 0x118); static_assert(offsetof(struct VMCBControlArea, bus_lock_threshold_counter) == 0x120); static_assert(offsetof(struct VMCBControlArea, update_irr) == 0x134); static_assert(offsetof(struct VMCBControlArea, allowed_sev_features) == 0x138); static_assert(offsetof(struct VMCBControlArea, guest_sev_features) == 0x140); static_assert(offsetof(struct VMCBControlArea, requested_irr) == 0x150); static_assert(offsetof(struct VMCBControlArea, host_reserved) == 0x3E0); static_assert(sizeof(struct VMCBControlArea) == 0x400); struct SegmentDescriptor { u16 selector; u16 attrib; u32 limit; u64 base; } __attribute__((packed)); static_assert(offsetof(struct SegmentDescriptor, selector) == 0); static_assert(offsetof(struct SegmentDescriptor, attrib) == 2); static_assert(offsetof(struct SegmentDescriptor, limit) == 4); static_assert(offsetof(struct SegmentDescriptor, base) == 8); static_assert(sizeof(struct SegmentDescriptor) == 0x10); struct LBRSTACK { u8 lbr_stack_from_to[256]; } __attribute__((packed)); static_assert(sizeof(struct LBRSTACK) == 0x100); struct VMCBStateSaveArea { struct SegmentDescriptor es; struct SegmentDescriptor cs; struct SegmentDescriptor ss; struct SegmentDescriptor ds; struct SegmentDescriptor fs; struct SegmentDescriptor gs; struct SegmentDescriptor gdtr; struct SegmentDescriptor ldtr; struct SegmentDescriptor idtr; struct SegmentDescriptor tr; u8 reserved_0[0x2B]; u8 cpl; u8 reserved_1[0x4]; u64 efer; u8 reserved_2[0x8]; u64 perf_ctl0; u64 perf_ctr0; u64 perf_ctl1; u64 perf_ctr1; u64 perf_ctl2; u64 perf_ctr2; u64 perf_ctl3; u64 perf_ctr3; u64 perf_ctl4; u64 perf_ctr4; u64 perf_ctl5; u64 perf_ctr5; u8 reserved_3[0x8]; u64 cr4; u64 cr3; u64 cr0; u64 dr7; u64 dr6; u64 rflags; u64 rip; u8 reserved_4[0x40]; u64 instr_retired_ctr; u64 perf_ctr_global_sts; u64 perf_ctr_global_ctl; u64 rsp; u64 s_cet; u64 ssp; u64 isst_addr; u64 rax; u64 star; u64 lstar; u64 cstar; u64 sfmask; u64 kernel_gs_base; u64 sysenter_cs; u64 sysenter_esp; u64 sysenter_eip; u64 cr2; u8 reserved_5[0x20]; u64 g_pat; u64 dbgctl; u64 br_from; u64 br_to; u64 lastexcpfrom; u64 lastexcpto; u64 dbgextnctl; u8 reserved_6[0x40]; u64 spec_ctrl; u8 reserved_7[0x388]; struct LBRSTACK lbr_stack_from_to; u64 lbr_select; u64 ibs_fetch_ctl; u64 ibs_fetch_linaddr; u64 ibs_op_ctl; u64 ibs_op_rip; u64 ibs_op_data; u64 ibs_op_data2; u64 ibs_op_data3; u64 ibs_dc_linaddr; u64 bp_ibstgt_rip; u64 ic_ibs_extd_ctl; u8 reserved_9[0x38]; } __attribute__((packed)); static_assert(offsetof(struct VMCBStateSaveArea, es) == 0x000); static_assert(offsetof(struct VMCBStateSaveArea, cs) == 0x010); static_assert(offsetof(struct VMCBStateSaveArea, ss) == 0x020); static_assert(offsetof(struct VMCBStateSaveArea, ds) == 0x030); static_assert(offsetof(struct VMCBStateSaveArea, fs) == 0x040); static_assert(offsetof(struct VMCBStateSaveArea, gs) == 0x050); static_assert(offsetof(struct VMCBStateSaveArea, gdtr) == 0x060); static_assert(offsetof(struct VMCBStateSaveArea, ldtr) == 0x070); static_assert(offsetof(struct VMCBStateSaveArea, idtr) == 0x080); static_assert(offsetof(struct VMCBStateSaveArea, tr) == 0x090); static_assert(offsetof(struct VMCBStateSaveArea, cpl) == 0x0CB); static_assert(offsetof(struct VMCBStateSaveArea, efer) == 0x0D0); static_assert(offsetof(struct VMCBStateSaveArea, perf_ctl0) == 0x0E0); static_assert(offsetof(struct VMCBStateSaveArea, perf_ctr0) == 0x0E8); static_assert(offsetof(struct VMCBStateSaveArea, perf_ctl1) == 0x0F0); static_assert(offsetof(struct VMCBStateSaveArea, perf_ctr1) == 0x0F8); static_assert(offsetof(struct VMCBStateSaveArea, perf_ctl2) == 0x100); static_assert(offsetof(struct VMCBStateSaveArea, perf_ctr2) == 0x108); static_assert(offsetof(struct VMCBStateSaveArea, perf_ctl3) == 0x110); static_assert(offsetof(struct VMCBStateSaveArea, perf_ctr3) == 0x118); static_assert(offsetof(struct VMCBStateSaveArea, perf_ctl4) == 0x120); static_assert(offsetof(struct VMCBStateSaveArea, perf_ctr4) == 0x128); static_assert(offsetof(struct VMCBStateSaveArea, perf_ctl5) == 0x130); static_assert(offsetof(struct VMCBStateSaveArea, perf_ctr5) == 0x138); static_assert(offsetof(struct VMCBStateSaveArea, cr4) == 0x148); static_assert(offsetof(struct VMCBStateSaveArea, cr3) == 0x150); static_assert(offsetof(struct VMCBStateSaveArea, cr0) == 0x158); static_assert(offsetof(struct VMCBStateSaveArea, dr7) == 0x160); static_assert(offsetof(struct VMCBStateSaveArea, dr6) == 0x168); static_assert(offsetof(struct VMCBStateSaveArea, rflags) == 0x170); static_assert(offsetof(struct VMCBStateSaveArea, rip) == 0x178); static_assert(offsetof(struct VMCBStateSaveArea, instr_retired_ctr) == 0x1C0); static_assert(offsetof(struct VMCBStateSaveArea, perf_ctr_global_sts) == 0x1C8); static_assert(offsetof(struct VMCBStateSaveArea, perf_ctr_global_ctl) == 0x1D0); static_assert(offsetof(struct VMCBStateSaveArea, rsp) == 0x1D8); static_assert(offsetof(struct VMCBStateSaveArea, rax) == 0x1F8); static_assert(offsetof(struct VMCBStateSaveArea, star) == 0x200); static_assert(offsetof(struct VMCBStateSaveArea, lstar) == 0x208); static_assert(offsetof(struct VMCBStateSaveArea, cstar) == 0x210); static_assert(offsetof(struct VMCBStateSaveArea, sfmask) == 0x218); static_assert(offsetof(struct VMCBStateSaveArea, kernel_gs_base) == 0x220); static_assert(offsetof(struct VMCBStateSaveArea, sysenter_cs) == 0x228); static_assert(offsetof(struct VMCBStateSaveArea, sysenter_esp) == 0x230); static_assert(offsetof(struct VMCBStateSaveArea, sysenter_eip) == 0x238); static_assert(offsetof(struct VMCBStateSaveArea, cr2) == 0x240); static_assert(offsetof(struct VMCBStateSaveArea, g_pat) == 0x268); static_assert(offsetof(struct VMCBStateSaveArea, dbgctl) == 0x270); static_assert(offsetof(struct VMCBStateSaveArea, br_from) == 0x278); static_assert(offsetof(struct VMCBStateSaveArea, br_to) == 0x280); static_assert(offsetof(struct VMCBStateSaveArea, lastexcpfrom) == 0x288); static_assert(offsetof(struct VMCBStateSaveArea, lastexcpto) == 0x290); static_assert(offsetof(struct VMCBStateSaveArea, dbgextnctl) == 0x298); static_assert(offsetof(struct VMCBStateSaveArea, spec_ctrl) == 0x2E0); static_assert(offsetof(struct VMCBStateSaveArea, lbr_stack_from_to) == 0x670); static_assert(offsetof(struct VMCBStateSaveArea, lbr_select) == 0x770); static_assert(offsetof(struct VMCBStateSaveArea, ibs_fetch_ctl) == 0x778); static_assert(offsetof(struct VMCBStateSaveArea, ibs_fetch_linaddr) == 0x780); static_assert(offsetof(struct VMCBStateSaveArea, ibs_op_ctl) == 0x788); static_assert(offsetof(struct VMCBStateSaveArea, ibs_op_rip) == 0x790); static_assert(offsetof(struct VMCBStateSaveArea, ibs_op_data) == 0x798); static_assert(offsetof(struct VMCBStateSaveArea, ibs_op_data2) == 0x7A0); static_assert(offsetof(struct VMCBStateSaveArea, ibs_op_data3) == 0x7A8); static_assert(offsetof(struct VMCBStateSaveArea, ibs_dc_linaddr) == 0x7B0); static_assert(offsetof(struct VMCBStateSaveArea, bp_ibstgt_rip) == 0x7B8); static_assert(offsetof(struct VMCBStateSaveArea, ic_ibs_extd_ctl) == 0x7C0); static_assert(sizeof(struct VMCBStateSaveArea) == 0x800); struct VMCB { struct VMCBControlArea control_area; struct VMCBStateSaveArea state_area; u8 reserved_0 [0x400]; } __attribute__((packed)); static_assert(offsetof(struct VMCB, control_area) == 0x000); static_assert(offsetof(struct VMCB, state_area) == 0x400); static_assert(sizeof(struct VMCB) == 0x1000); #endif