From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Kaushlendra Kumar <kaushlendra.kumar@intel.com>,
Shuah Khan <skhan@linuxfoundation.org>,
Sasha Levin <sashal@kernel.org>,
fj5851bi@fujitsu.com
Subject: [PATCH AUTOSEL 6.19-6.18] tools/cpupower: Fix inverted APERF capability check
Date: Wed, 11 Feb 2026 07:30:38 -0500 [thread overview]
Message-ID: <20260211123112.1330287-28-sashal@kernel.org> (raw)
In-Reply-To: <20260211123112.1330287-1-sashal@kernel.org>
From: Kaushlendra Kumar <kaushlendra.kumar@intel.com>
[ Upstream commit 24858a84163c8d04827166b3bcaed80612bb62fc ]
The capability check was inverted, causing the function to return
error when APERF support is available and proceed when it is not.
Negate the condition to return error only when APERF capability
is absent.
Link: https://lore.kernel.org/r/20251126091613.567480-1-kaushlendra.kumar@intel.com
Signed-off-by: Kaushlendra Kumar <kaushlendra.kumar@intel.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Now I have a complete picture. Let me write my analysis.
---
## Detailed Analysis
### 1. Commit Message Analysis
The commit message is crystal clear: "The capability check was inverted,
causing the function to return error when APERF support is available and
proceed when it is not." This is a straightforward logic inversion bug
fix.
### 2. Code Change Analysis
The change is a **single-character fix** — adding `!` to negate a
condition:
```273:274:tools/power/cpupower/utils/cpufreq-info.c
if (cpupower_cpu_info.caps & CPUPOWER_CAP_APERF)
return -EINVAL;
```
becomes:
```c
if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_APERF))
return -EINVAL;
```
### 3. Bug Origin and Root Cause
The bug was introduced by commit `26e16174f54d4` ("cpupower: Don't try
to read frequency from hardware when kernel uses aperfmperf"), authored
by Mario Limonciello (AMD) and merged for v6.14-rc1. That commit
intended to skip hardware frequency reading when APERF/MPERF is in use
(for amd-pstate), but the condition was written **backwards**.
### 4. Proof That the Condition is Inverted
The evidence is overwhelming:
**a) Consistency with all other APERF checks in the same codebase:**
In `nhm_idle.c` line 176:
```c
if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_APERF))
return NULL;
```
In `mperf_monitor.c` line 334:
```c
if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_APERF))
return NULL;
```
Both return error when APERF is **absent** (using `!`). The buggy
`get_freq_hardware()` was the only place doing the opposite — returning
error when APERF **is present**.
**b) Logical analysis of `get_freq_hardware()`:** The function reads
hardware frequency via `cpufreq_get_freq_hardware()` which reads
`cpuinfo_cur_freq` from sysfs. APERF/MPERF is the mechanism by which the
kernel determines actual hardware frequency. When APERF IS available,
the kernel CAN report accurate hardware frequency — so the function
SHOULD proceed. When APERF is NOT available, it SHOULD return error.
**c) Caller context in `debug_output_one()`:**
```516:517:tools/power/cpupower/utils/cpufreq-info.c
if (get_freq_hardware(cpu, 1) < 0)
get_freq_kernel(cpu, 1);
```
With the bug: On ALL modern x86 CPUs (which have APERF),
`get_freq_hardware()` always returns -EINVAL, so `cpupower frequency-
info -w` (hardware frequency query) always fails, and debug mode always
falls back to kernel frequency. The `--hwfreq`/`-w` option is completely
broken on modern systems.
With the fix: The function correctly reads hardware frequency when APERF
is available, and returns error (falling back to kernel method) only on
systems without APERF support.
### 5. Impact Assessment
- **Who is affected:** Virtually ALL modern x86 CPU users (Intel and
AMD) since they all have APERF/MPERF. The `CPUPOWER_CAP_APERF` is set
when `cpuid_ecx(6) & 0x1` (CPUID leaf 6, ECX bit 0 = APERF
availability), which has been present in x86 CPUs for well over a
decade.
- **What breaks:** `cpupower frequency-info --hwfreq` (`-w`) always
returns error on modern CPUs. The default debug output (`cpupower
frequency-info` or `-e`) never shows hardware-asserted frequency and
always falls back to kernel frequency.
- **Severity:** The `cpupower` tool is a userspace utility used for CPU
frequency monitoring and tuning. This bug makes a core feature
completely non-functional. It's not a kernel crash, but it's a real
functional breakage of an important diagnostic tool.
### 6. Scope and Risk
- **Change size:** Minimal — one character (`!` added to a condition).
This is about as small and surgical as a fix gets.
- **Risk of regression:** Essentially zero. The fix aligns the logic
with the clearly intended behavior (matching all other APERF checks in
the codebase) and restores a feature that was broken.
- **Files touched:** 1 file, 1 line changed.
- **Dependencies:** None. The fix is completely self-contained.
### 7. Applicability to Stable Trees
The buggy commit `26e16174f54d4` was merged for v6.14. It exists in the
v6.14 and later kernel releases. Therefore the fix is applicable to:
- 6.14.y (if still maintained)
- 6.15.y, 6.16.y, 6.17.y, 6.18.y, 6.19.y
The fix applies cleanly since no other code changes have touched this
specific condition.
### 8. Stable Kernel Criteria Assessment
1. **Obviously correct and tested:** Yes — the fix is trivially
verifiable by comparing with the two other APERF checks in the same
codebase and by logical analysis. It was submitted by Intel and
accepted by the maintainer.
2. **Fixes a real bug:** Yes — inverted capability check that completely
breaks the `--hwfreq` feature on modern CPUs.
3. **Important issue:** Yes — a core function of the `cpupower` tool is
broken on nearly all modern x86 hardware.
4. **Small and contained:** Yes — single character change in one file.
5. **No new features:** Correct — this is purely a bug fix restoring
intended behavior.
6. **Applies cleanly:** Yes — the buggy code exists unchanged in stable.
**YES**
tools/power/cpupower/utils/cpufreq-info.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/power/cpupower/utils/cpufreq-info.c b/tools/power/cpupower/utils/cpufreq-info.c
index 7d3732f5f2f6f..5fe01e516817e 100644
--- a/tools/power/cpupower/utils/cpufreq-info.c
+++ b/tools/power/cpupower/utils/cpufreq-info.c
@@ -270,7 +270,7 @@ static int get_freq_hardware(unsigned int cpu, unsigned int human)
{
unsigned long freq;
- if (cpupower_cpu_info.caps & CPUPOWER_CAP_APERF)
+ if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_APERF))
return -EINVAL;
freq = cpufreq_get_freq_hardware(cpu);
--
2.51.0
next prev parent reply other threads:[~2026-02-11 12:32 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-11 12:30 [PATCH AUTOSEL 6.19-5.10] s390/perf: Disable register readout on sampling events Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-5.10] arm64: Add support for TSV110 Spectre-BHB mitigation Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-5.10] xenbus: Use .freeze/.thaw to handle xenbus devices Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-5.10] s390/purgatory: Add -Wno-default-const-init-unsafe to KBUILD_CFLAGS Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-6.18] s390/boot: " Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-6.1] perf/arm-cmn: Support CMN-600AE Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-6.18] ntfs: ->d_compare() must not block Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-6.12] ACPI: x86: s2idle: Invoke Microsoft _DSM Function 9 (Turn On Display) Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-6.12] block: decouple secure erase size limit from discard size limit Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-5.10] sparc: don't reference obsolete termio struct for TC* constants Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-5.10] EFI/CPER: don't go past the ARM processor CPER record buffer Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19] ACPI: scan: Use async schedule function in acpi_scan_clear_dep_fn() Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-6.6] cpufreq: dt-platdev: Block the driver from probing on more QC platforms Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-5.10] EFI/CPER: don't dump the entire memory region Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-6.12] ACPI: battery: fix incorrect charging status when current is zero Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-6.18] rust: cpufreq: always inline functions using build_assert with arguments Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-6.18] blk-mq-sched: unify elevators checking for async requests Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-5.10] x86/xen/pvh: Enable PAE mode for 32-bit guest only when CONFIG_X86_PAE is set Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-6.12] APEI/GHES: ARM processor Error: don't go past allocated memory Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-6.18] md raid: fix hang when stopping arrays with metadata through dm-raid Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-5.10] tools/power cpupower: Reset errno before strtoull() Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-5.10] sparc: Synchronize user stack on fork and clone Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-5.10] blk-mq-debugfs: add missing debugfs_mutex in blk_mq_debugfs_register_hctxs() Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-5.10] rnbd-srv: Zero the rsp buffer before using it Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-6.12] alpha: fix user-space corruption during memory compaction Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-5.10] ACPICA: Abort AML bytecode execution when executing AML_FATAL_OP Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19] arm64: mte: Set TCMA1 whenever MTE is present in the kernel Sasha Levin
2026-02-11 12:30 ` Sasha Levin [this message]
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-5.15] ACPI: processor: Fix NULL-pointer dereference in acpi_processor_errata_piix4() Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-6.12] ACPI: resource: Add JWIPC JVC9100 to irq1_level_low_skip_override[] Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-6.6] perf/cxlpmu: Replace IRQF_ONESHOT with IRQF_NO_THREAD Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-6.6] md-cluster: fix NULL pointer dereference in process_metadata_update Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-5.10] APEI/GHES: ensure that won't go past CPER allocated record Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-6.12] powercap: intel_rapl: Add PL4 support for Ice Lake Sasha Levin
2026-02-11 12:30 ` [PATCH AUTOSEL 6.19-6.18] io_uring/timeout: annotate data race in io_flush_timeouts() Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260211123112.1330287-28-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=fj5851bi@fujitsu.com \
--cc=kaushlendra.kumar@intel.com \
--cc=patches@lists.linux.dev \
--cc=skhan@linuxfoundation.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox