在运行 Linux 的嵌入式系统中,我们在用户空间中有一个 PCI 驱动程序,利用 UIO 的内核驱动程序。应用程序可以触发__uio_register_device()
在内核中调用的设备的注册uio.c
。然后应用程序打开设备文件 ( /dev/uio0
)。然后它会通过取消注册设备(uio_unregister_device()
)来释放一些保存设备信息的内核内存,从而出现错误行为。然后应用程序关闭该文件 - 并且内核会发生恐慌,因为已释放的指针正在被访问。
除了修复应用程序之外,如何使 Linux 内核对此具有鲁棒性?
uio_open()
并uio_release()
获取指向关键分配内存的文件指针(在 中private_data
)。但uio_unregister_device()
没有这些信息,所以我不知道该怎么办。或者有没有办法强制关闭应用程序中的文件?对于正在发生的事情还有其他建议或不同的解释吗?
编辑:可以轻松地复制如下 - 并显示用户空间视角:
# replace '1234 abcd' by vendor id and device id
echo '1234 abcd' > /sys/bus/pci/drivers/uio_pci_generic/new_id
echo '0000:00:01.0' > /sys/bus/pci/drivers/uio_pci_generic/bind
# 'bind' may not even be needed. /dev/uio0 is created
cat /dev/uio0 &
# now be bad
echo '0000:00:01.0' > /sys/bus/pci/drivers/uio_pci_generic/unbind
kill <cat process ID>
# kernel panic...
导致崩溃的原因是Unable to handle kernel paging request at virtual address
- 具有三种不同的风格。或idev
是无效指针(不一定是 NULL,只是随机数据)idev->info
。idev->owner