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)