Bochs/bochs/cpu/vmx.h
Stanislav Shwartsman 2f3c7ff8e4 implemented SMAP (Supervisor Mode Access Protection) from [Intel Architecture Instruction Set Extensions Programming Reference] rev14
fixed enabling of ADX extensions in generic CPUID when enabled through .bochsrc

Small code cleanups on the way to implementation of APIC Registers Virtualization features disclosed in recent Intel SDM rev043
2012-09-10 15:22:26 +00:00

1013 lines
39 KiB
C
Raw Blame History

/////////////////////////////////////////////////////////////////////////
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2009-2012 Stanislav Shwartsman
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA B 02110-1301 USA
//
/////////////////////////////////////////////////////////////////////////
#ifndef _BX_VMX_INTEL_H_
#define _BX_VMX_INTEL_H_
#define VMX_VMCS_AREA_SIZE 4096
#define VMX_VMCS_REVISION_ID 0x10 /* better to be uniq bochs VMCS revision id */
// VMCS pointer is always 64-bit variable
#define BX_INVALID_VMCSPTR BX_CONST64(0xFFFFFFFFFFFFFFFF)
// bits supported in IA32_FEATURE_CONTROL MSR
#define BX_IA32_FEATURE_CONTROL_LOCK_BIT 0x1
#define BX_IA32_FEATURE_CONTROL_VMX_ENABLE_BIT 0x4
#define BX_IA32_FEATURE_CONTROL_BITS \
(BX_IA32_FEATURE_CONTROL_LOCK_BIT | BX_IA32_FEATURE_CONTROL_VMX_ENABLE_BIT)
// VMX error codes
enum VMX_error_code {
VMXERR_NO_ERROR = 0,
VMXERR_VMCALL_IN_VMX_ROOT_OPERATION = 1,
VMXERR_VMCLEAR_WITH_INVALID_ADDR = 2,
VMXERR_VMCLEAR_WITH_VMXON_VMCS_PTR = 3,
VMXERR_VMLAUNCH_NON_CLEAR_VMCS = 4,
VMXERR_VMRESUME_NON_LAUNCHED_VMCS = 5,
VMXERR_VMRESUME_VMCS_CORRUPTED = 6,
VMXERR_VMENTRY_INVALID_VM_CONTROL_FIELD = 7,
VMXERR_VMENTRY_INVALID_VM_HOST_STATE_FIELD = 8,
VMXERR_VMPTRLD_INVALID_PHYSICAL_ADDRESS = 9,
VMXERR_VMPTRLD_WITH_VMXON_PTR = 10,
VMXERR_VMPTRLD_INCORRECT_VMCS_REVISION_ID = 11,
VMXERR_UNSUPPORTED_VMCS_COMPONENT_ACCESS = 12,
VMXERR_VMWRITE_READ_ONLY_VMCS_COMPONENT = 13,
VMXERR_RESERVED14 = 14,
VMXERR_VMXON_IN_VMX_ROOT_OPERATION = 15,
VMXERR_VMENTRY_INVALID_EXECUTIVE_VMCS = 16,
VMXERR_VMENTRY_NON_LAUNCHED_EXECUTIVE_VMCS = 17,
VMXERR_VMENTRY_NOT_VMXON_EXECUTIVE_VMCS = 18,
VMXERR_VMCALL_NON_CLEAR_VMCS = 19,
VMXERR_VMCALL_INVALID_VMEXIT_FIELD = 20,
VMXERR_RESERVED21 = 21,
VMXERR_VMCALL_INVALID_MSEG_REVISION_ID = 22,
VMXERR_VMXOFF_WITH_CONFIGURED_SMM_MONITOR = 23,
VMXERR_VMCALL_WITH_INVALID_SMM_MONITOR_FEATURES = 24,
VMXERR_VMENTRY_INVALID_VM_CONTROL_FIELD_IN_EXECUTIVE_VMCS = 25,
VMXERR_VMENTRY_MOV_SS_BLOCKING = 26,
VMXERR_RESERVED27 = 27,
VMXERR_INVALID_INVEPT_INVVPID = 28
};
enum VMX_vmexit_reason {
VMX_VMEXIT_EXCEPTION_NMI = 0,
VMX_VMEXIT_EXTERNAL_INTERRUPT = 1,
VMX_VMEXIT_TRIPLE_FAULT = 2,
VMX_VMEXIT_INIT = 3,
VMX_VMEXIT_SIPI = 4,
VMX_VMEXIT_IO_SMI = 5,
VMX_VMEXIT_SMI = 6,
VMX_VMEXIT_INTERRUPT_WINDOW = 7,
VMX_VMEXIT_NMI_WINDOW = 8,
VMX_VMEXIT_TASK_SWITCH = 9,
VMX_VMEXIT_CPUID = 10,
VMX_VMEXIT_GETSEC = 11,
VMX_VMEXIT_HLT = 12,
VMX_VMEXIT_INVD = 13,
VMX_VMEXIT_INVLPG = 14,
VMX_VMEXIT_RDPMC = 15,
VMX_VMEXIT_RDTSC = 16,
VMX_VMEXIT_RSM = 17,
VMX_VMEXIT_VMCALL = 18,
VMX_VMEXIT_VMCLEAR = 19,
VMX_VMEXIT_VMLAUNCH = 20,
VMX_VMEXIT_VMPTRLD = 21,
VMX_VMEXIT_VMPTRST = 22,
VMX_VMEXIT_VMREAD = 23,
VMX_VMEXIT_VMRESUME = 24,
VMX_VMEXIT_VMWRITE = 25,
VMX_VMEXIT_VMXOFF = 26,
VMX_VMEXIT_VMXON = 27,
VMX_VMEXIT_CR_ACCESS = 28,
VMX_VMEXIT_DR_ACCESS = 29,
VMX_VMEXIT_IO_INSTRUCTION = 30,
VMX_VMEXIT_RDMSR = 31,
VMX_VMEXIT_WRMSR = 32,
VMX_VMEXIT_VMENTRY_FAILURE_GUEST_STATE = 33,
VMX_VMEXIT_VMENTRY_FAILURE_MSR = 34,
VMX_VMEXIT_RESERVED35 = 35,
VMX_VMEXIT_MWAIT = 36,
VMX_VMEXIT_MONITOR_TRAP_FLAG = 37,
VMX_VMEXIT_RESERVED38 = 38,
VMX_VMEXIT_MONITOR = 39,
VMX_VMEXIT_PAUSE = 40,
VMX_VMEXIT_VMENTRY_FAILURE_MCA = 41, // will never happen in Bochs
VMX_VMEXIT_RESERVED42 = 42,
VMX_VMEXIT_TPR_THRESHOLD = 43,
VMX_VMEXIT_APIC_ACCESS = 44,
VMX_VMEXIT_VIRTUALIZED_EOI = 45,
VMX_VMEXIT_GDTR_IDTR_ACCESS = 46,
VMX_VMEXIT_LDTR_TR_ACCESS = 47,
VMX_VMEXIT_EPT_VIOLATION = 48,
VMX_VMEXIT_EPT_MISCONFIGURATION = 49,
VMX_VMEXIT_INVEPT = 50,
VMX_VMEXIT_RDTSCP = 51,
VMX_VMEXIT_VMX_PREEMPTION_TIMER_EXPIRED = 52,
VMX_VMEXIT_INVVPID = 53,
VMX_VMEXIT_WBINVD = 54,
VMX_VMEXIT_XSETBV = 55,
VMX_VMEXIT_APIC_WRITE = 56,
VMX_VMEXIT_RDRAND = 57,
VMX_VMEXIT_INVPCID = 58,
VMX_VMEXIT_VMFUNC = 59,
VMX_VMEXIT_RESERVED60 = 60,
VMX_VMEXIT_RDSEED = 61
};
// VMexit on CR register access
enum {
VMX_VMEXIT_CR_ACCESS_CR_WRITE = 0,
VMX_VMEXIT_CR_ACCESS_CR_READ,
VMX_VMEXIT_CR_ACCESS_CLTS,
VMX_VMEXIT_CR_ACCESS_LMSW
};
// VMENTRY error on loading guest state qualification
enum VMX_vmentry_error {
VMENTER_ERR_NO_ERROR = 0,
VMENTER_ERR_GUEST_STATE_PDPTR_LOADING = 2,
VMENTER_ERR_GUEST_STATE_INJECT_NMI_BLOCKING_EVENTS = 3,
VMENTER_ERR_GUEST_STATE_LINK_POINTER = 4
};
// VMABORT error code
enum VMX_vmabort_code {
VMABORT_SAVING_GUEST_MSRS_FAILURE,
VMABORT_HOST_PDPTR_CORRUPTED,
VMABORT_VMEXIT_VMCS_CORRUPTED,
VMABORT_LOADING_HOST_MSRS,
VMABORT_VMEXIT_MACHINE_CHECK_ERROR
};
// VMX APIC ACCESS VMEXIT qualification
#define VMX_APIC_READ_INSTRUCTION_EXECUTION 0x0000
#define VMX_APIC_WRITE_INSTRUCTION_EXECUTION 0x1000
#define VMX_APIC_INSTRUCTION_FETCH 0x2000 /* won't happen because cpu::prefetch will crash */
#define VMX_APIC_ACCESS_DURING_EVENT_DELIVERY 0x3000
// VM Functions List
enum VMFunctions {
VMX_VMFUNC_EPTP_SWITCHING = 0
};
#define VMX_VMFUNC_EPTP_SWITCHING_MASK (BX_CONST64(1) << VMX_VMFUNC_EPTP_SWITCHING)
// =============
// VMCS fields
// =============
/* VMCS 16-bit control fields */
/* binary 0000_00xx_xxxx_xxx0 */
#define VMCS_16BIT_CONTROL_VPID 0x00000000 /* VPID */
#define VMCS_16BIT_CONTROL_POSTED_INTERRUPT_VECTOR 0x00000002 /* Posted Interrupts */
/* VMCS 16-bit guest-state fields */
/* binary 0000_10xx_xxxx_xxx0 */
#define VMCS_16BIT_GUEST_ES_SELECTOR 0x00000800
#define VMCS_16BIT_GUEST_CS_SELECTOR 0x00000802
#define VMCS_16BIT_GUEST_SS_SELECTOR 0x00000804
#define VMCS_16BIT_GUEST_DS_SELECTOR 0x00000806
#define VMCS_16BIT_GUEST_FS_SELECTOR 0x00000808
#define VMCS_16BIT_GUEST_GS_SELECTOR 0x0000080A
#define VMCS_16BIT_GUEST_LDTR_SELECTOR 0x0000080C
#define VMCS_16BIT_GUEST_TR_SELECTOR 0x0000080E
#define VMCS_16BIT_GUEST_INTERRUPT_STATUS 0x00000810 /* Virtual Interrupt Delivery */
/* VMCS 16-bit host-state fields */
/* binary 0000_11xx_xxxx_xxx0 */
#define VMCS_16BIT_HOST_ES_SELECTOR 0x00000C00
#define VMCS_16BIT_HOST_CS_SELECTOR 0x00000C02
#define VMCS_16BIT_HOST_SS_SELECTOR 0x00000C04
#define VMCS_16BIT_HOST_DS_SELECTOR 0x00000C06
#define VMCS_16BIT_HOST_FS_SELECTOR 0x00000C08
#define VMCS_16BIT_HOST_GS_SELECTOR 0x00000C0A
#define VMCS_16BIT_HOST_TR_SELECTOR 0x00000C0C
/* VMCS 64-bit control fields */
/* binary 0010_00xx_xxxx_xxx0 */
#define VMCS_64BIT_CONTROL_IO_BITMAP_A 0x00002000
#define VMCS_64BIT_CONTROL_IO_BITMAP_A_HI 0x00002001
#define VMCS_64BIT_CONTROL_IO_BITMAP_B 0x00002002
#define VMCS_64BIT_CONTROL_IO_BITMAP_B_HI 0x00002003
#define VMCS_64BIT_CONTROL_MSR_BITMAPS 0x00002004
#define VMCS_64BIT_CONTROL_MSR_BITMAPS_HI 0x00002005
#define VMCS_64BIT_CONTROL_VMEXIT_MSR_STORE_ADDR 0x00002006
#define VMCS_64BIT_CONTROL_VMEXIT_MSR_STORE_ADDR_HI 0x00002007
#define VMCS_64BIT_CONTROL_VMEXIT_MSR_LOAD_ADDR 0x00002008
#define VMCS_64BIT_CONTROL_VMEXIT_MSR_LOAD_ADDR_HI 0x00002009
#define VMCS_64BIT_CONTROL_VMENTRY_MSR_LOAD_ADDR 0x0000200A
#define VMCS_64BIT_CONTROL_VMENTRY_MSR_LOAD_ADDR_HI 0x0000200B
#define VMCS_64BIT_CONTROL_EXECUTIVE_VMCS_PTR 0x0000200C
#define VMCS_64BIT_CONTROL_EXECUTIVE_VMCS_PTR_HI 0x0000200D
#define VMCS_64BIT_CONTROL_TSC_OFFSET 0x00002010
#define VMCS_64BIT_CONTROL_TSC_OFFSET_HI 0x00002011
#define VMCS_64BIT_CONTROL_VIRTUAL_APIC_PAGE_ADDR 0x00002012 /* TPR shadow */
#define VMCS_64BIT_CONTROL_VIRTUAL_APIC_PAGE_ADDR_HI 0x00002013
#define VMCS_64BIT_CONTROL_APIC_ACCESS_ADDR 0x00002014 /* APIC virtualization */
#define VMCS_64BIT_CONTROL_APIC_ACCESS_ADDR_HI 0x00002015
#define VMCS_64BIT_CONTROL_POSTED_INTERRUPT_DESC_ADDR 0x00002016 /* Posted Interrupts */
#define VMCS_64BIT_CONTROL_POSTED_INTERRUPT_DESC_ADDR_HI 0x00002017
#define VMCS_64BIT_CONTROL_VMFUNC_CTRLS 0x00002018 /* VM Functions */
#define VMCS_64BIT_CONTROL_VMFUNC_CTRLS_HI 0x00002019
#define VMCS_64BIT_CONTROL_EPTPTR 0x0000201A /* EPT */
#define VMCS_64BIT_CONTROL_EPTPTR_HI 0x0000201B
#define VMCS_64BIT_CONTROL_EOI_EXIT_BITMAP0 0x0000201C /* Virtual Interrupt Delivery */
#define VMCS_64BIT_CONTROL_EOI_EXIT_BITMAP0_HI 0x0000201D
#define VMCS_64BIT_CONTROL_EOI_EXIT_BITMAP1 0x0000201E
#define VMCS_64BIT_CONTROL_EOI_EXIT_BITMAP1_HI 0x0000201F
#define VMCS_64BIT_CONTROL_EOI_EXIT_BITMAP2 0x00002020
#define VMCS_64BIT_CONTROL_EOI_EXIT_BITMAP2_HI 0x00002021
#define VMCS_64BIT_CONTROL_EOI_EXIT_BITMAP3 0x00002022
#define VMCS_64BIT_CONTROL_EOI_EXIT_BITMAP3_HI 0x00002023
#define VMCS_64BIT_CONTROL_EPTP_LIST_ADDRESS 0x00002024 /* VM Functions - EPTP switching */
#define VMCS_64BIT_CONTROL_EPTP_LIST_ADDRESS_HI 0x00002025
/* VMCS 64-bit read only data fields */
/* binary 0010_01xx_xxxx_xxx0 */
#define VMCS_64BIT_GUEST_PHYSICAL_ADDR 0x00002400 /* EPT */
#define VMCS_64BIT_GUEST_PHYSICAL_ADDR_HI 0x00002401
/* VMCS 64-bit guest state fields */
/* binary 0010_10xx_xxxx_xxx0 */
#define VMCS_64BIT_GUEST_LINK_POINTER 0x00002800
#define VMCS_64BIT_GUEST_LINK_POINTER_HI 0x00002801
#define VMCS_64BIT_GUEST_IA32_DEBUGCTL 0x00002802
#define VMCS_64BIT_GUEST_IA32_DEBUGCTL_HI 0x00002803
#define VMCS_64BIT_GUEST_IA32_PAT 0x00002804 /* PAT */
#define VMCS_64BIT_GUEST_IA32_PAT_HI 0x00002805
#define VMCS_64BIT_GUEST_IA32_EFER 0x00002806 /* EFER */
#define VMCS_64BIT_GUEST_IA32_EFER_HI 0x00002807
#define VMCS_64BIT_GUEST_IA32_PERF_GLOBAL_CTRL 0x00002808 /* Perf Global Ctrl */
#define VMCS_64BIT_GUEST_IA32_PERF_GLOBAL_CTRL_HI 0x00002809
#define VMCS_64BIT_GUEST_IA32_PDPTE0 0x0000280A /* EPT */
#define VMCS_64BIT_GUEST_IA32_PDPTE0_HI 0x0000280B
#define VMCS_64BIT_GUEST_IA32_PDPTE1 0x0000280C
#define VMCS_64BIT_GUEST_IA32_PDPTE1_HI 0x0000280D
#define VMCS_64BIT_GUEST_IA32_PDPTE2 0x0000280E
#define VMCS_64BIT_GUEST_IA32_PDPTE2_HI 0x0000280F
#define VMCS_64BIT_GUEST_IA32_PDPTE3 0x00002810
#define VMCS_64BIT_GUEST_IA32_PDPTE3_HI 0x00002811
/* VMCS 64-bit host state fields */
/* binary 0010_11xx_xxxx_xxx0 */
#define VMCS_64BIT_HOST_IA32_PAT 0x00002C00 /* PAT */
#define VMCS_64BIT_HOST_IA32_PAT_HI 0x00002C01
#define VMCS_64BIT_HOST_IA32_EFER 0x00002C02 /* EFER */
#define VMCS_64BIT_HOST_IA32_EFER_HI 0x00002C03
#define VMCS_64BIT_HOST_IA32_PERF_GLOBAL_CTRL 0x00002C04 /* Perf Global Ctrl */
#define VMCS_64BIT_HOST_IA32_PERF_GLOBAL_CTRL_HI 0x00002C05
/* VMCS 32_bit control fields */
/* binary 0100_00xx_xxxx_xxx0 */
#define VMCS_32BIT_CONTROL_PIN_BASED_EXEC_CONTROLS 0x00004000
#define VMCS_32BIT_CONTROL_PROCESSOR_BASED_VMEXEC_CONTROLS 0x00004002
#define VMCS_32BIT_CONTROL_EXECUTION_BITMAP 0x00004004
#define VMCS_32BIT_CONTROL_PAGE_FAULT_ERR_CODE_MASK 0x00004006
#define VMCS_32BIT_CONTROL_PAGE_FAULT_ERR_CODE_MATCH 0x00004008
#define VMCS_32BIT_CONTROL_CR3_TARGET_COUNT 0x0000400A
#define VMCS_32BIT_CONTROL_VMEXIT_CONTROLS 0x0000400C
#define VMCS_32BIT_CONTROL_VMEXIT_MSR_STORE_COUNT 0x0000400E
#define VMCS_32BIT_CONTROL_VMEXIT_MSR_LOAD_COUNT 0x00004010
#define VMCS_32BIT_CONTROL_VMENTRY_CONTROLS 0x00004012
#define VMCS_32BIT_CONTROL_VMENTRY_MSR_LOAD_COUNT 0x00004014
#define VMCS_32BIT_CONTROL_VMENTRY_INTERRUPTION_INFO 0x00004016
#define VMCS_32BIT_CONTROL_VMENTRY_EXCEPTION_ERR_CODE 0x00004018
#define VMCS_32BIT_CONTROL_VMENTRY_INSTRUCTION_LENGTH 0x0000401A
#define VMCS_32BIT_CONTROL_TPR_THRESHOLD 0x0000401C /* TPR shadow */
#define VMCS_32BIT_CONTROL_SECONDARY_VMEXEC_CONTROLS 0x0000401E
#define VMCS_32BIT_CONTROL_PAUSE_LOOP_EXITING_GAP 0x00004020 /* PAUSE loop exiting */
#define VMCS_32BIT_CONTROL_PAUSE_LOOP_EXITING_WINDOW 0x00004022 /* PAUSE loop exiting */
/* VMCS 32-bit read only data fields */
/* binary 0100_01xx_xxxx_xxx0 */
#define VMCS_32BIT_INSTRUCTION_ERROR 0x00004400
#define VMCS_32BIT_VMEXIT_REASON 0x00004402
#define VMCS_32BIT_VMEXIT_INTERRUPTION_INFO 0x00004404
#define VMCS_32BIT_VMEXIT_INTERRUPTION_ERR_CODE 0x00004406
#define VMCS_32BIT_IDT_VECTORING_INFO 0x00004408
#define VMCS_32BIT_IDT_VECTORING_ERR_CODE 0x0000440A
#define VMCS_32BIT_VMEXIT_INSTRUCTION_LENGTH 0x0000440C
#define VMCS_32BIT_VMEXIT_INSTRUCTION_INFO 0x0000440E
/* VMCS 32-bit guest-state fields */
/* binary 0100_10xx_xxxx_xxx0 */
#define VMCS_32BIT_GUEST_ES_LIMIT 0x00004800
#define VMCS_32BIT_GUEST_CS_LIMIT 0x00004802
#define VMCS_32BIT_GUEST_SS_LIMIT 0x00004804
#define VMCS_32BIT_GUEST_DS_LIMIT 0x00004806
#define VMCS_32BIT_GUEST_FS_LIMIT 0x00004808
#define VMCS_32BIT_GUEST_GS_LIMIT 0x0000480A
#define VMCS_32BIT_GUEST_LDTR_LIMIT 0x0000480C
#define VMCS_32BIT_GUEST_TR_LIMIT 0x0000480E
#define VMCS_32BIT_GUEST_GDTR_LIMIT 0x00004810
#define VMCS_32BIT_GUEST_IDTR_LIMIT 0x00004812
#define VMCS_32BIT_GUEST_ES_ACCESS_RIGHTS 0x00004814
#define VMCS_32BIT_GUEST_CS_ACCESS_RIGHTS 0x00004816
#define VMCS_32BIT_GUEST_SS_ACCESS_RIGHTS 0x00004818
#define VMCS_32BIT_GUEST_DS_ACCESS_RIGHTS 0x0000481A
#define VMCS_32BIT_GUEST_FS_ACCESS_RIGHTS 0x0000481C
#define VMCS_32BIT_GUEST_GS_ACCESS_RIGHTS 0x0000481E
#define VMCS_32BIT_GUEST_LDTR_ACCESS_RIGHTS 0x00004820
#define VMCS_32BIT_GUEST_TR_ACCESS_RIGHTS 0x00004822
#define VMCS_32BIT_GUEST_INTERRUPTIBILITY_STATE 0x00004824
#define VMCS_32BIT_GUEST_ACTIVITY_STATE 0x00004826
#define VMCS_32BIT_GUEST_SMBASE 0x00004828
#define VMCS_32BIT_GUEST_IA32_SYSENTER_CS_MSR 0x0000482A
#define VMCS_32BIT_GUEST_PREEMPTION_TIMER_VALUE 0x0000482E /* VMX preemption timer */
/* VMCS 32-bit host-state fields */
/* binary 0100_11xx_xxxx_xxx0 */
#define VMCS_32BIT_HOST_IA32_SYSENTER_CS_MSR 0x00004C00
/* VMCS natural width control fields */
/* binary 0110_00xx_xxxx_xxx0 */
#define VMCS_CONTROL_CR0_GUEST_HOST_MASK 0x00006000
#define VMCS_CONTROL_CR4_GUEST_HOST_MASK 0x00006002
#define VMCS_CONTROL_CR0_READ_SHADOW 0x00006004
#define VMCS_CONTROL_CR4_READ_SHADOW 0x00006006
#define VMCS_CR3_TARGET0 0x00006008
#define VMCS_CR3_TARGET1 0x0000600A
#define VMCS_CR3_TARGET2 0x0000600C
#define VMCS_CR3_TARGET3 0x0000600E
/* VMCS natural width read only data fields */
/* binary 0110_01xx_xxxx_xxx0 */
#define VMCS_VMEXIT_QUALIFICATION 0x00006400
#define VMCS_IO_RCX 0x00006402
#define VMCS_IO_RSI 0x00006404
#define VMCS_IO_RDI 0x00006406
#define VMCS_IO_RIP 0x00006408
#define VMCS_GUEST_LINEAR_ADDR 0x0000640A
/* VMCS natural width guest state fields */
/* binary 0110_10xx_xxxx_xxx0 */
#define VMCS_GUEST_CR0 0x00006800
#define VMCS_GUEST_CR3 0x00006802
#define VMCS_GUEST_CR4 0x00006804
#define VMCS_GUEST_ES_BASE 0x00006806
#define VMCS_GUEST_CS_BASE 0x00006808
#define VMCS_GUEST_SS_BASE 0x0000680A
#define VMCS_GUEST_DS_BASE 0x0000680C
#define VMCS_GUEST_FS_BASE 0x0000680E
#define VMCS_GUEST_GS_BASE 0x00006810
#define VMCS_GUEST_LDTR_BASE 0x00006812
#define VMCS_GUEST_TR_BASE 0x00006814
#define VMCS_GUEST_GDTR_BASE 0x00006816
#define VMCS_GUEST_IDTR_BASE 0x00006818
#define VMCS_GUEST_DR7 0x0000681A
#define VMCS_GUEST_RSP 0x0000681C
#define VMCS_GUEST_RIP 0x0000681E
#define VMCS_GUEST_RFLAGS 0x00006820
#define VMCS_GUEST_PENDING_DBG_EXCEPTIONS 0x00006822
#define VMCS_GUEST_IA32_SYSENTER_ESP_MSR 0x00006824
#define VMCS_GUEST_IA32_SYSENTER_EIP_MSR 0x00006826
/* VMCS natural width host state fields */
/* binary 0110_11xx_xxxx_xxx0 */
#define VMCS_HOST_CR0 0x00006C00
#define VMCS_HOST_CR3 0x00006C02
#define VMCS_HOST_CR4 0x00006C04
#define VMCS_HOST_FS_BASE 0x00006C06
#define VMCS_HOST_GS_BASE 0x00006C08
#define VMCS_HOST_TR_BASE 0x00006C0A
#define VMCS_HOST_GDTR_BASE 0x00006C0C
#define VMCS_HOST_IDTR_BASE 0x00006C0E
#define VMCS_HOST_IA32_SYSENTER_ESP_MSR 0x00006C10
#define VMCS_HOST_IA32_SYSENTER_EIP_MSR 0x00006C12
#define VMCS_HOST_RSP 0x00006C14
#define VMCS_HOST_RIP 0x00006C16
#define VMX_HIGHEST_VMCS_ENCODING (0x30)
// ===============================
// VMCS fields encoding/decoding
// ===============================
// extract VMCS field using its encoding
#define VMCS_FIELD(encoding) ((encoding) & 0x3ff)
// check if the VMCS field encoding corresponding to HI part of 64-bit value
#define IS_VMCS_FIELD_HI(encoding) ((encoding) & 1)
// bits 11:10 of VMCS field encoding indicate field's type
#define VMCS_FIELD_TYPE(encoding) (((encoding) >> 10) & 3)
#define VMCS_FIELD_TYPE_CONTROL 0x0
#define VMCS_FIELD_TYPE_READ_ONLY 0x1
#define VMCS_FIELD_TYPE_GUEST_STATE 0x2
#define VMCS_FIELD_TYPE_HOST_STATE 0x3
// bits 14:13 of VMCS field encoding indicate field's width
#define VMCS_FIELD_WIDTH(encoding) (((encoding) >> 13) & 3)
#define VMCS_FIELD_WIDTH_16BIT 0x0
#define VMCS_FIELD_WIDTH_64BIT 0x1
#define VMCS_FIELD_WIDTH_32BIT 0x2
#define VMCS_FIELD_WIDTH_NATURAL_WIDTH 0x3
#define VMCS_FIELD_INDEX(encoding) \
((VMCS_FIELD_WIDTH(encoding) << 2) + VMCS_FIELD_TYPE(encoding))
// =============
// VMCS layout
// =============
#define VMCS_REVISION_ID_FIELD_ADDR (0x0000)
#define VMCS_VMX_ABORT_FIELD_ADDR (0x0004)
#define VMCS_LAUNCH_STATE_FIELD_ADDR (0x0008)
// invent Bochs CPU VMCS layout - allocate 64 fields of each type
#define VMCS_DATA_OFFSET (0x0010)
#if ((VMCS_DATA_OFFSET + 4*(64*15 + VMX_HIGHEST_VMCS_ENCODING)) > VMX_VMCS_AREA_SIZE)
#error "VMCS area size exceeded !"
#endif
// =============
// VMCS state
// =============
enum VMX_state {
VMCS_STATE_CLEAR = 0,
VMCS_STATE_LAUNCHED
};
// ================
// VMCS structure
// ================
typedef struct bx_VMCS_GUEST_STATE
{
bx_address cr0;
bx_address cr3;
bx_address cr4;
bx_address dr7;
bx_address rip;
bx_address rsp;
bx_address rflags;
bx_segment_reg_t sregs[6];
bx_global_segment_reg_t gdtr;
bx_global_segment_reg_t idtr;
bx_segment_reg_t ldtr;
bx_segment_reg_t tr;
Bit64u ia32_debugctl_msr;
bx_address sysenter_esp_msr;
bx_address sysenter_eip_msr;
Bit32u sysenter_cs_msr;
Bit32u smbase;
Bit32u activity_state;
Bit32u interruptibility_state;
Bit32u tmpDR6;
Bit64u link_pointer;
#if BX_SUPPORT_VMX >= 2
#if BX_SUPPORT_X86_64
Bit64u efer_msr;
#endif
Bit64u pat_msr;
Bit64u pdptr[4];
#endif
} VMCS_GUEST_STATE;
typedef struct bx_VMCS_HOST_STATE
{
bx_address cr0;
bx_address cr3;
bx_address cr4;
Bit16u segreg_selector[6];
bx_address fs_base;
bx_address gs_base;
bx_address gdtr_base;
bx_address idtr_base;
Bit32u tr_selector;
bx_address tr_base;
bx_address rsp;
bx_address rip;
bx_address sysenter_esp_msr;
bx_address sysenter_eip_msr;
Bit32u sysenter_cs_msr;
#if BX_SUPPORT_VMX >= 2
#if BX_SUPPORT_X86_64
Bit64u efer_msr;
#endif
Bit64u pat_msr;
#endif
} VMCS_HOST_STATE;
typedef struct bx_VMX_Cap
{
//
// VMX Capabilities
//
Bit32u vmx_pin_vmexec_ctrl_supported_bits;
Bit32u vmx_proc_vmexec_ctrl_supported_bits;
Bit32u vmx_vmexec_ctrl2_supported_bits;
Bit32u vmx_vmexit_ctrl_supported_bits;
Bit32u vmx_vmentry_ctrl_supported_bits;
#if BX_SUPPORT_VMX >= 2
Bit64u vmx_ept_vpid_cap_supported_bits;
Bit64u vmx_vmfunc_supported_bits;
#endif
} VMX_CAP;
typedef struct bx_VMCS
{
//
// VM-Execution Control Fields
//
#define VMX_VM_EXEC_CTRL1_EXTERNAL_INTERRUPT_VMEXIT (1 << 0)
#define VMX_VM_EXEC_CTRL1_NMI_VMEXIT (1 << 3)
#define VMX_VM_EXEC_CTRL1_VIRTUAL_NMI (1 << 5) /* Virtual NMI */
#define VMX_VM_EXEC_CTRL1_VMX_PREEMPTION_TIMER_VMEXIT (1 << 6) /* VMX preemption timer */
#define VMX_VM_EXEC_CTRL1_PROCESS_POSTED_INTERRUPTS (1 << 7) /* Posted Interrupts */
#define VMX_VM_EXEC_CTRL1_SUPPORTED_BITS \
(BX_CPU_THIS_PTR vmx_cap.vmx_pin_vmexec_ctrl_supported_bits)
Bit32u vmexec_ctrls1;
#define VMX_VM_EXEC_CTRL2_INTERRUPT_WINDOW_VMEXIT (1 << 2)
#define VMX_VM_EXEC_CTRL2_TSC_OFFSET (1 << 3)
#define VMX_VM_EXEC_CTRL2_HLT_VMEXIT (1 << 7)
#define VMX_VM_EXEC_CTRL2_INVLPG_VMEXIT (1 << 9)
#define VMX_VM_EXEC_CTRL2_MWAIT_VMEXIT (1 << 10)
#define VMX_VM_EXEC_CTRL2_RDPMC_VMEXIT (1 << 11)
#define VMX_VM_EXEC_CTRL2_RDTSC_VMEXIT (1 << 12)
#define VMX_VM_EXEC_CTRL2_CR3_WRITE_VMEXIT (1 << 15) /* legacy must be '1 */
#define VMX_VM_EXEC_CTRL2_CR3_READ_VMEXIT (1 << 16) /* legacy must be '1 */
#define VMX_VM_EXEC_CTRL2_CR8_WRITE_VMEXIT (1 << 19) /* TPR shadow */
#define VMX_VM_EXEC_CTRL2_CR8_READ_VMEXIT (1 << 20) /* TPR shadow */
#define VMX_VM_EXEC_CTRL2_TPR_SHADOW (1 << 21) /* TPR shadow */
#define VMX_VM_EXEC_CTRL2_NMI_WINDOW_VMEXIT (1 << 22) /* Virtual NMI */
#define VMX_VM_EXEC_CTRL2_DRx_ACCESS_VMEXIT (1 << 23)
#define VMX_VM_EXEC_CTRL2_IO_VMEXIT (1 << 24)
#define VMX_VM_EXEC_CTRL2_IO_BITMAPS (1 << 25)
#define VMX_VM_EXEC_CTRL2_MONITOR_TRAP_FLAG (1 << 27) /* Monitor Trap Flag */
#define VMX_VM_EXEC_CTRL2_MSR_BITMAPS (1 << 28)
#define VMX_VM_EXEC_CTRL2_MONITOR_VMEXIT (1 << 29)
#define VMX_VM_EXEC_CTRL2_PAUSE_VMEXIT (1 << 30)
#define VMX_VM_EXEC_CTRL2_SECONDARY_CONTROLS (1 << 31)
#define VMX_VM_EXEC_CTRL2_SUPPORTED_BITS \
(BX_CPU_THIS_PTR vmx_cap.vmx_proc_vmexec_ctrl_supported_bits)
Bit32u vmexec_ctrls2;
#define VMX_VM_EXEC_CTRL3_VIRTUALIZE_APIC_ACCESSES (1 << 0) /* APIC virtualization */
#define VMX_VM_EXEC_CTRL3_EPT_ENABLE (1 << 1) /* EPT */
#define VMX_VM_EXEC_CTRL3_DESCRIPTOR_TABLE_VMEXIT (1 << 2) /* Descriptor Table VMEXIT */
#define VMX_VM_EXEC_CTRL3_RDTSCP (1 << 3)
#define VMX_VM_EXEC_CTRL3_VIRTUALIZE_X2APIC_MODE (1 << 4) /* Virtualize X2APIC */
#define VMX_VM_EXEC_CTRL3_VPID_ENABLE (1 << 5) /* VPID */
#define VMX_VM_EXEC_CTRL3_WBINVD_VMEXIT (1 << 6) /* WBINVD VMEXIT */
#define VMX_VM_EXEC_CTRL3_UNRESTRICTED_GUEST (1 << 7) /* Unrestricted Guest */
#define VMX_VM_EXEC_CTRL3_VIRTUALIZE_APIC_REGISTERS (1 << 8)
#define VMX_VM_EXEC_CTRL3_VIRTUAL_INT_DELIVERY (1 << 9)
#define VMX_VM_EXEC_CTRL3_PAUSE_LOOP_VMEXIT (1 << 10) /* PAUSE loop exiting */
#define VMX_VM_EXEC_CTRL3_RDRAND_VMEXIT (1 << 11)
#define VMX_VM_EXEC_CTRL3_INVPCID (1 << 12)
#define VMX_VM_EXEC_CTRL3_VMFUNC_ENABLE (1 << 13) /* VM Functions */
#define VMX_VM_EXEC_CTRL3_RDSEED_VMEXIT (1 << 16)
#define VMX_VM_EXEC_CTRL3_SUPPORTED_BITS \
(BX_CPU_THIS_PTR vmx_cap.vmx_vmexec_ctrl2_supported_bits)
Bit32u vmexec_ctrls3;
Bit32u vm_exceptions_bitmap;
Bit32u vm_pf_mask;
Bit32u vm_pf_match;
Bit64u io_bitmap_addr[2];
Bit64u tsc_offset;
bx_phy_address msr_bitmap_addr;
bx_address vm_cr0_mask;
bx_address vm_cr0_read_shadow;
bx_address vm_cr4_mask;
bx_address vm_cr4_read_shadow;
#define VMX_CR3_TARGET_MAX_CNT 4
Bit32u vm_cr3_target_cnt;
bx_address vm_cr3_target_value[VMX_CR3_TARGET_MAX_CNT];
#if BX_SUPPORT_X86_64
bx_phy_address virtual_apic_page_addr;
Bit32u vm_tpr_threshold;
bx_phy_address apic_access_page;
#endif
#if BX_SUPPORT_VMX >= 2
Bit64u eptptr;
Bit16u vpid;
#endif
Bit64u executive_vmcsptr;
#if BX_SUPPORT_VMX >= 2
// used for pause loop exiting
Bit32u pause_loop_exiting_gap;
Bit32u pause_loop_exiting_window;
Bit64u last_pause_time;
Bit32u first_pause_time;
#endif
//
// VM-Exit Control Fields
//
#define VMX_VMEXIT_CTRL1_SAVE_DBG_CTRLS (1 << 2) /* legacy must be '1 */
#define VMX_VMEXIT_CTRL1_HOST_ADDR_SPACE_SIZE (1 << 9)
#define VMX_VMEXIT_CTRL1_LOAD_PERF_GLOBAL_CTRL_MSR (1 << 12) /* Perf Global Control */
#define VMX_VMEXIT_CTRL1_INTA_ON_VMEXIT (1 << 15)
#define VMX_VMEXIT_CTRL1_STORE_PAT_MSR (1 << 18) /* PAT */
#define VMX_VMEXIT_CTRL1_LOAD_PAT_MSR (1 << 19) /* PAT */
#define VMX_VMEXIT_CTRL1_STORE_EFER_MSR (1 << 20) /* EFER */
#define VMX_VMEXIT_CTRL1_LOAD_EFER_MSR (1 << 21) /* EFER */
#define VMX_VMEXIT_CTRL1_STORE_VMX_PREEMPTION_TIMER (1 << 22) /* VMX preemption timer */
#define VMX_VMEXIT_CTRL1_SUPPORTED_BITS \
(BX_CPU_THIS_PTR vmx_cap.vmx_vmexit_ctrl_supported_bits)
Bit32u vmexit_ctrls;
Bit32u vmexit_msr_store_cnt;
bx_phy_address vmexit_msr_store_addr;
Bit32u vmexit_msr_load_cnt;
bx_phy_address vmexit_msr_load_addr;
//
// VM-Entry Control Fields
//
#define VMX_VMENTRY_CTRL1_LOAD_DBG_CTRLS (1 << 2) /* legacy must be '1 */
#define VMX_VMENTRY_CTRL1_X86_64_GUEST (1 << 9)
#define VMX_VMENTRY_CTRL1_SMM_ENTER (1 << 10)
#define VMX_VMENTRY_CTRL1_DEACTIVATE_DUAL_MONITOR_TREATMENT (1 << 11)
#define VMX_VMENTRY_CTRL1_LOAD_PERF_GLOBAL_CTRL_MSR (1 << 13) /* Perf Global Ctrl */
#define VMX_VMENTRY_CTRL1_LOAD_PAT_MSR (1 << 14) /* PAT */
#define VMX_VMENTRY_CTRL1_LOAD_EFER_MSR (1 << 15) /* EFER */
#define VMX_VMENTRY_CTRL1_SUPPORTED_BITS \
(BX_CPU_THIS_PTR vmx_cap.vmx_vmentry_ctrl_supported_bits)
Bit32u vmentry_ctrls;
Bit32u vmentry_msr_load_cnt;
bx_phy_address vmentry_msr_load_addr;
Bit32u vmentry_interr_info;
Bit32u vmentry_excep_err_code;
Bit32u vmentry_instr_length;
//
// VM Functions
//
#if BX_SUPPORT_VMX >= 2
#define VMX_VMFUNC_CTRL1_SUPPORTED_BITS \
(BX_CPU_THIS_PTR vmx_cap.vmx_vmfunc_supported_bits)
Bit64u vmfunc_ctrls;
Bit64u eptp_list_address;
#endif
//
// VMCS Hidden and Read-Only Fields
//
Bit32u idt_vector_info;
Bit32u idt_vector_error_code;
//
// VMCS Host State
//
VMCS_HOST_STATE host_state;
} VMCS_CACHE;
enum VMX_Activity_State {
BX_VMX_ACTIVE_STATE = 0,
BX_VMX_STATE_HLT,
BX_VMX_STATE_SHUTDOWN,
BX_VMX_STATE_WAIT_FOR_SIPI,
BX_VMX_LAST_ACTIVITY_STATE
};
#define PIN_VMEXIT(ctrl) (BX_CPU_THIS_PTR vmcs.vmexec_ctrls1 & (ctrl))
#define VMEXIT(ctrl) (BX_CPU_THIS_PTR vmcs.vmexec_ctrls2 & (ctrl))
#define SECONDARY_VMEXEC_CONTROL(ctrl) (BX_CPU_THIS_PTR vmcs.vmexec_ctrls3 & (ctrl))
#define BX_VMX_INTERRUPTS_BLOCKED_BY_STI (1 << 0)
#define BX_VMX_INTERRUPTS_BLOCKED_BY_MOV_SS (1 << 1)
#define BX_VMX_INTERRUPTS_BLOCKED_SMI_BLOCKED (1 << 2)
#define BX_VMX_INTERRUPTS_BLOCKED_NMI_BLOCKED (1 << 3)
#define BX_VMX_INTERRUPTIBILITY_STATE_MASK \
(BX_VMX_INTERRUPTS_BLOCKED_BY_STI | BX_VMX_INTERRUPTS_BLOCKED_BY_MOV_SS | \
BX_VMX_INTERRUPTS_BLOCKED_SMI_BLOCKED | \
BX_VMX_INTERRUPTS_BLOCKED_NMI_BLOCKED)
//
// IA32_VMX_BASIC MSR (0x480)
// --------------
//
// 31:00 32-bit VMCS revision id
// 32:47 VMCS region size, 0 <= size <= 4096
// 48:48 use 32-bit physical address, set when x86_64 disabled
// 49:49 support of dual-monitor treatment of SMI and SMM
// 53:50 memory type used for VMCS access
// 54:54 logical processor reports information in the VM-exit
// instruction-information field on VM exits due to
// execution of INS/OUTS
// 55:55 set if any VMX controls that default to `1 may be
// cleared to `0, also indicates that IA32_VMX_TRUE_PINBASED_CTLS,
// IA32_VMX_TRUE_PROCBASED_CTLS, IA32_VMX_TRUE_EXIT_CTLS and
// IA32_VMX_TRUE_ENTRY_CTLS MSRs are supported.
// 56:63 reserved, must be zero
//
#define VMX_MSR_VMX_BASIC_LO (VMX_VMCS_REVISION_ID)
#define VMX_MSR_VMX_BASIC_HI \
(VMX_VMCS_AREA_SIZE | ((!bx_cpuid_support_x86_64()) << 16) | \
(BX_MEMTYPE_WB << 18) | (1<<22)) | ((BX_SUPPORT_VMX >= 2) ? (1<<23) : 0)
#define VMX_MSR_VMX_BASIC \
((((Bit64u) VMX_MSR_VMX_BASIC_HI) << 32) | VMX_MSR_VMX_BASIC_LO)
// ------------------------------------------------------------------------
// reserved bit (must be '1) settings for VMX MSRs
// ------------------------------------------------------------------------
// -----------------------------------------
// 3322|2222|2222|1111|1111|11 | |
// 1098|7654|3210|9876|5432|1098|7654|3210
// -----------------------------------------
// ----.----.----.----.----.----.---1.-11- MSR (0x481) IA32_MSR_VMX_PINBASED_CTRLS
// ----.-1--.----.---1.111-.---1.-111.--1- MSR (0x482) IA32_MSR_VMX_PROCBASED_CTRLS
// ----.----.----.--11.-11-.11-1.1111.1111 MSR (0x483) IA32_MSR_VMX_VMEXIT_CTRLS
// ----.----.----.----.---1.---1.1111.1111 MSR (0x484) IA32_MSR_VMX_VMENTRY_CTRLS
//
// IA32_MSR_VMX_PINBASED_CTRLS MSR (0x481)
// ---------------------------
// Bits 1, 2 and 4 must be '1
// Allowed 0-settings: VMentry fail if a bit is '0 in pin-based vmexec controls
// but set to '1 in this MSR
#define VMX_MSR_VMX_PINBASED_CTRLS_LO (0x00000016)
// Allowed 1-settings: VMentry fail if a bit is '1 in pin-based vmexec controls
// but set to '0 in this MSR.
#define VMX_MSR_VMX_PINBASED_CTRLS_HI \
(VMX_VM_EXEC_CTRL1_SUPPORTED_BITS | VMX_MSR_VMX_PINBASED_CTRLS_LO)
#define VMX_MSR_VMX_PINBASED_CTRLS \
((((Bit64u) VMX_MSR_VMX_PINBASED_CTRLS_HI) << 32) | VMX_MSR_VMX_PINBASED_CTRLS_LO)
// IA32_MSR_VMX_TRUE_PINBASED_CTRLS MSR (0x48d)
// --------------------------------
// no changes from original IA32_MSR_VMX_PINBASED_CTRLS
#define VMX_MSR_VMX_TRUE_PINBASED_CTRLS_LO (VMX_MSR_VMX_PINBASED_CTRLS_LO)
#define VMX_MSR_VMX_TRUE_PINBASED_CTRLS_HI (VMX_MSR_VMX_PINBASED_CTRLS_HI)
#define VMX_MSR_VMX_TRUE_PINBASED_CTRLS \
((((Bit64u) VMX_MSR_VMX_TRUE_PINBASED_CTRLS_HI) << 32) | VMX_MSR_VMX_TRUE_PINBASED_CTRLS_LO)
// IA32_MSR_VMX_PROCBASED_CTRLS MSR (0x482)
// ----------------------------
// Bits 1, 4-6, 8, 13-16, 26 must be '1
// Bits 0, 17, 18 must be '0
// Bits 19-21 also must be '0 when x86-64 is not supported
// Allowed 0-settings (must be '1 bits)
#define VMX_MSR_VMX_PROCBASED_CTRLS_LO (0x0401E172)
// Allowed 1-settings
#define VMX_MSR_VMX_PROCBASED_CTRLS_HI \
(VMX_VM_EXEC_CTRL2_SUPPORTED_BITS | VMX_MSR_VMX_PROCBASED_CTRLS_LO)
#define VMX_MSR_VMX_PROCBASED_CTRLS \
((((Bit64u) VMX_MSR_VMX_PROCBASED_CTRLS_HI) << 32) | VMX_MSR_VMX_PROCBASED_CTRLS_LO)
// IA32_MSR_VMX_TRUE_PROCBASED_CTRLS MSR (0x48e)
// ---------------------------------
// Bits 15 and 16 no longer must be '1
#define VMX_MSR_VMX_TRUE_PROCBASED_CTRLS_LO (0x04006172)
#define VMX_MSR_VMX_TRUE_PROCBASED_CTRLS_HI (VMX_MSR_VMX_PROCBASED_CTRLS_HI)
#define VMX_MSR_VMX_TRUE_PROCBASED_CTRLS \
((((Bit64u) VMX_MSR_VMX_TRUE_PROCBASED_CTRLS_HI) << 32) | VMX_MSR_VMX_TRUE_PROCBASED_CTRLS_LO)
// IA32_MSR_VMX_VMEXIT_CTRLS MSR (0x483)
// -------------------------
// Bits 0-8, 10, 11, 13, 14, 16, 17 must be '1
// Allowed 0-settings (must be '1 bits)
#define VMX_MSR_VMX_VMEXIT_CTRLS_LO (0x00036DFF)
// Allowed 1-settings
#define VMX_MSR_VMX_VMEXIT_CTRLS_HI \
(VMX_VMEXIT_CTRL1_SUPPORTED_BITS | VMX_MSR_VMX_VMEXIT_CTRLS_LO)
#define VMX_MSR_VMX_VMEXIT_CTRLS \
((((Bit64u) VMX_MSR_VMX_VMEXIT_CTRLS_HI) << 32) | VMX_MSR_VMX_VMEXIT_CTRLS_LO)
// IA32_MSR_VMX_TRUE_VMEXIT_CTRLS MSR (0x48f)
// ------------------------------
// Bit 2 no longer must be '1
#define VMX_MSR_VMX_TRUE_VMEXIT_CTRLS_LO (0x00036DFB)
#define VMX_MSR_VMX_TRUE_VMEXIT_CTRLS_HI (VMX_MSR_VMX_VMEXIT_CTRLS_HI)
#define VMX_MSR_VMX_TRUE_VMEXIT_CTRLS \
((((Bit64u) VMX_MSR_VMX_TRUE_VMEXIT_CTRLS_HI) << 32) | VMX_MSR_VMX_TRUE_VMEXIT_CTRLS_LO)
// IA32_MSR_VMX_VMENTRY_CTRLS MSR (0x484)
// --------------------------
// Bits 0-8, 12 must be '1
// Allowed 0-settings (must be '1 bits)
#define VMX_MSR_VMX_VMENTRY_CTRLS_LO (0x000011FF)
// Allowed 1-settings
#define VMX_MSR_VMX_VMENTRY_CTRLS_HI \
(VMX_VMENTRY_CTRL1_SUPPORTED_BITS | VMX_MSR_VMX_VMENTRY_CTRLS_LO)
#define VMX_MSR_VMX_VMENTRY_CTRLS \
((((Bit64u) VMX_MSR_VMX_VMENTRY_CTRLS_HI) << 32) | VMX_MSR_VMX_VMENTRY_CTRLS_LO)
// IA32_MSR_VMX_TRUE_VMENTRY_CTRLS MSR (0x490)
// -------------------------------
// Bit 2 is longer must be '1
#define VMX_MSR_VMX_TRUE_VMENTRY_CTRLS_LO (0x000011FB)
#define VMX_MSR_VMX_TRUE_VMENTRY_CTRLS_HI (VMX_MSR_VMX_VMENTRY_CTRLS_HI)
#define VMX_MSR_VMX_TRUE_VMENTRY_CTRLS \
((((Bit64u) VMX_MSR_VMX_TRUE_VMENTRY_CTRLS_HI) << 32) | VMX_MSR_VMX_TRUE_VMENTRY_CTRLS_LO)
// IA32_MSR_VMX_MISC MSR (0x485)
// -----------------
// [4:0] - TSC:VMX_PREEMPTION_TIMER ratio
// [5] - VMEXITs store the value of EFER.LMA into the <20>x86-64 guest"
// VMENTRY control (must set to '1 if 'unrestricted guest' is supported)
// [6] - support VMENTER to HLT state
// [7] - support VMENTER to SHUTDOWN state
// [8] - support VMENTER to WAIT_FOR_SIPI state
// [24:16] - number of CR3 target values supported
// [27:25] - (N+1)*512 - recommended maximum MSRs in MSR store list
// [28] - MSR_IA32_SMM_MONITOR_CTL[2] enable
// [31-29] - Reserved
// [63:32] - MSEG revision ID used by processor
#if BX_SUPPORT_VMX >= 2
#define VMX_MISC_STORE_LMA_TO_X86_64_GUEST_VMENTRY_CONTROL (1<<5)
#else
#define VMX_MISC_STORE_LMA_TO_X86_64_GUEST_VMENTRY_CONTROL (0)
#endif
//Rate to increase VMX preemtion timer
#define VMX_MISC_PREEMPTION_TIMER_RATE (0)
#define VMX_MSR_MISC ((VMX_CR3_TARGET_MAX_CNT << 16) | \
VMX_MISC_STORE_LMA_TO_X86_64_GUEST_VMENTRY_CONTROL | \
VMX_MISC_PREEMPTION_TIMER_RATE)
//
// IA32_VMX_CR0_FIXED0 MSR (0x486) IA32_VMX_CR0_FIXED1 MSR (0x487)
// ------------------- -------------------
// allowed 0-setting in CR0 in VMX mode
// bits PE(0), NE(5) and PG(31) required to be set in CR0 to enter VMX mode
#define VMX_MSR_CR0_FIXED0_LO (0x80000021)
#define VMX_MSR_CR0_FIXED0_HI (0x00000000)
#define VMX_MSR_CR0_FIXED0 \
((((Bit64u) VMX_MSR_CR0_FIXED0_HI) << 32) | VMX_MSR_CR0_FIXED0_LO)
// allowed 1-setting in CR0 in VMX mode
#define VMX_MSR_CR0_FIXED1_LO (0xFFFFFFFF)
#define VMX_MSR_CR0_FIXED1_HI (0x00000000)
#define VMX_MSR_CR0_FIXED1 \
((((Bit64u) VMX_MSR_CR0_FIXED1_HI) << 32) | VMX_MSR_CR0_FIXED1_LO)
//
// IA32_VMX_CR4_FIXED0 MSR (0x488) IA32_VMX_CR4_FIXED1 MSR (0x489)
// ------------------- -------------------
// allowed 0-setting in CR0 in VMX mode
// bit VMXE(13) required to be set in CR4 to enter VMX mode
#define VMX_MSR_CR4_FIXED0_LO (0x00002000)
#define VMX_MSR_CR4_FIXED0_HI (0x00000000)
#define VMX_MSR_CR4_FIXED0 \
((((Bit64u) VMX_MSR_CR4_FIXED0_HI) << 32) | VMX_MSR_CR4_FIXED0_LO)
// allowed 1-setting in CR0 in VMX mode
#define VMX_MSR_CR4_FIXED1_LO (BX_CPU_THIS_PTR cr4_suppmask)
#define VMX_MSR_CR4_FIXED1_HI (0)
#define VMX_MSR_CR4_FIXED1 \
((((Bit64u) VMX_MSR_CR4_FIXED1_HI) << 32) | VMX_MSR_CR4_FIXED1_LO)
//
// IA32_VMX_VMCS_ENUM MSR (0x48a)
// ------------------
//
// 09:01 highest index value used for any VMCS encoding
// 63:10 reserved, must be zero
//
#define VMX_MSR_VMCS_ENUM_LO (VMX_HIGHEST_VMCS_ENCODING)
#define VMX_MSR_VMCS_ENUM_HI (0x00000000)
#define VMX_MSR_VMCS_ENUM \
((((Bit64u) VMX_MSR_VMCS_ENUM_HI) << 32) | VMX_MSR_VMCS_ENUM_LO)
// IA32_VMX_MSR_PROCBASED_CTRLS2 MSR (0x48b)
// -----------------------------
// Allowed 0-settings (must be '1 bits)
#define VMX_MSR_VMX_PROCBASED_CTRLS2_LO (0x00000000)
// Allowed 1-settings
#define VMX_MSR_VMX_PROCBASED_CTRLS2_HI \
(VMX_VM_EXEC_CTRL3_SUPPORTED_BITS | VMX_MSR_VMX_PROCBASED_CTRLS2_LO)
#define VMX_MSR_VMX_PROCBASED_CTRLS2 \
((((Bit64u) VMX_MSR_VMX_PROCBASED_CTRLS2_HI) << 32) | VMX_MSR_VMX_PROCBASED_CTRLS2_LO)
#if BX_SUPPORT_VMX >= 2
// IA32_VMX_EPT_VPID_CAP MSR (0x48c)
// ---------------------
enum VMX_INVEPT_INVVPID_type {
BX_INVEPT_INVVPID_INDIVIDUAL_ADDRESS_INVALIDATION = 0,
BX_INVEPT_INVVPID_SINGLE_CONTEXT_INVALIDATION,
BX_INVEPT_INVVPID_ALL_CONTEXT_INVALIDATION,
BX_INVEPT_INVVPID_SINGLE_CONTEXT_NON_GLOBAL_INVALIDATION
};
#define VMX_MSR_VMX_EPT_VPID_CAP \
(BX_CPU_THIS_PTR vmx_cap.vmx_ept_vpid_cap_supported_bits)
#define BX_VMX_EPT_ACCESS_DIRTY_ENABLED (BX_CPU_THIS_PTR vmcs.eptptr & 0x40)
#endif
#endif // _BX_VMX_INTEL_H_