* [PATCH 03/16] x86_energy_perf_policy: Harden with strtol()
2026-10-27 19:01 ` [PATCH 01/16] x86_energy_perf_policy: Rewrite Linux/Android MSR path discovery Len Brown
@ 2026-10-27 19:01 ` Len Brown
2026-10-27 19:01 ` [PATCH 07/16] x86_energy_perf_policy: Bound package iteration Len Brown
` (3 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Len Brown @ 2026-10-27 19:01 UTC (permalink / raw)
To: linux-pm; +Cc: Andy Shevchenko, Len Brown
From: Len Brown <len.brown@intel.com>
Replace atoi() with strtol() and proper error checking when parsing the
--hwp-use-pkg command-line argument value, and other spots.
Add explicit check that value is in valid range [0, 1].
Update associated error message strings.
parse_optarg_string() now returns long, as returned from strtol().
Assisted-by: GitHub-Copilot:Claude-Sonnet-4.6
Signed-off-by: Len Brown <len.brown@intel.com>
---
.../x86_energy_perf_policy.c | 71 ++++++++++---------
1 file changed, 39 insertions(+), 32 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 da89b267f357..d53427a059f3 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
@@ -191,7 +191,7 @@ int parse_cmdline_epb(int i)
return ENERGY_PERF_BIAS_PERFORMANCE;
}
if (i < 0 || i > ENERGY_PERF_BIAS_POWERSAVE)
- errx(1, "--epb must be from 0 to 15");
+ errx(1, "--epb must be 0 through 15");
return i;
}
@@ -305,8 +305,8 @@ int parse_cmdline_hwp_epp(int i)
case OPTARG_PERFORMANCE:
return HWP_EPP_PERFORMANCE;
}
- if (i < 0 || i > 0xff) {
- fprintf(stderr, "--hwp-epp must be from 0 to 0xff\n");
+ if (i < 0 || i > 255) {
+ fprintf(stderr, "--hwp-epp must be 0 through 255\n");
usage();
}
return i;
@@ -332,9 +332,9 @@ int parse_cmdline_turbo(int i)
return i;
}
-int parse_optarg_string(char *s)
+long parse_optarg_string(char *s)
{
- int i;
+ long i;
char *endptr;
if (!strncmp(s, "default", 7))
@@ -355,19 +355,13 @@ int parse_optarg_string(char *s)
if (!strncmp(s, "performance", 11))
return OPTARG_PERFORMANCE;
+ errno = 0;
i = strtol(s, &endptr, 0);
- if (s == endptr) {
- fprintf(stderr, "no digits in \"%s\"\n", s);
+ if (endptr == s || errno == ERANGE || i < 0 || i > 255) {
+ warnx("bad value \"%s\"", s);
usage();
}
- if (i == LONG_MIN || i == LONG_MAX)
- errx(-1, "%s", s);
- if (i > 0xFF)
- errx(-1, "%d (0x%x) must be < 256", i, i);
-
- if (i < 0)
- errx(-1, "%d (0x%x) must be >= 0", i, i);
return i;
}
@@ -424,9 +418,10 @@ void parse_cmdline_cpu(char *s)
int end_cpu;
startp++;
+ errno = 0;
end_cpu = strtol(startp, &endp, 10);
- if (startp == endp)
- continue;
+ if (startp == endp || errno == ERANGE)
+ errx(1, "Confused by end_cpu '%s'", startp);
while (cpu <= end_cpu) {
if (cpu > max_cpu_num)
@@ -469,11 +464,11 @@ void parse_cmdline_cpu(char *s)
break;
}
+ errno = 0;
cpu = strtol(startp, &endp, 10);
- if (startp == endp)
+ if (startp == endp || errno == ERANGE || cpu < 0 || cpu > max_cpu_num)
errx(1, "--cpu cpu-set: confused by '%s'", startp);
- if (cpu > max_cpu_num)
- errx(1, "Requested cpu%d exceeds max cpu%d", cpu, max_cpu_num);
+
CPU_SET_S(cpu, cpu_setsize, cpu_selected_set);
startp = endp;
}
@@ -504,9 +499,10 @@ void parse_cmdline_pkg(char *s)
int end_pkg;
startp++;
+ errno = 0;
end_pkg = strtol(startp, &endp, 10);
- if (startp == endp)
- continue;
+ if (startp == endp || errno == ERANGE)
+ errx(1, "Confused by end_pkg '%s'", startp);
while (pkg <= end_pkg) {
if (pkg > max_pkg_num)
@@ -523,9 +519,11 @@ void parse_cmdline_pkg(char *s)
return;
}
+ errno = 0;
pkg = strtol(startp, &endp, 10);
- if (pkg > max_pkg_num)
- errx(1, "Requested pkg%d Exceeds max pkg%d", pkg, max_pkg_num);
+ if (startp == endp || errno == ERANGE || pkg < 0 || pkg > max_pkg_num)
+ errx(1, "Confused by pkg '%s'", startp);
+
pkg_selected_set |= 1 << pkg;
startp = endp;
}
@@ -546,6 +544,7 @@ static int parse_cmdline_int(const char *s, int *out)
char *endp;
long val;
+ errno = 0;
val = strtol(s, &endp, 0);
if (endp == s || errno == ERANGE)
return -1;
@@ -714,13 +713,19 @@ void cmdline(int argc, char **argv)
case 't':
turbo_update_value = parse_cmdline_turbo(parse_optarg_string(optarg));
break;
- case 'u':
- update_hwp_use_pkg++;
- if (atoi(optarg) == 0)
- req_update.hwp_use_pkg = 0;
- else
- req_update.hwp_use_pkg = 1;
- break;
+ case 'u': {
+ char *endp;
+ long val;
+
+ update_hwp_use_pkg++;
+
+ errno = 0;
+ val = strtol(optarg, &endp, 10);
+ if (endp == optarg || errno == ERANGE || val < 0 || val > 1)
+ errx(1, "--hwp-use-pkg: must be 0 or 1");
+ req_update.hwp_use_pkg = val;
+ break;
+ }
case 'v':
print_version();
exit(0);
@@ -1016,8 +1021,9 @@ static int get_epb_sysfs(int cpu)
if (!read_sysfs(path, linebuf, 3))
return -1;
+ errno = 0;
val = strtol(linebuf, &endp, 0);
- if (endp == linebuf || errno == ERANGE)
+ if (endp == linebuf || errno == ERANGE || val < 0 || val > 15)
return -1;
return (int)val;
@@ -1040,8 +1046,9 @@ static int set_epb_sysfs(int cpu, int val)
if (ret <= 0)
return -1;
+ errno = 0;
val = strtol(linebuf, &endp, 0);
- if (endp == linebuf || errno == ERANGE)
+ if (endp == linebuf || errno == ERANGE || val < 0 || val > 15)
return -1;
return (int)val;
--
2.45.2
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 07/16] x86_energy_perf_policy: Bound package iteration
2026-10-27 19:01 ` [PATCH 01/16] x86_energy_perf_policy: Rewrite Linux/Android MSR path discovery Len Brown
2026-10-27 19:01 ` [PATCH 03/16] x86_energy_perf_policy: Harden with strtol() Len Brown
@ 2026-10-27 19:01 ` Len Brown
2026-10-27 19:01 ` [PATCH 08/16] x86_energy_perf_policy: Cleanup: Define HWP_WINDOW_MAX_USEC Len Brown
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Len Brown @ 2026-10-27 19:01 UTC (permalink / raw)
To: linux-pm; +Cc: Andy Shevchenko, Len Brown
From: Len Brown <len.brown@intel.com>
Add explicit bounds checking against MAX_PACKAGES in for_packages()
to prevent potential out-of-bounds bit shift operations.
Also, use consistent shift idiom: (1ULL << pkg_num)
Assisted-by: GitHub-Copilot:Claude-Sonnet-4.6
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
.../x86/x86_energy_perf_policy/x86_energy_perf_policy.c | 8 ++++----
1 file changed, 4 insertions(+), 4 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 e79462f93f3a..2d77f465f1ee 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
@@ -509,7 +509,7 @@ void parse_cmdline_pkg(char *s)
while (pkg <= end_pkg) {
if (pkg > max_pkg_num)
errx(1, "Requested pkg%d exceeds max pkg%d", pkg, max_pkg_num);
- pkg_selected_set |= 1 << pkg;
+ pkg_selected_set |= 1ULL << pkg;
pkg++;
}
startp = endp;
@@ -526,7 +526,7 @@ void parse_cmdline_pkg(char *s)
if (startp == endp || errno == ERANGE || pkg < 0 || pkg > max_pkg_num)
errx(1, "Confused by pkg '%s'", startp);
- pkg_selected_set |= 1 << pkg;
+ pkg_selected_set |= 1ULL << pkg;
startp = endp;
}
}
@@ -535,8 +535,8 @@ void for_packages(unsigned long long pkg_set, int (func) (int))
{
int pkg_num;
- for (pkg_num = 0; pkg_num <= max_pkg_num; ++pkg_num) {
- if (pkg_set & (1UL << pkg_num))
+ for (pkg_num = 0; pkg_num <= max_pkg_num && pkg_num < MAX_PACKAGES; ++pkg_num) {
+ if (pkg_set & (1ULL << pkg_num))
func(pkg_num);
}
}
--
2.45.2
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 08/16] x86_energy_perf_policy: Cleanup: Define HWP_WINDOW_MAX_USEC
2026-10-27 19:01 ` [PATCH 01/16] x86_energy_perf_policy: Rewrite Linux/Android MSR path discovery Len Brown
2026-10-27 19:01 ` [PATCH 03/16] x86_energy_perf_policy: Harden with strtol() Len Brown
2026-10-27 19:01 ` [PATCH 07/16] x86_energy_perf_policy: Bound package iteration Len Brown
@ 2026-10-27 19:01 ` Len Brown
2026-10-27 19:01 ` [PATCH 09/16] x86_energy_perf_policy: Cleanup: Define BCLK_MHZ Len Brown
2026-10-27 19:02 ` [PATCH 15/16] x86_energy_perf_policy: Simplify write_sysfs() return type Len Brown
4 siblings, 0 replies; 7+ messages in thread
From: Len Brown @ 2026-10-27 19:01 UTC (permalink / raw)
To: linux-pm; +Cc: Andy Shevchenko, Len Brown
From: Len Brown <len.brown@intel.com>
Define HWP_WINDOW_MAX_USEC
Doing so pointed out that it should be unsigned,
so change associated code that touches it to use unsigned.
Assisted-by: GitHub-Copilot:Claude-Sonnet-4.6
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
.../x86_energy_perf_policy/x86_energy_perf_policy.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 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 2d77f465f1ee..5fb6b0883e55 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
@@ -34,6 +34,9 @@
#define OPTARG_BALANCE_PERFORMANCE (INT_MAX - 4)
#define OPTARG_PERFORMANCE (INT_MAX - 5)
+/* Maximum HWP activity window duration in microseconds */
+#define HWP_WINDOW_MAX_USEC 1270000000U
+
struct msr_hwp_cap {
unsigned char highest;
unsigned char guaranteed;
@@ -259,7 +262,7 @@ int parse_cmdline_hwp_desired(int i)
return i;
}
-int parse_cmdline_hwp_window(int i)
+unsigned int parse_cmdline_hwp_window(unsigned int i)
{
unsigned int exponent;
@@ -273,13 +276,13 @@ int parse_cmdline_hwp_window(int i)
case OPTARG_PERFORMANCE:
return 0;
}
- if (i < 0 || i > 1270000000) {
- fprintf(stderr, "--hwp-window: 0 for auto; 1 - 1270000000 usec for window duration\n");
+ if (i > HWP_WINDOW_MAX_USEC) {
+ fprintf(stderr, "--hwp-window: 0 for auto; 1 - %u usec for window duration\n", HWP_WINDOW_MAX_USEC);
usage();
}
for (exponent = 0;; ++exponent) {
if (debug)
- printf("%d 10^%d\n", i, exponent);
+ printf("%u 10^%d\n", i, exponent);
if (i <= 127)
break;
@@ -287,7 +290,7 @@ int parse_cmdline_hwp_window(int i)
i = i / 10;
}
if (debug)
- fprintf(stderr, "%d*10^%d: 0x%x\n", i, exponent, (exponent << 7) | i);
+ fprintf(stderr, "%u*10^%d: 0x%x\n", i, exponent, (exponent << 7) | i);
return (exponent << 7) | i;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 09/16] x86_energy_perf_policy: Cleanup: Define BCLK_MHZ
2026-10-27 19:01 ` [PATCH 01/16] x86_energy_perf_policy: Rewrite Linux/Android MSR path discovery Len Brown
` (2 preceding siblings ...)
2026-10-27 19:01 ` [PATCH 08/16] x86_energy_perf_policy: Cleanup: Define HWP_WINDOW_MAX_USEC Len Brown
@ 2026-10-27 19:01 ` Len Brown
2026-10-27 19:02 ` [PATCH 15/16] x86_energy_perf_policy: Simplify write_sysfs() return type Len Brown
4 siblings, 0 replies; 7+ messages in thread
From: Len Brown @ 2026-10-27 19:01 UTC (permalink / raw)
To: linux-pm; +Cc: Andy Shevchenko, Len Brown
From: Len Brown <len.brown@intel.com>
Replace the hardcoded value 100 with a named symbolic constant BCLK_MHZ in
ratio_2_sysfs_khz() to document the assumed bus clock frequency.
Assisted-by: GitHub-Copilot:Claude-Sonnet-4.6
Signed-off-by: Len Brown <len.brown@intel.com>
---
.../x86/x86_energy_perf_policy/x86_energy_perf_policy.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
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 5fb6b0883e55..0a67b6f5381c 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
@@ -37,6 +37,10 @@
/* Maximum HWP activity window duration in microseconds */
#define HWP_WINDOW_MAX_USEC 1270000000U
+/* Nominal bus clock frequency in MHz - assumed for all HWP systems */
+#define BCLK_MHZ 100
+#define KHZ_PER_MHZ 1000
+
struct msr_hwp_cap {
unsigned char highest;
unsigned char guaranteed;
@@ -1163,7 +1167,7 @@ int print_pkg_msrs(int pkg)
*/
int ratio_2_sysfs_khz(int ratio)
{
- int bclk_khz = 100 * 1000; /* 100,000 KHz = 100 MHz */
+ int bclk_khz = BCLK_MHZ * KHZ_PER_MHZ; /* Convert MHz to KHz */
return ratio * bclk_khz;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 15/16] x86_energy_perf_policy: Simplify write_sysfs() return type
2026-10-27 19:01 ` [PATCH 01/16] x86_energy_perf_policy: Rewrite Linux/Android MSR path discovery Len Brown
` (3 preceding siblings ...)
2026-10-27 19:01 ` [PATCH 09/16] x86_energy_perf_policy: Cleanup: Define BCLK_MHZ Len Brown
@ 2026-10-27 19:02 ` Len Brown
4 siblings, 0 replies; 7+ messages in thread
From: Len Brown @ 2026-10-27 19:02 UTC (permalink / raw)
To: linux-pm; +Cc: Andy Shevchenko, Len Brown, Amarjeet
From: Len Brown <len.brown@intel.com>
Simplify error check in write_sysfs().
Suggested-by: Amarjeet <amarjeet@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
.../x86_energy_perf_policy/x86_energy_perf_policy.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 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 904ab803f5c7..2b4d48b520f2 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
@@ -900,14 +900,14 @@ static unsigned int read_sysfs(const char *path, char *buf, size_t buflen)
return (unsigned int)numread;
}
-static unsigned int write_sysfs(const char *path, char *buf, size_t buflen)
+static int write_sysfs(const char *path, char *buf, size_t buflen)
{
ssize_t numwritten;
int fd;
fd = open(path, O_WRONLY);
if (fd == -1)
- return 0;
+ return -1;
numwritten = write(fd, buf, buflen - 1);
if (numwritten < 1) {
@@ -919,7 +919,7 @@ static unsigned int write_sysfs(const char *path, char *buf, size_t buflen)
close(fd);
- return (unsigned int)numwritten;
+ return 0;
}
static int sysfs_read_string(const char *path, char *buf, size_t buflen)
@@ -944,7 +944,7 @@ static int sysfs_write_string(const char *path, const char *buf)
len = snprintf(tmp, sizeof(tmp), "%s\n", buf);
if (len < 0 || len >= (int)sizeof(tmp))
return -1;
- return write_sysfs(path, tmp, (size_t)len + 1) ? 0 : -1;
+ return write_sysfs(path, tmp, (size_t)len + 1);
}
void print_hwp_cap(int cpu, struct msr_hwp_cap *cap, char *str)
@@ -1050,7 +1050,6 @@ static int set_epb_sysfs(int cpu, int val)
char path[SYSFS_PATH_MAX];
char linebuf[3];
char *endp;
- int ret;
if (!has_epb)
return -1;
@@ -1058,8 +1057,7 @@ static int set_epb_sysfs(int cpu, int val)
snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/power/energy_perf_bias", cpu);
snprintf(linebuf, sizeof(linebuf), "%d", val);
- ret = write_sysfs(path, linebuf, 3);
- if (ret <= 0)
+ if (write_sysfs(path, linebuf, 3))
return -1;
errno = 0;
--
2.45.2
^ permalink raw reply related [flat|nested] 7+ messages in thread