Reading CPU model specific registers on linux

14,666

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.

Share:
14,666

Related videos on Youtube

Zwierzak
Author by

Zwierzak

Updated on September 18, 2022

Comments

  • Zwierzak
    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:

    Datasheet Vol 1

    Datasheet Vol 2

    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
      tijko over 7 years
      What does uname -r show and what arguments are you passing to rdmsr?
    • MSR
      MSR over 6 years
      There is no MSR 0x59c0. You cannot read what is not there.
  • Ruslan
    Ruslan almost 6 years
    If the problem were with permissions, you'd fail to open the file. The actual problem happens later, on pread, which returns EIO.
  • abu_bua
    abu_bua over 5 years
    That 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
    abu_bua over 5 years
    You are right, that means that the register doesn't exist.
  • Admin
    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
    Ruslan over 5 years
    @abu_bua actually this is right, and it nicely complements my answer. IA32—IA32_THERM_STATUS is at MCHBAR+0x59c0 in the memory space. Although it's indeed possible to read IA32_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
    abu_bua over 5 years
    Sorry, I missread the op' question!