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; 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
