Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arch, mm: make kernel_page_present() always available

For architectures that enable ARCH_HAS_SET_MEMORY having the ability to
verify that a page is mapped in the kernel direct map can be useful
regardless of hibernation.

Add RISC-V implementation of kernel_page_present(), update its forward
declarations and stubs to be a part of set_memory API and remove ugly
ifdefery in inlcude/linux/mm.h around current declarations of
kernel_page_present().

Link: https://lkml.kernel.org/r/20201109192128.960-5-rppt@kernel.org
Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: David Rientjes <rientjes@google.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: "Edgecombe, Rick P" <rick.p.edgecombe@intel.com>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Len Brown <len.brown@intel.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Paul Walmsley <paul.walmsley@sifive.com>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Will Deacon <will@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Mike Rapoport and committed by
Linus Torvalds
32a0de88 5d6ad668

+39 -13
+1
arch/arm64/include/asm/cacheflush.h
··· 140 140 141 141 int set_direct_map_invalid_noflush(struct page *page); 142 142 int set_direct_map_default_noflush(struct page *page); 143 + bool kernel_page_present(struct page *page); 143 144 144 145 #include <asm-generic/cacheflush.h> 145 146
+1 -3
arch/arm64/mm/pageattr.c
··· 186 186 187 187 set_memory_valid((unsigned long)page_address(page), numpages, enable); 188 188 } 189 + #endif /* CONFIG_DEBUG_PAGEALLOC */ 189 190 190 - #ifdef CONFIG_HIBERNATION 191 191 /* 192 192 * This function is used to determine if a linear map page has been marked as 193 193 * not-valid. Walk the page table and check the PTE_VALID bit. This is based ··· 234 234 ptep = pte_offset_kernel(pmdp, addr); 235 235 return pte_valid(READ_ONCE(*ptep)); 236 236 } 237 - #endif /* CONFIG_HIBERNATION */ 238 - #endif /* CONFIG_DEBUG_PAGEALLOC */
+1
arch/riscv/include/asm/set_memory.h
··· 24 24 25 25 int set_direct_map_invalid_noflush(struct page *page); 26 26 int set_direct_map_default_noflush(struct page *page); 27 + bool kernel_page_present(struct page *page); 27 28 28 29 #endif /* __ASSEMBLY__ */ 29 30
+29
arch/riscv/mm/pageattr.c
··· 198 198 __pgprot(0), __pgprot(_PAGE_PRESENT)); 199 199 } 200 200 #endif 201 + 202 + bool kernel_page_present(struct page *page) 203 + { 204 + unsigned long addr = (unsigned long)page_address(page); 205 + pgd_t *pgd; 206 + pud_t *pud; 207 + p4d_t *p4d; 208 + pmd_t *pmd; 209 + pte_t *pte; 210 + 211 + pgd = pgd_offset_k(addr); 212 + if (!pgd_present(*pgd)) 213 + return false; 214 + 215 + p4d = p4d_offset(pgd, addr); 216 + if (!p4d_present(*p4d)) 217 + return false; 218 + 219 + pud = pud_offset(p4d, addr); 220 + if (!pud_present(*pud)) 221 + return false; 222 + 223 + pmd = pmd_offset(pud, addr); 224 + if (!pmd_present(*pmd)) 225 + return false; 226 + 227 + pte = pte_offset_kernel(pmd, addr); 228 + return pte_present(*pte); 229 + }
+1
arch/x86/include/asm/set_memory.h
··· 82 82 83 83 int set_direct_map_invalid_noflush(struct page *page); 84 84 int set_direct_map_default_noflush(struct page *page); 85 + bool kernel_page_present(struct page *page); 85 86 86 87 extern int kernel_set_to_readonly; 87 88
+1 -3
arch/x86/mm/pat/set_memory.c
··· 2226 2226 2227 2227 arch_flush_lazy_mmu_mode(); 2228 2228 } 2229 + #endif /* CONFIG_DEBUG_PAGEALLOC */ 2229 2230 2230 - #ifdef CONFIG_HIBERNATION 2231 2231 bool kernel_page_present(struct page *page) 2232 2232 { 2233 2233 unsigned int level; ··· 2239 2239 pte = lookup_address((unsigned long)page_address(page), &level); 2240 2240 return (pte_val(*pte) & _PAGE_PRESENT); 2241 2241 } 2242 - #endif /* CONFIG_HIBERNATION */ 2243 - #endif /* CONFIG_DEBUG_PAGEALLOC */ 2244 2242 2245 2243 int __init kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, unsigned long address, 2246 2244 unsigned numpages, unsigned long page_flags)
-7
include/linux/mm.h
··· 2949 2949 if (debug_pagealloc_enabled_static()) 2950 2950 __kernel_map_pages(page, numpages, 0); 2951 2951 } 2952 - 2953 - #ifdef CONFIG_HIBERNATION 2954 - extern bool kernel_page_present(struct page *page); 2955 - #endif /* CONFIG_HIBERNATION */ 2956 2952 #else /* CONFIG_DEBUG_PAGEALLOC */ 2957 2953 static inline void debug_pagealloc_map_pages(struct page *page, int numpages) {} 2958 2954 static inline void debug_pagealloc_unmap_pages(struct page *page, int numpages) {} 2959 - #ifdef CONFIG_HIBERNATION 2960 - static inline bool kernel_page_present(struct page *page) { return true; } 2961 - #endif /* CONFIG_HIBERNATION */ 2962 2955 #endif /* CONFIG_DEBUG_PAGEALLOC */ 2963 2956 2964 2957 #ifdef __HAVE_ARCH_GATE_AREA
+5
include/linux/set_memory.h
··· 23 23 { 24 24 return 0; 25 25 } 26 + 27 + static inline bool kernel_page_present(struct page *page) 28 + { 29 + return true; 30 + } 26 31 #endif 27 32 28 33 #ifndef set_mce_nospec