Reading CPU model specific registers on linux
Solution 1
Notice the line:
pread(3, 0x7ffcd2bddf78, 8, 22976) = -1 EIO (Input/output error)
where 22976 = 0x59c0
, which is the MSR address you are trying to read. The EIO
error appears when in msr_read function the call to rdmsr_safe_on_cpu leading to rdmsr_safe macro calling the native_read_msr_safe function results in #GP exception on executing the RDMSR
instruction.
So, your CPU doesn't support the MSR you're trying to read.
But, as pointed out in the answer by duskwuff, you're reading the wrong datasheet. The offset 0x59c0 is the offset relative to MCHBAR
, which points to the memory space – it's not an address of any MSR. To find the correct MSR address you should read Volume 3B of the Intel's manual – System Programming Guide, namely, its chapter 14.4. There it's said that IA32_THERM_STATUS
(note, not IA32—IA32_THERM_STATUS
) MSR has address 0x19c.
Solution 2
You have misread the datasheet.
IA32—IA32_THERM_STATUS
is a configuration register in the platform PCI device, not a CPU MSR. It cannot be read using rdmsr
.
Related videos on Youtube
Zwierzak
Updated on September 18, 2022Comments
-
Zwierzak over 1 year
I am running Ubuntu 15.10 but testes it also on Debian. I have Intel i5-5675C processor. I am using msr-tools-1.3 to do it. I am able to read register 0x00001a2 with the following command:
rdmsr 0x00001a2
It gives me some good output according to the datasheet. However I can't do anything handy with this value.
I would like to read some model-specific registers from my CPU associated with temperature or voltage or something useful. Datasheet info:
From datasheet Vol 2: 5.2.52 IA32-IA32_THERM_STATUS,
rdmsr 0x000059c0 rdmsr: CPU 0 cannot read MSR 0x000059c0
I get an error like this. I have tried running it on all 4 CPU cores and have enabled modprobe and files are present in /dev/cpu/{CPU_ID}/msr:
sudo modprobe msr
Here is strace output:
sudo strace rdmsr 0x59c0 execve("/usr/sbin/rdmsr", ["rdmsr", "0x59c0"], [/* 25 vars */]) = 0 brk(0) = 0x84d000 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe87cb3f000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=92026, ...}) = 0 mmap(NULL, 92026, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fe87cb28000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0`\v\2\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=1869392, ...}) = 0 mmap(NULL, 3972864, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fe87c554000 mprotect(0x7fe87c714000, 2097152, PROT_NONE) = 0 mmap(0x7fe87c914000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c0000) = 0x7fe87c914000 mmap(0x7fe87c91a000, 16128, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fe87c91a000 close(3) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe87cb27000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe87cb26000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe87cb25000 arch_prctl(ARCH_SET_FS, 0x7fe87cb26700) = 0 mprotect(0x7fe87c914000, 16384, PROT_READ) = 0 mprotect(0x602000, 4096, PROT_READ) = 0 mprotect(0x7fe87cb41000, 4096, PROT_READ) = 0 munmap(0x7fe87cb28000, 92026) = 0 open("/dev/cpu/0/msr", O_RDONLY) = 3 pread(3, 0x7ffcd2bddf78, 8, 22976) = -1 EIO (Input/output error) write(2, "rdmsr: CPU 0 cannot read MSR 0x0"..., 40rdmsr: CPU 0 cannot read MSR 0x000059c0 ) = 40 exit_group(4) = ? +++ exited with 4 +++
-
tijko over 7 yearsWhat does
uname -r
show and what arguments are you passing tordmsr
? -
MSR over 6 yearsThere is no MSR 0x59c0. You cannot read what is not there.
-
-
Ruslan almost 6 yearsIf the problem were with permissions, you'd fail to open the file. The actual problem happens later, on
pread
, which returnsEIO
. -
abu_bua over 5 yearsThat is wrong! You can of course read the IA32_THERM_STATUS (in most cases address 0x19c). But you have to load the msr kernel before.
-
abu_bua over 5 yearsYou are right, that means that the register doesn't exist.
-
Admin over 5 years@abu_bua Context is important. The OP was specifically referring to a register described in the datasheet with offset 59c0h; this register is part of the platform PCI device. It's on page 144 of intel.com/content/dam/www/public/us/en/documents/datasheets/…
-
Ruslan over 5 years@abu_bua actually this is right, and it nicely complements my answer.
IA32—IA32_THERM_STATUS
is atMCHBAR+0x59c0
in the memory space. Although it's indeed possible to readIA32_THERM_STATUS
via the MSR interface at address 0x19c, the offset 0x59c0 found by the OP is related to MMIO, not MSRs. So definitely, the OP has misunderstood the datasheet. -
abu_bua over 5 yearsSorry, I missread the op' question!