Hi Eric,
On 2025/9/29 23:33, Eric Auger wrote:
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
You are absolutely right. That line of code is clearly part of the IOTLB
cache logic and doesn't belong in this commit.
I will move this change to the relevant IOTLB cache commit in the next
version of the series.
Thanks for catching that.
Best,
Tao
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