From 481006fbcb22ba1f134283c017aa3ae8a67e0d59 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Wed, 6 May 2026 10:00:00 -0400 Subject: [PATCH] x86_energy_perf_policy: Rewrite Linux/Android MSR path discovery First check that the Linux MSR driver path exists, modprobe if no. If still no, then check that the Android MSR driver path exists. Read or Write permissions are handled at run-time in the get_msr()/put_msr() error paths. Create set_msr_path() helper. Return -1 for all fatal errors. Suggested-by: Andy Shevchenko Assisted-by: GitHub-Copilot:Claude-Sonnet-4.6 Signed-off-by: Len Brown --- .../x86_energy_perf_policy.c | 73 ++++++++++++------- 1 file changed, 47 insertions(+), 26 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 0dc959e30076..8a15093a485e 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 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -98,6 +99,7 @@ unsigned char update_platform_profile; int soc_slider_balance; int soc_slider_offset; char platform_profile[64]; +char msr_path[64]; #define PATH_TO_CPU "/sys/devices/system/cpu/" #define SYSFS_PATH_MAX 255 @@ -799,21 +801,32 @@ void err_on_hypervisor(void) err(-1, "not supported on this virtual machine"); } +/* + * if (use_android_msr_path) + * msr_path = /dev/msr%d // Android + * else + * msr_path = /dev/cpu/%d/msr // Linux + */ +static void set_msr_path(int cpu) +{ + if (snprintf(msr_path, sizeof(msr_path), use_android_msr_path ? "/dev/msr%d" : "/dev/cpu/%d/msr", cpu) >= (int)sizeof(msr_path)) + err(-1, "MSR path buffer overflow for cpu%d", cpu); +} + int get_msr(int cpu, int offset, unsigned long long *msr) { int retval; - char pathname[32]; int fd; - sprintf(pathname, use_android_msr_path ? "/dev/msr%d" : "/dev/cpu/%d/msr", cpu); - fd = open(pathname, O_RDONLY); + set_msr_path(cpu); + fd = open(msr_path, O_RDONLY); if (fd < 0) - err(-1, "%s open failed, try chown or chmod +r %s, or run as root", pathname, use_android_msr_path ? "/dev/msr*" : "/dev/cpu/*/msr"); + err(-1, "%s open failed, try chown or chmod +r, or run as root", msr_path); retval = pread(fd, msr, sizeof(*msr), offset); if (retval != sizeof(*msr)) { err_on_hypervisor(); - err(-1, "%s offset 0x%llx read failed", pathname, (unsigned long long)offset); + err(-1, "%s offset 0x%llx read failed", msr_path, (unsigned long long)offset); } if (debug > 1) @@ -825,14 +838,13 @@ int get_msr(int cpu, int offset, unsigned long long *msr) int put_msr(int cpu, int offset, unsigned long long new_msr) { - char pathname[32]; int retval; int fd; - sprintf(pathname, use_android_msr_path ? "/dev/msr%d" : "/dev/cpu/%d/msr", cpu); - fd = open(pathname, O_RDWR); + set_msr_path(cpu); + fd = open(msr_path, O_RDWR); if (fd < 0) - err(-1, "%s open failed, try chown or chmod +r %s, or run as root", pathname, use_android_msr_path ? "/dev/msr*" : "/dev/cpu/*/msr"); + err(-1, "%s open failed, try chown or chmod +w, or run as root", msr_path); retval = pwrite(fd, &new_msr, sizeof(new_msr), offset); if (retval != sizeof(new_msr)) @@ -1601,32 +1613,41 @@ void set_base_cpu(void) err(-ENODEV, "No valid cpus found"); } -static void probe_android_msr_path(void) +/* return 0 if path exists */ +static int check_msr_path(void) { struct stat sb; - char test_path[32]; - sprintf(test_path, "/dev/msr%d", base_cpu); - if (stat(test_path, &sb) == 0) - use_android_msr_path = 1; + return stat(msr_path, &sb); } +/* + * Check Linux MSR path + * If it fails, try modprobe and check it again + * If still no joy, enable Android path and try again + */ void probe_dev_msr(void) { - struct stat sb; - char pathname[32]; + int retval; - probe_android_msr_path(); + use_android_msr_path = 0; + set_msr_path(base_cpu); + if (check_msr_path() == 0) + return; - sprintf(pathname, use_android_msr_path ? "/dev/msr%d" : "/dev/cpu/%d/msr", base_cpu); - if (stat(pathname, &sb)) { - if (system("/sbin/modprobe msr > /dev/null 2>&1")) { - if (use_android_msr_path) - err(-5, "no /dev/msr0, Try \"# modprobe msr\" "); - else - err(-5, "no /dev/cpu/0/msr, Try \"# modprobe msr\" "); - } - } + retval = system("/sbin/modprobe msr > /dev/null 2>&1"); + + if (check_msr_path() == 0) + return; + + use_android_msr_path = 1; + set_msr_path(base_cpu); + if (check_msr_path() == 0) + return; + + if (WIFEXITED(retval)) + retval = WEXITSTATUS(retval); + errx(-1, "\"msr\" driver support required, modprobe msr returned %d", retval); } static void get_cpuid_or_exit(unsigned int leaf, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx)