diff options
author | Anshuman Khandual <[email protected]> | 2019-07-16 16:27:30 -0700 |
---|---|---|
committer | Linus Torvalds <[email protected]> | 2019-07-16 19:23:22 -0700 |
commit | 6b95ab4218bfa59bc315105127ffe03aef3b5742 (patch) | |
tree | 5423404840a8be072840dfb1a4b109757003fb12 | |
parent | 5015a300a522c8fb542dc993140e4c360cf4cf5f (diff) |
mm/ioremap: check virtual address alignment while creating huge mappings
Virtual address alignment is essential in ensuring correct clearing for
all intermediate level pgtable entries and freeing associated pgtable
pages. An unaligned address can end up randomly freeing pgtable page
that potentially still contains valid mappings. Hence also check it's
alignment along with existing phys_addr check.
Signed-off-by: Anshuman Khandual <[email protected]>
Reviewed-by: Catalin Marinas <[email protected]>
Cc: Toshi Kani <[email protected]>
Cc: Will Deacon <[email protected]>
Cc: Chintan Pandya <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
-rw-r--r-- | lib/ioremap.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/lib/ioremap.c b/lib/ioremap.c index 063213685563..a95161d9c883 100644 --- a/lib/ioremap.c +++ b/lib/ioremap.c @@ -86,6 +86,9 @@ static int ioremap_try_huge_pmd(pmd_t *pmd, unsigned long addr, if ((end - addr) != PMD_SIZE) return 0; + if (!IS_ALIGNED(addr, PMD_SIZE)) + return 0; + if (!IS_ALIGNED(phys_addr, PMD_SIZE)) return 0; @@ -126,6 +129,9 @@ static int ioremap_try_huge_pud(pud_t *pud, unsigned long addr, if ((end - addr) != PUD_SIZE) return 0; + if (!IS_ALIGNED(addr, PUD_SIZE)) + return 0; + if (!IS_ALIGNED(phys_addr, PUD_SIZE)) return 0; @@ -166,6 +172,9 @@ static int ioremap_try_huge_p4d(p4d_t *p4d, unsigned long addr, if ((end - addr) != P4D_SIZE) return 0; + if (!IS_ALIGNED(addr, P4D_SIZE)) + return 0; + if (!IS_ALIGNED(phys_addr, P4D_SIZE)) return 0; |