调用msix_notify出现Invalid write内存错误的排查求助
调用msix_notify出现Invalid write内存错误的排查求助
各位好,我在QEMU环境下开发自定义PCIe设备相关逻辑时遇到了一个棘手的问题,调用msix_notify触发中断时,日志里始终报出错误:Invalid write at 0xFEE01004 region ‘null’,想请社区的大佬们帮忙排查一下问题所在。
现象与环境说明
- 我使用
msix_init_exclusive_bar来初始化MSI-X的独占BAR,在QEMU monitor中可以确认0xfee00000~0xfeefffff这个内存区域已经被挂载到系统内存区域中。 - 我在
msix_notify函数以及MSI-X内存区域的ops回调中添加了打印日志,发现0xFEE01004是驱动侧要写入QEMU的地址,这个错误是在msix_notify内部的地址检查环节触发的,负责检查的accepts函数定义在unassigned_mem_ops中。
相关代码片段
#include <qemu/osdep.h> #include <hw/pci/pci.h> #include <hw/pci/msix.h> #define SGPU_MSIX_VECTOR_COUNT 4 #define SGPU_MSIX_BAR_INDEX 0 typedef struct MyDevice { PCIDevice pci_dev; // 设备自定义字段 } MyDevice; // 初始化MSI-X void gpu_msix_init(MyDevice *dev, Error **errp) { int i; GPU_LOG("gpu_msix_init\n"); if (msix_init_exclusive_bar(&dev->pci_dev, SGPU_MSIX_VECTOR_COUNT, SGPU_MSIX_BAR_INDEX, errp) < 0) { GPU_LOG("msix_init_exclusive_bar failed!"); return; } if (!msix_present(&dev->pci_dev)) { GPU_LOG("msix_present failed!"); return; } PCIDevice *d = PCI_DEVICE(dev); for (i = 0; i < SGPU_MSIX_VECTOR_COUNT; i++) { msix_vector_use(d, i); } } // 检查向量是否有效(启用且未屏蔽) static bool is_valid_vector(MyDevice *dev, int vector) { PCIDevice *pcie_dev = &dev->pci_dev; if (msix_enabled(pcie_dev)) { if (!msix_is_masked(pcie_dev, vector)) { return true; } } return false; } // 触发中断逻辑 void trigger_interrupt(MyDevice *dev) { int vector; GPU_LOG("trigger_interrupt\n"); for (vector = 0; vector < SGPU_MSIX_VECTOR_COUNT; ++vector) { // 注:这里我后来发现之前传的是固定0,改成vector后问题依旧 if (!is_valid_vector(dev, vector)) { GPU_LOG("invalid vector=%d\n", vector); continue; } // 调用此函数时触发目标错误 msix_notify(dev, vector); } } // trigger_interrupt会在其他业务逻辑文件中被调用
已完成的排查动作
- 确认
msix_init_exclusive_bar调用返回成功,无错误码 - 通过
msix_present验证MSI-X功能已正确初始化 - 对所有MSI-X向量调用
msix_vector_use标记为设备已使用 - 触发中断前,通过
is_valid_vector确保向量处于启用且未被屏蔽的状态 - 修正了
trigger_interrupt中传参错误(原本固定传0给is_valid_vector,改为循环变量vector),但错误仍未解决
目前我还是没理清为什么会出现未分配内存区域的写入错误,有没有大佬能帮忙分析一下可能的原因?比如msix_notify的调用参数是否正确?或者MSI-X的初始化流程有没有遗漏的步骤?
内容来源于stack exchange
相关产品推荐
相关产品推荐

