有没有一种方法可以确定,在某些以编程方式定义的时间间隔内,当前核心上是否发生了SMM条目?
MSR_SMI_COUNT
)计算自系统启动以来发生的 SMI 次数。它是只读的并且特定于英特尔。您可以使用 /dev/cpu/CPUNUM/msr
接口从用户模式可编程地读取此寄存器(或任何其他 MSR 寄存器)。有几个工具使用接口显示 SMI 计数,包括 msr-tools(sudo rdmsr -a 0x34
)和 turbostat(sudo turbostat --msr 0x34
)。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信号。通常,这可以通过向I/O端口0xB2或0xB3写入一些8位值来完成。您可以参考芯片组手册,确定哪些I/O端口可能会触发SMI。
turbostat
版本 17.06.23 默认包含一个每个核心SMI的列。另外,添加新列的语法是turbostat --add msr0x34,u64,cpu,delta,SMM
(根据--help中TSC的示例推测的,我没有看到任何来自它和SMI列的计数,在不带其他参数运行时只显示类似vmstat
样式的输出,在每5秒打印一块行数据 :) - undefinednative_apic_mem_write(APIC_ICR, ...)
应该可以实现。 - undefined