Skip to content
This repository has been archived by the owner on Aug 5, 2022. It is now read-only.

Commit

Permalink
Add '-a' option for writing values to an MSR on all cpus
Browse files Browse the repository at this point in the history
Signed-off-by: Jin Kyu Song <[email protected]>
  • Loading branch information
Jin Kyu Song committed May 9, 2013
1 parent 583a157 commit b76e95b
Showing 1 changed file with 51 additions and 7 deletions.
58 changes: 51 additions & 7 deletions wrmsr.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,20 @@
#include <getopt.h>
#include <inttypes.h>
#include <sys/types.h>
#include <dirent.h>
#include <ctype.h>

#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;

Expand All @@ -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];

Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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,
Expand All @@ -127,5 +171,5 @@ int main(int argc, char *argv[])

close(fd);

exit(0);
return;
}

0 comments on commit b76e95b

Please sign in to comment.