On 6/1/26 1:42 PM, Shameer Kolothum wrote:
> When CMDQV is active, the first cold-plugged VFIO device establishes
> the viommu to host SMMUv3 association, and the guest's boot-time CMDQV
> configuration (VINTFs, VCMDQs) is built on top of that association.
>
> Hot-unplugging that device would release the viommu and tear down all
> CMDQV state. Hot-plugging another device behind a different host
> SMMUv3+CMDQV would then re-bind the same vSMMUv3 to new host hardware,
> while the guest keeps using its boot-time configuration and ends up
> issuing commands to the wrong host. Block hot-unplug of the
> establishing device to avoid this; retaining the binding across unplug
> is non-trivial and not required by any current use case.
>
> 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]>
Reviewed-by: Eric Auger <[email protected]>

Eric
> ---
>  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 5fc85fb89d..dd755c394d 100644
> --- a/hw/arm/smmuv3-accel.h
> +++ b/hw/arm/smmuv3-accel.h
> @@ -84,6 +84,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 9c3bd4413d..80900c2521 100644
> --- a/hw/arm/smmuv3-accel.c
> +++ b/hw/arm/smmuv3-accel.c
> @@ -759,6 +759,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;
> @@ -1082,6 +1094,12 @@ static void smmuv3_accel_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)


Reply via email to