From 695a2b9f1df15cd1f562344041700997b602a861 Mon Sep 17 00:00:00 2001 From: Bibek Kumar Patro Date: Fri, 10 Jan 2025 10:53:44 +0530 Subject: [PATCH] dma-mapping-fast: Fix PMD offset calculation for non-2M aligned start aperture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Modify PMD offset calculation for domains with start apertures not 2M aligned. Currently, when this happens, the PMD offset is calculated to the next PMD, and hence each IOVA is mapped as IOVA + offset, causing the IOVA to be tagged to the wrong PA. Issue occurrence - With the following sample aperture settings by a fastmap client: qcom,iommu-dma-addr-pool = <0x87f10000 0x07f00000>; qcom,iommu-geometry = <0x87f10000 0x07f00000>; The effective IOVA range is bounded to iova_base: 0x87f10000, iova_end: 0x8FE10000, which makes the IOVA base not aligned to a 2MB boundary. While calculating PTE, this adds an extra “default offset” to the PMD base (since all PMD pages’ base addresses are 2MB aligned), which further gets added on top of the actual offset obtained by (iova - base). This causes the final PMD offset to have an additional delta, causing the IOVA to be tagged to the wrong PA. ALIGN_DOWN(base, SZ_2M) helps to remove the extra “default offset,” helping to tag the IOVA to the right PA. ┌────────┐ PMD 1 base │ ├──────►┌┬──────┬┐◄── │ │ ││ ││ ALIGN_DOWN(base, SZ_2M) │PGD page├─┐ ││ old ││ │ │ │ ││offset││ │ │ │────►│└─ ││◄──── └────────┘ │wrong│ new ││ base │iova │offset─┘│◄──── │ └────────┘ right │ iova │ PMD 2 base └────►┌────────┐◄──── │ │ ALIGN_UP(base, SZ_2M) │ │ │ │ │ │ │ │ └┬───────┘ │PMD n base ┌┴───────┐ │ │ │ │ │ │ │ │ │ │ └────────┘ Change-Id: Ie320816ee91710fe06cf2337816d0fb8638ccbcb Fixes: 2e87440c3e6f ("iommu/io-pgtable-fast: optimize statically allocated pages") Signed-off-by: Bibek Kumar Patro Signed-off-by: Srinivasarao Pathipati --- drivers/iommu/io-pgtable-fast.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/io-pgtable-fast.c b/drivers/iommu/io-pgtable-fast.c index f07e93b33f05..67ca5c20c521 100644 --- a/drivers/iommu/io-pgtable-fast.c +++ b/drivers/iommu/io-pgtable-fast.c @@ -133,7 +133,7 @@ typeof(base) __base = (base); \ typeof(pmds) __pmds = (pmds); \ (__iova < __base) ? ERR_PTR(-EINVAL) : \ - __pmds + ((__iova - __base) >> AV8L_FAST_PAGE_SHIFT); \ + __pmds + ((__iova - ALIGN_DOWN(__base, SZ_2M)) >> AV8L_FAST_PAGE_SHIFT); \ }) static inline dma_addr_t av8l_dma_addr(void *addr)