[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 13/26] hw/arm/smmu-common: Add support for nested TLB
From: |
Peter Maydell |
Subject: |
[PULL 13/26] hw/arm/smmu-common: Add support for nested TLB |
Date: |
Thu, 18 Jul 2024 14:20:15 +0100 |
From: Mostafa Saleh <smostafa@google.com>
This patch adds support for nested (combined) TLB entries.
The main function combine_tlb() is not used here but in the next
patches, but to simplify the patches it is introduced first.
Main changes:
1) New field added in the SMMUTLBEntry struct: parent_perm, for
nested TLB, holds the stage-2 permission, this can be used to know
the origin of a permission fault from a cached entry as caching
the “and” of the permissions loses this information.
SMMUPTWEventInfo is used to hold information about PTW faults so
the event can be populated, the value of stage used to be set
based on the current stage for TLB permission faults, however
with the parent_perm, it is now set based on which perm has
the missing permission
When nesting is not enabled it has the same value as perm which
doesn't change the logic.
2) As combined TLB implementation is used, the combination logic
chooses:
- tg and level from the entry which has the smallest addr_mask.
- Based on that the iova that would be cached is recalculated.
- Translated_addr is chosen from stage-2.
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Signed-off-by: Mostafa Saleh <smostafa@google.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20240715084519.1189624-11-smostafa@google.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
include/hw/arm/smmu-common.h | 1 +
hw/arm/smmu-common.c | 37 ++++++++++++++++++++++++++++++++----
2 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
index f793b54388d..08775364723 100644
--- a/include/hw/arm/smmu-common.h
+++ b/include/hw/arm/smmu-common.h
@@ -77,6 +77,7 @@ typedef struct SMMUTLBEntry {
IOMMUTLBEntry entry;
uint8_t level;
uint8_t granule;
+ IOMMUAccessFlags parent_perm;
} SMMUTLBEntry;
/* Stage-2 configuration. */
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
index e374cae0db6..bf55b9c5a42 100644
--- a/hw/arm/smmu-common.c
+++ b/hw/arm/smmu-common.c
@@ -426,7 +426,8 @@ static int smmu_ptw_64_s1(SMMUTransCfg *cfg,
tlbe->entry.translated_addr = gpa;
tlbe->entry.iova = iova & ~mask;
tlbe->entry.addr_mask = mask;
- tlbe->entry.perm = PTE_AP_TO_PERM(ap);
+ tlbe->parent_perm = PTE_AP_TO_PERM(ap);
+ tlbe->entry.perm = tlbe->parent_perm;
tlbe->level = level;
tlbe->granule = granule_sz;
return 0;
@@ -547,7 +548,8 @@ static int smmu_ptw_64_s2(SMMUTransCfg *cfg,
tlbe->entry.translated_addr = gpa;
tlbe->entry.iova = ipa & ~mask;
tlbe->entry.addr_mask = mask;
- tlbe->entry.perm = s2ap;
+ tlbe->parent_perm = s2ap;
+ tlbe->entry.perm = tlbe->parent_perm;
tlbe->level = level;
tlbe->granule = granule_sz;
return 0;
@@ -562,6 +564,30 @@ error:
return -EINVAL;
}
+/*
+ * combine S1 and S2 TLB entries into a single entry.
+ * As a result the S1 entry is overriden with combined data.
+ */
+static void __attribute__((unused)) combine_tlb(SMMUTLBEntry *tlbe,
+ SMMUTLBEntry *tlbe_s2,
+ dma_addr_t iova,
+ SMMUTransCfg *cfg)
+{
+ if (tlbe_s2->entry.addr_mask < tlbe->entry.addr_mask) {
+ tlbe->entry.addr_mask = tlbe_s2->entry.addr_mask;
+ tlbe->granule = tlbe_s2->granule;
+ tlbe->level = tlbe_s2->level;
+ }
+
+ tlbe->entry.translated_addr = CACHED_ENTRY_TO_ADDR(tlbe_s2,
+ tlbe->entry.translated_addr);
+
+ tlbe->entry.iova = iova & ~tlbe->entry.addr_mask;
+ /* parent_perm has s2 perm while perm keeps s1 perm. */
+ tlbe->parent_perm = tlbe_s2->entry.perm;
+ return;
+}
+
/**
* smmu_ptw - Walk the page tables for an IOVA, according to @cfg
*
@@ -629,9 +655,12 @@ SMMUTLBEntry *smmu_translate(SMMUState *bs, SMMUTransCfg
*cfg, dma_addr_t addr,
cached_entry = smmu_iotlb_lookup(bs, cfg, &tt_combined, addr);
if (cached_entry) {
- if ((flag & IOMMU_WO) && !(cached_entry->entry.perm & IOMMU_WO)) {
+ if ((flag & IOMMU_WO) && !(cached_entry->entry.perm &
+ cached_entry->parent_perm & IOMMU_WO)) {
info->type = SMMU_PTW_ERR_PERMISSION;
- info->stage = cfg->stage;
+ info->stage = !(cached_entry->entry.perm & IOMMU_WO) ?
+ SMMU_STAGE_1 :
+ SMMU_STAGE_2;
return NULL;
}
return cached_entry;
--
2.34.1
- [PULL 10/26] hw/arm/smmu: Introduce CACHED_ENTRY_TO_ADDR, (continued)
- [PULL 10/26] hw/arm/smmu: Introduce CACHED_ENTRY_TO_ADDR, Peter Maydell, 2024/07/18
- [PULL 09/26] hw/arm/smmu: Consolidate ASID and VMID types, Peter Maydell, 2024/07/18
- [PULL 19/26] hw/arm/smmuv3: Handle translation faults according to SMMUPTWEventInfo, Peter Maydell, 2024/07/18
- [PULL 22/26] target/arm: Use float_status copy in sme_fmopa_s, Peter Maydell, 2024/07/18
- [PULL 24/26] tests/tcg/aarch64: Add test cases for SME FMOPA (widening), Peter Maydell, 2024/07/18
- [PULL 08/26] hw/arm/smmu: Split smmuv3_translate(), Peter Maydell, 2024/07/18
- [PULL 15/26] hw/arm/smmu: Support nesting in smmuv3_range_inval(), Peter Maydell, 2024/07/18
- [PULL 18/26] hw/arm/smmuv3: Support nested SMMUs in smmuv3_notify_iova(), Peter Maydell, 2024/07/18
- [PULL 23/26] target/arm: Use FPST_F16 for SME FMOPA (widening), Peter Maydell, 2024/07/18
- [PULL 12/26] hw/arm/smmu-common: Rework TLB lookup for nesting, Peter Maydell, 2024/07/18
- [PULL 13/26] hw/arm/smmu-common: Add support for nested TLB,
Peter Maydell <=
- [PULL 20/26] hw/arm/smmuv3: Support and advertise nesting, Peter Maydell, 2024/07/18
- [PULL 16/26] hw/arm/smmu: Introduce smmu_iotlb_inv_asid_vmid, Peter Maydell, 2024/07/18
- [PULL 05/26] hw/arm/smmu: Fix IPA for stage-2 events, Peter Maydell, 2024/07/18
- [PULL 14/26] hw/arm/smmu-common: Support nested translation, Peter Maydell, 2024/07/18
- [PULL 26/26] hvf: arm: Do not advance PC when raising an exception, Peter Maydell, 2024/07/18
- Re: [PULL 00/26] target-arm queue, Richard Henderson, 2024/07/18