On Mon, Jun 03, 2019 at 12:11:24PM +0530, Anshuman Khandual wrote: > diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c > index da02678..4bb65f3 100644 > --- a/arch/arm64/mm/fault.c > +++ b/arch/arm64/mm/fault.c > @@ -435,6 +435,14 @@ static bool is_el0_instruction_abort(unsigned int esr) > return ESR_ELx_EC(esr) == ESR_ELx_EC_IABT_LOW; > } > > +/* > + * This is applicable only for EL0 write aborts. > + */ > +static bool is_el0_write_abort(unsigned int esr) > +{ > + return (esr & ESR_ELx_WNR) && !(esr & ESR_ELx_CM); > +}
What makes this EL0 only? > + > static int __kprobes do_page_fault(unsigned long addr, unsigned int esr, > struct pt_regs *regs) > { > @@ -443,6 +451,9 @@ static int __kprobes do_page_fault(unsigned long addr, > unsigned int esr, > vm_fault_t fault, major = 0; > unsigned long vm_flags = VM_READ | VM_WRITE; > unsigned int mm_flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; > + bool is_user = user_mode(regs); > + bool is_el0_exec = is_el0_instruction_abort(esr); > + bool is_el0_write = is_el0_write_abort(esr); > > if (notify_page_fault(regs, esr)) > return 0; > @@ -454,12 +465,12 @@ static int __kprobes do_page_fault(unsigned long addr, > unsigned int esr, > if (faulthandler_disabled() || !mm) > goto no_context; > > - if (user_mode(regs)) > + if (is_user) > mm_flags |= FAULT_FLAG_USER; > > - if (is_el0_instruction_abort(esr)) { > + if (is_el0_exec) { > vm_flags = VM_EXEC; > - } else if ((esr & ESR_ELx_WNR) && !(esr & ESR_ELx_CM)) { > + } else if (is_el0_write) { > vm_flags = VM_WRITE; > mm_flags |= FAULT_FLAG_WRITE; > } This can be triggered by an EL1 write to a user mapping, so is_el0_write is misleading. -- Catalin