@@ -1,8 +1,11 @@
#include "pmu.h"
struct cpuid cpuid_10;
+struct pmu_caps pmu;
void pmu_init(void)
{
cpuid_10 = cpuid(10);
+ if (this_cpu_has(X86_FEATURE_PDCM))
+ pmu.perf_cap = rdmsr(MSR_IA32_PERF_CAPABILITIES);
}
\ No newline at end of file
@@ -33,7 +33,12 @@
#define EVNTSEL_INT (1 << EVNTSEL_INT_SHIFT)
#define EVNTSEL_INV (1 << EVNTSEL_INV_SHIF)
+struct pmu_caps {
+ u64 perf_cap;
+};
+
extern struct cpuid cpuid_10;
+extern struct pmu_caps pmu;
void pmu_init(void);
@@ -91,10 +96,17 @@ static inline bool pmu_gp_counter_is_available(int i)
static inline u64 this_cpu_perf_capabilities(void)
{
- if (!this_cpu_has(X86_FEATURE_PDCM))
- return 0;
+ return pmu.perf_cap;
+}
- return rdmsr(MSR_IA32_PERF_CAPABILITIES);
+static inline u64 pmu_lbr_version(void)
+{
+ return this_cpu_perf_capabilities() & PMU_CAP_LBR_FMT;
+}
+
+static inline bool pmu_has_full_writes(void)
+{
+ return this_cpu_perf_capabilities() & PMU_CAP_FW_WRITES;
}
#endif /* _X86_PMU_H_ */
@@ -669,7 +669,7 @@ int main(int ac, char **av)
check_counters();
- if (this_cpu_perf_capabilities() & PMU_CAP_FW_WRITES) {
+ if (pmu_has_full_writes()) {
gp_counter_base = MSR_IA32_PMC0;
report_prefix_push("full-width writes");
check_counters();
@@ -43,7 +43,6 @@ static bool test_init_lbr_from_exception(u64 index)
int main(int ac, char **av)
{
- u64 perf_cap;
int max, i;
setup_vm();
@@ -63,15 +62,13 @@ int main(int ac, char **av)
return report_summary();
}
- perf_cap = this_cpu_perf_capabilities();
-
- if (!(perf_cap & PMU_CAP_LBR_FMT)) {
+ if (!pmu_lbr_version()) {
report_skip("(Architectural) LBR is not supported.");
return report_summary();
}
printf("PMU version: %d\n", pmu_version());
- printf("LBR version: %ld\n", perf_cap & PMU_CAP_LBR_FMT);
+ printf("LBR version: %ld\n", pmu_lbr_version());
/* Look for LBR from and to MSRs */
lbr_from = MSR_LBR_CORE_FROM;