This series enables CXL (Compute Express Link) on the RISC-V 'virt'
machine (patch 1, mirroring hw/arm/virt), fixes two RISC-V-specific
gaps that block Type-3 enumeration today (patches 2 and 3), and
fixes one arch-agnostic CXL bug that surfaces as soon as a Type-3
device is brought online as system RAM (patch 4).
1/4 Wires up CXLState, the CXL host register region, the Fixed
Memory Windows and the ACPI0017 / CEDT plumbing on the
RISC-V virt machine, mirroring hw/arm/virt.
2/4 Adds an ACPI _DEP from ACPI0017 to the ACPI0016 CXL host
bridges so cxl_acpi probes after acpi_pci_root has attached
the bridges. Without this the CXL port topology comes up
incomplete on RISC-V because probe ordering is not guaranteed.
Kernel dependency: this patch relies on a small kernel-side
change that calls acpi_dev_clear_dependencies() in
acpi_pci_root_add(). That kernel patch has completed review
on linux-pci:
https://lore.kernel.org/linux-pci/20260526025118.38935-1-cp0613@linux.alibaba.com/
3/4 Reserves the top 256 MiB of the RISC-V virt 32-bit PCIe MMIO
window exclusively for CXL host bridges and emits it via the
ACPI0016 _CRS, so Linux can place the 64-bit non-prefetchable
CXL component/device register BARs below 4 GiB. PCI0's
mmio32 window and FDT 'ranges' are shrunk by the same amount.
4/4 Overlays a RAM alias of the Type-3 device's memory backend at
the committed HDM decoder's HPA range, so that
address_space_map() on CFMW addresses returns a direct host
pointer instead of taking the 4 KiB bounce-buffer path.
Without it, once 'daxctl online-memory' exposes CXL memory to
the kernel allocator, any virtio scatter list larger than
4 KiB into that range dies with:
virtio: bogus descriptor or out of resources
This bug is not RISC-V specific -- CFMW registration and the
bounce-buffer limit are both arch-agnostic -- but the RISC-V
virt machine is where the rest of this series first lights up
the daxctl + virtio path end-to-end.
Scope: the fix covers the common single-device, single-decoder
configuration. interleave_ways > 1 and HDM decoders inside a
CXL switch keep falling through to the existing cfmws_ops +
bounce-buffer path, exactly as today (no regression; left as
follow-up work). An alternative implementation that was
considered is teaching the CFMW MemoryRegion itself to expose
a ram_block; the overlay-on-commit approach was preferred as
it mirrors the existing PCI BAR / IOMMU MR overlay pattern
and is local to cxl_type3.
Tested on the RISC-V virt machine with EDK2 firmware and a buildroot
guest carrying the kernel patches above.
QEMU invocation (CXL-relevant options shown; EDK2 pflash, -bios,
-kernel, -append and the virtio-blk rootfs are as usual):
qemu-system-riscv64 \
-M virt,aia=aplic-imsic,acpi=on,cxl=on \
-cpu rv64 -smp 2 -m 4G,maxmem=8G,slots=8 \
-object memory-backend-ram,id=vmem0,share=on,size=4G \
-device pxb-cxl,bus_nr=12,bus=pcie.0,id=cxl.1 \
-device cxl-rp,port=0,bus=cxl.1,id=rp0,chassis=0,slot=2 \
-device cxl-type3,bus=rp0,volatile-memdev=vmem0,id=cxl-vmem0 \
-M cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G \
... # EDK2 pflash + -bios fw_dynamic.bin + -kernel Image
# + virtio-blk rootfs + -append "root=/dev/vda ..."
Verification (compare the two `free -h` outputs: total system memory
grows by 4 GiB after onlining):
# free -h
# cxl list
# cxl enable-memdev mem0
# cxl create-region -m -t ram -d decoder0.0 -w 1 mem0 -s 4G
# daxctl online-memory dax0.0
# free -h
Chen Pei (4):
hw/riscv/virt: Add CXL support to the RISC-V virt machine
hw/riscv/virt-acpi-build: Add _DEP to ACPI0017 for CXL host bridge
dependency
hw/riscv/virt,gpex: Provide 32-bit MMIO window for CXL host bridges
hw/cxl: Map committed HDM decoder ranges as RAM for direct DMA
hw/mem/cxl_type3.c | 81 +++++++++++++++++++++++++++++++++++
hw/pci-host/gpex-acpi.c | 36 +++++++++++++++-
hw/riscv/Kconfig | 2 +
hw/riscv/virt-acpi-build.c | 52 +++++++++++++++++++++++
hw/riscv/virt.c | 100 +++++++++++++++++++++++++++++++++++++++-----
include/hw/cxl/cxl_device.h | 4 ++
include/hw/pci-host/gpex.h | 1 +
include/hw/riscv/virt.h | 3 ++
8 files changed, 267 insertions(+), 12 deletions(-)
--
2.50.1