On 2025/12/3 00:39, Eric Auger wrote:

On 10/12/25 5:16 PM, Tao Tang wrote:
Introduce a bool secure_impl field to SMMUv3State and expose it as
a secure-impl device property. The introduction of this property is the
culminating step that activates the entire secure access data path,
tying together all previously merged logic to provide full support for
secure state accesses.

Add live migration support for the SMMUv3 secure register bank.

To correctly migrate the secure state, the migration logic must know
if the secure functionality is enabled. To facilitate this, a bool
secure_impl field is introduced and exposed as the secure-impl device
property. This property is introduced at the point it is first
required—for migration—and serves as the final piece of the series.

The introduction of this property also completes and activates the
entire secure access data path, tying together all previously merged
logic to provide full support for secure state accesses.

Usage:
     -global arm-smmuv3,secure-impl=true

When this property is enabled, the capability is advertised to the
guest via the S_IDR1.SECURE_IMPL bit.

The migration is implemented as follows:

- A new vmstate_smmuv3_secure_bank, referenced by the smmuv3/bank_s
subsection, serializes the secure bank's registers and queues.

- A companion smmuv3/gbpa_secure subsection mirrors the non-secure
GBPA handling, migrating the register only if its value diverges
from the reset default.

Signed-off-by: Tao Tang <[email protected]>
---
  hw/arm/smmuv3.c         | 75 +++++++++++++++++++++++++++++++++++++++++
  include/hw/arm/smmuv3.h |  1 +
  2 files changed, 76 insertions(+)

diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index 0b366895ec..ce41a12a36 100644
--- a/hw/arm/smmuv3.c
+++ b/hw/arm/smmuv3.c
@@ -337,6 +337,7 @@ static void smmuv3_init_regs(SMMUv3State *s)
memset(sbk->idr, 0, sizeof(sbk->idr));
      sbk->idr[1] = FIELD_DP32(sbk->idr[1], S_IDR1, S_SIDSIZE, 
SMMU_IDR1_SIDSIZE);
+    sbk->idr[1] = FIELD_DP32(sbk->idr[1], S_IDR1, SECURE_IMPL, s->secure_impl);
      sbk->gbpa = SMMU_GBPA_RESET_VAL;
      sbk->cmdq.entry_size = sizeof(struct Cmd);
      sbk->eventq.entry_size = sizeof(struct Evt);
@@ -2452,6 +2453,53 @@ static const VMStateDescription vmstate_smmuv3_queue = {
      },
  };
+static const VMStateDescription vmstate_smmuv3_secure_bank = {
+    .name = "smmuv3_secure_bank",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (const VMStateField[]) {
+        VMSTATE_UINT32(features, SMMUv3RegBank),
+        VMSTATE_UINT8(sid_split, SMMUv3RegBank),
+        VMSTATE_UINT32_ARRAY(cr, SMMUv3RegBank, 3),
+        VMSTATE_UINT32(cr0ack, SMMUv3RegBank),
+        VMSTATE_UINT32(irq_ctrl, SMMUv3RegBank),
+        VMSTATE_UINT32(gerror, SMMUv3RegBank),
+        VMSTATE_UINT32(gerrorn, SMMUv3RegBank),
+        VMSTATE_UINT64(gerror_irq_cfg0, SMMUv3RegBank),
+        VMSTATE_UINT32(gerror_irq_cfg1, SMMUv3RegBank),
+        VMSTATE_UINT32(gerror_irq_cfg2, SMMUv3RegBank),
+        VMSTATE_UINT64(strtab_base, SMMUv3RegBank),
+        VMSTATE_UINT32(strtab_base_cfg, SMMUv3RegBank),
+        VMSTATE_UINT64(eventq_irq_cfg0, SMMUv3RegBank),
+        VMSTATE_UINT32(eventq_irq_cfg1, SMMUv3RegBank),
+        VMSTATE_UINT32(eventq_irq_cfg2, SMMUv3RegBank),
+        VMSTATE_STRUCT(cmdq, SMMUv3RegBank, 0,
+                       vmstate_smmuv3_queue, SMMUQueue),
+        VMSTATE_STRUCT(eventq, SMMUv3RegBank, 0,
+                       vmstate_smmuv3_queue, SMMUQueue),
+        VMSTATE_END_OF_LIST(),
+    },
+};
+
+static bool smmuv3_secure_bank_needed(void *opaque)
+{
+    SMMUv3State *s = opaque;
+
+    return s->secure_impl;
+}
+
+static const VMStateDescription vmstate_smmuv3_bank_s = {
+    .name = "smmuv3/bank_s",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = smmuv3_secure_bank_needed,
+    .fields = (const VMStateField[]) {
+        VMSTATE_STRUCT(bank[SMMU_SEC_SID_S], SMMUv3State, 0,
+                       vmstate_smmuv3_secure_bank, SMMUv3RegBank),
+        VMSTATE_END_OF_LIST(),
+    },
+};
+
  static bool smmuv3_gbpa_needed(void *opaque)
  {
      SMMUv3State *s = opaque;
@@ -2472,6 +2520,25 @@ static const VMStateDescription vmstate_gbpa = {
      }
  };
+static bool smmuv3_gbpa_secure_needed(void *opaque)
I don't think you need that subsection. You can directly put this in the
secure subsection one. This was needed for NS to avoid breaking
migration but here you shall not need it.

Thanks

Eric


Thanks for the clarification. I'll drop the smmuv3/gbpa_secure subsection and just migrate the secure GBPA as part of the smmuv3/bank_s secure subsection, since we don't have any existing migration ABI to preserve for the secure state.


Also, many thanks for all your review work on this series. I'll prepare and send a v4 shortly, and if you have some time to look at it as well, that would be greatly appreciated.


Yours,

Tao


Reply via email to