/* * vmcs.h: VMCS related definitions * Copyright (c) 2004, Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program; If not, see . * */ #ifndef __ASM_X86_HVM_VMX_VMCS_H__ #define __ASM_X86_HVM_VMX_VMCS_H__ #include #include extern void vmcs_dump_vcpu(struct vcpu *v); extern void setup_vmcs_dump(void); extern int vmx_cpu_up_prepare(unsigned int cpu); extern void vmx_cpu_dead(unsigned int cpu); extern int vmx_cpu_up(void); extern int _vmx_cpu_up(bool bsp); extern void vmx_cpu_down(void); struct vmcs_struct { u32 vmcs_revision_id; unsigned char data [0]; /* vmcs size is read from MSR */ }; struct vmx_msr_entry { u32 index; u32 mbz; u64 data; }; #define EPT_DEFAULT_MT MTRR_TYPE_WRBACK struct ept_data { union { struct { uint64_t mt:3, /* Memory Type. */ wl:3, /* Walk length -1. */ ad:1, /* Enable EPT A/D bits. */ :5, /* rsvd. */ mfn:52; }; u64 eptp; }; /* Set of PCPUs needing an INVEPT before a VMENTER. */ cpumask_var_t invalidate; }; #define _VMX_DOMAIN_PML_ENABLED 0 #define VMX_DOMAIN_PML_ENABLED (1ul << _VMX_DOMAIN_PML_ENABLED) struct vmx_domain { unsigned long apic_access_mfn; /* VMX_DOMAIN_* */ unsigned int status; }; /* * Layout of the MSR bitmap, as interpreted by hardware: * - *_low covers MSRs 0 to 0x1fff * - *_ligh covers MSRs 0xc0000000 to 0xc0001fff */ struct vmx_msr_bitmap { unsigned long read_low [0x2000 / BITS_PER_LONG]; unsigned long read_high [0x2000 / BITS_PER_LONG]; unsigned long write_low [0x2000 / BITS_PER_LONG]; unsigned long write_high[0x2000 / BITS_PER_LONG]; }; struct pi_desc { DECLARE_BITMAP(pir, NR_VECTORS); union { struct { u16 on : 1, /* bit 256 - Outstanding Notification */ sn : 1, /* bit 257 - Suppress Notification */ rsvd_1 : 14; /* bit 271:258 - Reserved */ u8 nv; /* bit 279:272 - Notification Vector */ u8 rsvd_2; /* bit 287:280 - Reserved */ u32 ndst; /* bit 319:288 - Notification Destination */ }; u64 control; }; u32 rsvd[6]; } __attribute__ ((aligned (64))); #define NR_PML_ENTRIES 512 struct pi_blocking_vcpu { struct list_head list; spinlock_t *lock; }; struct arch_vmx_struct { /* Physical address of VMCS. */ paddr_t vmcs_pa; /* VMCS shadow machine address. */ paddr_t vmcs_shadow_maddr; /* Protects remote usage of VMCS (VMPTRLD/VMCLEAR). */ spinlock_t vmcs_lock; /* * Activation and launch status of this VMCS. * - Activated on a CPU by VMPTRLD. Deactivated by VMCLEAR. * - Launched on active CPU by VMLAUNCH when current VMCS. */ struct list_head active_list; int active_cpu; int launched; /* Cache of cpu execution control. */ u32 exec_control; u32 secondary_exec_control; u32 exception_bitmap; uint64_t shadow_gs; uint64_t star; uint64_t lstar; uint64_t cstar; uint64_t sfmask; struct vmx_msr_bitmap *msr_bitmap; unsigned int msr_count; struct vmx_msr_entry *msr_area; unsigned int host_msr_count; struct vmx_msr_entry *host_msr_area; unsigned long eoi_exitmap_changed; DECLARE_BITMAP(eoi_exit_bitmap, NR_VECTORS); struct pi_desc pi_desc; unsigned long host_cr0; /* Do we need to tolerate a spurious EPT_MISCONFIG VM exit? */ bool_t ept_spurious_misconfig; /* Is the guest in real mode? */ uint8_t vmx_realmode; /* Are we emulating rather than VMENTERing? */ uint8_t vmx_emulate; uint8_t lbr_fixup_enabled; /* Bitmask of segments that we can't safely use in virtual 8086 mode */ uint16_t vm86_segment_mask; /* Shadow CS, SS, DS, ES, FS, GS, TR while in virtual 8086 mode */ struct segment_register vm86_saved_seg[x86_seg_tr + 1]; /* Remember EFLAGS while in virtual 8086 mode */ uint32_t vm86_saved_eflags; int hostenv_migrated; /* Bitmap to control vmexit policy for Non-root VMREAD/VMWRITE */ struct page_info *vmread_bitmap; struct page_info *vmwrite_bitmap; struct page_info *pml_pg; /* * Before it is blocked, vCPU is added to the per-cpu list. * VT-d engine can send wakeup notification event to the * pCPU and wakeup the related vCPU. */ struct pi_blocking_vcpu pi_blocking; }; int vmx_create_vmcs(struct vcpu *v); void vmx_destroy_vmcs(struct vcpu *v); void vmx_vmcs_enter(struct vcpu *v); bool_t __must_check vmx_vmcs_try_enter(struct vcpu *v); void vmx_vmcs_exit(struct vcpu *v); void vmx_vmcs_reload(struct vcpu *v); #define CPU_BASED_VIRTUAL_INTR_PENDING 0x00000004 #define CPU_BASED_USE_TSC_OFFSETING 0x00000008 #define CPU_BASED_HLT_EXITING 0x00000080 #define CPU_BASED_INVLPG_EXITING 0x00000200 #define CPU_BASED_MWAIT_EXITING 0x00000400 #define CPU_BASED_RDPMC_EXITING 0x00000800 #define CPU_BASED_RDTSC_EXITING 0x00001000 #define CPU_BASED_CR3_LOAD_EXITING 0x00008000 #define CPU_BASED_CR3_STORE_EXITING 0x00010000 #define CPU_BASED_CR8_LOAD_EXITING 0x00080000 #define CPU_BASED_CR8_STORE_EXITING 0x00100000 #define CPU_BASED_TPR_SHADOW 0x00200000 #define CPU_BASED_VIRTUAL_NMI_PENDING 0x00400000 #define CPU_BASED_MOV_DR_EXITING 0x00800000 #define CPU_BASED_UNCOND_IO_EXITING 0x01000000 #define CPU_BASED_ACTIVATE_IO_BITMAP 0x02000000 #define CPU_BASED_MONITOR_TRAP_FLAG 0x08000000 #define CPU_BASED_ACTIVATE_MSR_BITMAP 0x10000000 #define CPU_BASED_MONITOR_EXITING 0x20000000 #define CPU_BASED_PAUSE_EXITING 0x40000000 #define CPU_BASED_ACTIVATE_SECONDARY_CONTROLS 0x80000000 extern u32 vmx_cpu_based_exec_control; #define PIN_BASED_EXT_INTR_MASK 0x00000001 #define PIN_BASED_NMI_EXITING 0x00000008 #define PIN_BASED_VIRTUAL_NMIS 0x00000020 #define PIN_BASED_PREEMPT_TIMER 0x00000040 #define PIN_BASED_POSTED_INTERRUPT 0x00000080 extern u32 vmx_pin_based_exec_control; #define VM_EXIT_SAVE_DEBUG_CNTRLS 0x00000004 #define VM_EXIT_IA32E_MODE 0x00000200 #define VM_EXIT_LOAD_PERF_GLOBAL_CTRL 0x00001000 #define VM_EXIT_ACK_INTR_ON_EXIT 0x00008000 #define VM_EXIT_SAVE_GUEST_PAT 0x00040000 #define VM_EXIT_LOAD_HOST_PAT 0x00080000 #define VM_EXIT_SAVE_GUEST_EFER 0x00100000 #define VM_EXIT_LOAD_HOST_EFER 0x00200000 #define VM_EXIT_SAVE_PREEMPT_TIMER 0x00400000 #define VM_EXIT_CLEAR_BNDCFGS 0x00800000 extern u32 vmx_vmexit_control; #define VM_ENTRY_IA32E_MODE 0x00000200 #define VM_ENTRY_SMM 0x00000400 #define VM_ENTRY_DEACT_DUAL_MONITOR 0x00000800 #define VM_ENTRY_LOAD_PERF_GLOBAL_CTRL 0x00002000 #define VM_ENTRY_LOAD_GUEST_PAT 0x00004000 #define VM_ENTRY_LOAD_GUEST_EFER 0x00008000 #define VM_ENTRY_LOAD_BNDCFGS 0x00010000 extern u32 vmx_vmentry_control; #define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001 #define SECONDARY_EXEC_ENABLE_EPT 0x00000002 #define SECONDARY_EXEC_DESCRIPTOR_TABLE_EXITING 0x00000004 #define SECONDARY_EXEC_ENABLE_RDTSCP 0x00000008 #define SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE 0x00000010 #define SECONDARY_EXEC_ENABLE_VPID 0x00000020 #define SECONDARY_EXEC_WBINVD_EXITING 0x00000040 #define SECONDARY_EXEC_UNRESTRICTED_GUEST 0x00000080 #define SECONDARY_EXEC_APIC_REGISTER_VIRT 0x00000100 #define SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY 0x00000200 #define SECONDARY_EXEC_PAUSE_LOOP_EXITING 0x00000400 #define SECONDARY_EXEC_ENABLE_INVPCID 0x00001000 #define SECONDARY_EXEC_ENABLE_VM_FUNCTIONS 0x00002000 #define SECONDARY_EXEC_ENABLE_VMCS_SHADOWING 0x00004000 #define SECONDARY_EXEC_ENABLE_PML 0x00020000 #define SECONDARY_EXEC_ENABLE_VIRT_EXCEPTIONS 0x00040000 #define SECONDARY_EXEC_XSAVES 0x00100000 #define SECONDARY_EXEC_TSC_SCALING 0x02000000 extern u32 vmx_secondary_exec_control; #define VMX_EPT_EXEC_ONLY_SUPPORTED 0x00000001 #define VMX_EPT_WALK_LENGTH_4_SUPPORTED 0x00000040 #define VMX_EPT_MEMORY_TYPE_UC 0x00000100 #define VMX_EPT_MEMORY_TYPE_WB 0x00004000 #define VMX_EPT_SUPERPAGE_2MB 0x00010000 #define VMX_EPT_SUPERPAGE_1GB 0x00020000 #define VMX_EPT_INVEPT_INSTRUCTION 0x00100000 #define VMX_EPT_AD_BIT 0x00200000 #define VMX_EPT_INVEPT_SINGLE_CONTEXT 0x02000000 #define VMX_EPT_INVEPT_ALL_CONTEXT 0x04000000 #define VMX_VPID_INVVPID_INSTRUCTION 0x00100000000ULL #define VMX_VPID_INVVPID_INDIVIDUAL_ADDR 0x10000000000ULL #define VMX_VPID_INVVPID_SINGLE_CONTEXT 0x20000000000ULL #define VMX_VPID_INVVPID_ALL_CONTEXT 0x40000000000ULL #define VMX_VPID_INVVPID_SINGLE_CONTEXT_RETAINING_GLOBAL 0x80000000000ULL extern u64 vmx_ept_vpid_cap; #define VMX_MISC_CR3_TARGET 0x01ff0000 #define VMX_MISC_VMWRITE_ALL 0x20000000 #define VMX_TSC_MULTIPLIER_MAX 0xffffffffffffffffULL #define cpu_has_wbinvd_exiting \ (vmx_secondary_exec_control & SECONDARY_EXEC_WBINVD_EXITING) #define cpu_has_vmx_virtualize_apic_accesses \ (vmx_secondary_exec_control & SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES) #define cpu_has_vmx_tpr_shadow \ (vmx_cpu_based_exec_control & CPU_BASED_TPR_SHADOW) #define cpu_has_vmx_vnmi \ (vmx_pin_based_exec_control & PIN_BASED_VIRTUAL_NMIS) #define cpu_has_vmx_msr_bitmap \ (vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_MSR_BITMAP) #define cpu_has_vmx_secondary_exec_control \ (vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) #define cpu_has_vmx_ept \ (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_EPT) #define cpu_has_vmx_dt_exiting \ (vmx_secondary_exec_control & SECONDARY_EXEC_DESCRIPTOR_TABLE_EXITING) #define cpu_has_vmx_vpid \ (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_VPID) #define cpu_has_monitor_trap_flag \ (vmx_cpu_based_exec_control & CPU_BASED_MONITOR_TRAP_FLAG) #define cpu_has_vmx_pat \ (vmx_vmentry_control & VM_ENTRY_LOAD_GUEST_PAT) #define cpu_has_vmx_unrestricted_guest \ (vmx_secondary_exec_control & SECONDARY_EXEC_UNRESTRICTED_GUEST) #define vmx_unrestricted_guest(v) \ ((v)->arch.hvm_vmx.secondary_exec_control & \ SECONDARY_EXEC_UNRESTRICTED_GUEST) #define cpu_has_vmx_ple \ (vmx_secondary_exec_control & SECONDARY_EXEC_PAUSE_LOOP_EXITING) #define cpu_has_vmx_apic_reg_virt \ (vmx_secondary_exec_control & SECONDARY_EXEC_APIC_REGISTER_VIRT) #define cpu_has_vmx_virtual_intr_delivery \ (vmx_secondary_exec_control & SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY) #define cpu_has_vmx_virtualize_x2apic_mode \ (vmx_secondary_exec_control & SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE) #define cpu_has_vmx_posted_intr_processing \ (vmx_pin_based_exec_control & PIN_BASED_POSTED_INTERRUPT) #define cpu_has_vmx_vmcs_shadowing \ (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_VMCS_SHADOWING) #define cpu_has_vmx_vmfunc \ (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_VM_FUNCTIONS) #define cpu_has_vmx_virt_exceptions \ (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_VIRT_EXCEPTIONS) #define cpu_has_vmx_pml \ (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_PML) #define cpu_has_vmx_mpx \ ((vmx_vmexit_control & VM_EXIT_CLEAR_BNDCFGS) && \ (vmx_vmentry_control & VM_ENTRY_LOAD_BNDCFGS)) #define cpu_has_vmx_xsaves \ (vmx_secondary_exec_control & SECONDARY_EXEC_XSAVES) #define cpu_has_vmx_tsc_scaling \ (vmx_secondary_exec_control & SECONDARY_EXEC_TSC_SCALING) #define VMCS_RID_TYPE_MASK 0x80000000 /* GUEST_INTERRUPTIBILITY_INFO flags. */ #define VMX_INTR_SHADOW_STI 0x00000001 #define VMX_INTR_SHADOW_MOV_SS 0x00000002 #define VMX_INTR_SHADOW_SMI 0x00000004 #define VMX_INTR_SHADOW_NMI 0x00000008 #define VMX_BASIC_REVISION_MASK 0x7fffffff #define VMX_BASIC_VMCS_SIZE_MASK (0x1fffULL << 32) #define VMX_BASIC_32BIT_ADDRESSES (1ULL << 48) #define VMX_BASIC_DUAL_MONITOR (1ULL << 49) #define VMX_BASIC_MEMORY_TYPE_MASK (0xfULL << 50) #define VMX_BASIC_INS_OUT_INFO (1ULL << 54) /* * bit 55 of IA32_VMX_BASIC MSR, indicating whether any VMX controls that * default to 1 may be cleared to 0. */ #define VMX_BASIC_DEFAULT1_ZERO (1ULL << 55) extern u64 vmx_basic_msr; #define cpu_has_vmx_ins_outs_instr_info \ (!!(vmx_basic_msr & VMX_BASIC_INS_OUT_INFO)) /* Guest interrupt status */ #define VMX_GUEST_INTR_STATUS_SUBFIELD_BITMASK 0x0FF #define VMX_GUEST_INTR_STATUS_SVI_OFFSET 8 /* VMFUNC leaf definitions */ #define VMX_VMFUNC_EPTP_SWITCHING (1ULL << 0) /* VMCS field encodings. */ #define VMCS_HIGH(x) ((x) | 1) enum vmcs_field { VIRTUAL_PROCESSOR_ID = 0x00000000, POSTED_INTR_NOTIFICATION_VECTOR = 0x00000002, EPTP_INDEX = 0x00000004, #define GUEST_SEG_SELECTOR(sel) (GUEST_ES_SELECTOR + (sel) * 2) /* ES ... GS */ 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_LDTR_SELECTOR = 0x0000080c, GUEST_TR_SELECTOR = 0x0000080e, GUEST_INTR_STATUS = 0x00000810, GUEST_PML_INDEX = 0x00000812, 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, IO_BITMAP_A = 0x00002000, IO_BITMAP_B = 0x00002002, MSR_BITMAP = 0x00002004, VM_EXIT_MSR_STORE_ADDR = 0x00002006, VM_EXIT_MSR_LOAD_ADDR = 0x00002008, VM_ENTRY_MSR_LOAD_ADDR = 0x0000200a, PML_ADDRESS = 0x0000200e, TSC_OFFSET = 0x00002010, VIRTUAL_APIC_PAGE_ADDR = 0x00002012, APIC_ACCESS_ADDR = 0x00002014, PI_DESC_ADDR = 0x00002016, VM_FUNCTION_CONTROL = 0x00002018, EPT_POINTER = 0x0000201a, EOI_EXIT_BITMAP0 = 0x0000201c, #define EOI_EXIT_BITMAP(n) (EOI_EXIT_BITMAP0 + (n) * 2) /* n = 0...3 */ EPTP_LIST_ADDR = 0x00002024, VMREAD_BITMAP = 0x00002026, VMWRITE_BITMAP = 0x00002028, VIRT_EXCEPTION_INFO = 0x0000202a, XSS_EXIT_BITMAP = 0x0000202c, TSC_MULTIPLIER = 0x00002032, GUEST_PHYSICAL_ADDRESS = 0x00002400, VMCS_LINK_POINTER = 0x00002800, GUEST_IA32_DEBUGCTL = 0x00002802, GUEST_PAT = 0x00002804, GUEST_EFER = 0x00002806, GUEST_PERF_GLOBAL_CTRL = 0x00002808, GUEST_PDPTE0 = 0x0000280a, #define GUEST_PDPTE(n) (GUEST_PDPTE0 + (n) * 2) /* n = 0...3 */ GUEST_BNDCFGS = 0x00002812, HOST_PAT = 0x00002c00, HOST_EFER = 0x00002c02, HOST_PERF_GLOBAL_CTRL = 0x00002c04, PIN_BASED_VM_EXEC_CONTROL = 0x00004000, CPU_BASED_VM_EXEC_CONTROL = 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_INTR_INFO = 0x00004016, VM_ENTRY_EXCEPTION_ERROR_CODE = 0x00004018, VM_ENTRY_INSTRUCTION_LEN = 0x0000401a, TPR_THRESHOLD = 0x0000401c, SECONDARY_VM_EXEC_CONTROL = 0x0000401e, PLE_GAP = 0x00004020, PLE_WINDOW = 0x00004022, VM_INSTRUCTION_ERROR = 0x00004400, VM_EXIT_REASON = 0x00004402, VM_EXIT_INTR_INFO = 0x00004404, VM_EXIT_INTR_ERROR_CODE = 0x00004406, IDT_VECTORING_INFO = 0x00004408, IDT_VECTORING_ERROR_CODE = 0x0000440a, VM_EXIT_INSTRUCTION_LEN = 0x0000440c, VMX_INSTRUCTION_INFO = 0x0000440e, #define GUEST_SEG_LIMIT(sel) (GUEST_ES_LIMIT + (sel) * 2) /* ES ... GS */ 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_LDTR_LIMIT = 0x0000480c, GUEST_TR_LIMIT = 0x0000480e, GUEST_GDTR_LIMIT = 0x00004810, GUEST_IDTR_LIMIT = 0x00004812, #define GUEST_SEG_AR_BYTES(sel) (GUEST_ES_AR_BYTES + (sel) * 2) /* ES ... GS */ GUEST_ES_AR_BYTES = 0x00004814, GUEST_CS_AR_BYTES = 0x00004816, GUEST_SS_AR_BYTES = 0x00004818, GUEST_DS_AR_BYTES = 0x0000481a, GUEST_FS_AR_BYTES = 0x0000481c, GUEST_GS_AR_BYTES = 0x0000481e, GUEST_LDTR_AR_BYTES = 0x00004820, GUEST_TR_AR_BYTES = 0x00004822, GUEST_INTERRUPTIBILITY_INFO = 0x00004824, GUEST_ACTIVITY_STATE = 0x00004826, GUEST_SMBASE = 0x00004828, GUEST_SYSENTER_CS = 0x0000482a, GUEST_PREEMPTION_TIMER = 0x0000482e, HOST_SYSENTER_CS = 0x00004c00, CR0_GUEST_HOST_MASK = 0x00006000, CR4_GUEST_HOST_MASK = 0x00006002, CR0_READ_SHADOW = 0x00006004, CR4_READ_SHADOW = 0x00006006, CR3_TARGET_VALUE0 = 0x00006008, #define CR3_TARGET_VALUE(n) (CR3_TARGET_VALUE0 + (n) * 2) /* n < CR3_TARGET_COUNT */ EXIT_QUALIFICATION = 0x00006400, GUEST_LINEAR_ADDRESS = 0x0000640a, GUEST_CR0 = 0x00006800, GUEST_CR3 = 0x00006802, GUEST_CR4 = 0x00006804, #define GUEST_SEG_BASE(sel) (GUEST_ES_BASE + (sel) * 2) /* ES ... GS */ 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_DBG_EXCEPTIONS = 0x00006822, GUEST_SYSENTER_ESP = 0x00006824, GUEST_SYSENTER_EIP = 0x00006826, 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_SYSENTER_ESP = 0x00006c10, HOST_SYSENTER_EIP = 0x00006c12, HOST_RSP = 0x00006c14, HOST_RIP = 0x00006c16, }; #define VMCS_VPID_WIDTH 16 #define VMX_GUEST_MSR 0 #define VMX_HOST_MSR 1 /* VM Instruction error numbers */ enum vmx_insn_errno { VMX_INSN_SUCCEED = 0, VMX_INSN_VMCLEAR_INVALID_PHYADDR = 2, VMX_INSN_VMLAUNCH_NONCLEAR_VMCS = 4, VMX_INSN_VMRESUME_NONLAUNCHED_VMCS = 5, VMX_INSN_INVALID_CONTROL_STATE = 7, VMX_INSN_INVALID_HOST_STATE = 8, VMX_INSN_VMPTRLD_INVALID_PHYADDR = 9, VMX_INSN_VMPTRLD_INCORRECT_VMCS_ID = 11, VMX_INSN_UNSUPPORTED_VMCS_COMPONENT = 12, VMX_INSN_VMXON_IN_VMX_ROOT = 15, VMX_INSN_VMENTRY_BLOCKED_BY_MOV_SS = 26, VMX_INSN_FAIL_INVALID = ~0, }; enum vmx_msr_intercept_type { VMX_MSR_R = 1, VMX_MSR_W = 2, VMX_MSR_RW = VMX_MSR_R | VMX_MSR_W, }; void vmx_clear_msr_intercept(struct vcpu *v, unsigned int msr, enum vmx_msr_intercept_type type); void vmx_set_msr_intercept(struct vcpu *v, unsigned int msr, enum vmx_msr_intercept_type type); int vmx_read_guest_msr(u32 msr, u64 *val); int vmx_write_guest_msr(u32 msr, u64 val); struct vmx_msr_entry *vmx_find_msr(u32 msr, int type); int vmx_add_msr(u32 msr, int type); void vmx_vmcs_switch(paddr_t from, paddr_t to); void vmx_set_eoi_exit_bitmap(struct vcpu *v, u8 vector); void vmx_clear_eoi_exit_bitmap(struct vcpu *v, u8 vector); bool vmx_msr_is_intercepted(struct vmx_msr_bitmap *msr_bitmap, unsigned int msr, bool is_write) __nonnull(1); void virtual_vmcs_enter(const struct vcpu *); void virtual_vmcs_exit(const struct vcpu *); u64 virtual_vmcs_vmread(const struct vcpu *, u32 encoding); enum vmx_insn_errno virtual_vmcs_vmread_safe(const struct vcpu *v, u32 vmcs_encoding, u64 *val); void virtual_vmcs_vmwrite(const struct vcpu *, u32 encoding, u64 val); enum vmx_insn_errno virtual_vmcs_vmwrite_safe(const struct vcpu *v, u32 vmcs_encoding, u64 val); static inline int vmx_add_guest_msr(u32 msr) { return vmx_add_msr(msr, VMX_GUEST_MSR); } static inline int vmx_add_host_load_msr(u32 msr) { return vmx_add_msr(msr, VMX_HOST_MSR); } DECLARE_PER_CPU(bool_t, vmxon); bool_t vmx_vcpu_pml_enabled(const struct vcpu *v); int vmx_vcpu_enable_pml(struct vcpu *v); void vmx_vcpu_disable_pml(struct vcpu *v); void vmx_vcpu_flush_pml_buffer(struct vcpu *v); bool_t vmx_domain_pml_enabled(const struct domain *d); int vmx_domain_enable_pml(struct domain *d); void vmx_domain_disable_pml(struct domain *d); void vmx_domain_flush_pml_buffers(struct domain *d); void vmx_domain_update_eptp(struct domain *d); #endif /* ASM_X86_HVM_VMX_VMCS_H__ */ /* * Local variables: * mode: C * c-file-style: "BSD" * c-basic-offset: 4 * tab-width: 4 * indent-tabs-mode: nil * End: */