From: Peter Feiner <pfei...@google.com>

Some Intel processors have an EPT feature whereby the accessed & dirty bits
in EPT entries can be updated by HW. MSR IA32_VMX_EPT_VPID_CAP exposes the
presence of this capability.

This bit will also expose "ept_ad" in /proc/cpuinfo/$proc/flags if feature
is present.

Signed-off-by: Peter Feiner <pfei...@google.com>
Signed-off-by: Peter Shier <psh...@google.com>
Reviewed-by: Jim Mattson <jmatt...@google.com>
---
 arch/x86/include/asm/cpufeatures.h |  2 +-
 arch/x86/kernel/cpu/intel.c        | 10 +++++++++-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/cpufeatures.h 
b/arch/x86/include/asm/cpufeatures.h
index 5701f5cecd312..7fff98fa58558 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -229,7 +229,7 @@
 
 #define X86_FEATURE_VMMCALL            ( 8*32+15) /* Prefer VMMCALL to VMCALL 
*/
 #define X86_FEATURE_XENPV              ( 8*32+16) /* "" Xen paravirtual guest 
*/
-
+#define X86_FEATURE_EPT_AD             ( 8*32+17) /* Intel Extended Page Table 
access-dirty bit */
 
 /* Intel-defined CPU features, CPUID level 0x00000007:0 (EBX), word 9 */
 #define X86_FEATURE_FSGSBASE           ( 9*32+ 0) /* RDFSBASE, WRFSBASE, 
RDGSBASE, WRGSBASE instructions*/
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index eb75564f2d257..c050cd6066af0 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -465,14 +465,17 @@ static void detect_vmx_virtcap(struct cpuinfo_x86 *c)
 #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
+#define x86_VMX_FEATURE_EPT_CAP_AD             0x00200000
 
        u32 vmx_msr_low, vmx_msr_high, msr_ctl, msr_ctl2;
+       u32 msr_vpid_cap, msr_ept_cap;
 
        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);
+       clear_cpu_cap(c, X86_FEATURE_EPT_AD);
 
        rdmsr(MSR_IA32_VMX_PROCBASED_CTLS, vmx_msr_low, vmx_msr_high);
        msr_ctl = vmx_msr_high | vmx_msr_low;
@@ -487,8 +490,13 @@ static void detect_vmx_virtcap(struct cpuinfo_x86 *c)
                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)
+               if (msr_ctl2 & X86_VMX_FEATURE_PROC_CTLS2_EPT) {
                        set_cpu_cap(c, X86_FEATURE_EPT);
+                       rdmsr(MSR_IA32_VMX_EPT_VPID_CAP,
+                             msr_ept_cap, msr_vpid_cap);
+                       if (msr_ept_cap & x86_VMX_FEATURE_EPT_CAP_AD)
+                               set_cpu_cap(c, X86_FEATURE_EPT_AD);
+               }
                if (msr_ctl2 & X86_VMX_FEATURE_PROC_CTLS2_VPID)
                        set_cpu_cap(c, X86_FEATURE_VPID);
        }
-- 
2.18.0.233.g985f88cf7e-goog

Reply via email to