Unverified Commit afb8c6fe authored by Pekka Enberg's avatar Pekka Enberg Committed by Palmer Dabbelt
Browse files

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: default avatarPekka Enberg <penberg@kernel.org>
Signed-off-by: default avatarPalmer Dabbelt <palmerdabbelt@google.com>
parent 67474301
Loading
Loading
Loading
Loading
+27 −21
Original line number Diff line number Diff line
@@ -156,6 +156,30 @@ static void inline vmalloc_fault(struct pt_regs *regs, int code, unsigned long a
	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
 * problem, and then passes it off to one of the appropriate routines.
@@ -236,28 +260,10 @@ retry:
good_area:
	code = SEGV_ACCERR;

	switch (cause) {
	case EXC_INST_PAGE_FAULT:
		if (!(vma->vm_flags & VM_EXEC)) {
			bad_area(regs, mm, code, addr);
			return;
		}
		break;
	case EXC_LOAD_PAGE_FAULT:
		if (!(vma->vm_flags & VM_READ)) {
	if (unlikely(access_error(cause, vma))) {
		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);
	}

	/*
	 * If for any reason at all we could not handle the fault,