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