On 5/19/26 12:37 PM, Shameer Kolothum wrote:
> When CMDQV is active, the first cold-plugged VFIO device establishes the
> viommu to host SMMUv3 association. Block its hot-unplug to preserve this
> association and the guest's boot time CMDQV configuration.
>
> Also abort at machine_done if cmdqv=on is requested but no cold-plugged
> VFIO device was present to initialize it.
To me this is still missing the "why", something along what you put in
https://lore.kernel.org/all/ia0pr12mb755515924ad70a273b7879a1ab...@ia0pr12mb7555.namprd12.prod.outlook.com/
Thanks
Eric
>
> Reviewed-by: Nicolin Chen <[email protected]>
> Signed-off-by: Shameer Kolothum <[email protected]>
> ---
> hw/arm/smmuv3-accel.h | 1 +
> hw/arm/smmuv3-accel.c | 18 ++++++++++++++++++
> 2 files changed, 19 insertions(+)
>
> diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h
> index 8cf35c2936..4d05eb100a 100644
> --- a/hw/arm/smmuv3-accel.h
> +++ b/hw/arm/smmuv3-accel.h
> @@ -85,6 +85,7 @@ typedef struct SMMUv3AccelDevice {
> IOMMUFDVdev *vdev;
> QLIST_ENTRY(SMMUv3AccelDevice) next;
> SMMUv3AccelState *s_accel;
> + Error *unplug_blocker; /* set when CMDQV is active to block hot-unplug */
> } SMMUv3AccelDevice;
>
> bool smmuv3_accel_init(SMMUv3State *s, Error **errp);
> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
> index dbb50d1795..03575808b3 100644
> --- a/hw/arm/smmuv3-accel.c
> +++ b/hw/arm/smmuv3-accel.c
> @@ -761,6 +761,18 @@ static bool smmuv3_accel_set_iommu_device(PCIBus *bus,
> void *opaque, int devfn,
> return false;
> }
>
> + /*
> + * CMDQV is active: block hot-unplug of the device that established the
> + * viommu association. Removing it would cause the vIOMMU to host SMMUv3
> + * association be changed via device hot-plug.
> + */
> + if (s->s_accel->cmdqv_ops) {
> + PCIDevice *pdev = pci_find_device(bus, pci_bus_num(bus), devfn);
> + error_setg(&accel_dev->unplug_blocker,
> + "CMDQV is active: removing the device that established
> the "
> + "viommu association would break the guest CMDQV");
> + qdev_add_unplug_blocker(DEVICE(pdev), accel_dev->unplug_blocker);
> + }
> done:
> accel_dev->hiodi = hiodi;
> accel_dev->s_accel = s->s_accel;
> @@ -1088,6 +1100,12 @@ static void smmuv3_machine_done(Notifier *notifier,
> void *data)
> "at least one cold-plugged VFIO device");
> exit(1);
> }
> +
> + if (s->cmdqv == ON_OFF_AUTO_ON && !accel->cmdqv) {
> + error_report("arm-smmuv3 cmdqv=on requires at least one cold-plugged
> "
> + "VFIO device");
> + exit(1);
> + }
> }
>
> bool smmuv3_accel_init(SMMUv3State *s, Error **errp)