[RFC PATCH 2/4] cpufreq/amd-pstate: Update cppc_req_cached before writing the MSR

From: David Vernet

Date: Tue Jul 28 2026 - 03:36:40 EST


msr_update_perf() and msr_set_epp() currently write MSR_AMD_CPPC_REQ
first and update cppc_req_cached only after the write succeeds. This
leaves a window in which the MSR holds the new request while the cache
holds the previous one. That's fine right now, but a subsequent patch
will add a per-core EPP boost that runs from scheduling context and
mutates that MSR from the contents of the cached value. If we update the
cache after writing the MSR, the sched callback could run between the
wrmsrq and the cache being updated, and accidentally overwrite the
intended value of the MSR by issuing a wrmsrq on the stale cached value.

To avoid this, let's update the cache prior to the MSR write, as is done
in intel_pstate_set_epp(). This should be a functional no-op.

Signed-off-by: David Vernet <void@xxxxxxxxxxxxx>
---
drivers/cpufreq/amd-pstate.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
index 6e255a22a0b8..5d7debb5a35c 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -262,17 +262,19 @@ static int msr_update_perf(struct cpufreq_policy *policy, u8 min_perf,
if (value == prev)
return 0;

+ WRITE_ONCE(cpudata->cppc_req_cached, value);
+
if (fast_switch) {
wrmsrq(MSR_AMD_CPPC_REQ, value);
} else {
int ret = wrmsrq_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value);

- if (ret)
+ if (ret) {
+ WRITE_ONCE(cpudata->cppc_req_cached, prev);
return ret;
+ }
}

- WRITE_ONCE(cpudata->cppc_req_cached, value);
-
return 0;
}

@@ -312,16 +314,16 @@ static int msr_set_epp(struct cpufreq_policy *policy, u8 epp)
if (value == prev)
return 0;

+ WRITE_ONCE(cpudata->cppc_req_cached, value);
+
ret = wrmsrq_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value);
if (ret) {
+ WRITE_ONCE(cpudata->cppc_req_cached, prev);
pr_err("failed to set energy perf value (%d)\n", ret);
return ret;
}

- /* update both so that msr_update_perf() can effectively check */
- WRITE_ONCE(cpudata->cppc_req_cached, value);
-
- return ret;
+ return 0;
}

DEFINE_STATIC_CALL(amd_pstate_set_epp, msr_set_epp);
--
2.53.0