aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/mm/fault.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64/mm/fault.c')
-rw-r--r--arch/arm64/mm/fault.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index c8beaa0da7df..05d2bd776c69 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -153,6 +153,11 @@ int ptep_set_access_flags(struct vm_area_struct *vma,
153} 153}
154#endif 154#endif
155 155
156static bool is_el1_instruction_abort(unsigned int esr)
157{
158 return ESR_ELx_EC(esr) == ESR_ELx_EC_IABT_CUR;
159}
160
156/* 161/*
157 * The kernel tried to access some page that wasn't present. 162 * The kernel tried to access some page that wasn't present.
158 */ 163 */
@@ -161,8 +166,9 @@ static void __do_kernel_fault(struct mm_struct *mm, unsigned long addr,
161{ 166{
162 /* 167 /*
163 * Are we prepared to handle this kernel fault? 168 * Are we prepared to handle this kernel fault?
169 * We are almost certainly not prepared to handle instruction faults.
164 */ 170 */
165 if (fixup_exception(regs)) 171 if (!is_el1_instruction_abort(esr) && fixup_exception(regs))
166 return; 172 return;
167 173
168 /* 174 /*
@@ -267,7 +273,8 @@ static inline bool is_permission_fault(unsigned int esr)
267 unsigned int ec = ESR_ELx_EC(esr); 273 unsigned int ec = ESR_ELx_EC(esr);
268 unsigned int fsc_type = esr & ESR_ELx_FSC_TYPE; 274 unsigned int fsc_type = esr & ESR_ELx_FSC_TYPE;
269 275
270 return (ec == ESR_ELx_EC_DABT_CUR && fsc_type == ESR_ELx_FSC_PERM); 276 return (ec == ESR_ELx_EC_DABT_CUR && fsc_type == ESR_ELx_FSC_PERM) ||
277 (ec == ESR_ELx_EC_IABT_CUR && fsc_type == ESR_ELx_FSC_PERM);
271} 278}
272 279
273static bool is_el0_instruction_abort(unsigned int esr) 280static bool is_el0_instruction_abort(unsigned int esr)
@@ -312,6 +319,9 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
312 if (regs->orig_addr_limit == KERNEL_DS) 319 if (regs->orig_addr_limit == KERNEL_DS)
313 die("Accessing user space memory with fs=KERNEL_DS", regs, esr); 320 die("Accessing user space memory with fs=KERNEL_DS", regs, esr);
314 321
322 if (is_el1_instruction_abort(esr))
323 die("Attempting to execute userspace memory", regs, esr);
324
315 if (!search_exception_tables(regs->pc)) 325 if (!search_exception_tables(regs->pc))
316 die("Accessing user space memory outside uaccess.h routines", regs, esr); 326 die("Accessing user space memory outside uaccess.h routines", regs, esr);
317 } 327 }