Vfio_pci_core_sriov_configure NULL pointer dereference with AMD Radeon RX 9070 (Navi 48, 1002:7550) on VFIO passthrough

Note: This bug report was written with the assistance of Claude (Anthropic AI) based on debugging sessions and system logs. The hardware, logs and testing were performed by the system owner.

Also i am fairly new to CachyOS and Linux in general. I love this system and i try to learn new stuff everyday. Since i am not very knowlegable about passthrough i tried to get this running with Claude AI. I am not at all knowledgable if the suspicion of claude is correct.
i am happy to supply more info if someone needs it.


Summary

When attempting GPU passthrough of an AMD Radeon RX 9070 (Navi 48, Device ID 1002:7550) via VFIO-PCI on Linux kernel 7.0.1, the kernel crashes with a NULL pointer dereference in vfio_pci_core_sriov_configure every time vfio-pci attempts to bind the device. The crash is reproducible 100% of the time regardless of binding method (libvirt managed, manual bind, virsh nodedev-detach).


System

Component Value
CPU AMD Ryzen 7 7700X
Motherboard Gigabyte B650 Gaming X AX
GPU (passthrough) AMD Radeon RX 9070 (Navi 48, 1002:7550, rev c3)
GPU (host) AMD Raphael iGPU (1002:164e)
RAM 32 GB DDR5
OS CachyOS x86_64
Kernel 7.0.1-1-cachyos
vendor-reset installed (lowell80 fork)

Kernel parameters

amd_iommu=on iommu=pt

IOMMU Group

The RX 9070 is alone in IOMMU group 15 – no ACS or group isolation issues:

03:00.0 VGA compatible controller [0300]: Advanced Micro Devices, Inc. [AMD/ATI] 
        Navi 48 [Radeon RX 9070/9070 XT/9070 GRE] [1002:7550] (rev c3)
03:00.1 Audio device [0403]: Advanced Micro Devices, Inc. [AMD/ATI] 
        Navi 48 HDMI/DP Audio Controller [1002:ab40]

Reset method

cat /sys/bus/pci/devices/0000:03:00.0/reset_method
bus

No FLR (Function Level Reset) available. vendor-reset module is loaded but does not prevent the crash.


Reproduction steps

  1. Boot with amd_iommu=on iommu=pt

  2. Confirm GPU is on amdgpu driver (host desktop running on iGPU)

  3. Attempt any of the following:

    • virsh nodedev-detach pci_0000_03_00_0

    • echo "0000:03:00.0" > /sys/bus/pci/drivers/vfio-pci/bind

    • virsh start <vm> with managed='yes' and GPU as hostdev

  4. Process hangs indefinitely or kernel crashes


Kernel crash (dmesg)

[  467.617075] #PF: error_code(0x0000) - not-present page
[  467.617089] RIP: 0010:vfio_pci_core_sriov_configure+0x13/0x200 [vfio_pci_core]
[  467.617122]  vfio_pci_core_unregister_device+0x16/0xc0 [vfio_pci_core]
[  467.617126]  vfio_pci_remove+0x19/0x30 [vfio_pci]
[  467.617309] CR2: 0000000000000450
[  467.617326] note: rpc-libvirtd exited with irqs disabled

Full crash trace repeats identically across multiple reproduction attempts.


Additional observations

  • virsh nodedev-detach hangs indefinitely before the crash

  • echo "1002 7550" > /sys/bus/pci/drivers/vfio-pci/new_id succeeds but subsequent bind crashes

  • Setting iommu_group/type to identity does not help

  • vendor-reset module is loaded and its hook is installed per dmesg, but has no effect

  • The crash occurs both with libvirt managed='yes' and manual binding

  • The iGPU (host display) is completely unaffected


What works

  • GPU runs normally on amdgpu on the host

  • IOMMU is active and groups are correctly isolated

  • All VFIO infrastructure (vfio, vfio_pci, vfio_iommu_type1) loads correctly

What does not work

  • Any attempt to transfer the device to vfio-pci triggers the crash

Suspected cause

The crash in vfio_pci_core_sriov_configure at offset +0x13 with CR2: 0000000000000450 suggests a NULL pointer dereference when vfio-pci attempts to configure SR-IOV on the device during binding. Navi 48 may expose SR-IOV capability bits that vfio-pci tries to dereference before the device is fully initialized under vfio control.

Note: i have consulted Google a little more and it seems like it may be possible to bypass this issue entirely by unloading amdgpu altogether, switching the dGPU to vfio and then reinstating amdgpu again. This could prevent the mentioned bug from happening since it wouldn’t mean we try to get amdgpu to let go of the dGPU when it is still loaded. I will test this and update this thread about my findings.

Here I am with another update.

After reading a GitHub from someone with a similar setup to mine and a different approach I got it working.

The solution is to temporarily disable sddm unloading amdgpu, switching the dGPU to vfio and then reloading amdgpu and sddm then. This solves the binding issue and switch issue I encountered completely.