reading reg from kernel driver module

261 views
Skip to first unread message

Ravindran Shanmugam

unread,
Oct 21, 2020, 1:44:38 PM10/21/20
to inside...@googlegroups.com
Hi,
How to read "/dev/cpu/0/msr" from a kernel driver. I think  msr is a model specific register in intel.  Datasheet says 'msr' can be accessed with rdmsr instruction and I need to read msr offset 0x1A2 and 0x19C (to read the core temperature which is available in msr#1a2). Not sure, how to invoke the assembly instruction in the driver code.
Any idea.?
Regards,
Ravi

Anil Kumar Pugalia

unread,
Oct 26, 2020, 12:58:21 PM10/26/20
to inside...@googlegroups.com

Typically, for such things there should be some kernel function or macro mapped to the assembly code. Search for something in the arch specific headers related to core (temperature) etc

Thanks & Regards
Anil
Passion: http://sysplay.in (Playing with Systems)
Ravindran Shanmugam wrote on 21/10/20 11:14 pm:
--
You received this message because you are subscribed to the Google Groups "SysPlay's Inside Linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to inside_linux...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/inside_linux/CAC4QDGcHB5Y%3DNF9JG5jHFbC-Afx3ga2J8XXFyNGZF%2BDbUya4eA%40mail.gmail.com.

muralidhara mk

unread,
Oct 28, 2020, 9:36:14 AM10/28/20
to inside...@googlegroups.com
Hi Ravindran,

You can use this simple example to read the MSR register addresses 0x1A2 and 0x19C


#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>

void rdmsr_on_cpu(uint64_t, int);
void read_msr_reg(int, uint64_t, int);

int main(int argc, char *argv[])
{
//      uint64_t reg = 0x1A2;
        uint64_t reg = 0x19C;
        int cpu = 0;   // Pass required CPU number

        rdmsr_on_cpu(reg, cpu);
}

void read_msr_reg(int fd, uint64_t reg, int cpu)
{
        uint64_t data;

        if (pread(fd, &data, sizeof(data), reg) != sizeof(data)) {
                printf("##### pread error\n");
                if (errno == EIO) {
                        fprintf(stderr, "rdmsr: CPU %d cannot read "
                                "MSR 0x%lx\n", cpu, reg);
                        exit(4);
                } else {
                        perror("rdmsr: pread");
                        exit(127);
                }
        }
//      data = (data & 0x1f00) >> 8;  Read particular bits as per spec
        printf("MSR reg data: %lx\n", data);
}

void rdmsr_on_cpu(uint64_t reg, int cpu)
{
        int i, fd;
        char msr_file_name[64];

        sprintf(msr_file_name, "/dev/cpu/%d/msr", cpu);

        fd = open(msr_file_name, O_RDWR);
        if (fd < 0) {
                if (errno == ENXIO) {
                        fprintf(stderr, "rdmsr: No CPU %d\n", cpu);
                        exit(2);
                } else if (errno == EIO) {
                        fprintf(stderr, "rdmsr: CPU %d doesn't support MSRs\n", cpu);
                        exit(3);
                } else {
                        perror("rdmsr: open failed");
                        exit(127);
                }
        }

        read_msr_reg(fd, reg, cpu);

        close(fd);
}


Ravindran Shanmugam

unread,
Nov 27, 2020, 12:47:31 PM11/27/20
to inside...@googlegroups.com
Thanks Muaralidhara, Anil for the inputs. Missed this for a while, let me try this solution.

Reply all
Reply to author
Forward
0 new messages