【发布时间】:2018-05-04 10:04:27
【问题描述】:
我按照here 给出的步骤和指示,现在可以获得一次计数器溢出中断。但我不能多次得到它。无论我管理什么,Iterrupt 确实会再次启动。尽管我负责清除中断掩码。
【问题讨论】:
标签: assembly intel qemu kvm interrupt-handling
我按照here 给出的步骤和指示,现在可以获得一次计数器溢出中断。但我不能多次得到它。无论我管理什么,Iterrupt 确实会再次启动。尽管我负责清除中断掩码。
【问题讨论】:
标签: assembly intel qemu kvm interrupt-handling
forum 讨论了这个问题,他们发现这是内核中的一个错误。但是,您可以通过以下方式规避它: 在您需要重新编程 msr MSR_PERF_FIXED_CTR0 (0x38d) 的任何地方,放置这些行:
Msr::write(Msr::MSR_PERF_FIXED_CTR0, 0xfffffffffff0ull);
Msr::write(Msr::MSR_PERF_FIXED_CTRL, 0x0);
Msr::write(Msr::MSR_PERF_FIXED_CTR0, 0xfffffffffff0ull);
Msr::write(Msr::MSR_PERF_FIXED_CTRL, 0xa);
值 0x0 和 0xa 之间的切换导致内核重新编程计数器。
【讨论】:
没有任何代码很难判断,但如果您已经收到第一个 PMI,那么计数器寄存器设置正确,问题可能出在上层1。
我会检查:
已将EOI 发送到 LAPIC。
我假设您使用固定向量配置了本地 APIC 的 PMI 寄存器。
在这种情况下,您必须将意向书发送到意向书登记处。
引用英特尔(第 10.8.5 章,第 3 卷)
对于除通过 NMI、SMI、INIT、ExtINT、启动或 INIT-Deassert 交付交付的中断之外的所有中断 模式下,中断处理程序必须包括对中断结束 (EOI) 寄存器的写入。
示例代码:
mov DWORD [APIC_BASE+0xb0], eax
对于未重定位的 LAPIC,有效地址是 0xfee000b0。
写入的值不相关,我拿起一个寄存器来保持指令的编码简短。
当然,您必须根据您的上下文正确访问 LAPIC。
设置IF 标志
清除 IF 标志是一个不太可能的假设,但也很容易排除。
由于中断门(但不是陷阱门)清除了IF,因此请确保您选择退出 ISR 的方式可以正确恢复IF。
1 如果我没记错的话,PMI 不需要重新武装。
【讨论】: