Skip to content

Instantly share code, notes, and snippets.

@muturik
Created August 22, 2021 23:05
Show Gist options
  • Save muturik/9e32d9c40f626e945e93deb07c02cb5b to your computer and use it in GitHub Desktop.
Save muturik/9e32d9c40f626e945e93deb07c02cb5b to your computer and use it in GitHub Desktop.
VMCS field encodings
#include <ntifs.h>
#include <stdint.h>
/*
Even though you can simply copy from kvm, linux kernels, etc.., it's better to copy them yourself as they change, plus who wants
to rely on another project for updates?
made using: This document contains all four volumes of the Intel 64 and IA-32 Architectures Software
Developer's Manual: Basic Architecture, Order Number 253665; Instruction Set Reference A-Z, Order
Number 325383; System Programming Guide, Order Number 325384; Model-Specific Registers, Order
Number 335592. Refer to all four volumes when evaluating your design needs.
credits to Derek rynd for the vmcs field encoding-related enums and macros
*/
enum vmcs_access_type
{
full = 0,
high = 1
};
enum vmcs_field_type
{
control = 0,
vmexit,
guest,
host
};
enum vmcs_field_width
{
word = 0,
quadword,
doubleword,
natural
};
// credits to Derek Rynd for these convenient macros
#define vmcs_encode_component( access, type, width, index ) ( unsigned )( ( unsigned short )( access ) | \
( ( unsigned short )( index ) << 1 ) | \
( ( unsigned short )( type ) << 10 ) | \
( ( unsigned short )( width ) << 13 ) )
#define vmcs_encode_component_full( type, width, index ) vmcs_encode_component( full, type, width, index )
#define vmcs_encode_component_full_16( type, index ) vmcs_encode_component_full( type, word, index )
#define vmcs_encode_component_full_32( type, index ) vmcs_encode_component_full( type, doubleword, index )
#define vmcs_encode_component_full_64( type, index ) vmcs_encode_component_full( type, quadword, index )
enum vmcs_fields
{
// 16-bit control fields
virtual_processor_id = 0x00000000,
posted_interrupt_notification_vector = 0x00000002,
eptp_index = 0x00000004,
// 64-bit control fields
address_io_bitmap_a_full = 0x00002000,
address_io_bitmap_a_high = 0x00002001,
address_io_bitmap_b_full = 0x00002002,
address_io_bitmap_b_high = 0x00002003,
address_msr_bitmaps_full = 0x00002004,
address_msr_bitmaps_high = 0x00002005,
vmexit_msr_store_address_full = 0x00002006,
vmexit_msr_store_address_high = 0x00002007,
vmexit_msr_load_address_full = 0x00002008,
vmexit_msr_load_address_high = 0x00002009,
vmentry_msr_load_address_full = 0x0000200A,
vmentry_msr_load_address_high = 0x0000200B,
executive_vmcs_pointer_full = 0x0000200C,
executive_vmcs_pointer_high = 0x0000200D,
pml_address_full = 0x0000200E,
pml_address_high = 0x0000200F,
tsc_offset_full = 0x00002010,
tsc_offset_high = 0x00002011,
virtual_apic_address_full = 0x00002012,
virtual_apic_address_high = 0x00002013,
apic_access_address_full = 0x00002014,
apic_access_address_high = 0x00002015,
posted_interrupt_descriptor_address_full = 0x00002016,
posted_intterupt_descriptor_address_high = 0x00002017,
vm_function_controls_full = 0x00002018,
vm_function_controls_high = 0x00002019,
ept_pointer_eptp_full = 0x0000201A,
ept_pointer_eptp_high = 0x0000201B,
eoi_exit_bitmap_0_full = 0x0000201C,
eoi_exit_bitmap_0_high = 0x0000201D,
eoi_exit_bitmap_1_full = 0x0000201E,
eoi_exit_bitmap_1_high = 0x0000201F,
eoi_exit_bitmap_2_full = 0x00002020,
eoi_exit_bitmap_2_high = 0x00002021,
eoi_exit_bitmap_3_full = 0x00002022,
eoi_exit_bitmap_3_high = 0x00002023,
eptp_list_address_full = 0x00002024,
eptp_list_address_high = 0x00002025,
vmread_bitmap_address_full = 0x00002026,
vmread_bitmap_address_high = 0x00002027,
vmwrite_bitmap_address_full = 0x00002028,
vmwrite_bitmap_address_high = 0x00002029,
virtualization_exception_information_address_full = 0x0000202A,
virtualization_exception_information_address_high = 0x0000202B,
xss_exiting_bitmap_full = 0x0000202C,
xss_exiting_bitmap_high = 0x0000202D,
encls_exiting_bitmap_full = 0x0000202E,
encls_exiting_bitmap_high = 0x0000202F,
sub_page_permission_table_pointer_full = 0x00002030,
sub_page_permission_table_pointer_high = 0x00002031,
tsc_multiplier_full = 0x00002032,
tsc_multiplier_high = 0x00002033,
tertiary_processor_based_vm_execution_controls_full = 0x00002034,
tertiary_processor_based_vm_execution_controls_high = 0x00002035,
enclv_exiting_bitmap_full = 0x00002036,
enclv_exiting_bitmap_high = 0x00002037,
// 32-bit control fields
pin_based_vm_execution_controls = 0x00004000,
primary_processor_based_vm_execution_controls = 0x00004002,
exception_bitmap = 0x00004004,
page_fault_error_code_mask = 0x00004006,
page_fault_error_code_match = 0x00004008,
cr3_target_count = 0x0000400A,
vm_exit_controls = 0x0000400C,
vm_exit_msr_store_count = 0x0000400E,
vm_exit_msr_load_count = 0x00004010,
vm_entry_controls = 0x00004012,
vm_entry_msr_load_count = 0x00004014,
vm_entry_interrupt_information_field = 0x00004016,
vm_entry_exception_error_code = 0x00004018,
vm_entry_instruction_length = 0x0000401A,
tpr_threshold = 0x0000401C,
secondary_processor_based_vm_execution_controls = 0x0000401E,
ple_gap = 0x00004020,
ple_window = 0x00004012,
// Natural-width control field
cr0_guest_host_mask = 0x00006000,
cr4_guest_host_mask = 0x00006002,
cr0_read_shadow = 0x00006004,
cr4_read_shadow = 0x00006006,
cr3_target_value_0 = 0x00006008,
cr3_target_value_1 = 0x0000600A,
cr3_target_value_2 = 0x0000600C,
cr3_target_value_3 = 0x0000600E,
// 16-bit guest state fields
guest_es_selector = 0x00000800,
guest_cs_selector = 0x00000802,
guest_ss_selector = 0x00000804,
guest_ds_selector = 0x00000806,
guest_fs_selector = 0x00000808,
guest_gs_selector = 0x0000080A,
guest_idtr_selector = 0x0000080C,
guest_tr_selector = 0x0000080E,
guest_interrupt_status = 0x00000810,
pml_index = 0x00000812,
// 64-bit guest state fields
vmcs_link_pointer_full = 0x00002800,
vmcs_link_pointer_high = 0x00002801,
guest_ia32_debugctl_full = 0x00002802,
guest_ia32_debugctl_high = 0x00002803,
guest_ia32_pat_full = 0x00002804,
guest_ia32_pat_high = 0x00002805,
guest_ia32_efer_full = 0x00002806,
guest_ia32_efer_high = 0x00002807,
guest_ia32_perf_global_ctrl_full = 0x00002808,
guest_ia32_perf_global_ctrl_high = 0x00002809,
guest_pdpte0_full = 0x0000280A,
guest_pdpte0_high = 0x0000280B,
guest_pdpte1_full = 0x0000280C,
guest_pdpte1_high = 0x0000280D,
guest_pdpte2_full = 0x0000280E,
guest_pdpte2_high = 0x0000280F,
guest_pdpte3_full = 0x00002810,
guest_pdpte3_high = 0x00002811,
guest_ia32_bndcfgs_full = 0x00002812,
guest_ia32_bndcfgs_high = 0x00002813,
guest_ia32_rtit_ctl_full = 0x00002814,
guest_ia32_rtit_ctl_high = 0x00002815,
guest_ia32_pkrs_full = 0x00002818,
guest_ia32_pkrs_high = 0x00002819,
// 32-bit guest state fields
guest_es_limit = 0x00004800,
guest_cs_limit = 0x00004802,
guest_ss_limit = 0x00004804,
guest_ds_limit = 0x00004806,
guest_fs_limit = 0x00004808,
guest_gs_limit = 0x0000480A,
guest_idtr_limit = 0x0000480C,
guest_tr_limit = 0x0000480E,
guest_gdtr_limit = 0x00004810,
guest_idtr_limit = 0x00004812,
guest_es_access_rights = 0x00004814,
guest_cs_access_rights = 0x00004816,
guest_ss_access_rights = 0x00004818,
guest_ds_access_rights = 0x0000481A,
guest_fs_access_rights = 0x0000481C,
guest_gs_access_rights = 0x0000481E,
guest_idtr_access_rights = 0x00004820,
guest_tr_access_rights = 0x00004822,
guest_interruptibility_state = 0x00004824,
guest_activity_state = 0x00004826,
guest_smbase = 0x00004828,
guest_ia32_sysenter_cs = 0x0000482A,
vmexit_preemption_timer_value = 0x0000482E,
// Natural-width guest state fields
guest_cr0 = 0x00006800,
guest_cr3 = 0x00006802,
guest_cr4 = 0x00006804,
guest_es_base = 0x00006806,
guest_cs_base = 0x00006808,
guest_ss_base = 0x0000680A,
guest_ds_base = 0x0000680C,
guest_fs_base = 0x0000680E,
guest_gs_base = 0x00006810,
guest_ldtr_base = 0x00006812,
guest_tr_base = 0x00006814,
guest_gdtr_base = 0x00006816,
guest_idtr_base = 0x00006818,
guest_dr7 = 0x0000681A,
guest_rsp = 0x0000681C,
guest_rip = 0x0000681E,
guest_rflags = 0x00006820,
guest_pending_debug_exceptions = 0x00006822,
guest_ia32_sysenter_esp = 0x00006824,
guest_ia32_sysenter_eip = 0x00006826,
guest_ia32_s_cet = 0x00006828,
guest_ia32_interrupt_ssp_table_addr = 0x0000682C,
// 16-bit host state fields
host_es_selector = 0x00000C00,
host_cs_selector = 0x00000C02,
host_ss_selector = 0x00000C04,
host_ds_selector = 0x00000C06,
host_fs_selector = 0x00000C08,
host_gs_selector = 0x00000C0A,
host_tr_selector = 0x00000C0C,
// 64-bit host state fields
host_ia32_pat_full = 0x00002C00,
host_ia32_pat_high = 0x00002C01,
host_ia32_efer_full = 0x00002C02,
host_ia32_efer_high = 0x00002C03,
host_ia32_perf_global_ctrl_full = 0x00002C04,
host_ia32_perf_global_ctrl_high = 0x00002C05,
host_ia32_pkrs_full = 0x00002C06,
host_ia32_pkrs_high = 0x00002C08,
// 32-bit host state fields
host_ia32_sysenter_cs = 0x00004C00,
// Natural-width host state fields
host_cr0 = 0x00006C00,
host_cr3 = 0x00006C02,
host_cr4 = 0x00006C04,
host_fs_base = 0x00006C06,
host_gs_base = 0x00006C08,
host_tr_base = 0x00006C0A,
host_gdtr_base = 0x00006C0C,
host_idtr_base = 0x00006C0E,
host_ia32_sysenter_esp = 0x00006C10,
host_ia32_sysenter_eip = 0x00006C12,
host_rsp = 0x00006C14,
host_rip = 0x00006C16,
host_ia32_s_cet = 0x00006C18,
host_ssp = 0x00006C1A,
host_ia32_interrupt_ssp_table_addr = 0x00006C1C,
// 64-bit read only data field
guest_physical_address_full = 0x00002400,
guest_physical_address_high = 0x00002401,
// 32-bit read only data fields
vm_instruction_error = 0x00004400,
exit_reason = 0x00004402,
vm_exit_interruption_information = 0x00004404,
vm_exit_interruption_error_code = 0x00004406,
idt_vectoring_information_field = 0x00004408,
idt_vectoring_error_code = 0x0000440A,
vm_exit_instruciton_length = 0x0000440C,
vm_exit_instruction_information = 0x0000440E,
// Natural-width read only data fields
exit_qualification = 0x00006400,
io_rcx = 0x00006402,
io_rsi = 0x00006404,
io_rdi = 0x00006406,
io_rip = 0x00006408,
guest_linear_address = 0x0000640A
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment