Re: [PATCH 07/10] hw/vfio/pci: Map the CXL memory on the guest decoder commit
Junjie Cao <[email protected]>
| Newsgroups | org.nongnu.qemu-devel,org.nongnu.qemu-arm |
|---|---|
| Message-ID | <[email protected]> |
Hi Manish,
On Thu, 13 Aug 2026 18:36:20 +0530, Manish Honap wrote:
> + switch (le32_to_cpu(cap) & 0xf) {
> + case 0: return 1;
> + case 1: return 2;
> + case 2: return 4;
> + case 3: return 6;
> + case 4: return 8;
> + default: return 1;
The encoding continues: 5h = 10 is the most a device may advertise,
and switch/host-bridge encodings go on to Ch = 32 (CXL r3.1
8.2.4.20.1), so a 10-decoder endpoint takes the fallback and "walk
every decoder" becomes "check decoder 0 only". Unreachable while the
kernel gates on a single decoder. cxl_decoder_count_dec() in
hw/cxl/cxl-component-utils.c already carries the full table and this
file already includes its header; reusing it needs a floor of 1 (it
decodes reserved encodings to 0) plus the stub treatment patch 6
gives cxl_get_hb_passthrough().
> + * GPA and never sees the host physical base the kernel shadow holds; the shadow
> + * base and size are not consulted here.
The cover has the guest driving its own virtual decoder, and this
patch handles a decommit. After a decommit, what refuses a re-commit
with a base elsewhere inside an oversized window (patch 6 only warns
on size > need)? The kernel FSM runs on the written shadow, QEMU maps
at the window base regardless, and the virtualized read-back also
reports the window base, so a divergence is silent -- guest accesses
at the base it programmed land in the CFMWS trap instead of the
device memory. If the FSM rejects any base other than the firmware
value, a comment here closes the question; otherwise the write trap
already sees every base write, so checking it against fmws_base on
commit is cheap.
> static void vfio_cxl_teardown(VFIOPCIDevice *vdev)
Nothing on the unrealize path drops the mapping: the teardown runs at
instance finalize, and the mapping itself blocks finalize, since
adding the region into system memory referenced its owner, the vdev,
and only the unmap drops that reference. An unplug flow that resets
the device escapes through vfio_pci_pre_reset()'s PCI_COMMAND clear;
ACPI hotplug eject unparents with no reset, so the vdev never
finalizes, the VFIO fd stays held, and the guest keeps reading the
removed device's HDM at the window base. Unmapping from vfio_exitfn()
with the rest of the unrealize-time teardown breaks the cycle.
Two notes from reading, no action needed:
The BASE_LOW[31:28]-only substitution is exact: cxl-fmw sizes are
validated as 256MiB multiples (hw/cxl/cxl-host.c) and both machines
hand cxl_fmws_set_memmap() a 256MiB-aligned start (hw/i386/pc.c,
hw/arm/virt.c), so fw->base cannot carry bits below 28.
Migration is blocked today by the auto-mode blocker your patch 3
comment describes, but the destination path already holds for the day
that lifts: vfio_pci_load_config() pushes PCI_COMMAND through
vfio_pci_write_config(), which re-runs the commit scan after the
machine-done notifier has bound the window.
Many thanks,
Junjie