This series adds CXL (Compute Express Link) support to the RISC-V virt
machine in QEMU, following the same approach as the ARM virt machine.
Prerequisite
------------
This series depends on Alireza Sanaee's v8 series [1]:
[1/3] hw/cxl: Use HPA in cxl_cfmws_find_device() rather than offset
in window
[2/3] hw/cxl: Allow cxl_cfmws_find_device() to filter on whether
interleaved paths are accepted
[3/3] hw/cxl: Add a performant (and correct) path for the non
interleaved cases
Patch [1/3] is already in the tree. Patches [2/3] and [3/3] have been
tested and verified functional on RISC-V QEMU with CXL enabled. They
are not included in this posting; please apply them before this series.
Series overview
---------------
[1/4] (hw/riscv/virt): Wires up the core CXL machine support --
Kconfig selects, CXLState, PCIBus pointer (pci_bus), cxl_machine_init(),
CXL host register region, FMW mapping, and machine_done hooks.
[2/4] (hw/riscv/virt-acpi-build): Adds ACPI0017 (CXLM) to the
DSDT with a _DEP on every ACPI0016 CXL host bridge device. The _DEP
ensures the OS defers ACPI0017 enumeration until acpi_pci_root has
attached all CXL host bridges, fixing a probe-ordering race that
leaves the CXL port topology incomplete. A corresponding kernel
change to call acpi_dev_clear_dependencies() in acpi_pci_root_add()
is required on the Linux side. That kernel patch has merged:
https://lore.kernel.org/linux-pci/[email protected]/
[3/4] (hw/riscv/virt, gpex): Reserves the top 256 MiB of the
32-bit MMIO window for CXL host bridges. CXL component-register
BARs are 64-bit non-prefetchable; per PCI-to-PCI Bridge Architecture
Specification Rev 1.2 §3.2.5.8-10, only the prefetchable window can
be 64-bit, so Linux places these BARs in the 32-bit non-prefetchable
bridge window. Without this reservation PCI0 consumes the entire
1 GiB 32-bit range and CXL bridges get an empty _CRS, preventing
BAR assignment.
[4/4] (tests/qtest): Adds a RISC-V bios-tables test for the CXL
variant. Expected AML golden files (DSDT.cxl, CEDT.cxl) are
generated and included.
Changes from v1
---------------
- hw/riscv/virt: PCIBus *bus renamed to PCIBus *pci_bus (Jonathan).
- hw/riscv/virt: Dropped outer if (s->pci_bus) guard around
cxl_hook_up_pxb_registers(); the function already handles a NULL
bus internally (Jonathan).
- hw/riscv/virt-acpi-build: All s->bus references updated to
s->pci_bus; iasl -d decompiled DSDT fragment added to commit
message.
- hw/riscv/virt,gpex: Commit message expanded with PCI-to-PCI Bridge
Spec §3.2.5.8/9/10 citations (Jonathan).
- Original patch 4 ("Map committed HDM decoder ranges as RAM for
direct DMA") dropped; superseded by Alireza Sanaee's v8 series [1],
which correctly handles the interleaved/non-interleaved split and
supports KVM.
- New patch 4: RISC-V ACPI bios-tables test for CXL, with golden AML
files generated and included.
[1]
https://lore.kernel.org/qemu-devel/[email protected]/
Test
---------------
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
tests/qtest: Add RISC-V ACPI bios tables test for CXL
hw/pci-host/gpex-acpi.c | 36 +++++++++-
hw/riscv/Kconfig | 2 +
hw/riscv/virt-acpi-build.c | 52 ++++++++++++++
hw/riscv/virt.c | 98 +++++++++++++++++++++++---
include/hw/pci-host/gpex.h | 1 +
include/hw/riscv/virt.h | 3 +
tests/data/acpi/riscv64/virt/CEDT.cxl | Bin 0 -> 108 bytes
tests/data/acpi/riscv64/virt/DSDT.cxl | Bin 0 -> 6212 bytes
tests/qtest/bios-tables-test.c | 54 ++++++++++++++
9 files changed, 234 insertions(+), 12 deletions(-)
create mode 100644 tests/data/acpi/riscv64/virt/CEDT.cxl
create mode 100644 tests/data/acpi/riscv64/virt/DSDT.cxl
--
2.50.1