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 <andriy.shevchenko@intel.com>
Assisted-by: GitHub-Copilot:Claude-Sonnet-4.6
Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
Len Brown 2026-05-06 10:00:00 -04:00
parent c03c1a1450
commit 481006fbcb

View File

@ -15,6 +15,7 @@
#include <sys/types.h>
#include <sched.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/resource.h>
#include <getopt.h>
#include <err.h>
@ -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)