diff options
author | Juan Yescas <jyescas@google.com> | 2024-03-05 13:19:55 -0800 |
---|---|---|
committer | Juan Yescas <jyescas@google.com> | 2024-03-15 02:47:31 +0000 |
commit | 7a356a435fc98cf9ecc10818b45fc431a52f185f (patch) | |
tree | b6a40db276b349e4b7fb5f6f66b75c5a1961c742 | |
parent | 69e29ebd6eba10a865f064e201a526ce5e151ecb (diff) | |
download | gs-7a356a435fc98cf9ecc10818b45fc431a52f185f.tar.gz |
iommu: pcie: Set correct pgtable base for PAGE_SIZE != 4K
The value for the page table base register was calculated under the
assumption that the PAGE_SIZE macro is defined as 4kb. This breaks in
configurations where PAGE_SIZE is set to 16kb or 64kb. Let's define a
new local macro named PT_BASE_SHIFT to use for this calculation. This
value is determined by the programming interface of the hardware and is
unrelated to the page size that the operating system is using.
Bug: 326481268
Bug: 318888819
Bug: 308663811
Test: Build and flash kernel with 4kb and 16kb page sizes
Change-Id: I744536c1442d2f6bf0b52272048a1a12acb7bb74
Signed-off-by: Juan Yescas <jyescas@google.com>
-rw-r--r-- | drivers/iommu/exynos-pcie-iommu.c | 14 | ||||
-rw-r--r-- | drivers/iommu/exynos-pcie-iommu.h | 4 |
2 files changed, 8 insertions, 10 deletions
diff --git a/drivers/iommu/exynos-pcie-iommu.c b/drivers/iommu/exynos-pcie-iommu.c index 189307cd2..2f7126b00 100644 --- a/drivers/iommu/exynos-pcie-iommu.c +++ b/drivers/iommu/exynos-pcie-iommu.c @@ -99,9 +99,9 @@ static void __sysmmu_tlb_invalidate_all(void __iomem *sfrbase, int pcie_vid) } static void __sysmmu_set_ptbase(void __iomem *sfrbase, - phys_addr_t pfn_pgtable, int pcie_vid) + phys_addr_t pgtable, int pcie_vid) { - writel_relaxed(pfn_pgtable, sfrbase + REG_PT_BASE_PPN_VID(pcie_vid)); + writel_relaxed(pgtable >> PT_BASE_SHIFT, sfrbase + REG_PT_BASE_PPN_VID(pcie_vid)); __sysmmu_tlb_invalidate_all(sfrbase, pcie_vid); } @@ -157,7 +157,7 @@ static void __sysmmu_enable_nocount(struct sysmmu_drvdata *drvdata, int pcie_vid __sysmmu_init_config(drvdata, pcie_vid); __sysmmu_set_ptbase(drvdata->sfrbase, - drvdata->pgtable / PAGE_SIZE, pcie_vid); + drvdata->pgtable, pcie_vid); spin_lock(&drvdata->mmu_ctrl_lock); if (!is_sysmmu_active(drvdata)) { @@ -683,7 +683,7 @@ void print_pcie_sysmmu_tlb(int hsi_block_num) pgtable = __raw_readl(g_sysmmu_drvdata[hsi_block_num]->sfrbase + REG_PT_BASE_PPN_VID(pcie_vid)); - pgtable <<= PAGE_SHIFT; + pgtable <<= PT_BASE_SHIFT; pr_info("Page Table Base Address : 0x%pap\n", &pgtable); } EXPORT_SYMBOL(print_pcie_sysmmu_tlb); @@ -700,7 +700,7 @@ static int show_fault_information(struct sysmmu_drvdata *drvdata, int flags, int pmmu_id, stream_id; pgtable = __raw_readl(drvdata->sfrbase + REG_PT_BASE_PPN_VID(pcie_vid)); - pgtable <<= PAGE_SHIFT; + pgtable <<= PT_BASE_SHIFT; info = __raw_readl(drvdata->sfrbase + REG_FAULT_INFO0_VID(pcie_vid)); @@ -739,7 +739,7 @@ static int show_fault_information(struct sysmmu_drvdata *drvdata, int flags, if (fault_id == SYSMMU_FAULT_PTW_ACCESS) pr_crit("System MMU has failed to access page table\n"); - if (!pfn_valid(pgtable >> PAGE_SHIFT)) { + if (!pfn_valid(PFN_DOWN(pgtable))) { pr_crit("Page table base is not in a valid memory region\n"); } else { sysmmu_pte_t *ent; @@ -1240,7 +1240,7 @@ static inline int check_memory_validation(phys_addr_t paddr) { int ret; - ret = pfn_valid(paddr >> PAGE_SHIFT); + ret = pfn_valid(PFN_DOWN(paddr)); if (!ret) { pr_err("Requested address 0x%pap is NOT in DRAM region!!\n", &paddr); return -EINVAL; diff --git a/drivers/iommu/exynos-pcie-iommu.h b/drivers/iommu/exynos-pcie-iommu.h index 77bd6c4e8..dfb2b5b06 100644 --- a/drivers/iommu/exynos-pcie-iommu.h +++ b/drivers/iommu/exynos-pcie-iommu.h @@ -23,9 +23,7 @@ typedef u64 sysmmu_iova_t; typedef u32 sysmmu_pte_t; -#define IOVM_NUM_PAGES(vmsize) ((vmsize) / PAGE_SIZE) -#define IOVM_BITMAP_SIZE(vmsize) \ - ((IOVM_NUM_PAGES(vmsize) + BITS_PER_BYTE) / BITS_PER_BYTE) +#define PT_BASE_SHIFT 12 #define SECT_ORDER 20 #define LPAGE_ORDER 16 |