summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2010-08-05 00:44:36 -0400
committerH. Peter Anvin <hpa@zytor.com>2010-08-04 23:11:49 -0700
commitd8e8ae15104c310893bb4eaab7a2d36b77cd9acb (patch)
tree48a80280ae703af6c80919d8031866339a4c9245
parentb1d9778d169efc1a336bcd9665daf5fd0b327572 (diff)
downloadmsr-tools-d8e8ae15104c310893bb4eaab7a2d36b77cd9acb.tar.gz
rdmsr, wrmsr: add '-a' parameter to operate on all processors
Now that even a laptop has multiple processors... it is handy to have the option to simultaneously read or write an MSR on all the processors in the system. We get the list of on-line processors from /proc/stat Signed-off-by: Len Brown <len.brown@intel.com> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--rdmsr.c70
-rw-r--r--wrmsr.c111
2 files changed, 137 insertions, 44 deletions
diff --git a/rdmsr.c b/rdmsr.c
index 5f173d7..f4be761 100644
--- a/rdmsr.c
+++ b/rdmsr.c
@@ -41,12 +41,15 @@ static const struct option long_options[] = {
{"zero-fill", 0, 0, '0'},
{"zero-pad", 0, 0, '0'},
{"raw", 0, 0, 'r'},
+ {"all", 0, 0, 'a'},
{"processor", 1, 0, 'p'},
{"cpu", 1, 0, 'p'},
{"bitfield", 1, 0, 'f'},
{0, 0, 0, 0}
};
-static const char short_options[] = "hVxXdoruc0p:f:";
+static const char short_options[] = "hVxXdoruc0ap:f:";
+
+static const char *proc_stat = "/proc/stat";
/* Number of decimal digits for a certain number of bits */
/* (int) ceil(log(2^n)/log(10)) */
@@ -84,23 +87,53 @@ void usage(void)
" --c-language -c Format output as a C language constant\n"
" --zero-pad -0 Output leading zeroes\n"
" --raw -r Raw binary output\n"
+ " --all -a all processors\n"
" --processor # -p Select processor number (default 0)\n"
" --bitfield h:l -f Output bits [h:l] only\n", program);
}
+void rdmsr_on_cpu(uint32_t reg, int cpu);
+
+void rdmsr_on_all_cpus(uint32_t reg)
+{
+ FILE *fp;
+ int retval;
+
+ fp = fopen(proc_stat, "r");
+ if (fp == NULL) {
+ perror(proc_stat);
+ exit(-1);
+ }
+
+ retval = fscanf(fp, "cpu %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n");
+ if (retval != 0) {
+ perror("/proc/stat format");
+ exit(-1);
+ }
+
+ for (;;) {
+ int cpu;
+
+ retval = fscanf(fp, "cpu%u %*d %*d %*d %*d %*d %*d %*d %*d %*d"
+ " %*d\n", &cpu);
+ if (retval != 1)
+ return;
+
+ rdmsr_on_cpu(reg, cpu);
+ }
+ fclose(fp);
+}
+
+unsigned int highbit = 63, lowbit = 0, bits;
+int mode = mo_hex;
+
int main(int argc, char *argv[])
{
uint32_t reg;
- uint64_t data;
- int c, fd;
- int mode = mo_hex;
+ int c;
int cpu = 0;
- unsigned int highbit = 63, lowbit = 0, bits;
unsigned long arg;
char *endarg;
- char *pat;
- int width;
- char msr_file_name[64];
program = argv[0];
@@ -139,6 +172,9 @@ int main(int argc, char *argv[])
case '0':
mode |= mo_fill;
break;
+ case 'a':
+ cpu = -1;
+ break;
case 'p':
arg = strtoul(optarg, &endarg, 0);
if (*endarg || arg > 255) {
@@ -168,6 +204,21 @@ int main(int argc, char *argv[])
reg = strtoul(argv[optind], NULL, 0);
+ if (cpu == -1)
+ rdmsr_on_all_cpus(reg);
+ else
+ rdmsr_on_cpu(reg, cpu);
+ exit(0);
+}
+void rdmsr_on_cpu(uint32_t reg, int cpu)
+{
+ uint64_t data;
+ int fd;
+ int mode = mo_hex;
+ char *pat;
+ int width;
+ char msr_file_name[64];
+
sprintf(msr_file_name, "/dev/cpu/%d/msr", cpu);
fd = open(msr_file_name, O_RDONLY);
if (fd < 0) {
@@ -308,6 +359,5 @@ int main(int argc, char *argv[])
if (pat)
printf(pat, width, data);
-
- exit(0);
+ return;
}
diff --git a/wrmsr.c b/wrmsr.c
index ab87921..a1a5eb6 100644
--- a/wrmsr.c
+++ b/wrmsr.c
@@ -31,12 +31,14 @@
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:";
+static const char *proc_stat = "/proc/stat";
const char *program;
void usage(void)
@@ -44,20 +46,85 @@ 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, uint64_t data, int cpu)
+{
+ 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) {
+ if (errno == ENXIO) {
+ fprintf(stderr, "wrmsr: No CPU %d\n", cpu);
+ exit(2);
+ } else if (errno == EIO) {
+ fprintf(stderr, "wrmsr: CPU %d doesn't support MSRs\n",
+ cpu);
+ exit(3);
+ } else {
+ perror("wrmsr: open");
+ exit(127);
+ }
+ }
+ if (pwrite(fd, &data, sizeof data, reg) != sizeof data) {
+ if (errno == EIO) {
+ fprintf(stderr,
+ "wrmsr: CPU %d cannot set MSR "
+ "0x%08"PRIx32" to 0x%016"PRIx64"\n",
+ cpu, reg, data);
+ exit(4);
+ } else {
+ perror("wrmsr: pwrite");
+ exit(127);
+ }
+ }
+ close(fd);
+}
+
+
+void wrmsr_on_all_cpus(uint32_t reg, uint64_t data)
+{
+ FILE *fp;
+ int retval;
+
+ fp = fopen(proc_stat, "r");
+ if (fp == NULL) {
+ perror(proc_stat);
+ exit(-1);
+ }
+
+ retval = fscanf(fp, "cpu %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n");
+ if (retval != 0) {
+ perror("/proc/stat format");
+ exit(-1);
+ }
+
+ for (;;) {
+ int cpu;
+
+ retval = fscanf(fp, "cpu%u %*d %*d %*d %*d %*d %*d %*d %*d "
+ "%*d %*d\n", &cpu);
+ if (retval != 1)
+ return;
+
+ wrmsr_on_cpu(reg, data, cpu);
+ }
+ fclose(fp);
+}
+
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 +138,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,39 +163,12 @@ int main(int argc, char *argv[])
reg = strtoul(argv[optind++], NULL, 0);
- sprintf(msr_file_name, "/dev/cpu/%d/msr", cpu);
- fd = open(msr_file_name, O_WRONLY);
- if (fd < 0) {
- if (errno == ENXIO) {
- fprintf(stderr, "wrmsr: No CPU %d\n", cpu);
- exit(2);
- } else if (errno == EIO) {
- fprintf(stderr, "wrmsr: CPU %d doesn't support MSRs\n",
- cpu);
- exit(3);
- } else {
- perror("wrmsr: open");
- exit(127);
- }
- }
-
while (optind < argc) {
data = strtoull(argv[optind++], NULL, 0);
- if (pwrite(fd, &data, sizeof data, reg) != sizeof data) {
- if (errno == EIO) {
- fprintf(stderr,
- "wrmsr: CPU %d cannot set MSR "
- "0x%08"PRIx32" to 0x%016"PRIx64"\n",
- cpu, reg, data);
- exit(4);
- } else {
- perror("wrmsr: pwrite");
- exit(127);
- }
- }
+ if (cpu == -1)
+ wrmsr_on_all_cpus(reg, data);
+ else
+ wrmsr_on_cpu(reg, data, cpu);
}
-
- close(fd);
-
exit(0);
}