From: Kaushlendra Kumar kaushlendra.kumar@intel.com
[ Upstream commit 62127655b7ab7b8c2997041aca48a81bf5c6da0c ]
The fopen_or_die() function was previously hardcoded to open files in read-only mode ("r"), ignoring the mode parameter passed to it. This patch corrects fopen_or_die() to use the provided mode argument, allowing for flexible file access as intended.
Additionally, the call to fopen_or_die() in err_on_hypervisor() incorrectly used the mode "ro", which is not a valid fopen mode. This is fixed to use the correct "r" mode.
Signed-off-by: Kaushlendra Kumar kaushlendra.kumar@intel.com Signed-off-by: Len Brown len.brown@intel.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
YES
- What it fixes - Corrects `fopen_or_die()` to honor the caller-provided mode instead of hardcoding read-only. This restores intended API semantics and prevents subtle bugs if any future or out-of-tree code uses it for write/append. - Fixed line: tools/power/x86/x86_energy_perf_policy/x86_energy_perf _policy.c:634 - Replaces an invalid fopen mode string `"ro"` with the valid `"r"` in `err_on_hypervisor()`. While previously masked by the hardcoded `"r"` inside `fopen_or_die()`, this was a latent bug and is now properly fixed. - Fixed line: tools/power/x86/x86_energy_perf_policy/x86_energy_perf _policy.c:648
- Scope and risk - Small, contained, two-line behavioral fixes in a userspace tool. No API or architectural changes; no kernel subsystems touched. - Call sites in this tool currently pass `"r"` (e.g., reading sysfs or `/proc`) and writes use plain `fopen("w")`, not `fopen_or_die()`. So runtime behavior for existing paths remains unchanged and risk of regression is effectively zero. - Read uses: tools/power/x86/x86_energy_perf_policy/x86_energy_perf_ policy.c:1254, tools/power/x86/x86_energy_perf_policy/x86_energy_p erf_policy.c:1300 - Direct write uses (not via `fopen_or_die()`): tools/power/x86/x86_ energy_perf_policy/x86_energy_perf_policy.c:972 - Harmonizes behavior with the sibling tool `turbostat`, whose `fopen_or_die()` already uses the provided mode argument. - Reference: tools/power/x86/turbostat/turbostat.c:4353
- User impact and history - This is a real bug: the function’s signature promised a mode, but it was ignored. That could cause confusing failures if any code attempted to open with `"w"`/`"a"` through `fopen_or_die()`. The invalid `"ro"` string is also a correctness issue (would fail if the mode were ever honored). - The bug has been present since the VM error-handling addition in 2020, and persists in released stable tags (e.g., v5.10, v5.15, v6.1, v6.6, v6.8, v6.10) where `err_on_hypervisor()` still passes `"ro"` and `fopen_or_die()` hardcodes `"r"`. This patch addresses both together, eliminating the latent defect in those series.
- Stable criteria - Important bugfix (correctness, latent functional bug, removes invalid mode usage). - Minimal, localized change with negligible regression risk. - No new features or architectural shifts; limited to `tools/power/x86`. - Improves consistency and future-proofing of the tool.
Given these points, this change is a strong candidate for stable backport.
.../power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c b/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c index ebda9c366b2ba..c883f211dbcc9 100644 --- a/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c +++ b/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c @@ -630,7 +630,7 @@ void cmdline(int argc, char **argv) */ FILE *fopen_or_die(const char *path, const char *mode) { - FILE *filep = fopen(path, "r"); + FILE *filep = fopen(path, mode);
if (!filep) err(1, "%s: open failed", path); @@ -644,7 +644,7 @@ void err_on_hypervisor(void) char *buffer;
/* On VMs /proc/cpuinfo contains a "flags" entry for hypervisor */ - cpuinfo = fopen_or_die("/proc/cpuinfo", "ro"); + cpuinfo = fopen_or_die("/proc/cpuinfo", "r");
buffer = malloc(4096); if (!buffer) {