Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux

Pull s390 updates from Martin Schwidefsky:
 "This it the second batch of s390 patches for the 3.6 merge window.
  Included is enablement for two common code changes, killable page
  faults and sorted exception tables.  And the regular set of cleanup
  and bug fix patches."

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
  s390: make use of user_mode() macro where possible
  s390/mm: rename user_mode variable to addressing_mode
  s390/mm: fix fault handling for page table walk case
  s390/mm: make page faults killable
  s390: update defconfig
  s390/mm: downgrade page table after fork of a 31 bit process
  s390/ipl: Use diagnose 8 command separation
  s390/linker script: use RO_DATA_SECTION
  s390/exceptions: sort exception table at build time
  s390/debug: remove module_exit function / move EXPORT_SYMBOLs
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 296cd32..76de6b6 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -90,6 +90,7 @@
 	select HAVE_MEMBLOCK_NODE_MAP
 	select HAVE_CMPXCHG_LOCAL
 	select ARCH_DISCARD_MEMBLOCK
+	select BUILDTIME_EXTABLE_SORT
 	select ARCH_INLINE_SPIN_TRYLOCK
 	select ARCH_INLINE_SPIN_TRYLOCK_BH
 	select ARCH_INLINE_SPIN_LOCK
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index 37d2bf2..967923d 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -7,6 +7,9 @@
 CONFIG_TASK_XACCT=y
 CONFIG_TASK_IO_ACCOUNTING=y
 CONFIG_AUDIT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_RCU_FAST_NO_HZ=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_CGROUPS=y
@@ -35,8 +38,6 @@
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_IBM_PARTITION=y
 CONFIG_DEFAULT_DEADLINE=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
 CONFIG_PREEMPT=y
 CONFIG_MEMORY_HOTPLUG=y
 CONFIG_MEMORY_HOTREMOVE=y
diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h
index 5c63615..b749c57 100644
--- a/arch/s390/include/asm/mmu_context.h
+++ b/arch/s390/include/asm/mmu_context.h
@@ -11,7 +11,6 @@
 #include <asm/uaccess.h>
 #include <asm/tlbflush.h>
 #include <asm/ctl_reg.h>
-#include <asm-generic/mm_hooks.h>
 
 static inline int init_new_context(struct task_struct *tsk,
 				   struct mm_struct *mm)
@@ -58,7 +57,7 @@
 	pgd_t *pgd = mm->pgd;
 
 	S390_lowcore.user_asce = mm->context.asce_bits | __pa(pgd);
-	if (user_mode != HOME_SPACE_MODE) {
+	if (addressing_mode != HOME_SPACE_MODE) {
 		/* Load primary space page table origin. */
 		asm volatile(LCTL_OPCODE" 1,1,%0\n"
 			     : : "m" (S390_lowcore.user_asce) );
@@ -91,4 +90,17 @@
         switch_mm(prev, next, current);
 }
 
+static inline void arch_dup_mmap(struct mm_struct *oldmm,
+				 struct mm_struct *mm)
+{
+#ifdef CONFIG_64BIT
+	if (oldmm->context.asce_limit < mm->context.asce_limit)
+		crst_table_downgrade(mm, oldmm->context.asce_limit);
+#endif
+}
+
+static inline void arch_exit_mmap(struct mm_struct *mm)
+{
+}
+
 #endif /* __S390_MMU_CONTEXT_H */
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
index c40fa91..11e4e32 100644
--- a/arch/s390/include/asm/processor.h
+++ b/arch/s390/include/asm/processor.h
@@ -120,7 +120,9 @@
 	regs->psw.mask	= psw_user_bits | PSW_MASK_BA;			\
 	regs->psw.addr	= new_psw | PSW_ADDR_AMODE;			\
 	regs->gprs[15]	= new_stackp;					\
+	__tlb_flush_mm(current->mm);					\
 	crst_table_downgrade(current->mm, 1UL << 31);			\
+	update_mm(current->mm, current);				\
 } while (0)
 
 /* Forward declaration, a strange C thing */
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h
index 57e8053..e6859d1 100644
--- a/arch/s390/include/asm/setup.h
+++ b/arch/s390/include/asm/setup.h
@@ -60,7 +60,7 @@
 #define SECONDARY_SPACE_MODE	2
 #define HOME_SPACE_MODE		3
 
-extern unsigned int user_mode;
+extern unsigned int addressing_mode;
 
 /*
  * Machine features detected in head.S
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index 21be961..ba500d8 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -110,6 +110,7 @@
 	NULL,
 	NULL
 };
+EXPORT_SYMBOL(debug_raw_view);
 
 struct debug_view debug_hex_ascii_view = {
 	"hex_ascii",
@@ -119,6 +120,7 @@
 	NULL,
 	NULL
 };
+EXPORT_SYMBOL(debug_hex_ascii_view);
 
 static struct debug_view debug_level_view = {
 	"level",
@@ -155,6 +157,7 @@
 	NULL,
 	NULL
 };
+EXPORT_SYMBOL(debug_sprintf_view);
 
 /* used by dump analysis tools to determine version of debug feature */
 static unsigned int __used debug_feature_version = __DEBUG_FEATURE_VERSION;
@@ -730,6 +733,7 @@
 	return debug_register_mode(name, pages_per_area, nr_areas, buf_size,
 				   S_IRUSR | S_IWUSR, 0, 0);
 }
+EXPORT_SYMBOL(debug_register);
 
 /*
  * debug_unregister:
@@ -748,6 +752,7 @@
 out:
 	return;
 }
+EXPORT_SYMBOL(debug_unregister);
 
 /*
  * debug_set_size:
@@ -810,7 +815,7 @@
         }
 	spin_unlock_irqrestore(&id->lock,flags);
 }
-
+EXPORT_SYMBOL(debug_set_level);
 
 /*
  * proceed_active_entry:
@@ -930,7 +935,7 @@
 	if (debug_stoppable)
 		debug_active = 0;
 }
-
+EXPORT_SYMBOL(debug_stop_all);
 
 void debug_set_critical(void)
 {
@@ -963,6 +968,7 @@
 
 	return active;
 }
+EXPORT_SYMBOL(debug_event_common);
 
 /*
  * debug_exception_common:
@@ -990,6 +996,7 @@
 
 	return active;
 }
+EXPORT_SYMBOL(debug_exception_common);
 
 /*
  * counts arguments in format string for sprintf view
@@ -1043,6 +1050,7 @@
 
 	return active;
 }
+EXPORT_SYMBOL(debug_sprintf_event);
 
 /*
  * debug_sprintf_exception:
@@ -1081,25 +1089,7 @@
 
 	return active;
 }
-
-/*
- * debug_init:
- * - is called exactly once to initialize the debug feature
- */
-
-static int
-__init debug_init(void)
-{
-	int rc = 0;
-
-	s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table);
-	mutex_lock(&debug_mutex);
-	debug_debugfs_root_entry = debugfs_create_dir(DEBUG_DIR_ROOT,NULL);
-	initialized = 1;
-	mutex_unlock(&debug_mutex);
-
-	return rc;
-}
+EXPORT_SYMBOL(debug_sprintf_exception);
 
 /*
  * debug_register_view:
@@ -1147,6 +1137,7 @@
 out:
 	return rc;
 }
+EXPORT_SYMBOL(debug_register_view);
 
 /*
  * debug_unregister_view:
@@ -1176,6 +1167,7 @@
 out:
 	return rc;
 }
+EXPORT_SYMBOL(debug_unregister_view);
 
 static inline char *
 debug_get_user_string(const char __user *user_buf, size_t user_len)
@@ -1485,6 +1477,7 @@
 		      except_str, entry->id.fields.cpuid, (void *) caller);
 	return rc;
 }
+EXPORT_SYMBOL(debug_dflt_header_fn);
 
 /*
  * prints debug data sprintf-formated:
@@ -1533,33 +1526,16 @@
 }
 
 /*
- * clean up module
+ * debug_init:
+ * - is called exactly once to initialize the debug feature
  */
-static void __exit debug_exit(void)
+static int __init debug_init(void)
 {
-	debugfs_remove(debug_debugfs_root_entry);
-	unregister_sysctl_table(s390dbf_sysctl_header);
-	return;
+	s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table);
+	mutex_lock(&debug_mutex);
+	debug_debugfs_root_entry = debugfs_create_dir(DEBUG_DIR_ROOT, NULL);
+	initialized = 1;
+	mutex_unlock(&debug_mutex);
+	return 0;
 }
-
-/*
- * module definitions
- */
 postcore_initcall(debug_init);
-module_exit(debug_exit);
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(debug_register);
-EXPORT_SYMBOL(debug_unregister); 
-EXPORT_SYMBOL(debug_set_level);
-EXPORT_SYMBOL(debug_stop_all);
-EXPORT_SYMBOL(debug_register_view);
-EXPORT_SYMBOL(debug_unregister_view);
-EXPORT_SYMBOL(debug_event_common);
-EXPORT_SYMBOL(debug_exception_common);
-EXPORT_SYMBOL(debug_hex_ascii_view);
-EXPORT_SYMBOL(debug_raw_view);
-EXPORT_SYMBOL(debug_dflt_header_fn);
-EXPORT_SYMBOL(debug_sprintf_view);
-EXPORT_SYMBOL(debug_sprintf_exception);
-EXPORT_SYMBOL(debug_sprintf_event);
diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c
index 1f6b428..619c5d3 100644
--- a/arch/s390/kernel/dis.c
+++ b/arch/s390/kernel/dis.c
@@ -1531,7 +1531,7 @@
 
 void show_code(struct pt_regs *regs)
 {
-	char *mode = (regs->psw.mask & PSW_MASK_PSTATE) ? "User" : "Krnl";
+	char *mode = user_mode(regs) ? "User" : "Krnl";
 	unsigned char code[64];
 	char buffer[64], *ptr;
 	mm_segment_t old_fs;
@@ -1540,7 +1540,7 @@
 
 	/* Get a snapshot of the 64 bytes surrounding the fault address. */
 	old_fs = get_fs();
-	set_fs((regs->psw.mask & PSW_MASK_PSTATE) ? USER_DS : KERNEL_DS);
+	set_fs(user_mode(regs) ? USER_DS : KERNEL_DS);
 	for (start = 32; start && regs->psw.addr >= 34 - start; start -= 2) {
 		addr = regs->psw.addr - 34 + start;
 		if (__copy_from_user(code + start - 2,
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index bc95a8e..83c3271 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -455,7 +455,6 @@
 	init_kernel_storage_key();
 	lockdep_init();
 	lockdep_off();
-	sort_main_extable();
 	setup_lowcore_early();
 	setup_facility_list();
 	detect_machine_type();
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index e64d141..6ffcd320 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -1583,7 +1583,7 @@
 
 static void vmcmd_run(struct shutdown_trigger *trigger)
 {
-	char *cmd, *next_cmd;
+	char *cmd;
 
 	if (strcmp(trigger->name, ON_REIPL_STR) == 0)
 		cmd = vmcmd_on_reboot;
@@ -1600,15 +1600,7 @@
 
 	if (strlen(cmd) == 0)
 		return;
-	do {
-		next_cmd = strchr(cmd, '\n');
-		if (next_cmd) {
-			next_cmd[0] = 0;
-			next_cmd += 1;
-		}
-		__cpcmd(cmd, NULL, 0, NULL);
-		cmd = next_cmd;
-	} while (cmd != NULL);
+	__cpcmd(cmd, NULL, 0, NULL);
 }
 
 static int vmcmd_init(void)
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 743c0f3..f86c81e 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -302,8 +302,8 @@
 }
 early_param("vmalloc", parse_vmalloc);
 
-unsigned int user_mode = HOME_SPACE_MODE;
-EXPORT_SYMBOL_GPL(user_mode);
+unsigned int addressing_mode = HOME_SPACE_MODE;
+EXPORT_SYMBOL_GPL(addressing_mode);
 
 static int set_amode_primary(void)
 {
@@ -328,7 +328,7 @@
  */
 static int __init early_parse_switch_amode(char *p)
 {
-	user_mode = PRIMARY_SPACE_MODE;
+	addressing_mode = PRIMARY_SPACE_MODE;
 	return 0;
 }
 early_param("switch_amode", early_parse_switch_amode);
@@ -336,9 +336,9 @@
 static int __init early_parse_user_mode(char *p)
 {
 	if (p && strcmp(p, "primary") == 0)
-		user_mode = PRIMARY_SPACE_MODE;
+		addressing_mode = PRIMARY_SPACE_MODE;
 	else if (!p || strcmp(p, "home") == 0)
-		user_mode = HOME_SPACE_MODE;
+		addressing_mode = HOME_SPACE_MODE;
 	else
 		return 1;
 	return 0;
@@ -347,7 +347,7 @@
 
 static void setup_addressing_mode(void)
 {
-	if (user_mode == PRIMARY_SPACE_MODE) {
+	if (addressing_mode == PRIMARY_SPACE_MODE) {
 		if (set_amode_primary())
 			pr_info("Address spaces switched, "
 				"mvcos available\n");
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index af2421a..01775c0 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -185,7 +185,7 @@
 {
 	char *mode;
 
-	mode = (regs->psw.mask & PSW_MASK_PSTATE) ? "User" : "Krnl";
+	mode = user_mode(regs) ? "User" : "Krnl";
 	printk("%s PSW : %p %p",
 	       mode, (void *) regs->psw.mask,
 	       (void *) regs->psw.addr);
@@ -225,7 +225,7 @@
 	       (void *) current->thread.ksp);
 	show_registers(regs);
 	/* Show stack backtrace if pt_regs is from kernel mode */
-	if (!(regs->psw.mask & PSW_MASK_PSTATE))
+	if (!user_mode(regs))
 		show_trace(NULL, (unsigned long *) regs->gprs[15]);
 	show_last_breaking_event(regs);
 }
@@ -300,7 +300,7 @@
 		       regs->int_code, si_signo) == NOTIFY_STOP)
 		return;
 
-        if (regs->psw.mask & PSW_MASK_PSTATE) {
+	if (user_mode(regs)) {
 		info.si_signo = si_signo;
 		info.si_errno = 0;
 		info.si_code = si_code;
@@ -341,7 +341,7 @@
 
 static void default_trap_handler(struct pt_regs *regs)
 {
-        if (regs->psw.mask & PSW_MASK_PSTATE) {
+	if (user_mode(regs)) {
 		report_user_fault(regs, SIGSEGV);
 		do_exit(SIGSEGV);
 	} else
@@ -410,7 +410,7 @@
 
 	location = get_psw_address(regs);
 
-	if (regs->psw.mask & PSW_MASK_PSTATE) {
+	if (user_mode(regs)) {
 		if (get_user(*((__u16 *) opcode), (__u16 __user *) location))
 			return;
 		if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) {
@@ -478,7 +478,7 @@
 
 	location = (__u16 __user *) get_psw_address(regs);
 
-        if (regs->psw.mask & PSW_MASK_PSTATE) {
+	if (user_mode(regs)) {
 		get_user(*((__u16 *) opcode), location);
 		switch (opcode[0]) {
 		case 0x28: /* LDR Rx,Ry   */
@@ -531,7 +531,7 @@
 		asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc));
 
 #ifdef CONFIG_MATHEMU
-        else if (regs->psw.mask & PSW_MASK_PSTATE) {
+	else if (user_mode(regs)) {
         	__u8 opcode[6];
 		get_user(*((__u16 *) opcode), location);
 		switch (opcode[0]) {
@@ -598,7 +598,7 @@
 static void space_switch_exception(struct pt_regs *regs)
 {
 	/* Set user psw back to home space mode. */
-	if (regs->psw.mask & PSW_MASK_PSTATE)
+	if (user_mode(regs))
 		regs->psw.mask |= PSW_ASC_HOME;
 	/* Send SIGILL. */
 	do_trap(regs, SIGILL, ILL_PRVOPC, "space switch event");
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c
index ea5590f..9a19ca3 100644
--- a/arch/s390/kernel/vdso.c
+++ b/arch/s390/kernel/vdso.c
@@ -84,7 +84,8 @@
  */
 static void vdso_init_data(struct vdso_data *vd)
 {
-	vd->ectg_available = user_mode != HOME_SPACE_MODE && test_facility(31);
+	vd->ectg_available =
+		addressing_mode != HOME_SPACE_MODE && test_facility(31);
 }
 
 #ifdef CONFIG_64BIT
@@ -101,7 +102,7 @@
 
 	lowcore->vdso_per_cpu_data = __LC_PASTE;
 
-	if (user_mode == HOME_SPACE_MODE || !vdso_enabled)
+	if (addressing_mode == HOME_SPACE_MODE || !vdso_enabled)
 		return 0;
 
 	segment_table = __get_free_pages(GFP_KERNEL, SEGMENT_ORDER);
@@ -146,7 +147,7 @@
 	unsigned long segment_table, page_table, page_frame;
 	u32 *psal, *aste;
 
-	if (user_mode == HOME_SPACE_MODE || !vdso_enabled)
+	if (addressing_mode == HOME_SPACE_MODE || !vdso_enabled)
 		return;
 
 	psal = (u32 *)(addr_t) lowcore->paste[4];
@@ -164,7 +165,7 @@
 {
 	unsigned long cr5;
 
-	if (user_mode == HOME_SPACE_MODE || !vdso_enabled)
+	if (addressing_mode == HOME_SPACE_MODE || !vdso_enabled)
 		return;
 	cr5 = offsetof(struct _lowcore, paste);
 	__ctl_load(cr5, 5, 5);
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index 21109c6..de8fa9b 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -45,7 +45,7 @@
 
 	.dummy : { *(.dummy) } :data
 
-	RODATA
+	RO_DATA_SECTION(PAGE_SIZE)
 
 #ifdef CONFIG_SHARED_KERNEL
 	. = ALIGN(0x100000);	/* VM shared segments are 1MB aligned */
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 6a12d1b..6c013f5 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -49,6 +49,7 @@
 #define VM_FAULT_BADCONTEXT	0x010000
 #define VM_FAULT_BADMAP		0x020000
 #define VM_FAULT_BADACCESS	0x040000
+#define VM_FAULT_SIGNAL	0x080000
 
 static unsigned long store_indication;
 
@@ -110,7 +111,7 @@
 	if (trans_exc_code == 2)
 		/* Access via secondary space, set_fs setting decides */
 		return current->thread.mm_segment.ar4;
-	if (user_mode == HOME_SPACE_MODE)
+	if (addressing_mode == HOME_SPACE_MODE)
 		/* User space if the access has been done via home space. */
 		return trans_exc_code == 3;
 	/*
@@ -219,7 +220,7 @@
 	case VM_FAULT_BADACCESS:
 	case VM_FAULT_BADMAP:
 		/* Bad memory access. Check if it is kernel or user space. */
-		if (regs->psw.mask & PSW_MASK_PSTATE) {
+		if (user_mode(regs)) {
 			/* User mode accesses just cause a SIGSEGV */
 			si_code = (fault == VM_FAULT_BADMAP) ?
 				SEGV_MAPERR : SEGV_ACCERR;
@@ -229,15 +230,19 @@
 	case VM_FAULT_BADCONTEXT:
 		do_no_context(regs);
 		break;
+	case VM_FAULT_SIGNAL:
+		if (!user_mode(regs))
+			do_no_context(regs);
+		break;
 	default: /* fault & VM_FAULT_ERROR */
 		if (fault & VM_FAULT_OOM) {
-			if (!(regs->psw.mask & PSW_MASK_PSTATE))
+			if (!user_mode(regs))
 				do_no_context(regs);
 			else
 				pagefault_out_of_memory();
 		} else if (fault & VM_FAULT_SIGBUS) {
 			/* Kernel mode? Handle exceptions or die */
-			if (!(regs->psw.mask & PSW_MASK_PSTATE))
+			if (!user_mode(regs))
 				do_no_context(regs);
 			else
 				do_sigbus(regs);
@@ -286,7 +291,7 @@
 
 	address = trans_exc_code & __FAIL_ADDR_MASK;
 	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
-	flags = FAULT_FLAG_ALLOW_RETRY;
+	flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
 	if (access == VM_WRITE || (trans_exc_code & store_indication) == 0x400)
 		flags |= FAULT_FLAG_WRITE;
 	down_read(&mm->mmap_sem);
@@ -335,6 +340,11 @@
 	 * the fault.
 	 */
 	fault = handle_mm_fault(mm, vma, address, flags);
+	/* No reason to continue if interrupted by SIGKILL. */
+	if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) {
+		fault = VM_FAULT_SIGNAL;
+		goto out;
+	}
 	if (unlikely(fault & VM_FAULT_ERROR))
 		goto out_up;
 
@@ -426,7 +436,7 @@
 	}
 
 	/* User mode accesses just cause a SIGSEGV */
-	if (regs->psw.mask & PSW_MASK_PSTATE) {
+	if (user_mode(regs)) {
 		do_sigsegv(regs, SEGV_MAPERR);
 		return;
 	}
@@ -441,6 +451,7 @@
 	struct pt_regs regs;
 	int access, fault;
 
+	/* Emulate a uaccess fault from kernel mode. */
 	regs.psw.mask = psw_kernel_bits | PSW_MASK_DAT | PSW_MASK_MCHECK;
 	if (!irqs_disabled())
 		regs.psw.mask |= PSW_MASK_IO | PSW_MASK_EXT;
@@ -450,12 +461,12 @@
 	regs.int_parm_long = (uaddr & PAGE_MASK) | 2;
 	access = write ? VM_WRITE : VM_READ;
 	fault = do_exception(&regs, access);
-	if (unlikely(fault)) {
-		if (fault & VM_FAULT_OOM)
-			return -EFAULT;
-		else if (fault & VM_FAULT_SIGBUS)
-			do_sigbus(&regs);
-	}
+	/*
+	 * Since the fault happened in kernel mode while performing a uaccess
+	 * all we need to do now is emulating a fixup in case "fault" is not
+	 * zero.
+	 * For the calling uaccess functions this results always in -EFAULT.
+	 */
 	return fault ? -EFAULT : 0;
 }
 
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c
index 5733842..c59a5ef 100644
--- a/arch/s390/mm/mmap.c
+++ b/arch/s390/mm/mmap.c
@@ -103,9 +103,15 @@
 
 int s390_mmap_check(unsigned long addr, unsigned long len)
 {
+	int rc;
+
 	if (!is_compat_task() &&
-	    len >= TASK_SIZE && TASK_SIZE < (1UL << 53))
-		return crst_table_upgrade(current->mm, 1UL << 53);
+	    len >= TASK_SIZE && TASK_SIZE < (1UL << 53)) {
+		rc = crst_table_upgrade(current->mm, 1UL << 53);
+		if (rc)
+			return rc;
+		update_mm(current->mm, current);
+	}
 	return 0;
 }
 
@@ -125,6 +131,7 @@
 		rc = crst_table_upgrade(mm, 1UL << 53);
 		if (rc)
 			return (unsigned long) rc;
+		update_mm(mm, current);
 		area = arch_get_unmapped_area(filp, addr, len, pgoff, flags);
 	}
 	return area;
@@ -147,6 +154,7 @@
 		rc = crst_table_upgrade(mm, 1UL << 53);
 		if (rc)
 			return (unsigned long) rc;
+		update_mm(mm, current);
 		area = arch_get_unmapped_area_topdown(filp, addr, len,
 						      pgoff, flags);
 	}
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index 1cab221..18df31d 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -85,7 +85,6 @@
 		crst_table_free(mm, table);
 	if (mm->context.asce_limit < limit)
 		goto repeat;
-	update_mm(mm, current);
 	return 0;
 }
 
@@ -93,9 +92,6 @@
 {
 	pgd_t *pgd;
 
-	if (mm->context.asce_limit <= limit)
-		return;
-	__tlb_flush_mm(mm);
 	while (mm->context.asce_limit > limit) {
 		pgd = mm->pgd;
 		switch (pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) {
@@ -118,7 +114,6 @@
 		mm->task_size = mm->context.asce_limit;
 		crst_table_free(mm, (unsigned long *) pgd);
 	}
-	update_mm(mm, current);
 }
 #endif
 
@@ -801,7 +796,7 @@
 	struct mm_struct *mm, *old_mm;
 
 	/* Do we have switched amode? If no, we cannot do sie */
-	if (user_mode == HOME_SPACE_MODE)
+	if (addressing_mode == HOME_SPACE_MODE)
 		return -EINVAL;
 
 	/* Do we have pgstes? if yes, we are done */
diff --git a/arch/s390/oprofile/backtrace.c b/arch/s390/oprofile/backtrace.c
index c82f62f..8a6811b 100644
--- a/arch/s390/oprofile/backtrace.c
+++ b/arch/s390/oprofile/backtrace.c
@@ -58,7 +58,7 @@
 	unsigned long head;
 	struct stack_frame* head_sf;
 
-	if (user_mode (regs))
+	if (user_mode(regs))
 		return;
 
 	head = regs->gprs[15];
diff --git a/scripts/sortextable.c b/scripts/sortextable.c
index 1ca9ceb..6acf834 100644
--- a/scripts/sortextable.c
+++ b/scripts/sortextable.c
@@ -247,6 +247,7 @@
 	case EM_X86_64:
 		custom_sort = sort_x86_table;
 		break;
+	case EM_S390:
 	case EM_MIPS:
 		break;
 	}  /* end switch */