X86 驱动程序将如何使用监视器指令(_-mm_-MONITOR-instructive)?

X86 驱动程序将如何使用监视器指令(_-mm_-MONITOR-instructive)?,x86,driver,cpu-architecture,smp,X86,Driver,Cpu Architecture,Smp,我正在探索监视器指令(或等效的内在\u mm\u监视器)的用法。虽然我找到了描述它们的文献,但我找不到任何关于如何使用它的具体例子/样本 任何人都可以分享一个如何在驱动程序中使用此指令/内部指令的示例吗?基本上,我想用它来监视内存范围。该指令使用RAX/EAX/AX中指定的地址来武装地址监视硬件。引自英特尔 监视器的状态由指令mwait使用 使用的有效地址大小(16、32或64位)取决于编码指令的有效地址大小(即,它可以用67h前缀覆盖,默认情况下与代码大小相同) rax/eax/ax中给出的地

我正在探索
监视器
指令(或等效的内在
\u mm\u监视器
)的用法。虽然我找到了描述它们的文献,但我找不到任何关于如何使用它的具体例子/样本

任何人都可以分享一个如何在驱动程序中使用此指令/内部指令的示例吗?基本上,我想用它来监视内存范围。

该指令使用
RAX/EAX/AX
中指定的地址来武装地址监视硬件。引自英特尔
监视器的状态由指令
mwait
使用

使用的有效地址大小(16、32或64位)取决于编码指令的有效地址大小(即,它可以用
67h
前缀覆盖,默认情况下与代码大小相同)

rax/eax/ax
中给出的地址是逻辑地址的偏移部分,用于配置监视器的线性地址从中计算。
段部分默认为
ds
,段覆盖前缀可用于更改段。
作为用于监视器的线性地址,分页不会影响监视器

位CPUID.01H:ECX.monitor[位3]1指示
监视器
(和
mwait
)指令的可用性。
这是一条特权指令,但英特尔声称:

指令在大于0的级别上有条件可用

检测这种情况的建议方法是尝试执行
monitor
,并处理最终的#UD异常(以自定义方式将其报告给userland程序)

监控的地址范围必须是可写回缓存的。
由于涉及缓存和缓存一致性子系统,地址范围的大小根据最小和最大大小给出。
CPUID.01H:EAX[位15:0]给出最小范围大小。这是硬件监视器监视的区域的长度。
然而,高速缓存一致性通信可能与较大的“块”(行)一起工作,如果监控区域包括后者,则与监控区域相邻的写操作将触发它。
这会产生最大范围大小,可以在CPUID.01H:EBX[位15:0]中找到它。
要正确使用
monitor
请确保所监视的数据结构符合最小范围大小,但也要确保没有代理将其旁边的地址写入最大范围大小

例如,如果最小范围大小为8个字节,最大范围大小为16个字节,请确保监视的结构适合8个字节,但再添加8个字节以达到总共16个字节,这样就不会发生从第8个字节到第16个字节的写入

在单集群系统中,上述两个值相等。我的都是64字节。
BIOS负责在多集群系统中报告
IA32\u MONITOR\u FILTER\u line\u size
中的缓存一致性行大小

出于指令排序和访问权限的目的,
监视器
是一个负载

monitor
允许程序员指定提示和扩展。
扩展在
ecx
中指定,提示在
edx
中指定
不支持的扩展将引发#GP异常,不支持的提示将被忽略。
据《英特尔手册》报道,我不知道对
监视器的任何扩展或提示

对于奔腾4 处理器(系列15,型号3),未定义扩展或提示

我相信这条线在总体上是正确的,它只是有一个过时的处理器型号。
此外,
监视器的伪代码
报告一个#GP
如果ECX≠ 0.

在不检查监视器状态的情况下启用监视器(使用
mwait
)不会造成任何伤害

内在的是
void\u mm\u监视器(void const*p、无符号扩展、无符号提示)


一旦启用监控器,可通过不同条件触发监控器:

  • 外部中断:NMI、SMM、INIT、BINIT、MCERR
  • 故障、中止,包括机器检查
  • 体系结构TLB失效,包括写入CR0、CR3、CR4和某些MSR写入
  • 由于快速系统调用和远端调用而自动转换
  • 屏蔽中断(如果启用)
  • 在监视的地址范围内的写入
程序员看不到监视器的状态,但可以使用
mwait

mwait
进入实施定义的低功耗状态,直到监视器处于触发状态。
如果监视器未进入待命状态或已被触发,则
mwait
nop
,否则会使处理器停止执行指令,直到监视器被触发

mwait
还可以提供扩展和提示。
扩展在
ecx
中设置,提示在
eax
中设置
在编写本文时,唯一的扩展是:

位0将中断视为中断事件,即使屏蔽(例如,即使EFLAGS.if=0)。仅当 CPUID.05H:ECX[位1]=1。
位31-1保留

提示允许程序员指定实现定义的低功耗模式

位3:0C状态中的子C状态,由位[7:4]表示
位7:4目标C状态
值为0表示C1;1表示C2等
0111b的值表示C0
注意:MWAIT扩展的目标C状态是特定于处理器的C状态,而不是ACPI C状态

CPUID.05h.EDX中给出了C模式的子状态数(因此可用性):

位03-00:使用MWAIT支持的C0*子C状态数。
位07-04:使用M支持的C1*子C状态数
struct MonitoredType
{
  int (*event)(struct MonitoredType const* m);              /*Return 0 to keep monitoring*/
  struct AnyType data;                                /*Less, in size, than MIN_MONITOR_RANGE*/
  char padding[MAX_MONITOR_RANGE - sizeof(AnyType)];
};

void wait_for_write(struct MonitoredType const* m)
{
   /* This may miss a write if it happens before MONITOR, beware of race conditions if necessary */
   do
   {
     _mm_monitor(&m->data, 0, 0);
     _mm_mwait(0, 0);
   } while ( ! m->event(m));
}