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. 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) -- 2.43.0
