[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 12/26] hw/arm/smmu-common: Rework TLB lookup for nesting
From: |
Peter Maydell |
Subject: |
[PULL 12/26] hw/arm/smmu-common: Rework TLB lookup for nesting |
Date: |
Thu, 18 Jul 2024 14:20:14 +0100 |
From: Mostafa Saleh <smostafa@google.com>
In the next patch, combine_tlb() will be added which combines 2 TLB
entries into one for nested translations, which chooses the granule
and level from the smallest entry.
This means that with nested translation, an entry can be cached with
the granule of stage-2 and not stage-1.
However, currently, the lookup for an IOVA is done with input stage
granule, which is stage-1 for nested configuration, which will not
work with the above logic.
This patch reworks lookup in that case, so it falls back to stage-2
granule if no entry is found using stage-1 granule.
Also, drop aligning the iova to avoid over-aligning in case the iova
is cached with a smaller granule, the TLB lookup will align the iova
anyway for each granule and level, and the page table walker doesn't
consider the page offset bits.
Signed-off-by: Mostafa Saleh <smostafa@google.com>
Reviewed-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20240715084519.1189624-10-smostafa@google.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/smmu-common.c | 64 +++++++++++++++++++++++++++++---------------
1 file changed, 43 insertions(+), 21 deletions(-)
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
index 7fbf8e22fe0..e374cae0db6 100644
--- a/hw/arm/smmu-common.c
+++ b/hw/arm/smmu-common.c
@@ -66,8 +66,10 @@ SMMUIOTLBKey smmu_get_iotlb_key(int asid, int vmid, uint64_t
iova,
return key;
}
-SMMUTLBEntry *smmu_iotlb_lookup(SMMUState *bs, SMMUTransCfg *cfg,
- SMMUTransTableInfo *tt, hwaddr iova)
+static SMMUTLBEntry *smmu_iotlb_lookup_all_levels(SMMUState *bs,
+ SMMUTransCfg *cfg,
+ SMMUTransTableInfo *tt,
+ hwaddr iova)
{
uint8_t tg = (tt->granule_sz - 10) / 2;
uint8_t inputsize = 64 - tt->tsz;
@@ -88,6 +90,36 @@ SMMUTLBEntry *smmu_iotlb_lookup(SMMUState *bs, SMMUTransCfg
*cfg,
}
level++;
}
+ return entry;
+}
+
+/**
+ * smmu_iotlb_lookup - Look up for a TLB entry.
+ * @bs: SMMU state which includes the TLB instance
+ * @cfg: Configuration of the translation
+ * @tt: Translation table info (granule and tsz)
+ * @iova: IOVA address to lookup
+ *
+ * returns a valid entry on success, otherwise NULL.
+ * In case of nested translation, tt can be updated to include
+ * the granule of the found entry as it might different from
+ * the IOVA granule.
+ */
+SMMUTLBEntry *smmu_iotlb_lookup(SMMUState *bs, SMMUTransCfg *cfg,
+ SMMUTransTableInfo *tt, hwaddr iova)
+{
+ SMMUTLBEntry *entry = NULL;
+
+ entry = smmu_iotlb_lookup_all_levels(bs, cfg, tt, iova);
+ /*
+ * For nested translation also try the s2 granule, as the TLB will insert
+ * it if the size of s2 tlb entry was smaller.
+ */
+ if (!entry && (cfg->stage == SMMU_NESTED) &&
+ (cfg->s2cfg.granule_sz != tt->granule_sz)) {
+ tt->granule_sz = cfg->s2cfg.granule_sz;
+ entry = smmu_iotlb_lookup_all_levels(bs, cfg, tt, iova);
+ }
if (entry) {
cfg->iotlb_hits++;
@@ -569,18 +601,21 @@ int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova,
IOMMUAccessFlags perm,
SMMUTLBEntry *smmu_translate(SMMUState *bs, SMMUTransCfg *cfg, dma_addr_t addr,
IOMMUAccessFlags flag, SMMUPTWEventInfo *info)
{
- uint64_t page_mask, aligned_addr;
SMMUTLBEntry *cached_entry = NULL;
SMMUTransTableInfo *tt;
int status;
/*
- * Combined attributes used for TLB lookup, as only one stage is supported,
- * it will hold attributes based on the enabled stage.
+ * Combined attributes used for TLB lookup, holds the attributes for
+ * the input stage.
*/
SMMUTransTableInfo tt_combined;
- if (cfg->stage == SMMU_STAGE_1) {
+ if (cfg->stage == SMMU_STAGE_2) {
+ /* Stage2. */
+ tt_combined.granule_sz = cfg->s2cfg.granule_sz;
+ tt_combined.tsz = cfg->s2cfg.tsz;
+ } else {
/* Select stage1 translation table. */
tt = select_tt(cfg, addr);
if (!tt) {
@@ -590,22 +625,9 @@ SMMUTLBEntry *smmu_translate(SMMUState *bs, SMMUTransCfg
*cfg, dma_addr_t addr,
}
tt_combined.granule_sz = tt->granule_sz;
tt_combined.tsz = tt->tsz;
-
- } else {
- /* Stage2. */
- tt_combined.granule_sz = cfg->s2cfg.granule_sz;
- tt_combined.tsz = cfg->s2cfg.tsz;
}
- /*
- * TLB lookup looks for granule and input size for a translation stage,
- * as only one stage is supported right now, choose the right values
- * from the configuration.
- */
- page_mask = (1ULL << tt_combined.granule_sz) - 1;
- aligned_addr = addr & ~page_mask;
-
- cached_entry = smmu_iotlb_lookup(bs, cfg, &tt_combined, aligned_addr);
+ cached_entry = smmu_iotlb_lookup(bs, cfg, &tt_combined, addr);
if (cached_entry) {
if ((flag & IOMMU_WO) && !(cached_entry->entry.perm & IOMMU_WO)) {
info->type = SMMU_PTW_ERR_PERMISSION;
@@ -616,7 +638,7 @@ SMMUTLBEntry *smmu_translate(SMMUState *bs, SMMUTransCfg
*cfg, dma_addr_t addr,
}
cached_entry = g_new0(SMMUTLBEntry, 1);
- status = smmu_ptw(cfg, aligned_addr, flag, cached_entry, info);
+ status = smmu_ptw(cfg, addr, flag, cached_entry, info);
if (status) {
g_free(cached_entry);
return NULL;
--
2.34.1
- [PULL 01/26] target/arm: Fix handling of LDAPR/STLR with negative offset, (continued)
- [PULL 01/26] target/arm: Fix handling of LDAPR/STLR with negative offset, Peter Maydell, 2024/07/18
- [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 <=
- [PULL 13/26] hw/arm/smmu-common: Add support for nested TLB, Peter Maydell, 2024/07/18
- [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