83 lines
2.6 KiB
Diff
83 lines
2.6 KiB
Diff
|
# Commit 190b667ac20e8175758f4a3a0f13c4d990e6af7e
|
||
|
# Date 2013-10-04 12:28:14 +0200
|
||
|
# Author Yang Zhang <yang.z.zhang@Intel.com>
|
||
|
# Committer Jan Beulich <jbeulich@suse.com>
|
||
|
Nested VMX: check VMX capability before read VMX related MSRs
|
||
|
|
||
|
VMX MSRs only available when the CPU support the VMX feature. In addition,
|
||
|
VMX_TRUE* MSRs only available when bit 55 of VMX_BASIC MSR is set.
|
||
|
|
||
|
Signed-off-by: Yang Zhang <yang.z.zhang@Intel.com>
|
||
|
|
||
|
Cleanup.
|
||
|
|
||
|
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||
|
Acked-by: Jun Nakajima <jun.nakajima@intel.com>
|
||
|
|
||
|
--- a/xen/arch/x86/hvm/vmx/vmcs.c
|
||
|
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
|
||
|
@@ -78,6 +78,7 @@ static DEFINE_PER_CPU(struct list_head,
|
||
|
static DEFINE_PER_CPU(bool_t, vmxon);
|
||
|
|
||
|
static u32 vmcs_revision_id __read_mostly;
|
||
|
+u64 __read_mostly vmx_basic_msr;
|
||
|
|
||
|
static void __init vmx_display_features(void)
|
||
|
{
|
||
|
@@ -301,6 +302,8 @@ static int vmx_init_vmcs_config(void)
|
||
|
vmx_vmexit_control = _vmx_vmexit_control;
|
||
|
vmx_vmentry_control = _vmx_vmentry_control;
|
||
|
cpu_has_vmx_ins_outs_instr_info = !!(vmx_basic_msr_high & (1U<<22));
|
||
|
+ vmx_basic_msr = ((u64)vmx_basic_msr_high << 32) |
|
||
|
+ vmx_basic_msr_low;
|
||
|
vmx_display_features();
|
||
|
}
|
||
|
else
|
||
|
--- a/xen/arch/x86/hvm/vmx/vvmx.c
|
||
|
+++ b/xen/arch/x86/hvm/vmx/vvmx.c
|
||
|
@@ -1814,12 +1814,33 @@ int nvmx_handle_invvpid(struct cpu_user_
|
||
|
int nvmx_msr_read_intercept(unsigned int msr, u64 *msr_content)
|
||
|
{
|
||
|
struct vcpu *v = current;
|
||
|
+ unsigned int ecx, dummy;
|
||
|
u64 data = 0, host_data = 0;
|
||
|
int r = 1;
|
||
|
|
||
|
if ( !nestedhvm_enabled(v->domain) )
|
||
|
return 0;
|
||
|
|
||
|
+ /* VMX capablity MSRs are available only when guest supports VMX. */
|
||
|
+ hvm_cpuid(0x1, &dummy, &dummy, &ecx, &dummy);
|
||
|
+ if ( !(ecx & cpufeat_mask(X86_FEATURE_VMXE)) )
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ /*
|
||
|
+ * Those MSRs are available only when bit 55 of
|
||
|
+ * MSR_IA32_VMX_BASIC is set.
|
||
|
+ */
|
||
|
+ switch ( msr )
|
||
|
+ {
|
||
|
+ case MSR_IA32_VMX_TRUE_PINBASED_CTLS:
|
||
|
+ case MSR_IA32_VMX_TRUE_PROCBASED_CTLS:
|
||
|
+ case MSR_IA32_VMX_TRUE_EXIT_CTLS:
|
||
|
+ case MSR_IA32_VMX_TRUE_ENTRY_CTLS:
|
||
|
+ if ( !(vmx_basic_msr & VMX_BASIC_DEFAULT1_ZERO) )
|
||
|
+ return 0;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+
|
||
|
rdmsrl(msr, host_data);
|
||
|
|
||
|
/*
|
||
|
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h
|
||
|
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
|
||
|
@@ -284,6 +284,8 @@ extern bool_t cpu_has_vmx_ins_outs_instr
|
||
|
*/
|
||
|
#define VMX_BASIC_DEFAULT1_ZERO (1ULL << 55)
|
||
|
|
||
|
+extern u64 vmx_basic_msr;
|
||
|
+
|
||
|
/* Guest interrupt status */
|
||
|
#define VMX_GUEST_INTR_STATUS_SUBFIELD_BITMASK 0x0FF
|
||
|
#define VMX_GUEST_INTR_STATUS_SVI_OFFSET 8
|