Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

x86/cpu/amd: Enable the fixed Instructions Retired counter IRPERF

Commit

aaf248848db50 ("perf/x86/msr: Add AMD IRPERF (Instructions Retired)
performance counter")

added support for access to the free-running counter via 'perf -e
msr/irperf/', but when exercised, it always returns a 0 count:

BEFORE:

$ perf stat -e instructions,msr/irperf/ true

Performance counter stats for 'true':

624,833 instructions
0 msr/irperf/

Simply set its enable bit - HWCR bit 30 - to make it start counting.

Enablement is restricted to all machines advertising IRPERF capability,
except those susceptible to an erratum that makes the IRPERF return
bad values.

That erratum occurs in Family 17h models 00-1fh [1], but not in F17h
models 20h and above [2].

AFTER (on a family 17h model 31h machine):

$ perf stat -e instructions,msr/irperf/ true

Performance counter stats for 'true':

621,690 instructions
622,490 msr/irperf/

[1] Revision Guide for AMD Family 17h Models 00h-0Fh Processors
[2] Revision Guide for AMD Family 17h Models 30h-3Fh Processors

The revision guides are available from the bugzilla Link below.

[ bp: Massage commit message. ]

Fixes: aaf248848db50 ("perf/x86/msr: Add AMD IRPERF (Instructions Retired) performance counter")
Signed-off-by: Kim Phillips <kim.phillips@amd.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: stable@vger.kernel.org
Link: https://bugzilla.kernel.org/show_bug.cgi?id=206537
Link: http://lkml.kernel.org/r/20200214201805.13830-1-kim.phillips@amd.com

authored by

Kim Phillips and committed by
Borislav Petkov
21b5ee59 df6d4f9d

+16
+2
arch/x86/include/asm/msr-index.h
··· 512 512 #define MSR_K7_HWCR 0xc0010015 513 513 #define MSR_K7_HWCR_SMMLOCK_BIT 0 514 514 #define MSR_K7_HWCR_SMMLOCK BIT_ULL(MSR_K7_HWCR_SMMLOCK_BIT) 515 + #define MSR_K7_HWCR_IRPERF_EN_BIT 30 516 + #define MSR_K7_HWCR_IRPERF_EN BIT_ULL(MSR_K7_HWCR_IRPERF_EN_BIT) 515 517 #define MSR_K7_FID_VID_CTL 0xc0010041 516 518 #define MSR_K7_FID_VID_STATUS 0xc0010042 517 519
+14
arch/x86/kernel/cpu/amd.c
··· 28 28 29 29 static const int amd_erratum_383[]; 30 30 static const int amd_erratum_400[]; 31 + static const int amd_erratum_1054[]; 31 32 static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum); 32 33 33 34 /* ··· 973 972 /* AMD CPUs don't reset SS attributes on SYSRET, Xen does. */ 974 973 if (!cpu_has(c, X86_FEATURE_XENPV)) 975 974 set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS); 975 + 976 + /* 977 + * Turn on the Instructions Retired free counter on machines not 978 + * susceptible to erratum #1054 "Instructions Retired Performance 979 + * Counter May Be Inaccurate". 980 + */ 981 + if (cpu_has(c, X86_FEATURE_IRPERF) && 982 + !cpu_has_amd_erratum(c, amd_erratum_1054)) 983 + msr_set_bit(MSR_K7_HWCR, MSR_K7_HWCR_IRPERF_EN_BIT); 976 984 } 977 985 978 986 #ifdef CONFIG_X86_32 ··· 1108 1098 1109 1099 static const int amd_erratum_383[] = 1110 1100 AMD_OSVW_ERRATUM(3, AMD_MODEL_RANGE(0x10, 0, 0, 0xff, 0xf)); 1101 + 1102 + /* #1054: Instructions Retired Performance Counter May Be Inaccurate */ 1103 + static const int amd_erratum_1054[] = 1104 + AMD_OSVW_ERRATUM(0, AMD_MODEL_RANGE(0x17, 0, 0, 0x2f, 0xf)); 1111 1105 1112 1106 1113 1107 static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum)