arm64: Fix for the arm64 kern_addr_valid() function
authorDave Anderson <anderson@redhat.com>
Tue, 15 Apr 2014 17:53:24 +0000 (18:53 +0100)
committerMark Brown <broonie@linaro.org>
Wed, 23 Jul 2014 23:51:40 +0000 (00:51 +0100)
Fix for the arm64 kern_addr_valid() function to recognize
virtual addresses in the kernel logical memory map.  The
function fails as written because it does not check whether
the addresses in that region are mapped at the pmd level to
2MB or 512MB pages, continues the page table walk to the
pte level, and issues a garbage value to pfn_valid().

Tested on 4K-page and 64K-page kernels.

Signed-off-by: Dave Anderson <anderson@redhat.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
(cherry picked from commit da6e4cb67c6dd1f72257c0a4a97c26dc4e80d3a7)
Signed-off-by: Mark Brown <broonie@linaro.org>
arch/arm64/include/asm/pgtable.h
arch/arm64/mm/mmu.c

index 56336f19b60da46702e8b9de1082c69e6a71f1c8..d786b8940bbecaf271e88a3ae069b033c2daafc1 100644 (file)
@@ -86,14 +86,12 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
 #define PAGE_COPY_EXEC         __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
 #define PAGE_READONLY          __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
 #define PAGE_READONLY_EXEC     __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
-#define PAGE_EXECONLY          __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_PXN)
 
 #define __P000  PAGE_NONE
 #define __P001  PAGE_READONLY
 #define __P010  PAGE_COPY
 #define __P011  PAGE_COPY
 #define __P100  PAGE_READONLY_EXEC
-#define __P100  PAGE_EXECONLY
 #define __P101  PAGE_READONLY_EXEC
 #define __P110  PAGE_COPY_EXEC
 #define __P111  PAGE_COPY_EXEC
@@ -103,7 +101,6 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
 #define __S010  PAGE_SHARED
 #define __S011  PAGE_SHARED
 #define __S100  PAGE_READONLY_EXEC
-#define __S100  PAGE_EXECONLY
 #define __S101  PAGE_READONLY_EXEC
 #define __S110  PAGE_SHARED_EXEC
 #define __S111  PAGE_SHARED_EXEC
index 37d02a863c0e7f81fa54ad41e6820a55cc49aa81..639dca61ad7a31fb770de6fc2f295b797909fe5a 100644 (file)
@@ -371,6 +371,9 @@ int kern_addr_valid(unsigned long addr)
        if (pmd_none(*pmd))
                return 0;
 
+       if (pmd_sect(*pmd))
+               return pfn_valid(pmd_pfn(*pmd));
+
        pte = pte_offset_kernel(pmd, addr);
        if (pte_none(*pte))
                return 0;