Начиная с Nehalem, регистр MSR 0x34 (называемый MSR_SMI_COUNT
) подсчитывает количество SMI, которые произошли с момента загрузки системы.Это только для чтения и для Intel.Вы можете программировать чтение из этого регистра (или любого другого регистра MSR) из пользовательского режима, используя интерфейс /dev/cpu/CPUNUM/msr
.Есть несколько инструментов, которые используют интерфейс для отображения количества SMI, включая msr-tools (sudo rdmsr -a 0x34
) и турбостат (sudo turbostat --msr 0x34
).
Я извлек этот код изИсходный код турбостата (/source/tools/power/x86/turbostat/turbostat.c).Функция get_msr_fd
возвращает файловый дескриптор файла msr
.Функция get_msr
принимает номер ЦП, смещение MSR (0x34 для MSR_SMI_COUNT
) и указатель на 64-разрядное местоположение, в котором будет храниться значение MSR (хотя 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-битное значение в порт ввода-вывода 0xB2 или 0xB3.Вы можете обратиться к руководству по вашему чипсету, чтобы определить, какие порты ввода / вывода могут вызвать SMI.