Messages in this thread Patch in this message | | | From | Andi Kleen <> | Subject | [PATCH 2/3] x86, perf: Support custom test values for extra_regs | Date | Mon, 29 Jun 2015 14:22:14 -0700 |
| |
From: Andi Kleen <ak@linux.intel.com>
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 <ak@linux.intel.com> --- 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
| |