Hi Shameer,

On 9/4/26 8:05 PM, Shameer Kolothum wrote:
> Add a subsection carrying idr[0] to idr[5], needed when accel=on. pre_load
I would explain what you try to achieve before the how.
> saves the locally resolved values and post_load fails the migration if the
> incoming ones differ. Accepting the source values would leave QEMU
> advertising features the destination host cannot provide.
>
> Signed-off-by: Shameer Kolothum <[email protected]>
> ---
>  hw/arm/smmuv3-accel.h       |  1 +
>  include/hw/arm/smmuv3.h     |  7 ++++-
>  hw/arm/smmuv3-accel-stubs.c | 12 ++++++++
>  hw/arm/smmuv3-accel.c       | 58 +++++++++++++++++++++++++++++++++++++
>  hw/arm/smmuv3.c             |  1 +
>  5 files changed, 78 insertions(+), 1 deletion(-)
>
> diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h
> index ea11d513cc..a91d188d61 100644
> --- a/hw/arm/smmuv3-accel.h
> +++ b/hw/arm/smmuv3-accel.h
> @@ -99,6 +99,7 @@ void smmuv3_accel_idr_override(SMMUv3State *s);
>  bool smmuv3_accel_alloc_veventq(SMMUv3State *s, Error **errp);
>  int smmuv3_accel_event_read_validate(IOMMUFDVeventq *veventq, uint32_t type,
>                                       void *buf, size_t size, Error **errp);
> +extern const VMStateDescription vmstate_smmuv3_accel;
>  void smmuv3_accel_reset(SMMUv3State *s);
>  SMMUv3AccelCmdqvType smmuv3_accel_cmdqv_type(Object *obj);
>  
> diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
> index d39fe8850b..9e0836b81a 100644
> --- a/include/hw/arm/smmuv3.h
> +++ b/include/hw/arm/smmuv3.h
> @@ -26,6 +26,9 @@
>  
>  #define TYPE_SMMUV3_IOMMU_MEMORY_REGION "smmuv3-iommu-memory-region"
>  
> +/* Number of IDR registers, IDR0 to IDR5 */
> +#define SMMU_NUM_IDR 6
> +
>  typedef struct SMMUQueue {
>       uint64_t base; /* base register */
>       uint32_t prod;
> @@ -41,7 +44,9 @@ struct SMMUv3State {
>      uint8_t sid_size;
>      uint8_t sid_split;
>  
> -    uint32_t idr[6];
> +    uint32_t idr[SMMU_NUM_IDR];
> +    /* Locally resolved IDRs, saved by pre_load for post_load to check */
> +    uint32_t local_idr[SMMU_NUM_IDR];
>      uint32_t iidr;
>      uint32_t aidr;
>      uint32_t cr[3];
> diff --git a/hw/arm/smmuv3-accel-stubs.c b/hw/arm/smmuv3-accel-stubs.c
> index b8dd7e7b89..b57b5c01e7 100644
> --- a/hw/arm/smmuv3-accel-stubs.c
> +++ b/hw/arm/smmuv3-accel-stubs.c
> @@ -8,6 +8,7 @@
>  #include "qapi/error.h"
>  #include "hw/arm/smmuv3.h"
>  #include "hw/arm/smmuv3-accel.h"
> +#include "migration/vmstate.h"
>  
>  bool smmuv3_accel_init(SMMUv3State *s, Error **errp)
>  {
> @@ -53,6 +54,17 @@ int smmuv3_accel_event_read_validate(IOMMUFDVeventq 
> *veventq, uint32_t type,
>      return 0;
>  }
>  
> +static bool smmuv3_accel_vmstate_needed(void *opaque)
> +{
> +    return false;
> +}
> +
> +const VMStateDescription vmstate_smmuv3_accel = {
> +    .name = "smmuv3/accel",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .needed = smmuv3_accel_vmstate_needed,
> +};
>  
>  void smmuv3_accel_reset(SMMUv3State *s)
>  {
> diff --git a/hw/arm/smmuv3-accel.c b/hw/arm/smmuv3-accel.c
> index 73509dbd8d..287ea91fbe 100644
> --- a/hw/arm/smmuv3-accel.c
> +++ b/hw/arm/smmuv3-accel.c
> @@ -18,6 +18,7 @@
>  
>  #include "smmuv3-internal.h"
>  #include "smmuv3-accel.h"
> +#include "migration/vmstate.h"
>  #include "system/runstate.h"
>  #include "system/system.h"
>  #include "tegra241-cmdqv.h"
> @@ -1096,6 +1097,63 @@ bool smmuv3_accel_attach_gbpa_hwpt(SMMUv3State *s, 
> Error **errp)
>      return all_ok;
>  }
>  
> +static bool smmuv3_accel_vmstate_pre_load(void *opaque, Error **errp)
> +{
> +    SMMUv3State *s = opaque;
> +
> +    if (!s->s_accel) {
> +        error_setg(errp, "Incoming stream carries SMMUv3 accelerator state "
> +                   "but this arm-smmuv3 has accel=off");
> +        return false;
> +    }
> +
> +    /* Save the locally resolved IDRs before the stream overwrites them. */
> +    memcpy(s->local_idr, s->idr, sizeof(s->idr));
> +    return true;
> +}
> +
> +static bool smmuv3_accel_vmstate_post_load(void *opaque, int version_id,
> +                                           Error **errp)
> +{
> +    ERRP_GUARD();
> +    SMMUv3State *s = opaque;
> +    int i;
> +
> +    for (i = 0; i < ARRAY_SIZE(s->idr); i++) {
> +        if (s->idr[i] == s->local_idr[i]) {
> +            continue;
> +        }
> +        error_setg(errp, "SMMUv3 IDR%d mismatch: source 0x%08x, "
> +                   "destination 0x%08x", i, s->idr[i],
> +                   s->local_idr[i]);
> +        error_append_hint(errp, "ril, ats, oas and ssidsize must resolve to "
> +                          "the same values on source and destination.\n");
don't you want to be more precise then and just check the corresponding
fields?


> +        return false;
> +    }
> +
> +    return true;
> +}
> +
> +static bool smmuv3_accel_vmstate_needed(void *opaque)
> +{
> +    SMMUv3State *s = opaque;
> +
> +    return s->accel;
> +}
> +
> +const VMStateDescription vmstate_smmuv3_accel = {
> +    .name = "smmuv3/accel",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .needed = smmuv3_accel_vmstate_needed,
> +    .pre_load_errp = smmuv3_accel_vmstate_pre_load,
> +    .post_load_errp = smmuv3_accel_vmstate_post_load,
> +    .fields = (const VMStateField[]) {
> +        VMSTATE_UINT32_ARRAY(idr, SMMUv3State, SMMU_NUM_IDR),
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> +
>  void smmuv3_accel_reset(SMMUv3State *s)
>  {
>      SMMUv3AccelState *accel = s->s_accel;
> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
> index ed19536a4d..66d95e1076 100644
> --- a/hw/arm/smmuv3.c
> +++ b/hw/arm/smmuv3.c
> @@ -2137,6 +2137,7 @@ static const VMStateDescription vmstate_smmuv3 = {
>      },
>      .subsections = (const VMStateDescription * const []) {
>          &vmstate_gbpa,
> +        &vmstate_smmuv3_accel,
>          NULL
>      }
>  };
Thanks

Eric


Reply via email to