@@ -302,6 +302,9 @@ static inline void arch_set_max_freq_ratio(bool turbo_disabled) { }
static inline void freq_invariance_set_perf_ratio(u64 ratio, bool turbo_disabled) { }
#endif
+extern u64 get_host_aperf(void);
+extern u64 get_host_mperf(void);
+
extern void arch_scale_freq_tick(void);
#define arch_scale_freq_tick arch_scale_freq_tick
@@ -40,8 +40,8 @@ static void init_counter_refs(void)
{
u64 aperf, mperf;
- rdmsrl(MSR_IA32_APERF, aperf);
- rdmsrl(MSR_IA32_MPERF, mperf);
+ aperf = get_host_aperf();
+ mperf = get_host_mperf();
this_cpu_write(cpu_samples.aperf, aperf);
this_cpu_write(cpu_samples.mperf, mperf);
@@ -94,6 +94,20 @@ void arch_set_max_freq_ratio(bool turbo_disabled)
}
EXPORT_SYMBOL_GPL(arch_set_max_freq_ratio);
+u64 get_host_aperf(void)
+{
+ WARN_ON_ONCE(!irqs_disabled());
+ return native_read_msr(MSR_IA32_APERF);
+}
+EXPORT_SYMBOL_GPL(get_host_aperf);
+
+u64 get_host_mperf(void)
+{
+ WARN_ON_ONCE(!irqs_disabled());
+ return native_read_msr(MSR_IA32_MPERF);
+}
+EXPORT_SYMBOL_GPL(get_host_mperf);
+
static bool __init turbo_disabled(void)
{
u64 misc_en;
@@ -474,8 +488,8 @@ void arch_scale_freq_tick(void)
if (!cpu_feature_enabled(X86_FEATURE_APERFMPERF))
return;
- rdmsrl(MSR_IA32_APERF, aperf);
- rdmsrl(MSR_IA32_MPERF, mperf);
+ aperf = get_host_aperf();
+ mperf = get_host_mperf();
acnt = aperf - s->aperf;
mcnt = mperf - s->mperf;
@@ -446,8 +446,8 @@ static inline bool amd_pstate_sample(struct amd_cpudata *cpudata)
unsigned long flags;
local_irq_save(flags);
- rdmsrl(MSR_IA32_APERF, aperf);
- rdmsrl(MSR_IA32_MPERF, mperf);
+ aperf = get_host_aperf();
+ mperf = get_host_mperf();
tsc = rdtsc();
if (cpudata->prev.mperf == mperf || cpudata->prev.tsc == tsc) {
@@ -27,6 +27,7 @@
#include <linux/vmalloc.h>
#include <linux/pm_qos.h>
#include <linux/bitfield.h>
+#include <linux/topology.h>
#include <trace/events/power.h>
#include <asm/cpu.h>
@@ -2423,8 +2424,8 @@ static inline bool intel_pstate_sample(struct cpudata *cpu, u64 time)
u64 tsc;
local_irq_save(flags);
- rdmsrl(MSR_IA32_APERF, aperf);
- rdmsrl(MSR_IA32_MPERF, mperf);
+ aperf = get_host_aperf();
+ mperf = get_host_mperf();
tsc = rdtsc();
if (cpu->prev_mperf == mperf || cpu->prev_tsc == tsc) {
local_irq_restore(flags);