# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 9b77ba29108d9e0ad4fcae90d9df51888d8d1244
# Parent 71d000e59b134dd5abcdac060c3c8a3ac6163d9a
The VMCS control bits in the current tree are not optimal. Attached is
a patch to improve the VMCS control bits setting. It also adds checks to
detect any non-optimal or incompatible settings for the VMCS control
bits based on MSRs, and fixes a bug associated with vmcs region freeing.
Signed-off-by: Nitin A Kamble <nitin.a.kamble@xxxxxxxxx>
Signed-off-by: Jun Nakajima <jun.nakajima@xxxxxxxxx>
Signed-off-by: Xin Li <xin.b.li@xxxxxxxxx>
diff -r 71d000e59b13 -r 9b77ba29108d xen/include/asm-x86/vmx.h
--- a/xen/include/asm-x86/vmx.h Thu Jul 14 08:00:35 2005
+++ b/xen/include/asm-x86/vmx.h Thu Jul 14 08:00:55 2005
@@ -46,32 +46,61 @@
#define MONITOR_PIN_BASED_EXEC_CONTROLS_RESERVED_VALUE 0x00000016
#define MONITOR_PIN_BASED_EXEC_CONTROLS \
+ ( \
MONITOR_PIN_BASED_EXEC_CONTROLS_RESERVED_VALUE | \
PIN_BASED_EXT_INTR_MASK | \
- PIN_BASED_NMI_EXITING
+ PIN_BASED_NMI_EXITING \
+ )
#define MONITOR_CPU_BASED_EXEC_CONTROLS_RESERVED_VALUE 0x0401e172
-#define MONITOR_CPU_BASED_EXEC_CONTROLS \
+#define _MONITOR_CPU_BASED_EXEC_CONTROLS \
+ ( \
MONITOR_CPU_BASED_EXEC_CONTROLS_RESERVED_VALUE | \
CPU_BASED_HLT_EXITING | \
CPU_BASED_INVDPG_EXITING | \
CPU_BASED_MWAIT_EXITING | \
CPU_BASED_MOV_DR_EXITING | \
- CPU_BASED_UNCOND_IO_EXITING | \
+ CPU_BASED_UNCOND_IO_EXITING \
+ )
+
+#define MONITOR_CPU_BASED_EXEC_CONTROLS_IA32E_MODE \
+ ( \
CPU_BASED_CR8_LOAD_EXITING | \
- CPU_BASED_CR8_STORE_EXITING
-
-#define MONITOR_VM_EXIT_CONTROLS_RESERVED_VALUE 0x0003edff
-
-#define VM_EXIT_CONTROLS_IA_32E_MODE 0x00000200
-
-#define MONITOR_VM_EXIT_CONTROLS \
+ CPU_BASED_CR8_STORE_EXITING \
+ )
+
+#define MONITOR_VM_EXIT_CONTROLS_RESERVED_VALUE 0x0003edff
+
+#define MONITOR_VM_EXIT_CONTROLS_IA32E_MODE 0x00000200
+
+#define _MONITOR_VM_EXIT_CONTROLS \
+ ( \
MONITOR_VM_EXIT_CONTROLS_RESERVED_VALUE |\
- VM_EXIT_ACK_INTR_ON_EXIT
+ VM_EXIT_ACK_INTR_ON_EXIT \
+ )
+
+#if defined (__x86_64__)
+#define MONITOR_CPU_BASED_EXEC_CONTROLS \
+ ( \
+ _MONITOR_CPU_BASED_EXEC_CONTROLS | \
+ MONITOR_CPU_BASED_EXEC_CONTROLS_IA32E_MODE \
+ )
+#define MONITOR_VM_EXIT_CONTROLS \
+ ( \
+ _MONITOR_VM_EXIT_CONTROLS | \
+ MONITOR_VM_EXIT_CONTROLS_IA32E_MODE \
+ )
+#else
+#define MONITOR_CPU_BASED_EXEC_CONTROLS \
+ _MONITOR_CPU_BASED_EXEC_CONTROLS
+
+#define MONITOR_VM_EXIT_CONTROLS \
+ _MONITOR_VM_EXIT_CONTROLS
+#endif
#define VM_ENTRY_CONTROLS_RESERVED_VALUE 0x000011ff
-#define VM_ENTRY_CONTROLS_IA_32E_MODE 0x00000200
+#define VM_ENTRY_CONTROLS_IA32E_MODE 0x00000200
#define MONITOR_VM_ENTRY_CONTROLS VM_ENTRY_CONTROLS_RESERVED_VALUE
/*
* Exit Reasons
diff -r 71d000e59b13 -r 9b77ba29108d xen/arch/x86/vmx.c
--- a/xen/arch/x86/vmx.c Thu Jul 14 08:00:35 2005
+++ b/xen/arch/x86/vmx.c Thu Jul 14 08:00:55 2005
@@ -262,6 +262,20 @@
extern long do_block(void);
void do_nmi(struct cpu_user_regs *, unsigned long);
+static int check_vmx_controls(ctrls, msr)
+{
+ u32 vmx_msr_low, vmx_msr_high;
+
+ rdmsr(msr, vmx_msr_low, vmx_msr_high);
+ if (ctrls < vmx_msr_low || ctrls > vmx_msr_high) {
+ printk("Insufficient VMX capability 0x%x, "
+ "msr=0x%x,low=0x%8x,high=0x%x\n",
+ ctrls, msr, vmx_msr_low, vmx_msr_high);
+ return 0;
+ }
+ return 1;
+}
+
int start_vmx(void)
{
struct vmcs_struct *vmcs;
@@ -291,6 +305,19 @@
IA32_FEATURE_CONTROL_MSR_LOCK |
IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON, 0);
}
+
+ if (!check_vmx_controls(MONITOR_PIN_BASED_EXEC_CONTROLS,
+ MSR_IA32_VMX_PINBASED_CTLS_MSR))
+ return 0;
+ if (!check_vmx_controls(MONITOR_CPU_BASED_EXEC_CONTROLS,
+ MSR_IA32_VMX_PROCBASED_CTLS_MSR))
+ return 0;
+ if (!check_vmx_controls(MONITOR_VM_EXIT_CONTROLS,
+ MSR_IA32_VMX_EXIT_CTLS_MSR))
+ return 0;
+ if (!check_vmx_controls(MONITOR_VM_ENTRY_CONTROLS,
+ MSR_IA32_VMX_ENTRY_CTLS_MSR))
+ return 0;
set_in_cr4(X86_CR4_VMXE); /* Enable VMXE */
@@ -965,7 +992,7 @@
set_bit(VMX_CPU_STATE_LMA_ENABLED,
&d->arch.arch_vmx.cpu_state);
__vmread(VM_ENTRY_CONTROLS, &vm_entry_value);
- vm_entry_value |= VM_ENTRY_CONTROLS_IA_32E_MODE;
+ vm_entry_value |= VM_ENTRY_CONTROLS_IA32E_MODE;
__vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
#if CONFIG_PAGING_LEVELS >= 4
@@ -1028,7 +1055,7 @@
clear_bit(VMX_CPU_STATE_LMA_ENABLED,
&d->arch.arch_vmx.cpu_state);
__vmread(VM_ENTRY_CONTROLS, &vm_entry_value);
- vm_entry_value &= ~VM_ENTRY_CONTROLS_IA_32E_MODE;
+ vm_entry_value &= ~VM_ENTRY_CONTROLS_IA32E_MODE;
__vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
}
}
diff -r 71d000e59b13 -r 9b77ba29108d xen/arch/x86/vmx_vmcs.c
--- a/xen/arch/x86/vmx_vmcs.c Thu Jul 14 08:00:35 2005
+++ b/xen/arch/x86/vmx_vmcs.c Thu Jul 14 08:00:55 2005
@@ -55,25 +55,22 @@
{
int order;
- order = (vmcs_size >> PAGE_SHIFT) - 1;
+ order = get_order(vmcs_size);
free_xenheap_pages(vmcs, order);
}
static inline int construct_vmcs_controls(void)
{
int error = 0;
-
+
error |= __vmwrite(PIN_BASED_VM_EXEC_CONTROL,
MONITOR_PIN_BASED_EXEC_CONTROLS);
error |= __vmwrite(CPU_BASED_VM_EXEC_CONTROL,
MONITOR_CPU_BASED_EXEC_CONTROLS);
-#if defined (__x86_64__)
- error |= __vmwrite(VM_EXIT_CONTROLS,
- MONITOR_VM_EXIT_CONTROLS | VM_EXIT_CONTROLS_IA_32E_MODE);
-#else
+
error |= __vmwrite(VM_EXIT_CONTROLS, MONITOR_VM_EXIT_CONTROLS);
-#endif
+
error |= __vmwrite(VM_ENTRY_CONTROLS, MONITOR_VM_ENTRY_CONTROLS);
return error;
diff -r 71d000e59b13 -r 9b77ba29108d xen/include/asm-x86/msr.h
--- a/xen/include/asm-x86/msr.h Thu Jul 14 08:00:35 2005
+++ b/xen/include/asm-x86/msr.h Thu Jul 14 08:00:55 2005
@@ -94,6 +94,11 @@
/* MSRs & bits used for VMX enabling */
#define MSR_IA32_VMX_BASIC_MSR 0x480
+#define MSR_IA32_VMX_PINBASED_CTLS_MSR 0x481
+#define MSR_IA32_VMX_PROCBASED_CTLS_MSR 0x482
+#define MSR_IA32_VMX_EXIT_CTLS_MSR 0x483
+#define MSR_IA32_VMX_ENTRY_CTLS_MSR 0x484
+#define MSR_IA32_VMX_MISC_MSR 0x485
#define IA32_FEATURE_CONTROL_MSR 0x3a
#define IA32_FEATURE_CONTROL_MSR_LOCK 0x1
#define IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON 0x4
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|