From: Greg Hackmann Date: Thu, 28 Aug 2014 21:00:10 +0000 (-0700) Subject: ANDROID: arm64: check for upper PAGE_SHIFT bits in pfn_valid() X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=04742a7b495e3c4344941bdf2e2c642d94149435;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git ANDROID: arm64: check for upper PAGE_SHIFT bits in pfn_valid() pfn_valid() returns a false positive when the lower (64 - PAGE_SHIFT) bits match a valid pfn but some of the upper bits are set. This caused a kernel panic in kpageflags_read() when a userspace utility parsed /proc/*/pagemap, neglected to discard the upper flag bits, and tried to lseek()+read() from the corresponding offset in /proc/kpageflags. A valid pfn will never have the upper PAGE_SHIFT bits set, so simply check for this before passing the pfn to memblock_is_memory(). Change-Id: Ief5d8cd4dd93cbecd545a634a8d5885865cb5970 Signed-off-by: Greg Hackmann --- diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 5960bef0170d..fc741fabb2c9 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -285,9 +285,11 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) #endif /* CONFIG_NUMA */ #ifdef CONFIG_HAVE_ARCH_PFN_VALID +#define PFN_MASK ((1UL << (64 - PAGE_SHIFT)) - 1) + int pfn_valid(unsigned long pfn) { - return memblock_is_map_memory(pfn << PAGE_SHIFT); + return (pfn & PFN_MASK) == pfn && memblock_is_map_memory(pfn << PAGE_SHIFT); } EXPORT_SYMBOL(pfn_valid); #endif