From: Manish Honap <[email protected]>
Hello,
This series adds cxl-type2, an emulated CXL Type-2 device with volatile
device memory. It is emulated in such a way that all the Linux checks
are satisfied so that CXL passthrough using vfio-pci (vfio-cxl) can be
developed and tested in a guest without Type-2 hardware.
This series builds on the Type-2 model from Zhi's series (carried in
Cédric's tree) and carries one fix from Shuai's tree. Shuai's tree also
set up the decoders through device properties and stubbed CXL Reset; the
firmware setup and CXL Reset here are new code.
Carried patches keep their authors, with a note for each change.
The device:
- PCI ID 1b36:0017 and the processing accelerator class 0x1200;
- PCIe DVSEC for CXL Devices with CXL.cache, CXL.mem, one HDM range,
cache write-back and invalidate, CXL Reset and Mem Clr; Register
Locator and Flex Bus Port DVSECs;
- CXL.cache advertised but not modelled. The device sends no CXL.cache
requests, and its memory is host RAM, which is coherent already. A
cache write-back and invalidate completes at once. The capability is
set because vfio-cxl takes a device as Type-2 only when it reports
both CXL.cache and CXL.mem;
- component registers with one HDM decoder;
- slot 0, function 0 below a CXL root port of a pxb-cxl, memory in one
fixed memory window selected with fmw-index, cold plug only (no
hotplug or unplug), not migratable.
No Linux driver claims the device on its own. cxl_pci does not bind to
the accelerator class, and sfc, the other driver that calls the CXL
core Type-2 interface, matches only its own devices. A guest binds
cxl-type2 to vfio-pci, which hands it to vfio-cxl. Testing the CXL core
Type-2 interface without vfio-cxl needs a driver for 1b36:0017 that
calls it. There is none yet.
QEMU has no firmware that commits the HDM decoders of a CXL route at
boot, and Linux attaches a Type-2 device only to a committed region
(devm_cxl_probe_mem()). So QEMU does that step itself. cxl-type2
registers its range with its pxb-cxl at realize (patch 13). At every
reset the pxb-cxl commits HDM decoder 0 for it (patch 12), and the
device commits its own decoder with Lock On Commit and enables
CXL.cache, CXL.mem and HDM decoding (patch 14). A pxb-cxl with a
registered range keeps its HDM decoder even with a single root port,
where it would otherwise pass accesses through. Type-3 devices, and
pxb-cxl without a registered range, are not affected.
A CXL Reset keeps the locked decoder committed, as RWL fields are not
affected by CXL Reset once locked (CXL r4.0 Table 8-1). DVSEC Control,
the range bases and HDM Decoder Global Control return to their
defaults, which leaves Mem_Enable and HDM Decoder Enable at 0. While
either is 0 the device drops CXL.mem, so guest accesses to its memory
fail until software sets both bits again. The CXL.io part of the reset
is not emulated. CONFIG_LOCK makes the RWL DVSEC fields read only until
a system reset.
Patches:
- 1-7: Shared CXL code: read-0 ops for the CXL.io range of the
component registers, helpers from Zhi, an HDM decoder count,
DVSEC bit names, a device-neutral view for the direct mapping
code, PCI IDs;
- 8-17: The device; patch 16 also exports the default component
register write handling, so the device can check the enable
bits after a write;
- 18: Docs;
Left for later series:
- The CXL device registers with the mailbox, event logs and MSI-X, and
the CDAT;
- Direct mapping lifecycle fixes for Type-3 and switch topologies, and
Lock On Commit in host bridges and switches;
- Fixes for guest-triggered aborts on 1 and 2 byte mailbox writes and a
repeated DOE Go;
- Software-programmed decoders, for Linux-created Type-2 regions;
- A Type-2 device below a CXL switch, and migration.
Testing:
- Build every commit for x86_64 and aarch64, checkpatch for style.
- vfio-cxl selftest (vfio_cxl_type2_test) in an Arm L1 guest on KVM,
with the device below a CXL root port and an SMMUv3: 19 of 19 pass
- Not tested: x86_64 L1, a build without CONFIG_CXL_TYPE2_DEVICE.
The Linux vfio-cxl series(v5) this was tested with:
https://lore.kernel.org/r/[email protected]
Sent as RFC to get comments on the series structure and to request
1b36:0017 devid for cxl-type2 device allocation.
References:
[PATCH RFC 0/5] hw/cxl: Type 2 Device RFC
https://lore.kernel.org/linux-cxl/[email protected]/
Type-2 emulation trees:
[1] Zhi Wang
https://github.com/zhiwang-nvidia/qemu/commits/zhi/qemu-type2-emulation-for-review
[2] Cédric Le Goater
https://github.com/legoater/qemu/tree/cxl-type2
[3] Shuai Xue
https://gitee.com/axiqia/qemu-kvm/tree/cxl-type2-test
Manish Honap (12):
hw/cxl: Make HDM decoder initialization count-aware
hw/cxl: Define the CXL Device DVSEC capability and control bits
hw/cxl: Find the memory of a CXL device through one helper
hw/pci: Add PCI IDs for the CXL Type-2 device
hw/mem: Require a CXL root port of a pxb-cxl for cxl-type2
hw/pci-bridge: Add firmware HDM decoder state to pxb-cxl
hw/mem: Bind cxl-type2 to a fixed memory window
hw/mem: Commit the cxl-type2 HDM decoder at reset
hw/mem: Add CXL.cache with cache write-back and invalidate to
cxl-type2
hw/mem: Implement CXL Reset for cxl-type2
hw/mem: Clear the cxl-type2 volatile memory on a CXL Reset request
docs/cxl: Document the CXL Type-2 device
Shuai Xue (1):
hw/cxl: Give the component register .io sub-region read-0 ops
Zhi Wang (5):
hw/cxl: Factor out cxl_host_addr_to_dpa()
hw/cxl: Introduce cxl_component_update_dvsec()
hw/cxl: Introduce CXL type-2 device emulation
hw/cxl: Add the CXL type-2 DVSECs and component registers
hw/cxl: Map the CXL type-2 device memory through the fixed windows
MAINTAINERS | 1 +
docs/specs/pci-ids.rst | 2 +
docs/system/devices/cxl.rst | 68 +++
hw/cxl/cxl-component-utils.c | 227 +++++++++-
hw/cxl/cxl-host.c | 130 ++++--
hw/mem/Kconfig | 5 +
hw/mem/cxl_type2.c | 580 ++++++++++++++++++++++++
hw/mem/cxl_type2_stubs.c | 20 +
hw/mem/cxl_type3.c | 68 +--
hw/mem/meson.build | 2 +
hw/pci-bridge/pci_expander_bridge_cxl.c | 27 +-
include/hw/cxl/cxl.h | 1 +
include/hw/cxl/cxl_component.h | 26 ++
include/hw/cxl/cxl_device.h | 27 ++
include/hw/cxl/cxl_pci.h | 31 ++
include/hw/pci/pci.h | 1 +
include/hw/pci/pci_bridge.h | 6 +
include/hw/pci/pci_ids.h | 3 +
18 files changed, 1102 insertions(+), 123 deletions(-)
create mode 100644 hw/mem/cxl_type2.c
create mode 100644 hw/mem/cxl_type2_stubs.c
base-commit: f71afb409a87c4ecd0f9d63a5963eb645dfab780
--
2.53.0