summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2009-12-07 12:51:46 +0100
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2009-12-07 12:51:34 +0100
commit1ab947de293f43812276b60cf9fa21127e7a5bb2 (patch)
tree55d9882b6f137beba39030880a6b24c695e4ebb6 /arch
parent50d7280d430484a890ddcadc7f738b5b6dd28bf1 (diff)
[S390] fault handler access flags check.
Simplify the check of the vma->flags in do_exception for the different fault types. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/s390/mm/fault.c30
1 files changed, 13 insertions, 17 deletions
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 0dcfcfb5b5be..5a9e9a77dc16 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -286,7 +286,7 @@ static noinline void do_fault_error(struct pt_regs *regs, long int_code,
* 11 Page translation -> 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)
{
struct task_struct *tsk;
@@ -337,19 +337,8 @@ static inline int do_exception(struct pt_regs *regs, int write,
* we can handle it..
*/
fault = VM_FAULT_BADACCESS;
-#ifdef CONFIG_S390_EXEC_PROTECT
- if (unlikely((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_SECONDARY &&
- (trans_exc_code & 3) == 0 && !(vma->vm_flags & VM_EXEC)))
+ if (unlikely(!(vma->vm_flags & access)))
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;
- }
if (is_vm_hugetlb_page(vma))
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
* 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))
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);
return;
}
- fault = do_exception(regs, 1, trans_exc_code);
+ fault = do_exception(regs, VM_WRITE, trans_exc_code);
if (unlikely(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)
{
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))
do_fault_error(regs, int_code & 255, trans_exc_code, fault);
}