有没有办法确定SMM中断发生了?

时间:2018-06-11 04:54:56

标签: x86 hardware intel

对于某些有条理定义的时间间隔,是否有办法确定当前核心是否发生了SMM条目?

1 个答案:

答案 0 :(得分:3)

从Nehalem开始,MSR寄存器0x34(称为MSR_SMI_COUNT)计算自系统引导以来发生的SMI数。它是只读的,特定于英特尔。您可以使用/dev/cpu/CPUNUM/msr接口从用户模式读取此寄存器(或任何其他MSR寄存器)的可编程性。有几个工具使用该界面显示SMI计数,包括msr-toolssudo rdmsr -a 0x34)和turbostat(sudo turbostat --msr 0x34)。

我从turbostat源代码(/source/tools/power/x86/turbostat/turbostat.c)中提取了这段代码。 get_msr_fd函数返回msr文件的文件描述符。 get_msr函数接受CPU编号,MSR偏移(MSR_SMI_COUNT的0x34),以及指向将保存MSR值的64位位置的指针(尽管MSR_SMI_COUNT是一个32位计数器,高32位保留。)

int get_msr_fd(int cpu)
{
    char pathname[32];
    int fd;

    fd = fd_percpu[cpu];

    if (fd)
        return fd;

    sprintf(pathname, "/dev/cpu/%d/msr", cpu);
    fd = open(pathname, O_RDONLY);
    if (fd < 0)
        err(-1, "%s open failed, try chown or chmod +r /dev/cpu/*/msr, or run as root", pathname);

    fd_percpu[cpu] = fd;

    return fd;
}

int get_msr(int cpu, off_t offset, unsigned long long *msr)
{
    ssize_t retval;

    retval = pread(get_msr_fd(cpu), msr, sizeof(*msr), offset);

    if (retval != sizeof *msr)
        err(-1, "cpu%d: msr offset 0x%llx read failed", cpu, (unsigned long long)offset);

    return 0;
}

SMI可能每秒发生多次,或者可能不会长时间发生。但是,观察MSR_SMI_COUNT中的更改的一种方法是发布同步SMI。通常,这可以通过将一些8位值写入I / O端口0xB2或0xB3来完成。您可以参考芯片组手册来确定哪些I / O端口可能触发SMI。