The Arm SMMUv3 architecture uses a SEC_SID (Secure StreamID) flag to
select between two distinct programming interfaces: Secure and
Non-secure. The QEMU model must reflect this fundamental hardware
separation for all memory operations, including TLB lookups.

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 secure attribute to an index (1 for
secure, 0 for non-secure).

This index is then passed down to smmuv3_translate. Inside the
translate function, the local is_secure flag is now derived directly
from the iommu_index. 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 <tangtao1...@phytium.com.cn>
---
 hw/arm/smmuv3.c | 34 +++++++++++++++++++++++++++++++---
 1 file changed, 31 insertions(+), 3 deletions(-)

diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index 972cbc872f..1a2e795985 100644
--- a/hw/arm/smmuv3.c
+++ b/hw/arm/smmuv3.c
@@ -1137,6 +1137,33 @@ static void smmuv3_fixup_event(SMMUEventInfo *event, 
hwaddr iova)
     }
 }
 
+/*
+ * 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)
+{
+    /*
+     * Map transaction attributes to IOMMU index:
+     * - Secure transactions (attrs.secure = 1) -> iommu_idx = 1
+     * - Non-secure transactions (attrs.secure = 0) -> iommu_idx = 0
+     * - Unspecified attributes are treated as non-secure for compat
+     */
+    return attrs.secure ? 1 : 0;
+}
+
+static int smmuv3_num_indexes(IOMMUMemoryRegion *iommu)
+{
+    /* ARM SMMU supports 2 IOMMU indexes: non-secure (0) and secure (1) */
+    return 2;
+}
+
 /* Entry point to SMMU, does everything. */
 static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
                                       IOMMUAccessFlags flag, int iommu_idx)
@@ -1149,16 +1176,15 @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion 
*mr, hwaddr addr,
                            .inval_ste_allowed = false};
     SMMUTranslationStatus status;
     SMMUTransCfg *cfg = NULL;
+    bool is_secure = (iommu_idx == 1);
     IOMMUTLBEntry entry = {
-        .target_as = smmu_get_address_space(false),
+        .target_as = smmu_get_address_space(is_secure),
         .iova = addr,
         .translated_addr = addr,
         .addr_mask = ~(hwaddr)0,
         .perm = IOMMU_NONE,
     };
     SMMUTLBEntry *cached_entry = NULL;
-    /* We don't support secure translation for now */
-    bool is_secure = false;
 
     qemu_mutex_lock(&s->mutex);
 
@@ -2639,6 +2665,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


Reply via email to