Pull x86 mm updates from Ingo Molnar: "The changes in here are: - text_poke() fixes and an extensive set of executability lockdowns, to (hopefully) eliminate the last residual circumstances under which we are using W|X mappings even temporarily on x86 kernels. This required a broad range of surgery in text patching facilities, module loading, trampoline handling and other bits. - tweak page fault messages to be more informative and more structured. - remove DISCONTIGMEM support on x86-32 and make SPARSEMEM the default. - reduce KASLR granularity on 5-level paging kernels from 512 GB to 1 GB. - misc other changes and updates" * 'x86-mm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (36 commits) x86/mm: Initialize PGD cache during mm initialization x86/alternatives: Add comment about module removal races x86/kprobes: Use vmalloc special flag x86/ftrace: Use vmalloc special flag bpf: Use vmalloc special flag modules: Use vmalloc special flag mm/vmalloc: Add flag for freeing of special permsissions mm/hibernation: Make hibernation handle unmapped pages x86/mm/cpa: Add set_direct_map_*() functions x86/alternatives: Remove the return value of text_poke_*() x86/jump-label: Remove support for custom text poker x86/modules: Avoid breaking W^X while loading modules x86/kprobes: Set instruction page as executable x86/ftrace: Set trampoline pages as executable x86/kgdb: Avoid redundant comparison of patched code x86/alternatives: Use temporary mm for text poking x86/alternatives: Initialize temporary mm for patching fork: Provide a function for copying init_mm uprobes: Initialize uprobes earlier x86/mm: Save debug registers when loading a temporary mm ...
Showing the changes to include/linux (6 of 40 files). Show all
Unified · Split
| @@ -20,6 +20,7 @@ · 19 unmodified lines | |||
| 20 | #include <linux/set_memory.h> | 20 | #include <linux/set_memory.h> |
| 21 | #include <linux/kallsyms.h> | 21 | #include <linux/kallsyms.h> |
| 22 | #include <linux/if_vlan.h> | 22 | #include <linux/if_vlan.h> |
| 23 | #include <linux/vmalloc.h> | ||
| 23 | 24 | ||
| 24 | #include <net/sch_generic.h> | 25 | #include <net/sch_generic.h> |
| 25 | 26 | ||
| @@ -503,7 +504,6 @@ struct bpf_prog { · 477 unmodified lines | |||
| 503 | u16 pages; /* Number of allocated pages */ | 504 | u16 pages; /* Number of allocated pages */ |
| 504 | u16 jited:1, /* Is our filter JIT'ed? */ | 505 | u16 jited:1, /* Is our filter JIT'ed? */ |
| 505 | jit_requested:1,/* archs need to JIT the prog */ | 506 | jit_requested:1,/* archs need to JIT the prog */ |
| 506 | undo_set_mem:1, /* Passed set_memory_ro() checkpoint */ | ||
| 507 | gpl_compatible:1, /* Is filter GPL compatible? */ | 507 | gpl_compatible:1, /* Is filter GPL compatible? */ |
| 508 | cb_access:1, /* Is control block accessed? */ | 508 | cb_access:1, /* Is control block accessed? */ |
| 509 | dst_needed:1, /* Do we need dst entry? */ | 509 | dst_needed:1, /* Do we need dst entry? */ |
| @@ -733,24 +733,15 @@ bpf_ctx_narrow_access_ok(u32 off, u32 size, u32 size_default) · 223 unmodified lines | |||
| 733 | 733 | ||
| 734 | static inline void bpf_prog_lock_ro(struct bpf_prog *fp) | 734 | static inline void bpf_prog_lock_ro(struct bpf_prog *fp) |
| 735 | { | 735 | { |
| 736 | fp->undo_set_mem = 1; | 736 | set_vm_flush_reset_perms(fp); |
| 737 | set_memory_ro((unsigned long)fp, fp->pages); | 737 | set_memory_ro((unsigned long)fp, fp->pages); |
| 738 | } | 738 | } |
| 739 | 739 | ||
| 740 | static inline void bpf_prog_unlock_ro(struct bpf_prog *fp) | ||
| 741 | { | ||
| 742 | if (fp->undo_set_mem) | ||
| 743 | set_memory_rw((unsigned long)fp, fp->pages); | ||
| 744 | } | ||
| 745 | |||
| 746 | static inline void bpf_jit_binary_lock_ro(struct bpf_binary_header *hdr) | 740 | static inline void bpf_jit_binary_lock_ro(struct bpf_binary_header *hdr) |
| 747 | { | 741 | { |
| 742 | set_vm_flush_reset_perms(hdr); | ||
| 748 | set_memory_ro((unsigned long)hdr, hdr->pages); | 743 | set_memory_ro((unsigned long)hdr, hdr->pages); |
| 749 | } | 744 | set_memory_x((unsigned long)hdr, hdr->pages); |
| 750 | |||
| 751 | static inline void bpf_jit_binary_unlock_ro(struct bpf_binary_header *hdr) | ||
| 752 | { | ||
| 753 | set_memory_rw((unsigned long)hdr, hdr->pages); | ||
| 754 | } | 745 | } |
| 755 | 746 | ||
| 756 | static inline struct bpf_binary_header * | 747 | static inline struct bpf_binary_header * |
| @@ -788,7 +779,6 @@ void __bpf_prog_free(struct bpf_prog *fp); · 31 unmodified lines | |||
| 788 | 779 | ||
| 789 | static inline void bpf_prog_unlock_free(struct bpf_prog *fp) | 780 | static inline void bpf_prog_unlock_free(struct bpf_prog *fp) |
| 790 | { | 781 | { |
| 791 | bpf_prog_unlock_ro(fp); | ||
| 792 | __bpf_prog_free(fp); | 782 | __bpf_prog_free(fp); |
| 793 | } | 783 | } |
| 794 | 784 | ||
| @@ -2610,37 +2610,31 @@ static inline void kernel_poison_pages(struct page *page, int numpages, · 2609 unmodified lines | |||
| 2610 | int enable) { } | 2610 | int enable) { } |
| 2611 | #endif | 2611 | #endif |
| 2612 | 2612 | ||
| 2613 | #ifdef CONFIG_DEBUG_PAGEALLOC | ||
| 2614 | extern bool _debug_pagealloc_enabled; | 2613 | extern bool _debug_pagealloc_enabled; |
| 2615 | extern void __kernel_map_pages(struct page *page, int numpages, int enable); | ||
| 2616 | 2614 | ||
| 2617 | static inline bool debug_pagealloc_enabled(void) | 2615 | static inline bool debug_pagealloc_enabled(void) |
| 2618 | { | 2616 | { |
| 2619 | return _debug_pagealloc_enabled; | 2617 | return IS_ENABLED(CONFIG_DEBUG_PAGEALLOC) && _debug_pagealloc_enabled; |
| 2620 | } | 2618 | } |
| 2621 | 2619 | ||
| 2620 | #if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_ARCH_HAS_SET_DIRECT_MAP) | ||
| 2621 | extern void __kernel_map_pages(struct page *page, int numpages, int enable); | ||
| 2622 | |||
| 2622 | static inline void | 2623 | static inline void |
| 2623 | kernel_map_pages(struct page *page, int numpages, int enable) | 2624 | kernel_map_pages(struct page *page, int numpages, int enable) |
| 2624 | { | 2625 | { |
| 2625 | if (!debug_pagealloc_enabled()) | ||
| 2626 | return; | ||
| 2627 | |||
| 2628 | __kernel_map_pages(page, numpages, enable); | 2626 | __kernel_map_pages(page, numpages, enable); |
| 2629 | } | 2627 | } |
| 2630 | #ifdef CONFIG_HIBERNATION | 2628 | #ifdef CONFIG_HIBERNATION |
| 2631 | extern bool kernel_page_present(struct page *page); | 2629 | extern bool kernel_page_present(struct page *page); |
| 2632 | #endif /* CONFIG_HIBERNATION */ | 2630 | #endif /* CONFIG_HIBERNATION */ |
| 2633 | #else /* CONFIG_DEBUG_PAGEALLOC */ | 2631 | #else /* CONFIG_DEBUG_PAGEALLOC || CONFIG_ARCH_HAS_SET_DIRECT_MAP */ |
| 2634 | static inline void | 2632 | static inline void |
| 2635 | kernel_map_pages(struct page *page, int numpages, int enable) {} | 2633 | kernel_map_pages(struct page *page, int numpages, int enable) {} |
| 2636 | #ifdef CONFIG_HIBERNATION | 2634 | #ifdef CONFIG_HIBERNATION |
| 2637 | static inline bool kernel_page_present(struct page *page) { return true; } | 2635 | static inline bool kernel_page_present(struct page *page) { return true; } |
| 2638 | #endif /* CONFIG_HIBERNATION */ | 2636 | #endif /* CONFIG_HIBERNATION */ |
| 2639 | static inline bool debug_pagealloc_enabled(void) | 2637 | #endif /* CONFIG_DEBUG_PAGEALLOC || CONFIG_ARCH_HAS_SET_DIRECT_MAP */ |
| 2640 | { | ||
| 2641 | return false; | ||
| 2642 | } | ||
| 2643 | #endif /* CONFIG_DEBUG_PAGEALLOC */ | ||
| 2644 | 2638 | ||
| 2645 | #ifdef __HAVE_ARCH_GATE_AREA | 2639 | #ifdef __HAVE_ARCH_GATE_AREA |
| 2646 | extern struct vm_area_struct *get_gate_vma(struct mm_struct *mm); | 2640 | extern struct vm_area_struct *get_gate_vma(struct mm_struct *mm); |
| @@ -76,6 +76,7 @@ extern void exit_itimers(struct signal_struct *); · 75 unmodified lines | |||
| 76 | extern long _do_fork(unsigned long, unsigned long, unsigned long, int __user *, int __user *, unsigned long); | 76 | extern long _do_fork(unsigned long, unsigned long, unsigned long, int __user *, int __user *, unsigned long); |
| 77 | extern long do_fork(unsigned long, unsigned long, unsigned long, int __user *, int __user *); | 77 | extern long do_fork(unsigned long, unsigned long, unsigned long, int __user *, int __user *); |
| 78 | struct task_struct *fork_idle(int); | 78 | struct task_struct *fork_idle(int); |
| 79 | struct mm_struct *copy_init_mm(void); | ||
| 79 | extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); | 80 | extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); |
| 80 | extern long kernel_wait4(pid_t, int __user *, int, struct rusage *); | 81 | extern long kernel_wait4(pid_t, int __user *, int, struct rusage *); |
| 81 | 82 | ||
| @@ -17,6 +17,17 @@ static inline int set_memory_x(unsigned long addr, int numpages) { return 0; } · 16 unmodified lines | |||
| 17 | static inline int set_memory_nx(unsigned long addr, int numpages) { return 0; } | 17 | static inline int set_memory_nx(unsigned long addr, int numpages) { return 0; } |
| 18 | #endif | 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 | #ifndef set_mce_nospec | 31 | #ifndef set_mce_nospec |
| 21 | static inline int set_mce_nospec(unsigned long pfn) | 32 | static inline int set_mce_nospec(unsigned long pfn) |
| 22 | { | 33 | { |
| @@ -115,6 +115,7 @@ struct uprobes_state { · 114 unmodified lines | |||
| 115 | struct xol_area *xol_area; | 115 | struct xol_area *xol_area; |
| 116 | }; | 116 | }; |
| 117 | 117 | ||
| 118 | extern void __init uprobes_init(void); | ||
| 118 | extern int set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); | 119 | extern int set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); |
| 119 | extern int set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); | 120 | extern int set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); |
| 120 | extern bool is_swbp_insn(uprobe_opcode_t *insn); | 121 | extern bool is_swbp_insn(uprobe_opcode_t *insn); |
| @@ -154,6 +155,10 @@ extern void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr, · 33 unmodified lines | |||
| 154 | struct uprobes_state { | 155 | struct uprobes_state { |
| 155 | }; | 156 | }; |
| 156 | 157 | ||
| 158 | static inline void uprobes_init(void) | ||
| 159 | { | ||
| 160 | } | ||
| 161 | |||
| 157 | #define uprobe_get_trap_addr(regs) instruction_pointer(regs) | 162 | #define uprobe_get_trap_addr(regs) instruction_pointer(regs) |
| 158 | 163 | ||
| 159 | static inline int | 164 | static inline int |
| @@ -21,6 +21,11 @@ struct notifier_block; /* in notifier.h */ · 20 unmodified lines | |||
| 21 | #define VM_UNINITIALIZED 0x00000020 /* vm_struct is not fully initialized */ | 21 | #define VM_UNINITIALIZED 0x00000020 /* vm_struct is not fully initialized */ |
| 22 | #define VM_NO_GUARD 0x00000040 /* don't add guard page */ | 22 | #define VM_NO_GUARD 0x00000040 /* don't add guard page */ |
| 23 | #define VM_KASAN 0x00000080 /* has allocated kasan shadow memory */ | 23 | #define VM_KASAN 0x00000080 /* has allocated kasan shadow memory */ |
| 24 | /* | ||
| 25 | * Memory with VM_FLUSH_RESET_PERMS cannot be freed in an interrupt or with | ||
| 26 | * vfree_atomic(). | ||
| 27 | */ | ||
| 28 | #define VM_FLUSH_RESET_PERMS 0x00000100 /* Reset direct map and flush TLB on unmap */ | ||
| 24 | /* bits [20..32] reserved for arch specific ioremap internals */ | 29 | /* bits [20..32] reserved for arch specific ioremap internals */ |
| 25 | 30 | ||
| 26 | /* | 31 | /* |
| @@ -142,6 +147,13 @@ extern int map_kernel_range_noflush(unsigned long start, unsigned long size, · 115 unmodified lines | |||
| 142 | pgprot_t prot, struct page **pages); | 147 | pgprot_t prot, struct page **pages); |
| 143 | extern void unmap_kernel_range_noflush(unsigned long addr, unsigned long size); | 148 | extern void unmap_kernel_range_noflush(unsigned long addr, unsigned long size); |
| 144 | extern void unmap_kernel_range(unsigned long addr, unsigned long size); | 149 | extern void unmap_kernel_range(unsigned long addr, unsigned long size); |
| 150 | static inline void set_vm_flush_reset_perms(void *addr) | ||
| 151 | { | ||
| 152 | struct vm_struct *vm = find_vm_area(addr); | ||
| 153 | |||
| 154 | if (vm) | ||
| 155 | vm->flags |= VM_FLUSH_RESET_PERMS; | ||
| 156 | } | ||
| 145 | #else | 157 | #else |
| 146 | static inline int | 158 | static inline int |
| 147 | map_kernel_range_noflush(unsigned long start, unsigned long size, | 159 | map_kernel_range_noflush(unsigned long start, unsigned long size, |
| @@ -157,6 +169,9 @@ static inline void · 9 unmodified lines | |||
| 157 | unmap_kernel_range(unsigned long addr, unsigned long size) | 169 | unmap_kernel_range(unsigned long addr, unsigned long size) |
| 158 | { | 170 | { |
| 159 | } | 171 | } |
| 172 | static inline void set_vm_flush_reset_perms(void *addr) | ||
| 173 | { | ||
| 174 | } | ||
| 160 | #endif | 175 | #endif |
| 161 | 176 | ||
| 162 | /* Allocate/destroy a 'vmalloc' VM area. */ | 177 | /* Allocate/destroy a 'vmalloc' VM area. */ |