有没有办法判断SMM中断发生了?

问题描述 投票:0回答:1

有没有办法从用户空间确定,对于某些以编程方式定义的间隔,当前核心上是否出现了 SMM 条目?

x86 hardware intel
1个回答
5
投票

从 Nehalem 开始,MSR 寄存器 0x34(称为

MSR_SMI_COUNT
)统计自系统启动以来发生的 SMI 数量。它是只读的且特定于英特尔。您可以使用
/dev/cpu/CPUNUM/msr
接口从用户模式可编程地读取该寄存器(或任何其他 MSR 寄存器)。有多种工具使用该界面来显示 SMI 计数,包括 msr-tools (
sudo 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。

© www.soinside.com 2019 - 2024. All rights reserved.