From nobody Fri Oct 2 09:21:38 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id E754C371046; Mon, 3 Aug 2026 10:03:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785751383; cv=none; b=rrWgJ7Yr43tfIvof8rAyzgBJazmKik1dC00UUkbRfq+G7Y+pNcUqGYNIk81RVAzCNJSqyO3/JK24ygVLkcKcWfxiUBoXf4zdR0gcPpahcQhQW6on/opB4p31wgqmvwzI2/OfRQAjsRXyrmjOTvKkolXZtKL6rUdV7P05i7QPQMc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785751383; c=relaxed/simple; bh=TdGjTLd7CFgZjqZPky+2Tqgc86QPVB5Ryw4ljGn3VoE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=BweZ1LKJ1TKiQ8rFT4bI+eyjOnoyryekaM707oy5j0Z0BOeIweHLIkR+QwpS8CFOH/lJiV6ylQpbmtlitmtYuVdaPU9v9EBUxmavNKer/bz2V0ST/dz+IutJg7iLsJFmujclyCt1Wa5TGYLbiG7RD5ncvhfV39v7GaQ0QxozUqQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=eoQ/C9M1; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="eoQ/C9M1" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4431C1476; Mon, 3 Aug 2026 03:02:56 -0700 (PDT) Received: from e127648.cambridge.arm.com (e127648.arm.com [10.1.39.91]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 4713C3F66F; Mon, 3 Aug 2026 03:02:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1785751380; bh=TdGjTLd7CFgZjqZPky+2Tqgc86QPVB5Ryw4ljGn3VoE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eoQ/C9M1L8XXd6M+eOO/C6DEZ3B8IXNTQkYFkzK6uLFxN3b5+Uktb3Iaj613nE0uD 9iTaT2L7g9GajIEl13Fj0nJIBhSC9F2z88DCsAq/D5wnI/sCaIeh5phDbfmp6wQbV7 si+t1tTFOBgfr+9FC7bC8Ki8jSKrn05O8JF2fSW0= From: Christian Loehle To: christian.loehle@arm.com, "Rafael J . Wysocki" , Viresh Kumar Cc: linux-pm@vger.kernel.org, linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, Len Brown , Jie Zhan , Lifeng Zheng , Pierre Gondois , Sumit Gupta , Sudeep Holla , Ionela Voinescu , zhongqiu.han@oss.qualcomm.com Subject: [PATCH v3 1/3] ACPI: CPPC: Reject desired_perf reads on ACPI 6.6+ Date: Mon, 3 Aug 2026 11:02:49 +0100 Message-Id: <18ee922e97441b99b9ab346fe559d837d05eb5e7.1785749175.git.christian.loehle@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: <20260729100245.2628302-1-christian.loehle@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When CPPC feedback counters cannot provide a usable sample, cppc-cpufreq calls cppc_get_desired_perf() because some platforms repurpose Desired Performance to report actual delivered performance. The fallback was added for platforms on which Desired Performance reflects delivered performance. ACPI 6.6 defines the register as write-only, so invoking that workaround on an ACPI 6.6 or later platform would require an invalid register read. Make cppc_get_desired_perf() return -EOPNOTSUPP in that case. When checking the FADT minor revision, mask off its upper errata-generation bits and compare only the specification minor version. The FADT revision may not accurately describe the semantics implemented by _CPC. If a nominally pre-6.6 platform implements Desired Performance as write-only, a read may return zero and make cppc_cpufreq_get_rate() report 0 kHz. Treat a zero read as unusable and fall back to the cached OSPM request, just as for a failed read. Fixes: c47195631960 ("cppc_cpufreq: Use desired perf if feedback ctrs are 0= or unchanged") Cc: stable@vger.kernel.org Suggested-by: Sumit Gupta Signed-off-by: Christian Loehle --- drivers/acpi/cppc_acpi.c | 15 ++++++++++++++- drivers/cpufreq/cppc_cpufreq.c | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 53d09ca98f06..6e5381f8de38 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -1316,15 +1316,28 @@ static int cppc_set_reg_val(int cpu, enum cppc_regs= reg_idx, u64 val) return cpc_write(cpu, reg, val); } =20 +static bool cppc_desired_perf_readable(void) +{ + u8 minor_revision =3D acpi_gbl_FADT.minor_revision & 0x0f; + + return acpi_gbl_FADT.header.revision < 6 || + (acpi_gbl_FADT.header.revision =3D=3D 6 && minor_revision < 6); +} + /** * cppc_get_desired_perf - Get the desired performance register value. * @cpunum: CPU from which to get desired performance. * @desired_perf: Return address. * - * Return: 0 for success, -EIO otherwise. + * Return: 0 for success, -EOPNOTSUPP for ACPI 6.6 or later, and a negative + * errno otherwise. */ int cppc_get_desired_perf(int cpunum, u64 *desired_perf) { + /* ACPI 6.6 no longer specifies Desired Performance as readable. */ + if (!cppc_desired_perf_readable()) + return -EOPNOTSUPP; + return cppc_get_reg_val(cpunum, DESIRED_PERF, desired_perf); } EXPORT_SYMBOL_GPL(cppc_get_desired_perf); diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index 6fe0e972952a..80893844353c 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -836,7 +836,7 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int = cpu) * value first as some platforms may update the actual delivered perf * there; if failed, resort to the cached desired perf. */ - if (cppc_get_desired_perf(cpu, &delivered_perf)) + if (cppc_get_desired_perf(cpu, &delivered_perf) || !delivered_perf) delivered_perf =3D cpu_data->perf_ctrls.desired_perf; =20 return cppc_perf_to_khz(&cpu_data->perf_caps, delivered_perf); --=20 2.34.1 From nobody Fri Oct 2 09:21:38 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 3B83E3749E8; Mon, 3 Aug 2026 10:03:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785751384; cv=none; b=Ld7Np3xAtipbjw2c8vLPetIfo5JIC3ZAs71PnNo5FyDVoKnEmWLeGsWC+C6+RyVrbjD3Epn6/jx1mrTBP+XMwUrtRvV5C/N3SkEynjVd6ErkktxQUdDvDRPIlMEwPhBNYA56v/NOjSFgcKKXXffRvLEWMTekvOppWTNzDV+jDnY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785751384; c=relaxed/simple; bh=N5i8lCBq5ATn2JQLxF3uEd9Jiqi76J5Sc3I8Bxay8c8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=XmrLEQF+MPQcsI+pW9HJnno6u8VZhw6qYup4ma5v76O+2DKLXkevfKaxCPk1LHgbgilop5xjcJJgYBgGiCfAR9dSjUhuNgw0z5R/bn8YCiQNnHLG/9Wjs5teYbaw5Az+IfriuRdVWOFgboGL6rb5HQ/3uVFSOHsBnyOA4tQqWjo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=liTBZQZt; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="liTBZQZt" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 9FF31143D; Mon, 3 Aug 2026 03:02:58 -0700 (PDT) Received: from e127648.cambridge.arm.com (e127648.arm.com [10.1.39.91]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 9FF273F66F; Mon, 3 Aug 2026 03:03:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1785751382; bh=N5i8lCBq5ATn2JQLxF3uEd9Jiqi76J5Sc3I8Bxay8c8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=liTBZQZtZG2fQqPX27mmOFQSgdGKxh4K9lwDfbBlEktSge5NaKJjM54GdpEzTSmh0 azmbmRuhd3u1Qw+2lN8ZDzP0X0rI42nZnjaHZSDSxoVrUgLWM3Zgj0uEcAscuKecpn 9z8LOINtAFAey75rpwqYISsjwV+/Y11OGRq+lsZg= From: Christian Loehle To: christian.loehle@arm.com, "Rafael J . Wysocki" , Viresh Kumar Cc: linux-pm@vger.kernel.org, linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, Len Brown , Jie Zhan , Lifeng Zheng , Pierre Gondois , Sumit Gupta , Sudeep Holla , Ionela Voinescu , zhongqiu.han@oss.qualcomm.com Subject: [PATCH v3 2/3] ACPI: CPPC: Skip desired_perf read in cppc_get_perf() Date: Mon, 3 Aug 2026 11:02:50 +0100 Message-Id: <7bebbf542419fb8d786ba1fcd195c668c22c1e64.1785749175.git.christian.loehle@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: <20260729100245.2628302-1-christian.loehle@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" ACPI 6.6 changed the Optional Attribute of Desired Performance from Read/Write to Write. cppc_get_perf() nevertheless reads the register when initializing performance controls, even though cppc-cpufreq overwrites the value before using it. Use the readability check from cppc_get_desired_perf() and leave desired_perf zero instead of reading it on ACPI 6.6 or later. Also exclude the register from PCC read-command detection so it cannot trigger an otherwise unnecessary read command. Fixes: 658fa7b1c47a ("ACPI: CPPC: Add cppc_get_perf() API to read performan= ce controls") Cc: stable@vger.kernel.org Suggested-by: Zhongqiu Han Reviewed-by: Zhongqiu Han Signed-off-by: Christian Loehle --- drivers/acpi/cppc_acpi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 6e5381f8de38..210988d57b71 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -1843,6 +1843,7 @@ int cppc_get_perf(int cpu, struct cppc_perf_ctrls *pe= rf_ctrls) u64 desired_perf =3D 0, min =3D 0, max =3D 0, energy_perf =3D 0, auto_sel= =3D 0; int pcc_ss_id =3D per_cpu(cpu_pcc_subspace_idx, cpu); struct cppc_pcc_data *pcc_ss_data =3D NULL; + bool read_desired_perf =3D cppc_desired_perf_readable(); int ret =3D 0, regs_in_pcc =3D 0; =20 if (!cpc_desc) { @@ -1862,7 +1863,8 @@ int cppc_get_perf(int cpu, struct cppc_perf_ctrls *pe= rf_ctrls) auto_sel_reg =3D &cpc_desc->cpc_regs[AUTO_SEL_ENABLE]; =20 /* Are any of the regs PCC ?*/ - if (CPC_IN_PCC(desired_perf_reg) || CPC_IN_PCC(min_perf_reg) || + if ((read_desired_perf && CPC_IN_PCC(desired_perf_reg)) || + CPC_IN_PCC(min_perf_reg) || CPC_IN_PCC(max_perf_reg) || CPC_IN_PCC(energy_perf_reg) || CPC_IN_PCC(auto_sel_reg)) { if (pcc_ss_id < 0) { @@ -1894,7 +1896,7 @@ int cppc_get_perf(int cpu, struct cppc_perf_ctrls *pe= rf_ctrls) } perf_ctrls->min_perf =3D min; =20 - if (CPC_SUPPORTED(desired_perf_reg)) { + if (read_desired_perf && CPC_SUPPORTED(desired_perf_reg)) { ret =3D cpc_read(cpu, desired_perf_reg, &desired_perf); if (ret) goto out_err; --=20 2.34.1 From nobody Fri Oct 2 09:21:38 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id AB4C3377A8F; Mon, 3 Aug 2026 10:03:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785751387; cv=none; b=rhZpK7ceFsh2x5tFOXWIIWtCPfS2cbn4HLdhO5YlowtCm1IK18PKj/6EKQ3F/QrSVcjCahHv8nOetChmOXfUtz813r3gGPlZyCuZUlnkyw6xVbl32/xDRrwTvREJ9X2DcsT/T9P4bXubzUzP6cHjjESxnUEZ51GrTINjfKJlD7o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785751387; c=relaxed/simple; bh=fjmpkl3Ntq52aGykdPAVs2wIJ99r43BbiIRM0bjf3Mw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=fZ0+JZztAkx83fN5I+DBIJ985OuGzrTtjGead1uHjZRzmf7dw94YBqjv6dg66zTobs5h5N/OtPMJn64GJn+pzHu2zVgJNsVRi+PLaL9WU1qy/FyVIZinxmd2zHJIyKRQMj/+mPkUw+XKRX58/2ksebyUHrofLKcumIKOj3kdaUQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=QlF/BPcg; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="QlF/BPcg" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 05AE91476; Mon, 3 Aug 2026 03:03:01 -0700 (PDT) Received: from e127648.cambridge.arm.com (e127648.arm.com [10.1.39.91]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 090403F632; Mon, 3 Aug 2026 03:03:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1785751385; bh=fjmpkl3Ntq52aGykdPAVs2wIJ99r43BbiIRM0bjf3Mw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QlF/BPcgdKEETmDBLV+9q2EkSWLnjHDXYS7eVKQwfilBuWF7PG1bdk/ldefjPNg9Z 5W2UidGJ7yTT2N7W4O64hCqlkxifCdhzY2GkhllLd4o6pNpCH/fAPDAkziXM+hIg6E slhQvEYg0TnW2i7hmrlQbxuZyBdbB09JoRHxL5Vk= From: Christian Loehle To: christian.loehle@arm.com, "Rafael J . Wysocki" , Viresh Kumar Cc: linux-pm@vger.kernel.org, linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, Len Brown , Jie Zhan , Lifeng Zheng , Pierre Gondois , Sumit Gupta , Sudeep Holla , Ionela Voinescu , zhongqiu.han@oss.qualcomm.com Subject: [PATCH v3 3/3] ACPI: CPPC: Stop reading desired_perf in cppc_get_perf() Date: Mon, 3 Aug 2026 11:02:51 +0100 Message-Id: <14182aecaaa89840f8cfd8d40cf4ddadc84aa844.1785749175.git.christian.loehle@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: <20260729100245.2628302-1-christian.loehle@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" cppc_get_perf() has one in-tree caller, cppc_cpufreq_get_cpu_data(). It uses the function to preserve existing controls before writing them, but overwrites desired_perf with highest_perf before the first cppc_set_perf(). Consequently, the current Desired Performance value is not consumed. Remove the Desired Performance read from this aggregate getter and document that the field is returned as zero. Reviewed-by: Zhongqiu Han Signed-off-by: Christian Loehle --- drivers/acpi/cppc_acpi.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 210988d57b71..8ce2033ba993 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -1828,22 +1828,22 @@ int cppc_set_enable(int cpu, bool enable) EXPORT_SYMBOL_GPL(cppc_set_enable); =20 /** - * cppc_get_perf - Get a CPU's performance controls. + * cppc_get_perf - Get a CPU's readable performance controls. * @cpu: CPU for which to get performance controls. * @perf_ctrls: ptr to cppc_perf_ctrls. See cppc_acpi.h * + * Desired Performance is not read and is returned as 0. + * * Return: 0 for success with perf_ctrls, -ERRNO otherwise. */ int cppc_get_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) { struct cpc_desc *cpc_desc =3D per_cpu(cpc_desc_ptr, cpu); - struct cpc_register_resource *desired_perf_reg, - *min_perf_reg, *max_perf_reg, + struct cpc_register_resource *min_perf_reg, *max_perf_reg, *energy_perf_reg, *auto_sel_reg; - u64 desired_perf =3D 0, min =3D 0, max =3D 0, energy_perf =3D 0, auto_sel= =3D 0; + u64 min =3D 0, max =3D 0, energy_perf =3D 0, auto_sel =3D 0; int pcc_ss_id =3D per_cpu(cpu_pcc_subspace_idx, cpu); struct cppc_pcc_data *pcc_ss_data =3D NULL; - bool read_desired_perf =3D cppc_desired_perf_readable(); int ret =3D 0, regs_in_pcc =3D 0; =20 if (!cpc_desc) { @@ -1856,16 +1856,14 @@ int cppc_get_perf(int cpu, struct cppc_perf_ctrls *= perf_ctrls) return -EINVAL; } =20 - desired_perf_reg =3D &cpc_desc->cpc_regs[DESIRED_PERF]; min_perf_reg =3D &cpc_desc->cpc_regs[MIN_PERF]; max_perf_reg =3D &cpc_desc->cpc_regs[MAX_PERF]; energy_perf_reg =3D &cpc_desc->cpc_regs[ENERGY_PERF]; auto_sel_reg =3D &cpc_desc->cpc_regs[AUTO_SEL_ENABLE]; =20 /* Are any of the regs PCC ?*/ - if ((read_desired_perf && CPC_IN_PCC(desired_perf_reg)) || - CPC_IN_PCC(min_perf_reg) || - CPC_IN_PCC(max_perf_reg) || CPC_IN_PCC(energy_perf_reg) || + if (CPC_IN_PCC(min_perf_reg) || CPC_IN_PCC(max_perf_reg) || + CPC_IN_PCC(energy_perf_reg) || CPC_IN_PCC(auto_sel_reg)) { if (pcc_ss_id < 0) { pr_debug("Invalid pcc_ss_id for CPU:%d\n", cpu); @@ -1896,12 +1894,7 @@ int cppc_get_perf(int cpu, struct cppc_perf_ctrls *p= erf_ctrls) } perf_ctrls->min_perf =3D min; =20 - if (read_desired_perf && CPC_SUPPORTED(desired_perf_reg)) { - ret =3D cpc_read(cpu, desired_perf_reg, &desired_perf); - if (ret) - goto out_err; - } - perf_ctrls->desired_perf =3D desired_perf; + perf_ctrls->desired_perf =3D 0; =20 if (CPC_SUPPORTED(energy_perf_reg)) { ret =3D cpc_read(cpu, energy_perf_reg, &energy_perf); --=20 2.34.1