On 9/26/25 5:08 AM, Tao Tang wrote:
> Resending patches 12–14/14 that were missing due to a send issue. Sorry
> for the noise.
>
> The Arm SMMUv3 architecture uses a SEC_SID (Secure StreamID) to select
> the programming interface. To support future extensions like RME, which
> defines four security states (Non-secure, Secure, Realm, and Root), the
> QEMU model must cleanly separate these contexts for all operations.
>
> This commit leverages the generic iommu_index to represent this
> security context. The core IOMMU layer now uses the SMMU's .attrs_to_index
> callback to map a transaction's ARMSecuritySpace attribute to the
> corresponding iommu_index.
>
> This index is then passed down to smmuv3_translate and used throughout
> the model to select the correct register bank and processing logic. This
> makes the iommu_index the clear QEMU equivalent of the architectural
> SEC_SID, cleanly separating the contexts for all subsequent lookups.
>
> Signed-off-by: Tao Tang <[email protected]>
> ---
> hw/arm/smmuv3.c | 37 ++++++++++++++++++++++++++++++++++++-
> 1 file changed, 36 insertions(+), 1 deletion(-)
>
> diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
> index eec36d5fd2..c92cc0f06a 100644
> --- a/hw/arm/smmuv3.c
> +++ b/hw/arm/smmuv3.c
> @@ -1099,6 +1099,38 @@ static void smmuv3_fixup_event(SMMUEventInfo *event,
> hwaddr iova)
> }
> }
>
> +static SMMUSecurityIndex smmuv3_attrs_to_security_index(MemTxAttrs attrs)
> +{
> + switch (attrs.space) {
> + case ARMSS_Secure:
> + return SMMU_SEC_IDX_S;
> + case ARMSS_NonSecure:
> + default:
> + return SMMU_SEC_IDX_NS;
> + }
> +}
> +
> +/*
> + * ARM SMMU IOMMU index mapping (implements SEC_SID from ARM SMMU):
> + * iommu_idx = 0: Non-secure transactions
> + * iommu_idx = 1: Secure transactions
> + *
> + * The iommu_idx parameter effectively implements the SEC_SID
> + * (Security Stream ID) attribute from the ARM SMMU architecture
> + * specification, which allows the SMMU to differentiate between
> + * secure and non-secure transactions at the hardware level.
> + */
> +static int smmuv3_attrs_to_index(IOMMUMemoryRegion *iommu, MemTxAttrs attrs)
> +{
> + return smmuv3_attrs_to_security_index(attrs);
> +}
> +
> +static int smmuv3_num_indexes(IOMMUMemoryRegion *iommu)
> +{
> + /* Support 2 IOMMU indexes for now: NS/S */
> + return SMMU_SEC_IDX_NUM;
> +}
> +
> /* Entry point to SMMU, does everything. */
> static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
> IOMMUAccessFlags flag, int iommu_idx)
> @@ -1111,7 +1143,7 @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion
> *mr, hwaddr addr,
> .inval_ste_allowed = false};
> SMMUTranslationStatus status;
> SMMUTransCfg *cfg = NULL;
> - SMMUSecurityIndex sec_idx = SMMU_SEC_IDX_NS;
> + SMMUSecurityIndex sec_idx = iommu_idx;
> IOMMUTLBEntry entry = {
> .target_as = &address_space_memory,
> .iova = addr,
> @@ -1155,6 +1187,7 @@ epilogue:
> entry.perm = cached_entry->entry.perm;
> entry.translated_addr = CACHED_ENTRY_TO_ADDR(cached_entry, addr);
> entry.addr_mask = cached_entry->entry.addr_mask;
> + entry.target_as = cached_entry->entry.target_as;
this change looks unrelated to the commit desc.
Eric
> trace_smmuv3_translate_success(mr->parent_obj.name, sid, addr,
> entry.translated_addr, entry.perm,
> cfg->stage);
> @@ -2534,6 +2567,8 @@ static void
> smmuv3_iommu_memory_region_class_init(ObjectClass *klass,
>
> imrc->translate = smmuv3_translate;
> imrc->notify_flag_changed = smmuv3_notify_flag_changed;
> + imrc->attrs_to_index = smmuv3_attrs_to_index;
> + imrc->num_indexes = smmuv3_num_indexes;
> }
>
> static const TypeInfo smmuv3_type_info = {
> --
> 2.34.1
>