diff options
Diffstat (limited to 'arch/arm/mm')
-rw-r--r-- | arch/arm/mm/alignment.c | 2 | ||||
-rw-r--r-- | arch/arm/mm/fault.c | 24 | ||||
-rw-r--r-- | arch/arm/mm/ioremap.c | 16 | ||||
-rw-r--r-- | arch/arm/mm/pageattr.c | 42 | ||||
-rw-r--r-- | arch/arm/mm/proc-v7m.S | 20 |
5 files changed, 80 insertions, 24 deletions
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index ea81e89e7740..adbb3817d0be 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -990,7 +990,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) * there is no work pending for this thread. */ raw_local_irq_disable(); - if (!(current_thread_info()->flags & _TIF_WORK_MASK)) + if (!(read_thread_flags() & _TIF_WORK_MASK)) set_cr(cr_no_alignment); } diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index bc8779d54a64..a062e07516dd 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -17,6 +17,7 @@ #include <linux/sched/debug.h> #include <linux/highmem.h> #include <linux/perf_event.h> +#include <linux/kfence.h> #include <asm/system_misc.h> #include <asm/system_info.h> @@ -99,6 +100,11 @@ void show_pte(const char *lvl, struct mm_struct *mm, unsigned long addr) { } #endif /* CONFIG_MMU */ +static inline bool is_write_fault(unsigned int fsr) +{ + return (fsr & FSR_WRITE) && !(fsr & FSR_CM); +} + static void die_kernel_fault(const char *msg, struct mm_struct *mm, unsigned long addr, unsigned int fsr, struct pt_regs *regs) @@ -111,7 +117,7 @@ static void die_kernel_fault(const char *msg, struct mm_struct *mm, show_pte(KERN_ALERT, mm, addr); die("Oops", regs, fsr); bust_spinlocks(0); - do_exit(SIGKILL); + make_task_dead(SIGKILL); } /* @@ -131,10 +137,14 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, /* * No handler, we'll have to terminate things with extreme prejudice. */ - if (addr < PAGE_SIZE) + if (addr < PAGE_SIZE) { msg = "NULL pointer dereference"; - else + } else { + if (kfence_handle_page_fault(addr, is_write_fault(fsr), regs)) + return; + msg = "paging request"; + } die_kernel_fault(msg, mm, addr, fsr, regs); } @@ -191,8 +201,8 @@ void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs) } #ifdef CONFIG_MMU -#define VM_FAULT_BADMAP 0x010000 -#define VM_FAULT_BADACCESS 0x020000 +#define VM_FAULT_BADMAP ((__force vm_fault_t)0x010000) +#define VM_FAULT_BADACCESS ((__force vm_fault_t)0x020000) static inline bool is_permission_fault(unsigned int fsr) { @@ -261,7 +271,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) if (user_mode(regs)) flags |= FAULT_FLAG_USER; - if ((fsr & FSR_WRITE) && !(fsr & FSR_CM)) { + if (is_write_fault(fsr)) { flags |= FAULT_FLAG_WRITE; vm_flags = VM_WRITE; } @@ -312,7 +322,7 @@ retry: return 0; } - if (!(fault & VM_FAULT_ERROR) && flags & FAULT_FLAG_ALLOW_RETRY) { + if (!(fault & VM_FAULT_ERROR)) { if (fault & VM_FAULT_RETRY) { flags |= FAULT_FLAG_TRIED; goto retry; diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c index 6e830b9418c9..197f8eb3a775 100644 --- a/arch/arm/mm/ioremap.c +++ b/arch/arm/mm/ioremap.c @@ -459,16 +459,20 @@ void pci_ioremap_set_mem_type(int mem_type) pci_ioremap_mem_type = mem_type; } -int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr) +int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr) { - BUG_ON(offset + SZ_64K - 1 > IO_SPACE_LIMIT); + unsigned long vaddr = (unsigned long)PCI_IOBASE + res->start; - return ioremap_page_range(PCI_IO_VIRT_BASE + offset, - PCI_IO_VIRT_BASE + offset + SZ_64K, - phys_addr, + if (!(res->flags & IORESOURCE_IO)) + return -EINVAL; + + if (res->end > IO_SPACE_LIMIT) + return -EINVAL; + + return ioremap_page_range(vaddr, vaddr + resource_size(res), phys_addr, __pgprot(get_mem_type(pci_ioremap_mem_type)->prot_pte)); } -EXPORT_SYMBOL_GPL(pci_ioremap_io); +EXPORT_SYMBOL(pci_remap_iospace); void __iomem *pci_remap_cfgspace(resource_size_t res_cookie, size_t size) { diff --git a/arch/arm/mm/pageattr.c b/arch/arm/mm/pageattr.c index 9790ae3a8c68..c3c34fe714b0 100644 --- a/arch/arm/mm/pageattr.c +++ b/arch/arm/mm/pageattr.c @@ -32,14 +32,31 @@ static bool in_range(unsigned long start, unsigned long size, size <= range_end - start; } +/* + * This function assumes that the range is mapped with PAGE_SIZE pages. + */ +static int __change_memory_common(unsigned long start, unsigned long size, + pgprot_t set_mask, pgprot_t clear_mask) +{ + struct page_change_data data; + int ret; + + data.set_mask = set_mask; + data.clear_mask = clear_mask; + + ret = apply_to_page_range(&init_mm, start, size, change_page_range, + &data); + + flush_tlb_kernel_range(start, start + size); + return ret; +} + static int change_memory_common(unsigned long addr, int numpages, pgprot_t set_mask, pgprot_t clear_mask) { unsigned long start = addr & PAGE_MASK; unsigned long end = PAGE_ALIGN(addr) + numpages * PAGE_SIZE; unsigned long size = end - start; - int ret; - struct page_change_data data; WARN_ON_ONCE(start != addr); @@ -50,14 +67,7 @@ static int change_memory_common(unsigned long addr, int numpages, !in_range(start, size, VMALLOC_START, VMALLOC_END)) return -EINVAL; - data.set_mask = set_mask; - data.clear_mask = clear_mask; - - ret = apply_to_page_range(&init_mm, start, size, change_page_range, - &data); - - flush_tlb_kernel_range(start, end); - return ret; + return __change_memory_common(start, size, set_mask, clear_mask); } int set_memory_ro(unsigned long addr, int numpages) @@ -87,3 +97,15 @@ int set_memory_x(unsigned long addr, int numpages) __pgprot(0), __pgprot(L_PTE_XN)); } + +int set_memory_valid(unsigned long addr, int numpages, int enable) +{ + if (enable) + return __change_memory_common(addr, PAGE_SIZE * numpages, + __pgprot(L_PTE_VALID), + __pgprot(0)); + else + return __change_memory_common(addr, PAGE_SIZE * numpages, + __pgprot(0), + __pgprot(L_PTE_VALID)); +} diff --git a/arch/arm/mm/proc-v7m.S b/arch/arm/mm/proc-v7m.S index 84459c1d31b8..335144d50134 100644 --- a/arch/arm/mm/proc-v7m.S +++ b/arch/arm/mm/proc-v7m.S @@ -194,6 +194,26 @@ ENDPROC(__v7m_setup) .endm /* + * Match ARM Cortex-M55 processor. + */ + .type __v7m_cm55_proc_info, #object +__v7m_cm55_proc_info: + .long 0x410fd220 /* ARM Cortex-M55 0xD22 */ + .long 0xff0ffff0 /* Mask off revision, patch release */ + __v7m_proc __v7m_cm55_proc_info, __v7m_cm7_setup, hwcaps = HWCAP_EDSP, cache_fns = v7m_cache_fns, proc_fns = cm7_processor_functions + .size __v7m_cm55_proc_info, . - __v7m_cm55_proc_info + + /* + * Match ARM Cortex-M33 processor. + */ + .type __v7m_cm33_proc_info, #object +__v7m_cm33_proc_info: + .long 0x410fd210 /* ARM Cortex-M33 0xD21 */ + .long 0xff0ffff0 /* Mask off revision, patch release */ + __v7m_proc __v7m_cm33_proc_info, __v7m_setup, hwcaps = HWCAP_EDSP + .size __v7m_cm33_proc_info, . - __v7m_cm33_proc_info + + /* * Match ARM Cortex-M7 processor. */ .type __v7m_cm7_proc_info, #object |