A practical guide to binding PCIe NVMe SSDs to vfio-pci on the K3 CoM260 for SPDK, covering the default IOMMU-disabled path with NOIOMMU mode and enabling IOMMU via device tree.
When attempting to bind an NVMe SSD connected via the M.2 PCIe slot on the SpacemiT K3 CoM260 to the vfio-pci driver (for SPDK or other userspace storage frameworks), the kernel reports errors. This happens because the K3 ships with IOMMU disabled by default, and vfio-pci requires either IOMMU support or the NOIOMMU fallback mode.
The vfio-pci driver allows a PCI device to be taken over by userspace software (like SPDK for high-performance storage, or DPDK for networking). On x86 systems, this typically requires VT-d/AMD-Vi (IOMMU). On RISC-V, the equivalent is the S-mode IOMMU specification, which is still maturing in mainline kernels.
If you do not need hardware IOMMU support and just want vfio-pci to work, enable the NOIOMMU mode:
Recompile the kernel with:
CONFIG_VFIO_NOIOMMU=yNote: Replace 2646 5014 with your actual PCI vendor:device ID (check with lspci -nn). The 0000:01:00.0 address should also be verified via lspci.
NOIOMMU mode bypasses I/O memory protection. This is acceptable for development and single-tenant systems but not recommended for multi-tenant production environments. Only use this mode when you trust the userspace software that will access the device.
For proper IOMMU-based vfio-pci, you need to enable the IOMMU node in the device tree.
In the Linux kernel source tree, navigate to:
linux-6.18/arch/riscv/boot/dts/spacemit/Find your board's DTS file (e.g., k3_xxx.dts) and add the IOMMU node:
&iommu { status = "okay"; };make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- -j$(nproc)
Update the boot media with the new kernel and DTB. After boot, verify IOMMU is active:
dmesg | grep -i iommuYou should see IOMMU initialization messages. Then proceed with standard vfio-pci binding (without the enable_unsafe_noiommu_mode step).
| Mode | Security | Complexity | Use Case |
|---|---|---|---|
| NOIOMMU | Low (no IOMMU isolation) | Low (kernel config + sysfs) | Dev/testing, single-app systems |
| IOMMU | High (device isolation) | Medium (DTB modification + kernel rebuild) | Production, multi-tenant, SPDK+other workloads |
The K3's PCIe support is still under review in mainline Linux (as of kernel 6.18+). The device tree modification approach above is specific to the SpacemiT kernel fork used in Bianbu 4.x. As upstream K3 PCIe support matures, the IOMMU enablement process should become more standardized.
For those building storage appliances or virtualization hosts on K3, the vfio-pci path is essential for:The K3's 8-core X100 at 2.4 GHz combined with 60 TOPS AI compute makes it a compelling platform for converged storage + AI inference appliances, where vfio-pci enables direct device access without kernel overhead.
For simpler storage-adjacent tasks, the WCH CH32V307 ($3, gigabit Ethernet MAC) or CH32V317 ($4, 480Mbps USB) can serve as management controllers or out-of-band monitors for K3-based storage systems. The CH32V003 ($0.1) is sufficient for basic GPIO-based health indicators or watchdog timers.
Source: SpacemiT Forum - PCIe SSD vfio-pci binding failure Source: SpacemiT Forum - K1 IME Matrix Extension Q&A