From b76e95b51a53dafb2a9675d07bc1e08fa1ff1dc8 Mon Sep 17 00:00:00 2001 From: Jin Kyu Song Date: Wed, 8 May 2013 12:03:55 -0700 Subject: [PATCH] Add '-a' option for writing values to an MSR on all cpus Signed-off-by: Jin Kyu Song --- wrmsr.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 7 deletions(-) diff --git a/wrmsr.c b/wrmsr.c index ab87921..8a601b9 100644 --- a/wrmsr.c +++ b/wrmsr.c @@ -25,17 +25,20 @@ #include #include #include +#include +#include #include "version.h" static const struct option long_options[] = { {"help", 0, 0, 'h'}, {"version", 0, 0, 'V'}, + {"all", 0, 0, 'a'}, {"processor", 1, 0, 'p'}, {"cpu", 1, 0, 'p'}, {0, 0, 0, 0} }; -static const char short_options[] = "hVp:"; +static const char short_options[] = "hVap:"; const char *program; @@ -44,20 +47,43 @@ void usage(void) fprintf(stderr, "Usage: %s [options] regno value...\n" " --help -h Print this help\n" " --version -V Print current version\n" + " --all -a all processors\n" " --processor # -p Select processor number (default 0)\n", program); } +void wrmsr_on_cpu(uint32_t reg, int cpu, int valcnt, char *regvals[]); + +/* filter out ".", "..", "microcode" in /dev/cpu */ +int dir_filter(const struct dirent *dirp) +{ + if (isdigit(dirp->d_name[0])) + return 1; + else + return 0; +} + +void wrmsr_on_all_cpus(uint32_t reg, int valcnt, char *regvals[]) +{ + struct dirent **namelist; + int dir_entries; + + dir_entries = scandir("/dev/cpu", &namelist, dir_filter, 0); + while (dir_entries--) { + wrmsr_on_cpu(reg, atoi(namelist[dir_entries]->d_name), + valcnt, regvals); + free(namelist[dir_entries]); + } + free(namelist); +} + int main(int argc, char *argv[]) { uint32_t reg; - uint64_t data; - int fd; int c; int cpu = 0; unsigned long arg; char *endarg; - char msr_file_name[64]; program = argv[0]; @@ -71,6 +97,9 @@ int main(int argc, char *argv[]) fprintf(stderr, "%s: version %s\n", program, VERSION_STRING); exit(0); + case 'a': + cpu = -1; + break; case 'p': arg = strtoul(optarg, &endarg, 0); if (*endarg || arg > 255) { @@ -93,6 +122,21 @@ int main(int argc, char *argv[]) reg = strtoul(argv[optind++], NULL, 0); + if (cpu == -1) { + wrmsr_on_all_cpus(reg, argc - optind, &argv[optind]); + } else { + wrmsr_on_cpu(reg, cpu, argc - optind, &argv[optind]); + } + + exit(0); +} + +void wrmsr_on_cpu(uint32_t reg, int cpu, int valcnt, char *regvals[]) +{ + uint64_t data; + int fd; + char msr_file_name[64]; + sprintf(msr_file_name, "/dev/cpu/%d/msr", cpu); fd = open(msr_file_name, O_WRONLY); if (fd < 0) { @@ -109,8 +153,8 @@ int main(int argc, char *argv[]) } } - while (optind < argc) { - data = strtoull(argv[optind++], NULL, 0); + while (valcnt--) { + data = strtoull(*regvals++, NULL, 0); if (pwrite(fd, &data, sizeof data, reg) != sizeof data) { if (errno == EIO) { fprintf(stderr, @@ -127,5 +171,5 @@ int main(int argc, char *argv[]) close(fd); - exit(0); + return; }