aboutsummaryrefslogtreecommitdiff
path: root/arch/s390/mm/fault.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-09 11:15:23 -0800
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-09 11:15:23 -0800
commit531021f2ca681faf58f926771f85bb5c76f13eba (patch)
treeb730cd35a1bde5f2ddd85e080a6269df96c50074 /arch/s390/mm/fault.c
parent451688ba0b488faf274e13dc591734b1e695642c (diff)
parent6252d702c5311ce916caf75ed82e5c8245171c92 (diff)
Merge branch 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6: [S390] dynamic page tables. [S390] Add four level page tables for CONFIG_64BIT=y. [S390] 1K/2K page table pages. [S390] Remove a.out header file. [S390] sclp_vt220: Fix vt220 initialization [S390] qdio: avoid hang when establishing qdio queues [S390] VMEM_MAX_PHYS overflow on 31 bit. [S390] zcrypt: Do not start ap poll thread per default [S390] Fix __ffs_word_loop/__ffz_word_loop inlnie assembly. [S390] Wire up new timerfd syscalls. [S390] Update default configuration.
Diffstat (limited to 'arch/s390/mm/fault.c')
-rw-r--r--arch/s390/mm/fault.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 2456b52ed06..ed13d429a48 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -32,6 +32,7 @@
#include <asm/system.h>
#include <asm/pgtable.h>
#include <asm/s390_ext.h>
+#include <asm/mmu_context.h>
#ifndef CONFIG_64BIT
#define __FAIL_ADDR_MASK 0x7ffff000
@@ -444,6 +445,45 @@ void __kprobes do_dat_exception(struct pt_regs *regs, unsigned long error_code)
do_exception(regs, error_code & 0xff, 0);
}
+#ifdef CONFIG_64BIT
+void __kprobes do_asce_exception(struct pt_regs *regs, unsigned long error_code)
+{
+ struct mm_struct *mm;
+ struct vm_area_struct *vma;
+ unsigned long address;
+ int space;
+
+ mm = current->mm;
+ address = S390_lowcore.trans_exc_code & __FAIL_ADDR_MASK;
+ space = check_space(current);
+
+ if (unlikely(space == 0 || in_atomic() || !mm))
+ goto no_context;
+
+ local_irq_enable();
+
+ down_read(&mm->mmap_sem);
+ vma = find_vma(mm, address);
+ up_read(&mm->mmap_sem);
+
+ if (vma) {
+ update_mm(mm, current);
+ return;
+ }
+
+ /* User mode accesses just cause a SIGSEGV */
+ if (regs->psw.mask & PSW_MASK_PSTATE) {
+ current->thread.prot_addr = address;
+ current->thread.trap_no = error_code;
+ do_sigsegv(regs, error_code, SEGV_MAPERR, address);
+ return;
+ }
+
+no_context:
+ do_no_context(regs, error_code, address);
+}
+#endif
+
#ifdef CONFIG_PFAULT
/*
* 'pfault' pseudo page faults routines.