summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAnshuman Khandual <anshuman.khandual@arm.com>2019-07-16 16:27:30 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-08-06 19:08:11 +0200
commit9c283c282397226a3ee208f5b8d2370229d4de41 (patch)
tree13a8f92f0b65ac7e8d3885342d233f2fb41517d8 /lib
parent4c546fa3e8163072996fb24d39a6489a1d5ecb8e (diff)
downloadlinux-stable-9c283c282397226a3ee208f5b8d2370229d4de41.tar.gz
linux-stable-9c283c282397226a3ee208f5b8d2370229d4de41.tar.bz2
linux-stable-9c283c282397226a3ee208f5b8d2370229d4de41.zip
mm/ioremap: check virtual address alignment while creating huge mappings
[ Upstream commit 6b95ab4218bfa59bc315105127ffe03aef3b5742 ] 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 <anshuman.khandual@arm.com> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Cc: Toshi Kani <toshi.kani@hpe.com> Cc: Will Deacon <will.deacon@arm.com> Cc: Chintan Pandya <cpandya@codeaurora.org> Cc: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/ioremap.c9
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;