public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Martin Schwidefsky <schwidefsky@de.ibm.com>
To: linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>,
	Martin Schwidefsky <schwidefsky@de.ibm.com>
Subject: [patch 01/52] [PATCH] Improve address space check.
Date: Fri, 13 Nov 2009 16:08:25 +0100	[thread overview]
Message-ID: <20091113150909.239905899@de.ibm.com> (raw)
In-Reply-To: 20091113150824.351347652@de.ibm.com

[-- Attachment #1: 100-mm-check-space.diff --]
[-- Type: text/plain, Size: 8147 bytes --]

From: Martin Schwidefsky <schwidefsky@de.ibm.com>

A data access in access-register mode always is a user mode access,
the code to inspect the access-registers can be removed. The second
change is to use a different test to check for no-execute fault.
The third change is to pass the translation exception identification
as parameter, in theory the trans_exc_code in the lowcore could have
been overwritten by the time the call to check_space from do_no_context
is done.

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---

 arch/s390/mm/fault.c |   99 +++++++++++++++++++++++----------------------------
 1 file changed, 45 insertions(+), 54 deletions(-)

Index: quilt-2.6/arch/s390/mm/fault.c
===================================================================
--- quilt-2.6.orig/arch/s390/mm/fault.c	2009-11-13 15:48:32.000000000 +0100
+++ quilt-2.6/arch/s390/mm/fault.c	2009-11-13 16:08:12.000000000 +0100
@@ -100,39 +100,28 @@
 
 /*
  * Returns the address space associated with the fault.
- * Returns 0 for kernel space, 1 for user space and
- * 2 for code execution in user space with noexec=on.
+ * Returns 0 for kernel space and 1 for user space.
  */
-static inline int check_space(struct task_struct *tsk)
+static inline int user_space_fault(unsigned long trans_exc_code)
 {
 	/*
-	 * The lowest two bits of S390_lowcore.trans_exc_code
-	 * indicate which paging table was used.
+	 * The lowest two bits of the translation exception
+	 * identification indicate which paging table was used.
 	 */
-	int desc = S390_lowcore.trans_exc_code & 3;
-
-	if (desc == 3)	/* Home Segment Table Descriptor */
-		return switch_amode == 0;
-	if (desc == 2)	/* Secondary Segment Table Descriptor */
-		return tsk->thread.mm_segment.ar4;
-#ifdef CONFIG_S390_SWITCH_AMODE
-	if (unlikely(desc == 1)) { /* STD determined via access register */
-		/* %a0 always indicates primary space. */
-		if (S390_lowcore.exc_access_id != 0) {
-			save_access_regs(tsk->thread.acrs);
-			/*
-			 * An alet of 0 indicates primary space.
-			 * An alet of 1 indicates secondary space.
-			 * Any other alet values generate an
-			 * alen-translation exception.
-			 */
-			if (tsk->thread.acrs[S390_lowcore.exc_access_id])
-				return tsk->thread.mm_segment.ar4;
-		}
-	}
-#endif
-	/* Primary Segment Table Descriptor */
-	return switch_amode << s390_noexec;
+	trans_exc_code &= 3;
+	if (trans_exc_code == 2)
+		/* Access via secondary space, set_fs setting decides */
+		return current->thread.mm_segment.ar4;
+	if (!switch_amode)
+		/* User space if the access has been done via home space. */
+		return trans_exc_code == 3;
+	/*
+	 * If the user space is not the home space the kernel runs in home
+	 * space. Access via secondary space has already been covered,
+	 * access via primary space or access register is from user space
+	 * and access via home space is from the kernel.
+	 */
+	return trans_exc_code != 3;
 }
 
 /*
@@ -162,9 +151,10 @@
 }
 
 static void do_no_context(struct pt_regs *regs, unsigned long error_code,
-			  unsigned long address)
+			  unsigned long trans_exc_code)
 {
 	const struct exception_table_entry *fixup;
+	unsigned long address;
 
 	/* Are we prepared to handle this kernel fault?  */
 	fixup = search_exception_tables(regs->psw.addr & __FIXUP_MASK);
@@ -177,7 +167,8 @@
 	 * Oops. The kernel tried to access some bad page. We'll have to
 	 * terminate things with extreme prejudice.
 	 */
-	if (check_space(current) == 0)
+	address = trans_exc_code & __FAIL_ADDR_MASK;
+	if (user_space_fault(trans_exc_code) == 0)
 		printk(KERN_ALERT "Unable to handle kernel pointer dereference"
 		       " at virtual kernel address %p\n", (void *)address);
 	else
@@ -188,7 +179,8 @@
 	do_exit(SIGKILL);
 }
 
-static void do_low_address(struct pt_regs *regs, unsigned long error_code)
+static void do_low_address(struct pt_regs *regs, unsigned long error_code,
+			   unsigned long trans_exc_code)
 {
 	/* Low-address protection hit in kernel mode means
 	   NULL pointer write access in kernel mode.  */
@@ -198,11 +190,11 @@
 		do_exit(SIGKILL);
 	}
 
-	do_no_context(regs, error_code, 0);
+	do_no_context(regs, error_code, trans_exc_code);
 }
 
 static void do_sigbus(struct pt_regs *regs, unsigned long error_code,
-		      unsigned long address)
+		      unsigned long trans_exc_code)
 {
 	struct task_struct *tsk = current;
 	struct mm_struct *mm = tsk->mm;
@@ -212,13 +204,13 @@
 	 * Send a sigbus, regardless of whether we were in kernel
 	 * or user mode.
 	 */
-	tsk->thread.prot_addr = address;
+	tsk->thread.prot_addr = trans_exc_code & __FAIL_ADDR_MASK;
 	tsk->thread.trap_no = error_code;
 	force_sig(SIGBUS, tsk);
 
 	/* Kernel mode? Handle exceptions or die */
 	if (!(regs->psw.mask & PSW_MASK_PSTATE))
-		do_no_context(regs, error_code, address);
+		do_no_context(regs, error_code, trans_exc_code);
 }
 
 #ifdef CONFIG_S390_EXEC_PROTECT
@@ -272,13 +264,13 @@
  *   3b       Region third trans.  ->  Not present       (nullification)
  */
 static inline void
-do_exception(struct pt_regs *regs, unsigned long error_code, int write)
+do_exception(struct pt_regs *regs, unsigned long error_code, int write,
+	     unsigned long trans_exc_code)
 {
 	struct task_struct *tsk;
 	struct mm_struct *mm;
 	struct vm_area_struct *vma;
 	unsigned long address;
-	int space;
 	int si_code;
 	int fault;
 
@@ -288,18 +280,15 @@
 	tsk = current;
 	mm = tsk->mm;
 
-	/* get the failing address and the affected space */
-	address = S390_lowcore.trans_exc_code & __FAIL_ADDR_MASK;
-	space = check_space(tsk);
-
 	/*
 	 * Verify that the fault happened in user space, that
 	 * we are not in an interrupt and that there is a 
 	 * user context.
 	 */
-	if (unlikely(space == 0 || in_atomic() || !mm))
+	if (unlikely(!user_space_fault(trans_exc_code) || in_atomic() || !mm))
 		goto no_context;
 
+	address = trans_exc_code & __FAIL_ADDR_MASK;
 	/*
 	 * When we get here, the fault happened in the current
 	 * task's user address space, so we can switch on the
@@ -315,7 +304,8 @@
 		goto bad_area;
 
 #ifdef CONFIG_S390_EXEC_PROTECT
-	if (unlikely((space == 2) && !(vma->vm_flags & VM_EXEC)))
+	if (unlikely((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_SECONDARY &&
+		     (trans_exc_code & 3) == 0 && !(vma->vm_flags & VM_EXEC)))
 		if (!signal_return(mm, regs, address, error_code))
 			/*
 			 * signal_return() has done an up_read(&mm->mmap_sem)
@@ -397,12 +387,14 @@
 	}
 
 no_context:
-	do_no_context(regs, error_code, address);
+	do_no_context(regs, error_code, trans_exc_code);
 }
 
 void __kprobes do_protection_exception(struct pt_regs *regs,
 				       long error_code)
 {
+	unsigned long trans_exc_code = S390_lowcore.trans_exc_code;
+
 	/* Protection exception is supressing, decrement psw address. */
 	regs->psw.addr -= (error_code >> 16);
 	/*
@@ -410,31 +402,30 @@
 	 * as a special case because the translation exception code
 	 * field is not guaranteed to contain valid data in this case.
 	 */
-	if (unlikely(!(S390_lowcore.trans_exc_code & 4))) {
-		do_low_address(regs, error_code);
+	if (unlikely(!(trans_exc_code & 4))) {
+		do_low_address(regs, error_code, trans_exc_code);
 		return;
 	}
-	do_exception(regs, 4, 1);
+	do_exception(regs, 4, 1, trans_exc_code);
 }
 
 void __kprobes do_dat_exception(struct pt_regs *regs, long error_code)
 {
-	do_exception(regs, error_code & 0xff, 0);
+	do_exception(regs, error_code & 0xff, 0, S390_lowcore.trans_exc_code);
 }
 
 #ifdef CONFIG_64BIT
 void __kprobes do_asce_exception(struct pt_regs *regs, unsigned long error_code)
 {
+	unsigned long trans_exc_code = S390_lowcore.trans_exc_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);
+	address = trans_exc_code & __FAIL_ADDR_MASK;
 
-	if (unlikely(space == 0 || in_atomic() || !mm))
+	if (unlikely(!user_space_fault(trans_exc_code) || in_atomic() || !mm))
 		goto no_context;
 
 	local_irq_enable();
@@ -457,7 +448,7 @@
 	}
 
 no_context:
-	do_no_context(regs, error_code, address);
+	do_no_context(regs, error_code, trans_exc_code);
 }
 #endif
 


  reply	other threads:[~2009-11-13 15:20 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-11-13 15:08 [patch 00/52] s390 patches for the next merge window (2.6.33) Martin Schwidefsky
2009-11-13 15:08 ` Martin Schwidefsky [this message]
2009-11-13 15:08 ` [patch 02/52] [PATCH] Improve address space mode selection Martin Schwidefsky
2009-11-13 15:08 ` [patch 03/52] [PATCH] Improve notify_page_fault implementation Martin Schwidefsky
2009-11-13 15:08 ` [patch 04/52] [PATCH] fault handler performance optimization Martin Schwidefsky
2009-11-13 15:08 ` [patch 05/52] [PATCH] fault handler access flags check Martin Schwidefsky
2009-11-13 15:08 ` [patch 06/52] [PATCH] Use do_exception() in pagetable walk usercopy functions Martin Schwidefsky
2009-11-13 15:08 ` [patch 07/52] [PATCH] Improve code generated by atomic operations Martin Schwidefsky
2009-11-13 15:08 ` [patch 08/52] [PATCH] dasd: support DIAG access for read-only devices Martin Schwidefsky
2009-11-13 15:08 ` [patch 09/52] [PATCH] cmm: free pages on hibernate Martin Schwidefsky
2009-11-13 15:08 ` [patch 10/52] [PATCH] smp: remove unused typedef and defines Martin Schwidefsky
2009-11-13 15:08 ` [patch 11/52] [PATCH] dasd: remove dead code Martin Schwidefsky
2009-11-13 15:08 ` [patch 12/52] [PATCH] use generic termbits.h header file Martin Schwidefsky
2009-11-13 15:08 ` [patch 13/52] [PATCH] use generic sockios.h " Martin Schwidefsky
2009-11-13 15:08 ` [patch 14/52] [PATCH] MAINTAINERS: Add s390 drivers block Martin Schwidefsky
2009-11-13 15:08 ` [patch 15/52] [PATCH] zcrypt: initialize ap_messages for cex3 exploitation Martin Schwidefsky
2009-11-13 15:08 ` [patch 16/52] [PATCH] zcrypt: special command support " Martin Schwidefsky
2009-11-13 15:08 ` [patch 17/52] [PATCH] zcrypt: add support for cex3 device types Martin Schwidefsky
2009-11-13 15:08 ` [patch 18/52] [PATCH] zcrypt: use definitions for cex3 Martin Schwidefsky
2009-11-13 15:08 ` [patch 19/52] [PATCH] zcrypt: adjust speed rating between cex2 and pcixcc Martin Schwidefsky
2009-11-13 15:08 ` [patch 20/52] [PATCH] zcrypt: adjust speed rating of cex3 adapters Martin Schwidefsky
2009-11-13 15:08 ` [patch 21/52] [PATCH] dasd: enable prefix independent of pav support Martin Schwidefsky
2009-11-13 15:08 ` [patch 22/52] [PATCH] dasd: improve error recovery for internal I/O Martin Schwidefsky
2009-11-13 15:08 ` [patch 23/52] [PATCH] dasd: remove strings from s390dbf Martin Schwidefsky
2009-11-13 15:08 ` [patch 24/52] [PATCH] s390: use change recording override for kernel mapping Martin Schwidefsky
2009-11-13 15:08 ` [patch 25/52] [PATCH] sclp: improve servicability setting Martin Schwidefsky
2009-11-13 15:08 ` [patch 26/52] [PATCH] cio: fix double free in case of probe failure Martin Schwidefsky
2009-11-13 15:08 ` [patch 27/52] [PATCH] cio: fix repeat setting of cdev parent association Martin Schwidefsky
2009-11-13 15:08 ` [patch 28/52] [PATCH] cio: introduce parent-initiated device move Martin Schwidefsky
2009-11-13 15:08 ` [patch 29/52] [PATCH] cio: introduce subchannel todos Martin Schwidefsky
2009-11-13 15:08 ` [patch 30/52] [PATCH] cio: introduce ccw device todos Martin Schwidefsky
2009-11-13 15:08 ` [patch 31/52] [PATCH] cio: inform user when online/offline processing fails Martin Schwidefsky
2009-11-13 15:08 ` [patch 32/52] [PATCH] cio: handle error during device recognition consistently Martin Schwidefsky
2009-11-13 15:08 ` [patch 33/52] [PATCH] cio: handle error during path verification consistently Martin Schwidefsky
2009-11-13 15:08 ` [patch 34/52] [PATCH] cio: ensure proper locking during device recognition Martin Schwidefsky
2009-11-13 15:08 ` [patch 35/52] [PATCH] cio: dont panic in non-fatal conditions Martin Schwidefsky
2009-11-13 15:09 ` [patch 36/52] [PATCH] cio: consistent infrastructure for internal I/O requests Martin Schwidefsky
2009-11-13 15:09 ` [patch 37/52] [PATCH] cio: use ccw request infrastructure for sense id Martin Schwidefsky
2009-11-13 15:09 ` [patch 38/52] [PATCH] cio: use ccw request infrastructure for pgid Martin Schwidefsky
2009-11-13 15:09 ` [patch 39/52] [PATCH] cio: allow setting not-operational devices offline Martin Schwidefsky
2009-11-13 15:09 ` [patch 40/52] [PATCH] cio: remove intretry flag Martin Schwidefsky
2009-11-13 15:09 ` [patch 41/52] [PATCH] cio: split PGID settings and status Martin Schwidefsky
2009-11-13 15:09 ` [patch 42/52] [PATCH] cio: use sense-pgid operation for path verification Martin Schwidefsky
2009-11-13 15:09 ` [patch 43/52] [PATCH] cio: make steal lock procedure more robust Martin Schwidefsky
2009-11-13 15:09 ` [patch 44/52] [PATCH] cio: remove registered flag from ccw_device_private Martin Schwidefsky
2009-11-13 15:09 ` [patch 45/52] [PATCH] cio: add per device initialization status flag Martin Schwidefsky
2009-11-13 15:09 ` [patch 46/52] [PATCH] cio: fix quiesce state Martin Schwidefsky
2009-11-13 15:09 ` [patch 47/52] [PATCH] cio: handle failed disable_subchannel after device recognition Martin Schwidefsky
2009-11-13 15:09 ` [patch 48/52] [PATCH] cio: handle busy subchannel in ccw_device_move_to_sch Martin Schwidefsky
2009-11-13 15:09 ` [patch 49/52] [PATCH] cio: quiesce subchannel in io_subchannel_remove Martin Schwidefsky
2009-11-13 15:09 ` [patch 50/52] [PATCH] cio: change locking " Martin Schwidefsky
2009-11-13 15:09 ` [patch 51/52] [PATCH] cio: improve error recovery for internal I/Os Martin Schwidefsky
2009-11-13 15:09 ` [patch 52/52] [PATCH] cio: dont unregister a busy device in ccw_device_set_offline Martin Schwidefsky
2009-11-13 15:28 ` [patch 00/52] s390 patches for the next merge window (2.6.33) Arnd Bergmann
2009-11-13 15:31   ` s390: move keyboard compat ioctls into tty3270 driver Arnd Bergmann
2009-11-16  8:33     ` Martin Schwidefsky

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20091113150909.239905899@de.ibm.com \
    --to=schwidefsky@de.ibm.com \
    --cc=heiko.carstens@de.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox