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

x86/mm/cpa: Add set_direct_map_*() functions

Add two new functions set_direct_map_default_noflush() and
set_direct_map_invalid_noflush() for setting the direct map alias for the
page to its default valid permissions and to an invalid state that cannot
be cached in a TLB, respectively. These functions do not flush the TLB.

Note, __kernel_map_pages() does something similar but flushes the TLB and
doesn't reset the permission bits to default on all architectures.

Also add an ARCH config ARCH_HAS_SET_DIRECT_MAP for specifying whether
these have an actual implementation or a default empty one.

Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: <akpm@linux-foundation.org>
Cc: <ard.biesheuvel@linaro.org>
Cc: <deneen.t.dock@intel.com>
Cc: <kernel-hardening@lists.openwall.com>
Cc: <kristen@linux.intel.com>
Cc: <linux_dti@icloud.com>
Cc: <will.deacon@arm.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Nadav Amit <nadav.amit@gmail.com>
Cc: Rik van Riel <riel@surriel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: https://lkml.kernel.org/r/20190426001143.4983-15-namit@vmware.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Rick Edgecombe and committed by
Ingo Molnar
d253ca0c 0a203df5

+30 -3
+4
arch/Kconfig
··· 249 249 config ARCH_HAS_SET_MEMORY 250 250 bool 251 251 252 + # Select if arch has all set_direct_map_invalid/default() functions 253 + config ARCH_HAS_SET_DIRECT_MAP 254 + bool 255 + 252 256 # Select if arch init_task must go in the __init_task_data section 253 257 config ARCH_TASK_STRUCT_ON_STACK 254 258 bool
+1
arch/x86/Kconfig
··· 65 65 select ARCH_HAS_UACCESS_FLUSHCACHE if X86_64 66 66 select ARCH_HAS_UACCESS_MCSAFE if X86_64 && X86_MCE 67 67 select ARCH_HAS_SET_MEMORY 68 + select ARCH_HAS_SET_DIRECT_MAP 68 69 select ARCH_HAS_STRICT_KERNEL_RWX 69 70 select ARCH_HAS_STRICT_MODULE_RWX 70 71 select ARCH_HAS_SYNC_CORE_BEFORE_USERMODE
+3
arch/x86/include/asm/set_memory.h
··· 85 85 int set_pages_ro(struct page *page, int numpages); 86 86 int set_pages_rw(struct page *page, int numpages); 87 87 88 + int set_direct_map_invalid_noflush(struct page *page); 89 + int set_direct_map_default_noflush(struct page *page); 90 + 88 91 extern int kernel_set_to_readonly; 89 92 void set_kernel_text_rw(void); 90 93 void set_kernel_text_ro(void);
+11 -3
arch/x86/mm/pageattr.c
··· 2209 2209 return set_memory_rw(addr, numpages); 2210 2210 } 2211 2211 2212 - #ifdef CONFIG_DEBUG_PAGEALLOC 2213 - 2214 2212 static int __set_pages_p(struct page *page, int numpages) 2215 2213 { 2216 2214 unsigned long tempaddr = (unsigned long) page_address(page); ··· 2247 2249 return __change_page_attr_set_clr(&cpa, 0); 2248 2250 } 2249 2251 2252 + int set_direct_map_invalid_noflush(struct page *page) 2253 + { 2254 + return __set_pages_np(page, 1); 2255 + } 2256 + 2257 + int set_direct_map_default_noflush(struct page *page) 2258 + { 2259 + return __set_pages_p(page, 1); 2260 + } 2261 + 2262 + #ifdef CONFIG_DEBUG_PAGEALLOC 2250 2263 void __kernel_map_pages(struct page *page, int numpages, int enable) 2251 2264 { 2252 2265 if (PageHighMem(page)) ··· 2291 2282 } 2292 2283 2293 2284 #ifdef CONFIG_HIBERNATION 2294 - 2295 2285 bool kernel_page_present(struct page *page) 2296 2286 { 2297 2287 unsigned int level;
+11
include/linux/set_memory.h
··· 17 17 static inline int set_memory_nx(unsigned long addr, int numpages) { return 0; } 18 18 #endif 19 19 20 + #ifndef CONFIG_ARCH_HAS_SET_DIRECT_MAP 21 + static inline int set_direct_map_invalid_noflush(struct page *page) 22 + { 23 + return 0; 24 + } 25 + static inline int set_direct_map_default_noflush(struct page *page) 26 + { 27 + return 0; 28 + } 29 + #endif 30 + 20 31 #ifndef set_mce_nospec 21 32 static inline int set_mce_nospec(unsigned long pfn) 22 33 {