Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ab947de authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Martin Schwidefsky
Browse files

[S390] fault handler access flags check.



Simplify the check of the vma->flags in do_exception for the
different fault types.

Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 50d7280d
Loading
Loading
Loading
Loading
+13 −17
Original line number Original line Diff line number Diff line
@@ -286,7 +286,7 @@ static noinline void do_fault_error(struct pt_regs *regs, long int_code,
 *   11       Page translation     ->  Not present       (nullification)
 *   11       Page translation     ->  Not present       (nullification)
 *   3b       Region third trans.  ->  Not present       (nullification)
 *   3b       Region third trans.  ->  Not present       (nullification)
 */
 */
static inline int do_exception(struct pt_regs *regs, int write,
static inline int do_exception(struct pt_regs *regs, int access,
			       unsigned long trans_exc_code)
			       unsigned long trans_exc_code)
{
{
	struct task_struct *tsk;
	struct task_struct *tsk;
@@ -337,19 +337,8 @@ static inline int do_exception(struct pt_regs *regs, int write,
	 * we can handle it..
	 * we can handle it..
	 */
	 */
	fault = VM_FAULT_BADACCESS;
	fault = VM_FAULT_BADACCESS;
#ifdef CONFIG_S390_EXEC_PROTECT
	if (unlikely(!(vma->vm_flags & access)))
	if (unlikely((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_SECONDARY &&
		     (trans_exc_code & 3) == 0 && !(vma->vm_flags & VM_EXEC)))
		goto out_up;
#endif
	if (!write) {
		/* page not present, check vm flags */
		if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
			goto out_up;
	} else {
		if (!(vma->vm_flags & VM_WRITE))
		goto out_up;
		goto out_up;
	}


	if (is_vm_hugetlb_page(vma))
	if (is_vm_hugetlb_page(vma))
		address &= HPAGE_MASK;
		address &= HPAGE_MASK;
@@ -358,7 +347,8 @@ static inline int do_exception(struct pt_regs *regs, int write,
	 * make sure we exit gracefully rather than endlessly redo
	 * make sure we exit gracefully rather than endlessly redo
	 * the fault.
	 * the fault.
	 */
	 */
	fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0);
	fault = handle_mm_fault(mm, vma, address,
				(access == VM_WRITE) ? FAULT_FLAG_WRITE : 0);
	if (unlikely(fault & VM_FAULT_ERROR))
	if (unlikely(fault & VM_FAULT_ERROR))
		goto out_up;
		goto out_up;


@@ -399,7 +389,7 @@ void __kprobes do_protection_exception(struct pt_regs *regs, long int_code)
		do_low_address(regs, int_code, trans_exc_code);
		do_low_address(regs, int_code, trans_exc_code);
		return;
		return;
	}
	}
	fault = do_exception(regs, 1, trans_exc_code);
	fault = do_exception(regs, VM_WRITE, trans_exc_code);
	if (unlikely(fault))
	if (unlikely(fault))
		do_fault_error(regs, 4, trans_exc_code, fault);
		do_fault_error(regs, 4, trans_exc_code, fault);
}
}
@@ -407,9 +397,15 @@ void __kprobes do_protection_exception(struct pt_regs *regs, long int_code)
void __kprobes do_dat_exception(struct pt_regs *regs, long int_code)
void __kprobes do_dat_exception(struct pt_regs *regs, long int_code)
{
{
	unsigned long trans_exc_code = S390_lowcore.trans_exc_code;
	unsigned long trans_exc_code = S390_lowcore.trans_exc_code;
	int fault;
	int access, fault;


	fault = do_exception(regs, 0, trans_exc_code);
	access = VM_READ | VM_EXEC | VM_WRITE;
#ifdef CONFIG_S390_EXEC_PROTECT
	if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_SECONDARY &&
	    (trans_exc_code & 3) == 0)
		access = VM_EXEC;
#endif
	fault = do_exception(regs, access, trans_exc_code);
	if (unlikely(fault))
	if (unlikely(fault))
		do_fault_error(regs, int_code & 255, trans_exc_code, fault);
		do_fault_error(regs, int_code & 255, trans_exc_code, fault);
}
}