assembly 在x86上发送IPI后,内存写入是否可见?

lkaoscv7  于 2023-05-29  发布在  其他
关注(0)|答案(1)|浏览(131)

我已经阅读了Intel 64和IA-32 Architectures SDM vol 3A,9.2 Memory Ordering,但有一个问题一直困扰着我。
如果我先写一个内存地址,然后用x2 APIC发送一个处理器间中断(IPI),这意味着发送IPI不需要写内存(只需使用wrmsr)。另一个核心接收IPI并读取内存,它会读取正确的值吗?
例如:
初始x = 0
处理器0:

mov [ _x], 1
wrmsr       # use x2APIC to send IPI

处理器1:

# resive IPI, in the interrupt service routine:
mov r1, [ _x]

是否允许r1 = 0?

nwwlzxa7

nwwlzxa71#

这是一个有趣的问题。从表面上看,人们可能会认为,由于WRMSR是一条序列化指令,它会刷新前面的内存写入,一切正常。即使如此,引用手册:
这些指令强制处理器完成先前指令对标志、寄存器和存储器的所有修改,并在获取并执行下一条指令之前,将所有缓冲写入存储器
(强调我的)
它没有说任何关于发送IPI的顺序,因为这是当前指令的一部分,而不是下一个指令。因此,这在理论上意味着另一个核心可以执行mov r1, [ _x],而发起核心仍然忙碌刷新内容,但考虑到目标核心需要服务中断,这可能具有更高的延迟,这是非常不可能的。
正如@harold提到的,这一点是没有实际意义的,因为WRMSR并不总是序列化的。阅读我最初错过的脚注:
WRMSR到IA32_TSC_DEADLINE MSR(MSR索引6 E0 H)和X2 APIC MSR(MSR索引802 H到83 FH)未串行化。
因此,绝对不能保证对x的写入被刷新。

相关问题