thebeanogamer / rpms / qemu-kvm

Forked from rpms/qemu-kvm 5 months ago
Clone

Blame SOURCES/kvm-hw-arm-smmu-Introduce-SMMUTLBEntry-for-PTW-and-IOTLB.patch

c687bc
From 602f17920e422e2b8d3ce485e56066a97b74e723 Mon Sep 17 00:00:00 2001
c687bc
From: eperezma <eperezma@redhat.com>
c687bc
Date: Tue, 12 Jan 2021 14:36:29 -0500
c687bc
Subject: [PATCH 05/17] hw/arm/smmu: Introduce SMMUTLBEntry for PTW and IOTLB
c687bc
 value
c687bc
MIME-Version: 1.0
c687bc
Content-Type: text/plain; charset=UTF-8
c687bc
Content-Transfer-Encoding: 8bit
c687bc
c687bc
RH-Author: eperezma <eperezma@redhat.com>
c687bc
Message-id: <20210112143638.374060-5-eperezma@redhat.com>
c687bc
Patchwork-id: 100597
c687bc
O-Subject: [RHEL-8.4.0 qemu-kvm PATCH v2 04/13] hw/arm/smmu: Introduce SMMUTLBEntry for PTW and IOTLB value
c687bc
Bugzilla: 1843852
c687bc
RH-Acked-by: Xiao Wang <jasowang@redhat.com>
c687bc
RH-Acked-by: Peter Xu <peterx@redhat.com>
c687bc
RH-Acked-by: Auger Eric <eric.auger@redhat.com>
c687bc
c687bc
From: Eric Auger <eric.auger@redhat.com>
c687bc
c687bc
Introduce a specialized SMMUTLBEntry to store the result of
c687bc
the PTW and cache in the IOTLB. This structure extends the
c687bc
generic IOMMUTLBEntry struct with the level of the entry and
c687bc
the granule size.
c687bc
c687bc
Those latter will be useful when implementing range invalidation.
c687bc
c687bc
Signed-off-by: Eric Auger <eric.auger@redhat.com>
c687bc
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
c687bc
Message-id: 20200728150815.11446-5-eric.auger@redhat.com
c687bc
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
c687bc
(cherry picked from commit a7550158556b7fc2f2baaecf9092499c6687b160)
c687bc
Signed-off-by: Eugenio PĂ©rez <eperezma@redhat.com>
c687bc
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
c687bc
---
c687bc
 hw/arm/smmu-common.c         | 32 +++++++++++++++++---------------
c687bc
 hw/arm/smmuv3.c              | 10 +++++-----
c687bc
 include/hw/arm/smmu-common.h | 12 +++++++++---
c687bc
 3 files changed, 31 insertions(+), 23 deletions(-)
c687bc
c687bc
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
c687bc
index 0b89c9fbbbc..06e9e38b007 100644
c687bc
--- a/hw/arm/smmu-common.c
c687bc
+++ b/hw/arm/smmu-common.c
c687bc
@@ -64,11 +64,11 @@ SMMUIOTLBKey smmu_get_iotlb_key(uint16_t asid, uint64_t iova)
c687bc
     return key;
c687bc
 }
c687bc
 
c687bc
-IOMMUTLBEntry *smmu_iotlb_lookup(SMMUState *bs, SMMUTransCfg *cfg,
c687bc
-                                 hwaddr iova)
c687bc
+SMMUTLBEntry *smmu_iotlb_lookup(SMMUState *bs, SMMUTransCfg *cfg,
c687bc
+                                hwaddr iova)
c687bc
 {
c687bc
     SMMUIOTLBKey key = smmu_get_iotlb_key(cfg->asid, iova);
c687bc
-    IOMMUTLBEntry *entry = g_hash_table_lookup(bs->iotlb, &key);
c687bc
+    SMMUTLBEntry *entry = g_hash_table_lookup(bs->iotlb, &key);
c687bc
 
c687bc
     if (entry) {
c687bc
         cfg->iotlb_hits++;
c687bc
@@ -86,7 +86,7 @@ IOMMUTLBEntry *smmu_iotlb_lookup(SMMUState *bs, SMMUTransCfg *cfg,
c687bc
     return entry;
c687bc
 }
c687bc
 
c687bc
-void smmu_iotlb_insert(SMMUState *bs, SMMUTransCfg *cfg, IOMMUTLBEntry *entry)
c687bc
+void smmu_iotlb_insert(SMMUState *bs, SMMUTransCfg *cfg, SMMUTLBEntry *new)
c687bc
 {
c687bc
     SMMUIOTLBKey *key = g_new0(SMMUIOTLBKey, 1);
c687bc
 
c687bc
@@ -94,9 +94,9 @@ void smmu_iotlb_insert(SMMUState *bs, SMMUTransCfg *cfg, IOMMUTLBEntry *entry)
c687bc
         smmu_iotlb_inv_all(bs);
c687bc
     }
c687bc
 
c687bc
-    *key = smmu_get_iotlb_key(cfg->asid, entry->iova);
c687bc
-    trace_smmu_iotlb_insert(cfg->asid, entry->iova);
c687bc
-    g_hash_table_insert(bs->iotlb, key, entry);
c687bc
+    *key = smmu_get_iotlb_key(cfg->asid, new->entry.iova);
c687bc
+    trace_smmu_iotlb_insert(cfg->asid, new->entry.iova);
c687bc
+    g_hash_table_insert(bs->iotlb, key, new);
c687bc
 }
c687bc
 
c687bc
 inline void smmu_iotlb_inv_all(SMMUState *s)
c687bc
@@ -217,7 +217,7 @@ SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_addr_t iova)
c687bc
  * @cfg: translation config
c687bc
  * @iova: iova to translate
c687bc
  * @perm: access type
c687bc
- * @tlbe: IOMMUTLBEntry (out)
c687bc
+ * @tlbe: SMMUTLBEntry (out)
c687bc
  * @info: handle to an error info
c687bc
  *
c687bc
  * Return 0 on success, < 0 on error. In case of error, @info is filled
c687bc
@@ -227,7 +227,7 @@ SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_addr_t iova)
c687bc
  */
c687bc
 static int smmu_ptw_64(SMMUTransCfg *cfg,
c687bc
                        dma_addr_t iova, IOMMUAccessFlags perm,
c687bc
-                       IOMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
c687bc
+                       SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
c687bc
 {
c687bc
     dma_addr_t baseaddr, indexmask;
c687bc
     int stage = cfg->stage;
c687bc
@@ -247,8 +247,8 @@ static int smmu_ptw_64(SMMUTransCfg *cfg,
c687bc
     baseaddr = extract64(tt->ttb, 0, 48);
c687bc
     baseaddr &= ~indexmask;
c687bc
 
c687bc
-    tlbe->iova = iova;
c687bc
-    tlbe->addr_mask = (1 << granule_sz) - 1;
c687bc
+    tlbe->entry.iova = iova;
c687bc
+    tlbe->entry.addr_mask = (1 << granule_sz) - 1;
c687bc
 
c687bc
     while (level <= 3) {
c687bc
         uint64_t subpage_size = 1ULL << level_shift(level, granule_sz);
c687bc
@@ -299,14 +299,16 @@ static int smmu_ptw_64(SMMUTransCfg *cfg,
c687bc
             goto error;
c687bc
         }
c687bc
 
c687bc
-        tlbe->translated_addr = gpa + (iova & mask);
c687bc
-        tlbe->perm = PTE_AP_TO_PERM(ap);
c687bc
+        tlbe->entry.translated_addr = gpa + (iova & mask);
c687bc
+        tlbe->entry.perm = PTE_AP_TO_PERM(ap);
c687bc
+        tlbe->level = level;
c687bc
+        tlbe->granule = granule_sz;
c687bc
         return 0;
c687bc
     }
c687bc
     info->type = SMMU_PTW_ERR_TRANSLATION;
c687bc
 
c687bc
 error:
c687bc
-    tlbe->perm = IOMMU_NONE;
c687bc
+    tlbe->entry.perm = IOMMU_NONE;
c687bc
     return -EINVAL;
c687bc
 }
c687bc
 
c687bc
@@ -322,7 +324,7 @@ error:
c687bc
  * return 0 on success
c687bc
  */
c687bc
 inline int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
c687bc
-             IOMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
c687bc
+                    SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
c687bc
 {
c687bc
     if (!cfg->aa64) {
c687bc
         /*
c687bc
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
c687bc
index 34dea4df4da..ad8212779d3 100644
c687bc
--- a/hw/arm/smmuv3.c
c687bc
+++ b/hw/arm/smmuv3.c
c687bc
@@ -614,7 +614,7 @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
c687bc
     SMMUTranslationStatus status;
c687bc
     SMMUState *bs = ARM_SMMU(s);
c687bc
     uint64_t page_mask, aligned_addr;
c687bc
-    IOMMUTLBEntry *cached_entry = NULL;
c687bc
+    SMMUTLBEntry *cached_entry = NULL;
c687bc
     SMMUTransTableInfo *tt;
c687bc
     SMMUTransCfg *cfg = NULL;
c687bc
     IOMMUTLBEntry entry = {
c687bc
@@ -664,7 +664,7 @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
c687bc
 
c687bc
     cached_entry = smmu_iotlb_lookup(bs, cfg, aligned_addr);
c687bc
     if (cached_entry) {
c687bc
-        if ((flag & IOMMU_WO) && !(cached_entry->perm & IOMMU_WO)) {
c687bc
+        if ((flag & IOMMU_WO) && !(cached_entry->entry.perm & IOMMU_WO)) {
c687bc
             status = SMMU_TRANS_ERROR;
c687bc
             if (event.record_trans_faults) {
c687bc
                 event.type = SMMU_EVT_F_PERMISSION;
c687bc
@@ -677,7 +677,7 @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
c687bc
         goto epilogue;
c687bc
     }
c687bc
 
c687bc
-    cached_entry = g_new0(IOMMUTLBEntry, 1);
c687bc
+    cached_entry = g_new0(SMMUTLBEntry, 1);
c687bc
 
c687bc
     if (smmu_ptw(cfg, aligned_addr, flag, cached_entry, &ptw_info)) {
c687bc
         g_free(cached_entry);
c687bc
@@ -731,9 +731,9 @@ epilogue:
c687bc
     switch (status) {
c687bc
     case SMMU_TRANS_SUCCESS:
c687bc
         entry.perm = flag;
c687bc
-        entry.translated_addr = cached_entry->translated_addr +
c687bc
+        entry.translated_addr = cached_entry->entry.translated_addr +
c687bc
                                     (addr & page_mask);
c687bc
-        entry.addr_mask = cached_entry->addr_mask;
c687bc
+        entry.addr_mask = cached_entry->entry.addr_mask;
c687bc
         trace_smmuv3_translate_success(mr->parent_obj.name, sid, addr,
c687bc
                                        entry.translated_addr, entry.perm);
c687bc
         break;
c687bc
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
c687bc
index bceba40885c..277923bdc0a 100644
c687bc
--- a/include/hw/arm/smmu-common.h
c687bc
+++ b/include/hw/arm/smmu-common.h
c687bc
@@ -52,6 +52,12 @@ typedef struct SMMUTransTableInfo {
c687bc
     uint8_t granule_sz;        /* granule page shift */
c687bc
 } SMMUTransTableInfo;
c687bc
 
c687bc
+typedef struct SMMUTLBEntry {
c687bc
+    IOMMUTLBEntry entry;
c687bc
+    uint8_t level;
c687bc
+    uint8_t granule;
c687bc
+} SMMUTLBEntry;
c687bc
+
c687bc
 /*
c687bc
  * Generic structure populated by derived SMMU devices
c687bc
  * after decoding the configuration information and used as
c687bc
@@ -140,7 +146,7 @@ static inline uint16_t smmu_get_sid(SMMUDevice *sdev)
c687bc
  * pair, according to @cfg translation config
c687bc
  */
c687bc
 int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
c687bc
-             IOMMUTLBEntry *tlbe, SMMUPTWEventInfo *info);
c687bc
+             SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info);
c687bc
 
c687bc
 /**
c687bc
  * select_tt - compute which translation table shall be used according to
c687bc
@@ -153,8 +159,8 @@ IOMMUMemoryRegion *smmu_iommu_mr(SMMUState *s, uint32_t sid);
c687bc
 
c687bc
 #define SMMU_IOTLB_MAX_SIZE 256
c687bc
 
c687bc
-IOMMUTLBEntry *smmu_iotlb_lookup(SMMUState *bs, SMMUTransCfg *cfg, hwaddr iova);
c687bc
-void smmu_iotlb_insert(SMMUState *bs, SMMUTransCfg *cfg, IOMMUTLBEntry *entry);
c687bc
+SMMUTLBEntry *smmu_iotlb_lookup(SMMUState *bs, SMMUTransCfg *cfg, hwaddr iova);
c687bc
+void smmu_iotlb_insert(SMMUState *bs, SMMUTransCfg *cfg, SMMUTLBEntry *entry);
c687bc
 SMMUIOTLBKey smmu_get_iotlb_key(uint16_t asid, uint64_t iova);
c687bc
 void smmu_iotlb_inv_all(SMMUState *s);
c687bc
 void smmu_iotlb_inv_asid(SMMUState *s, uint16_t asid);
c687bc
-- 
c687bc
2.27.0
c687bc