diff mbox

iommu/arm-smmu: change pud/pmd entry fill sequence

Message ID 1388750486-5060-1-git-send-email-yifan.zhangm@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Yifan Zhang Jan. 3, 2014, 12:01 p.m. UTC
From: Yifan Zhang <zhangyf@marvell.com>

Pgd/pud entry should be filled only once when their next level pud/pmd
created, the value should be pud/pmd start address, while in current
code, pgd/pud entry is filled every time when pud/pmd walk occurs,
the value is pud/pmd start address + iova pud/pmd index , this is
incorrect; Besides, when pud/pmd are created, we need to add pud/pmd
index, then pass to next level, while in currect code, if a new pud/pmd
created, their iova pud/pmd index is not taken into account, only
existing pud/pmd do. This patch change pud/pmd entry fill sequence,
fixes the 2 bugs.

Signed-off-by: Yifan Zhang <zhangyf@marvell.com>
---
 drivers/iommu/arm-smmu.c |   14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

Comments

Will Deacon Jan. 6, 2014, 2:28 p.m. UTC | #1
On Fri, Jan 03, 2014 at 12:01:26PM +0000, Yifan Zhang wrote:
> From: Yifan Zhang <zhangyf@marvell.com>
> 
> Pgd/pud entry should be filled only once when their next level pud/pmd
> created, the value should be pud/pmd start address, while in current
> code, pgd/pud entry is filled every time when pud/pmd walk occurs,
> the value is pud/pmd start address + iova pud/pmd index , this is
> incorrect; Besides, when pud/pmd are created, we need to add pud/pmd
> index, then pass to next level, while in currect code, if a new pud/pmd
> created, their iova pud/pmd index is not taken into account, only
> existing pud/pmd do. This patch change pud/pmd entry fill sequence,
> fixes the 2 bugs.
> 
> Signed-off-by: Yifan Zhang <zhangyf@marvell.com>

Thanks Yifan, this looks good to me. It's strange that I got the pte
handling correct, but screwed up the equivalent pmd and pud code!

Will
Will Deacon Jan. 14, 2014, 10:07 a.m. UTC | #2
On Tue, Jan 14, 2014 at 09:02:49AM +0000, Yifan Zhang wrote:
> It seems this patch is still not merged yet, any concerns about it ?

No, I was planning to send it at -rc1 with a CC stable.

Will
Yifan Zhang Jan. 14, 2014, 10:13 a.m. UTC | #3
Got it, Thanks :-)

On Tue, Jan 14, 2014 at 6:07 PM, Will Deacon <will.deacon@arm.com> wrote:
> On Tue, Jan 14, 2014 at 09:02:49AM +0000, Yifan Zhang wrote:
>> It seems this patch is still not merged yet, any concerns about it ?
>
> No, I was planning to send it at -rc1 with a CC stable.
>
> Will
diff mbox

Patch

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index e46a887..e3168a2 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1317,6 +1317,11 @@  static int arm_smmu_alloc_init_pmd(struct arm_smmu_device *smmu, pud_t *pud,
 		pmd = pmd_alloc_one(NULL, addr);
 		if (!pmd)
 			return -ENOMEM;
+
+		pud_populate(NULL, pud, pmd);
+		arm_smmu_flush_pgtable(smmu, pud, sizeof(*pud));
+
+		pmd += pmd_index(addr);
 	} else
 #endif
 		pmd = pmd_offset(pud, addr);
@@ -1325,8 +1330,6 @@  static int arm_smmu_alloc_init_pmd(struct arm_smmu_device *smmu, pud_t *pud,
 		next = pmd_addr_end(addr, end);
 		ret = arm_smmu_alloc_init_pte(smmu, pmd, addr, end, pfn,
 					      flags, stage);
-		pud_populate(NULL, pud, pmd);
-		arm_smmu_flush_pgtable(smmu, pud, sizeof(*pud));
 		phys += next - addr;
 	} while (pmd++, addr = next, addr < end);
 
@@ -1346,6 +1349,11 @@  static int arm_smmu_alloc_init_pud(struct arm_smmu_device *smmu, pgd_t *pgd,
 		pud = pud_alloc_one(NULL, addr);
 		if (!pud)
 			return -ENOMEM;
+
+		pgd_populate(NULL, pgd, pud);
+		arm_smmu_flush_pgtable(smmu, pgd, sizeof(*pgd));
+
+		pud += pud_index(addr);
 	} else
 #endif
 		pud = pud_offset(pgd, addr);
@@ -1354,8 +1362,6 @@  static int arm_smmu_alloc_init_pud(struct arm_smmu_device *smmu, pgd_t *pgd,
 		next = pud_addr_end(addr, end);
 		ret = arm_smmu_alloc_init_pmd(smmu, pud, addr, next, phys,
 					      flags, stage);
-		pgd_populate(NULL, pud, pgd);
-		arm_smmu_flush_pgtable(smmu, pgd, sizeof(*pgd));
 		phys += next - addr;
 	} while (pud++, addr = next, addr < end);