From: Andi Kleen <[email protected]>

Current kernels always test extra registers at boot with RMW
cycle, to catch lying virtual machines.

For a new register the standard 0x1ff test value does not work,
as 0x1ff is not a valid value and causes an #GP.

Add the ability to add custom test values to an extra_reg
into the description tables.

Signed-off-by: Andi Kleen <[email protected]>
---
 arch/x86/kernel/cpu/perf_event.h                    | 15 +++++++++++----
 arch/x86/kernel/cpu/perf_event_intel.c              |  3 ++-
 arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c |  5 +++--
 3 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index 3598f67..2a4701c 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -422,23 +422,30 @@ struct extra_reg {
        u64                     valid_mask;
        int                     idx;  /* per_xxx->regs[] reg index */
        bool                    extra_msr_access;
+       u64                     test_value;
 };
 
-#define EVENT_EXTRA_REG(e, ms, m, vm, i) {     \
+#define EVENT_EXTRA_REG(e, ms, m, vm, i, t) {  \
        .event = (e),                   \
        .msr = (ms),                    \
        .config_mask = (m),             \
        .valid_mask = (vm),             \
        .idx = EXTRA_REG_##i,           \
        .extra_msr_access = true,       \
+       .test_value = t,                \
        }
 
 #define INTEL_EVENT_EXTRA_REG(event, msr, vm, idx)     \
-       EVENT_EXTRA_REG(event, msr, ARCH_PERFMON_EVENTSEL_EVENT, vm, idx)
+       EVENT_EXTRA_REG(event, msr, ARCH_PERFMON_EVENTSEL_EVENT, vm, idx, \
+                       0x1ffUL)
 
 #define INTEL_UEVENT_EXTRA_REG(event, msr, vm, idx) \
        EVENT_EXTRA_REG(event, msr, ARCH_PERFMON_EVENTSEL_EVENT | \
-                       ARCH_PERFMON_EVENTSEL_UMASK, vm, idx)
+                       ARCH_PERFMON_EVENTSEL_UMASK, vm, idx, 0x1ffUL)
+
+#define INTEL_UEVENT_EXTRA_REG_TVAL(event, msr, vm, idx, tval) \
+       EVENT_EXTRA_REG(event, msr, ARCH_PERFMON_EVENTSEL_EVENT | \
+                       ARCH_PERFMON_EVENTSEL_UMASK, vm, idx, tval)
 
 #define INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(c) \
        INTEL_UEVENT_EXTRA_REG(c, \
@@ -446,7 +453,7 @@ struct extra_reg {
                               0xffff, \
                               LDLAT)
 
-#define EVENT_EXTRA_END EVENT_EXTRA_REG(0, 0, 0, 0, RSP_0)
+#define EVENT_EXTRA_END EVENT_EXTRA_REG(0, 0, 0, 0, RSP_0, 0)
 
 union perf_capabilities {
        struct {
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c 
b/arch/x86/kernel/cpu/perf_event_intel.c
index 7c397e8..4df6783 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -3575,7 +3575,8 @@ __init int intel_pmu_init(void)
         */
        if (x86_pmu.extra_regs) {
                for (er = x86_pmu.extra_regs; er->msr; er++) {
-                       er->extra_msr_access = check_msr(er->msr, 0x1ffUL);
+                       er->extra_msr_access = check_msr(er->msr,
+                                                        er->test_value);
                        /* Disable LBR select mapping */
                        if ((er->idx == EXTRA_REG_LBR) && !er->extra_msr_access)
                                x86_pmu.lbr_sel_map = NULL;
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c 
b/arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c
index 2749965..5bfa493 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c
@@ -136,11 +136,12 @@
                                NHMEX_M_PMON_CTL_FLAG_MODE)
 #define MBOX_INC_SEL_EXTAR_REG(c, r) \
                EVENT_EXTRA_REG(MBOX_INC_SEL(c), NHMEX_M0_MSR_PMU_##r, \
-                               MBOX_INC_SEL_MASK, (u64)-1, NHMEX_M_##r)
+                               MBOX_INC_SEL_MASK, (u64)-1, NHMEX_M_##r, \
+                               0x1ffUL)
 #define MBOX_SET_FLAG_SEL_EXTRA_REG(c, r) \
                EVENT_EXTRA_REG(MBOX_SET_FLAG_SEL(c), NHMEX_M0_MSR_PMU_##r, \
                                MBOX_SET_FLAG_SEL_MASK, \
-                               (u64)-1, NHMEX_M_##r)
+                               (u64)-1, NHMEX_M_##r, 0x1ffUL)
 
 /* NHM-EX Rbox */
 #define NHMEX_R_MSR_GLOBAL_CTL                 0xe00
-- 
2.4.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to