如何从内核模块读取/写入LAPIC寄存器?

时间:2019-04-16 18:25:33

标签: linux-kernel intel apic

我正在尝试禁用所有中断。它们大多数都很容易,但是我遇到了不可屏蔽中断(NMI)的问题。 要禁用它们,我想在本地APIC中操作LVT寄存器。 目前,我正在内核模块内进行测试,原因是环境,最终代码应运行。

如何读取/写入APIC的内存映射寄存器?

我已经阅读了许多文章,每个人都建议执行此过程。 我还尝试直接访问* mapped指针,该指针可以解决相同的结果。

我实现了对正确地址的查找,而不是foo()函数。但是根据英特尔手册和我的个人检查,APIC总是被映射到物理地址0xFEE00000,这很有趣,因为我也在具有2 GB RAM的虚拟机上尝试了该程序。

phys_addr_t apic_base_phys = foo(); // fee00000
void __iomem *mapped = ioremap(apic_base_phys + 0x20, 0x4);

if(mapped == NULL){
    printk(KERN_INFO "nullpointer\n");
} else {
    uint32_t value = ioread32(mapped);
    printk(KERN_INFO "Value: %x\n", value); // 0xffffffff
}

iounmap(mapped);

输出:

[ 1329.743182] apic_base_phys: fee00000
[ 1329.743198] Value: ffffffff

地址0xFEE00020应该输出本地APIC ID,该ID可能不是0xFFFFFFFF。
我还尝试读取0xFEE00030,它应该输出LAPIC版本。

1 个答案:

答案 0 :(得分:1)

我自己解决了这个问题:在我的系统上运行更新的x2APIC。这会使用其他传输模式。

可以通过在启动选项中添加nox2apic来禁用此功能。