| From foo@baz Sun Jun 17 12:07:33 CEST 2018 |
| From: Kan Liang <kan.liang@linux.intel.com> |
| Date: Wed, 25 Apr 2018 14:57:17 -0400 |
| Subject: perf/x86/intel: Don't enable freeze-on-smi for PerfMon V1 |
| |
| From: Kan Liang <kan.liang@linux.intel.com> |
| |
| [ Upstream commit 4e949e9b9d1e3edcdab3b54656c5851bd9e49c67 ] |
| |
| The SMM freeze feature was introduced since PerfMon V2. But the current |
| code unconditionally enables the feature for all platforms. It can |
| generate #GP exception, if the related FREEZE_WHILE_SMM bit is set for |
| the machine with PerfMon V1. |
| |
| To disable the feature for PerfMon V1, perf needs to |
| - Remove the freeze_on_smi sysfs entry by moving intel_pmu_attrs to |
| intel_pmu, which is only applied to PerfMon V2 and later. |
| - Check the PerfMon version before flipping the SMM bit when starting CPU |
| |
| Fixes: 6089327f5424 ("perf/x86: Add sysfs entry to freeze counters on SMI") |
| Signed-off-by: Kan Liang <kan.liang@linux.intel.com> |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> |
| Cc: ak@linux.intel.com |
| Cc: eranian@google.com |
| Cc: acme@redhat.com |
| Link: https://lkml.kernel.org/r/1524682637-63219-1-git-send-email-kan.liang@linux.intel.com |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/x86/events/intel/core.c | 9 ++++++--- |
| 1 file changed, 6 insertions(+), 3 deletions(-) |
| |
| --- a/arch/x86/events/intel/core.c |
| +++ b/arch/x86/events/intel/core.c |
| @@ -3331,7 +3331,8 @@ static void intel_pmu_cpu_starting(int c |
| |
| cpuc->lbr_sel = NULL; |
| |
| - flip_smm_bit(&x86_pmu.attr_freeze_on_smi); |
| + if (x86_pmu.version > 1) |
| + flip_smm_bit(&x86_pmu.attr_freeze_on_smi); |
| |
| if (!cpuc->shared_regs) |
| return; |
| @@ -3494,6 +3495,8 @@ static __initconst const struct x86_pmu |
| .cpu_dying = intel_pmu_cpu_dying, |
| }; |
| |
| +static struct attribute *intel_pmu_attrs[]; |
| + |
| static __initconst const struct x86_pmu intel_pmu = { |
| .name = "Intel", |
| .handle_irq = intel_pmu_handle_irq, |
| @@ -3524,6 +3527,8 @@ static __initconst const struct x86_pmu |
| .format_attrs = intel_arch3_formats_attr, |
| .events_sysfs_show = intel_event_sysfs_show, |
| |
| + .attrs = intel_pmu_attrs, |
| + |
| .cpu_prepare = intel_pmu_cpu_prepare, |
| .cpu_starting = intel_pmu_cpu_starting, |
| .cpu_dying = intel_pmu_cpu_dying, |
| @@ -3902,8 +3907,6 @@ __init int intel_pmu_init(void) |
| |
| x86_pmu.max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, x86_pmu.num_counters); |
| |
| - |
| - x86_pmu.attrs = intel_pmu_attrs; |
| /* |
| * Quirk: v2 perfmon does not report fixed-purpose events, so |
| * assume at least 3 events, when not running in a hypervisor: |