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));
}