Re: [PATCH v2] ACPI: CPPC: Move reference performance to capabilities

From: Nathan Chancellor

Date: Tue Mar 10 2026 - 17:32:32 EST


On Tue, Mar 10, 2026 at 01:05:04PM +0800, zhangpengjie (A) wrote:
> Thanks for testing and reporting this! The error code -14 (-EFAULT)
> you are seeing is exactly due to a logical flaw introduced in that commit
>  when handling the local `ref` variable. On platforms that do not support
>  the reference performance register, the code falls into the `else` branch
> and correctly assigns `perf_caps->reference_perf = nom;`.
> However, it forgets to update the local `ref` variable. Because `ref`
> remains
> uninitialized (or 0), the subsequent sanity check
>  `if (!high || !low || !nom || !ref || !min_nonlinear)`  fails and
> mistakenly returns

Thanks for confirming!

>  `-EFAULT` (-14).  Could you please apply the following diff and see if it
> resolves
>  the amd_pstate initialization failure on your test machine?
>
> diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
> index 07bbf5b366a4..ac90c0c55c14 100644
> --- a/drivers/acpi/cppc_acpi.c
> +++ b/drivers/acpi/cppc_acpi.c
> @@ -1411,7 +1411,8 @@ int cppc_get_perf_caps(int cpunum, struct
> cppc_perf_caps *perf_caps)
>                 cpc_read(cpunum, reference_reg, &ref);
>                 perf_caps->reference_perf = ref;
>         } else {
> -               perf_caps->reference_perf = nom;
> +               ref = nom;
> +               perf_caps->reference_perf = ref;
>         }
>
>         if (guaranteed_reg->type != ACPI_TYPE_BUFFER  ||

Yeah, I tested the following slightly different but functionally
equivalent diff and it appears to cure my problems. Thanks for the quick
reply. If it would be helpful for a follow up submission:

Tested-by: Nathan Chancellor <nathan@xxxxxxxxxx>

diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
index 07bbf5b366a4..5ad922eb937a 100644
--- a/drivers/acpi/cppc_acpi.c
+++ b/drivers/acpi/cppc_acpi.c
@@ -1407,12 +1407,11 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps)
* If reference perf register is not supported then we should
* use the nominal perf value
*/
- if (CPC_SUPPORTED(reference_reg)) {
+ if (CPC_SUPPORTED(reference_reg))
cpc_read(cpunum, reference_reg, &ref);
- perf_caps->reference_perf = ref;
- } else {
- perf_caps->reference_perf = nom;
- }
+ else
+ ref = nom;
+ perf_caps->reference_perf = ref;

if (guaranteed_reg->type != ACPI_TYPE_BUFFER ||
IS_NULL_REG(&guaranteed_reg->cpc_entry.reg)) {