|
@@ -196,6 +196,44 @@ static int __cpuinit intel_num_cpu_cores(struct cpuinfo_x86 *c)
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
+static void __cpuinit detect_vmx_virtcap(struct cpuinfo_x86 *c)
|
|
|
+{
|
|
|
+ /* Intel VMX MSR indicated features */
|
|
|
+#define X86_VMX_FEATURE_PROC_CTLS_TPR_SHADOW 0x00200000
|
|
|
+#define X86_VMX_FEATURE_PROC_CTLS_VNMI 0x00400000
|
|
|
+#define X86_VMX_FEATURE_PROC_CTLS_2ND_CTLS 0x80000000
|
|
|
+#define X86_VMX_FEATURE_PROC_CTLS2_VIRT_APIC 0x00000001
|
|
|
+#define X86_VMX_FEATURE_PROC_CTLS2_EPT 0x00000002
|
|
|
+#define X86_VMX_FEATURE_PROC_CTLS2_VPID 0x00000020
|
|
|
+
|
|
|
+ u32 vmx_msr_low, vmx_msr_high, msr_ctl, msr_ctl2;
|
|
|
+
|
|
|
+ clear_cpu_cap(c, X86_FEATURE_TPR_SHADOW);
|
|
|
+ clear_cpu_cap(c, X86_FEATURE_VNMI);
|
|
|
+ clear_cpu_cap(c, X86_FEATURE_FLEXPRIORITY);
|
|
|
+ clear_cpu_cap(c, X86_FEATURE_EPT);
|
|
|
+ clear_cpu_cap(c, X86_FEATURE_VPID);
|
|
|
+
|
|
|
+ rdmsr(MSR_IA32_VMX_PROCBASED_CTLS, vmx_msr_low, vmx_msr_high);
|
|
|
+ msr_ctl = vmx_msr_high | vmx_msr_low;
|
|
|
+ if (msr_ctl & X86_VMX_FEATURE_PROC_CTLS_TPR_SHADOW)
|
|
|
+ set_cpu_cap(c, X86_FEATURE_TPR_SHADOW);
|
|
|
+ if (msr_ctl & X86_VMX_FEATURE_PROC_CTLS_VNMI)
|
|
|
+ set_cpu_cap(c, X86_FEATURE_VNMI);
|
|
|
+ if (msr_ctl & X86_VMX_FEATURE_PROC_CTLS_2ND_CTLS) {
|
|
|
+ rdmsr(MSR_IA32_VMX_PROCBASED_CTLS2,
|
|
|
+ vmx_msr_low, vmx_msr_high);
|
|
|
+ msr_ctl2 = vmx_msr_high | vmx_msr_low;
|
|
|
+ if ((msr_ctl2 & X86_VMX_FEATURE_PROC_CTLS2_VIRT_APIC) &&
|
|
|
+ (msr_ctl & X86_VMX_FEATURE_PROC_CTLS_TPR_SHADOW))
|
|
|
+ set_cpu_cap(c, X86_FEATURE_FLEXPRIORITY);
|
|
|
+ if (msr_ctl2 & X86_VMX_FEATURE_PROC_CTLS2_EPT)
|
|
|
+ set_cpu_cap(c, X86_FEATURE_EPT);
|
|
|
+ if (msr_ctl2 & X86_VMX_FEATURE_PROC_CTLS2_VPID)
|
|
|
+ set_cpu_cap(c, X86_FEATURE_VPID);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static void __cpuinit init_intel(struct cpuinfo_x86 *c)
|
|
|
{
|
|
|
unsigned int l2 = 0;
|
|
@@ -289,6 +327,9 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
|
|
|
|
|
|
/* Work around errata */
|
|
|
srat_detect_node();
|
|
|
+
|
|
|
+ if (cpu_has(c, X86_FEATURE_VMX))
|
|
|
+ detect_vmx_virtcap(c);
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_X86_32
|