riscv/mm/fault: Move access error check to function

Move the access error check into a access_error() function to simplify
the control flow in do_page_fault().

Signed-off-by: Pekka Enberg <penberg@kernel.org>
Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>
This commit is contained in:
Pekka Enberg 2020-08-25 19:41:17 +03:00 committed by Palmer Dabbelt
parent 6747430197
commit afb8c6fee8
No known key found for this signature in database
GPG key ID: 2E1319F35FBB1889

View file

@ -156,6 +156,30 @@ static void inline vmalloc_fault(struct pt_regs *regs, int code, unsigned long a
local_flush_tlb_page(addr); local_flush_tlb_page(addr);
} }
static inline bool access_error(unsigned long cause, struct vm_area_struct *vma)
{
switch (cause) {
case EXC_INST_PAGE_FAULT:
if (!(vma->vm_flags & VM_EXEC)) {
return true;
}
break;
case EXC_LOAD_PAGE_FAULT:
if (!(vma->vm_flags & VM_READ)) {
return true;
}
break;
case EXC_STORE_PAGE_FAULT:
if (!(vma->vm_flags & VM_WRITE)) {
return true;
}
break;
default:
panic("%s: unhandled cause %lu", __func__, cause);
}
return false;
}
/* /*
* This routine handles page faults. It determines the address and the * This routine handles page faults. It determines the address and the
* problem, and then passes it off to one of the appropriate routines. * problem, and then passes it off to one of the appropriate routines.
@ -236,27 +260,9 @@ asmlinkage void do_page_fault(struct pt_regs *regs)
good_area: good_area:
code = SEGV_ACCERR; code = SEGV_ACCERR;
switch (cause) { if (unlikely(access_error(cause, vma))) {
case EXC_INST_PAGE_FAULT: bad_area(regs, mm, code, addr);
if (!(vma->vm_flags & VM_EXEC)) { return;
bad_area(regs, mm, code, addr);
return;
}
break;
case EXC_LOAD_PAGE_FAULT:
if (!(vma->vm_flags & VM_READ)) {
bad_area(regs, mm, code, addr);
return;
}
break;
case EXC_STORE_PAGE_FAULT:
if (!(vma->vm_flags & VM_WRITE)) {
bad_area(regs, mm, code, addr);
return;
}
break;
default:
panic("%s: unhandled cause %lu", __func__, cause);
} }
/* /*