8fced6
From 79718d8c67c9c54fa86a77f66aa8784aca7651d5 Mon Sep 17 00:00:00 2001
8fced6
From: eperezma <eperezma@redhat.com>
8fced6
Date: Tue, 12 Jan 2021 14:36:26 -0500
8fced6
Subject: [PATCH 02/17] hw/arm/smmu-common: Factorize some code in
8fced6
 smmu_ptw_64()
8fced6
MIME-Version: 1.0
8fced6
Content-Type: text/plain; charset=UTF-8
8fced6
Content-Transfer-Encoding: 8bit
8fced6
8fced6
RH-Author: eperezma <eperezma@redhat.com>
8fced6
Message-id: <20210112143638.374060-2-eperezma@redhat.com>
8fced6
Patchwork-id: 100594
8fced6
O-Subject: [RHEL-8.4.0 qemu-kvm PATCH v2 01/13] hw/arm/smmu-common: Factorize some code in smmu_ptw_64()
8fced6
Bugzilla: 1843852
8fced6
RH-Acked-by: Xiao Wang <jasowang@redhat.com>
8fced6
RH-Acked-by: Peter Xu <peterx@redhat.com>
8fced6
RH-Acked-by: Auger Eric <eric.auger@redhat.com>
8fced6
8fced6
From: Eric Auger <eric.auger@redhat.com>
8fced6
8fced6
Page and block PTE decoding can share some code. Let's
8fced6
first handle table PTE and factorize some code shared by
8fced6
page and block PTEs.
8fced6
8fced6
Signed-off-by: Eric Auger <eric.auger@redhat.com>
8fced6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8fced6
Message-id: 20200728150815.11446-2-eric.auger@redhat.com
8fced6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8fced6
(cherry picked from commit 1733837d7cdb207653a849a5f1fa78de878c6ac1)
8fced6
Signed-off-by: Eugenio PĂ©rez <eperezma@redhat.com>
8fced6
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
8fced6
---
8fced6
 hw/arm/smmu-common.c | 48 ++++++++++++++++----------------------------
8fced6
 1 file changed, 17 insertions(+), 31 deletions(-)
8fced6
8fced6
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
8fced6
index 245817d23e9..d2ba8b224ba 100644
8fced6
--- a/hw/arm/smmu-common.c
8fced6
+++ b/hw/arm/smmu-common.c
8fced6
@@ -187,7 +187,7 @@ static int smmu_ptw_64(SMMUTransCfg *cfg,
8fced6
         uint64_t subpage_size = 1ULL << level_shift(level, granule_sz);
8fced6
         uint64_t mask = subpage_size - 1;
8fced6
         uint32_t offset = iova_level_offset(iova, inputsize, level, granule_sz);
8fced6
-        uint64_t pte;
8fced6
+        uint64_t pte, gpa;
8fced6
         dma_addr_t pte_addr = baseaddr + offset * sizeof(pte);
8fced6
         uint8_t ap;
8fced6
 
8fced6
@@ -200,56 +200,42 @@ static int smmu_ptw_64(SMMUTransCfg *cfg,
8fced6
         if (is_invalid_pte(pte) || is_reserved_pte(pte, level)) {
8fced6
             trace_smmu_ptw_invalid_pte(stage, level, baseaddr,
8fced6
                                        pte_addr, offset, pte);
8fced6
-            info->type = SMMU_PTW_ERR_TRANSLATION;
8fced6
-            goto error;
8fced6
+            break;
8fced6
         }
8fced6
 
8fced6
-        if (is_page_pte(pte, level)) {
8fced6
-            uint64_t gpa = get_page_pte_address(pte, granule_sz);
8fced6
+        if (is_table_pte(pte, level)) {
8fced6
+            ap = PTE_APTABLE(pte);
8fced6
 
8fced6
-            ap = PTE_AP(pte);
8fced6
             if (is_permission_fault(ap, perm)) {
8fced6
                 info->type = SMMU_PTW_ERR_PERMISSION;
8fced6
                 goto error;
8fced6
             }
8fced6
-
8fced6
-            tlbe->translated_addr = gpa + (iova & mask);
8fced6
-            tlbe->perm = PTE_AP_TO_PERM(ap);
8fced6
+            baseaddr = get_table_pte_address(pte, granule_sz);
8fced6
+            level++;
8fced6
+            continue;
8fced6
+        } else if (is_page_pte(pte, level)) {
8fced6
+            gpa = get_page_pte_address(pte, granule_sz);
8fced6
             trace_smmu_ptw_page_pte(stage, level, iova,
8fced6
                                     baseaddr, pte_addr, pte, gpa);
8fced6
-            return 0;
8fced6
-        }
8fced6
-        if (is_block_pte(pte, level)) {
8fced6
+        } else {
8fced6
             uint64_t block_size;
8fced6
-            hwaddr gpa = get_block_pte_address(pte, level, granule_sz,
8fced6
-                                               &block_size);
8fced6
-
8fced6
-            ap = PTE_AP(pte);
8fced6
-            if (is_permission_fault(ap, perm)) {
8fced6
-                info->type = SMMU_PTW_ERR_PERMISSION;
8fced6
-                goto error;
8fced6
-            }
8fced6
 
8fced6
+            gpa = get_block_pte_address(pte, level, granule_sz,
8fced6
+                                        &block_size);
8fced6
             trace_smmu_ptw_block_pte(stage, level, baseaddr,
8fced6
                                      pte_addr, pte, iova, gpa,
8fced6
                                      block_size >> 20);
8fced6
-
8fced6
-            tlbe->translated_addr = gpa + (iova & mask);
8fced6
-            tlbe->perm = PTE_AP_TO_PERM(ap);
8fced6
-            return 0;
8fced6
         }
8fced6
-
8fced6
-        /* table pte */
8fced6
-        ap = PTE_APTABLE(pte);
8fced6
-
8fced6
+        ap = PTE_AP(pte);
8fced6
         if (is_permission_fault(ap, perm)) {
8fced6
             info->type = SMMU_PTW_ERR_PERMISSION;
8fced6
             goto error;
8fced6
         }
8fced6
-        baseaddr = get_table_pte_address(pte, granule_sz);
8fced6
-        level++;
8fced6
-    }
8fced6
 
8fced6
+        tlbe->translated_addr = gpa + (iova & mask);
8fced6
+        tlbe->perm = PTE_AP_TO_PERM(ap);
8fced6
+        return 0;
8fced6
+    }
8fced6
     info->type = SMMU_PTW_ERR_TRANSLATION;
8fced6
 
8fced6
 error:
8fced6
-- 
8fced6
2.27.0
8fced6