Linux Intel Xeon平台PCIe MSI中断触发及共享内存访问技术问询
PCIe MSI及DMA内存访问配置解答
Q1 外置板卡触发MSI中断及本地测试方法
- MSI中断的本质是PCIe存储器写事务,不需要操作Linux侧Switch的控制寄存器,外置板卡直接发起PCIe存储器写TLP即可触发:
写请求的目标地址填你转储的Switch MSI Capability段的0xfee003d8(32位地址场景无需使用高位地址),写数据填你配置的MSI消息值(你当前转储的MsgData为0x0,可根据实际中断需求调整为对应值,并非固定写0/1),该请求会直接上报到Xeon CPU的本地APIC触发对应中断。你提到的0xFEEE_0D38为示例地址,实际使用以你转储的0xfee003d8为准。 - Linux侧本地测试获取该地址访问指针的方法:
0xfee开头的地址为APIC的MMIO空间,不属于普通内存,不能直接访问虚拟地址,需按场景映射:- 内核态测试:调用
ioremap(0xfee003d8, 4)获取虚拟地址指针,通过writel()写入对应MSI消息值即可触发中断,使用完成后调用iounmap()释放映射。 - 用户态测试:以root权限打开
/dev/mem,通过mmap映射该物理地址偏移得到用户态虚拟地址,直接写入即可触发,需提前确认内核未开启CONFIG_STRICT_DEVMEM限制该地址段访问。
- 内核态测试:调用
Q2 外置板卡写入Linux侧DRAM地址0xB0000000的配置方法
你需要依次完成PCIe Switch地址范围配置和Linux侧内存预留/权限配置,无需修改CPU硬件寄存器:
- 调整PCIe Switch下行端口地址范围
从你转储的配置可知,当前Switch的MemBase/MemLim为0x90509050,对应允许上行转发的内存地址范围为0x90500000 ~ 0x905FFFFF,未包含0xB0000000,需修改该配置项,将0xB0000000纳入允许转发范围。例如要开放0xB0000000 ~ 0xB00FFFFF的1M空间,可将MemBase/MemLim值改为0xB000B000,同时需要将Switch配置空间Command寄存器的总线主控位(bit2)置1,允许Switch转发DMA请求。 - Linux侧内存预留与权限配置
- 若未开启VT-d(IOMMU):
在内核启动参数中添加memmap=1M$0xB0000000(可根据实际使用的内存大小调整1M为对应值),预留该段内存不被内核默认分配,避免数据被意外覆盖。Linux侧需要访问该段内存时,内核态用ioremap(0xB0000000, 大小)获取虚拟地址,用户态映射/dev/mem即可访问。 - 若开启了VT-d(IOMMU):
除上述配置外,可在内核启动参数添加iommu=pt开启IOMMU直通模式,允许PCIe设备直接访问物理内存;也可手动为Switch对应的IOMMU组配置IOVA地址映射,将0xB0000000物理地址映射为外置板卡可访问的IOVA地址。
配置完成后,外置板卡直接发起目标地址为0xB0000000的PCIe存储器写请求,即可直接写入对应DRAM地址。
内容的提问来源于stack exchange,提问作者Always Learning
相关产品推荐
相关产品推荐

