public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [patch 0/6] s390 bug fixes for 2.6.21
@ 2007-03-26 20:52 Heiko Carstens
  2007-03-26 20:52 ` [patch 1/6] dasd: Work around gcc bug Heiko Carstens
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Heiko Carstens @ 2007-03-26 20:52 UTC (permalink / raw)
  To: linux-kernel, linux-s390

s390 bug fixes for 2.6.21

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [patch 1/6] dasd: Work around gcc bug.
  2007-03-26 20:52 [patch 0/6] s390 bug fixes for 2.6.21 Heiko Carstens
@ 2007-03-26 20:52 ` Heiko Carstens
  2007-03-26 20:52 ` [patch 2/6] Fix TCP/UDP pseudo header checksum computation Heiko Carstens
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Heiko Carstens @ 2007-03-26 20:52 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Martin Schwidefsky, Peter Oberparleiter

[-- Attachment #1: 001-dasd-gcc-bug.diff --]
[-- Type: text/plain, Size: 1506 bytes --]

From: Peter Oberparleiter <peter.oberparleiter@de.ibm.com>

gcc incorrectly removes initialization of register 0 in dasd diag
inline assembly. Use different register to work around this compiler
bug.

Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
---

 drivers/s390/block/dasd_diag.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

Index: linux-2.6/drivers/s390/block/dasd_diag.c
===================================================================
--- linux-2.6.orig/drivers/s390/block/dasd_diag.c
+++ linux-2.6/drivers/s390/block/dasd_diag.c
@@ -65,7 +65,7 @@ static const u8 DASD_DIAG_CMS1[] = { 0xc
  * resulting condition code and DIAG return code. */
 static inline int dia250(void *iob, int cmd)
 {
-	register unsigned long reg0 asm ("0") = (unsigned long) iob;
+	register unsigned long reg2 asm ("2") = (unsigned long) iob;
 	typedef union {
 		struct dasd_diag_init_io init_io;
 		struct dasd_diag_rw_io rw_io;
@@ -74,15 +74,15 @@ static inline int dia250(void *iob, int 
 
 	rc = 3;
 	asm volatile(
-		"	diag	0,%2,0x250\n"
+		"	diag	2,%2,0x250\n"
 		"0:	ipm	%0\n"
 		"	srl	%0,28\n"
-		"	or	%0,1\n"
+		"	or	%0,3\n"
 		"1:\n"
 		EX_TABLE(0b,1b)
 		: "+d" (rc), "=m" (*(addr_type *) iob)
-		: "d" (cmd), "d" (reg0), "m" (*(addr_type *) iob)
-		: "1", "cc");
+		: "d" (cmd), "d" (reg2), "m" (*(addr_type *) iob)
+		: "3", "cc");
 	return rc;
 }
 

-- 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [patch 2/6] Fix TCP/UDP pseudo header checksum computation.
  2007-03-26 20:52 [patch 0/6] s390 bug fixes for 2.6.21 Heiko Carstens
  2007-03-26 20:52 ` [patch 1/6] dasd: Work around gcc bug Heiko Carstens
@ 2007-03-26 20:52 ` Heiko Carstens
  2007-03-26 20:52 ` [patch 3/6] kprobes: Align probe address Heiko Carstens
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Heiko Carstens @ 2007-03-26 20:52 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Martin Schwidefsky

[-- Attachment #1: 002-tcpudp-fix.diff --]
[-- Type: text/plain, Size: 2803 bytes --]

From: Heiko Carstens <heiko.carstens@de.ibm.com>

git commit f994aae1bd8e4813d59a2ed64d17585fe42d03fc changed the
function declaration of csum_tcpudp_nofold. Argument types were
changed from unsigned long to __be32 (unsigned int). Therefore we
lost the implicit type conversion that zeroed the upper half of the
registers that are used to pass parameters. Since the inline assembly
relied on this we ended up adding random values and wrong checksums
were created.
Showed only up on machines with more than 4GB since gcc produced code
where the registers that are used to pass 'saddr' and 'daddr' previously
contained addresses before calling this function.
Fix this by using 32 bit arithmetics and convert code to C, since gcc
produces better code than these hand-optimized versions.

Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
---

 include/asm-s390/checksum.h |   59 +++++++++++---------------------------------
 1 files changed, 15 insertions(+), 44 deletions(-)

Index: linux-2.6/include/asm-s390/checksum.h
===================================================================
--- linux-2.6.orig/include/asm-s390/checksum.h
+++ linux-2.6/include/asm-s390/checksum.h
@@ -121,50 +121,21 @@ csum_tcpudp_nofold(__be32 saddr, __be32 
                    unsigned short len, unsigned short proto,
                    __wsum sum)
 {
-#ifndef __s390x__
-	asm volatile(
-		"	alr	%0,%1\n" /* sum += saddr */
-		"	brc	12,0f\n"
-		"	ahi	%0,1\n"  /* add carry */
-		"0:"
-		: "+&d" (sum) : "d" (saddr) : "cc");
-	asm volatile(
-		"	alr	%0,%1\n" /* sum += daddr */
-		"	brc	12,1f\n"
-		"	ahi	%0,1\n"  /* add carry */
-		"1:"
-		: "+&d" (sum) : "d" (daddr) : "cc");
-	asm volatile(
-		"	alr	%0,%1\n" /* sum += len + proto */
-		"	brc	12,2f\n"
-		"	ahi	%0,1\n"  /* add carry */
-		"2:"
-		: "+&d" (sum)
-		: "d" (len + proto)
-		: "cc");
-#else /* __s390x__ */
-	asm volatile(
-		"	lgfr	%0,%0\n"
-		"	algr	%0,%1\n"  /* sum += saddr */
-		"	brc	12,0f\n"
-		"	aghi	%0,1\n"   /* add carry */
-		"0:	algr	%0,%2\n"  /* sum += daddr */
-		"	brc	12,1f\n"
-		"	aghi	%0,1\n"   /* add carry */
-		"1:	algfr	%0,%3\n"  /* sum += len + proto */
-		"	brc	12,2f\n"
-		"	aghi	%0,1\n"   /* add carry */
-		"2:	srlg	0,%0,32\n"
-		"	alr	%0,0\n"   /* fold to 32 bits */
-		"	brc	12,3f\n"
-		"	ahi	%0,1\n"   /* add carry */
-		"3:	llgfr	%0,%0"
-		: "+&d" (sum)
-		: "d" (saddr), "d" (daddr),
-		  "d" (len + proto)
-		: "cc", "0");
-#endif /* __s390x__ */
-	return sum;
+	__u32 csum = (__force __u32)sum;
+
+	csum += (__force __u32)saddr;
+	if (csum < (__force __u32)saddr)
+		csum++;
+
+	csum += (__force __u32)daddr;
+	if (csum < (__force __u32)daddr)
+		csum++;
+
+	csum += len + proto;
+	if (csum < len + proto)
+		csum++;
+
+	return (__force __wsum)csum;
 }
 
 /*

-- 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [patch 3/6] kprobes: Align probe address.
  2007-03-26 20:52 [patch 0/6] s390 bug fixes for 2.6.21 Heiko Carstens
  2007-03-26 20:52 ` [patch 1/6] dasd: Work around gcc bug Heiko Carstens
  2007-03-26 20:52 ` [patch 2/6] Fix TCP/UDP pseudo header checksum computation Heiko Carstens
@ 2007-03-26 20:52 ` Heiko Carstens
  2007-03-26 20:52 ` [patch 4/6] cio: Device status validity Heiko Carstens
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Heiko Carstens @ 2007-03-26 20:52 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Martin Schwidefsky, David Wilder

[-- Attachment #1: 003-kprobes.diff --]
[-- Type: text/plain, Size: 1374 bytes --]

From: David Wilder <dwilder@us.ibm.com>

Running a probe on s390 with a probe address that is not 4 byte aligned
results in a Kernel BUG.  The problem is that the stura instruction used
by swap_instruction requires the destination address to be 4 byte aligned.
As stura only writes 4 bytes, aligning to the next 4 byte aligned address
results in the breakpoint instruction being stored past the probe address.
The fix is to align the address backward (to the previous 4 byte aligned
address) and writing the two byte breakpoint instruction in the appropriate
bytes.

Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: David Wilder <dwilder@us.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
---

 arch/s390/kernel/kprobes.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

Index: linux-2.6/arch/s390/kernel/kprobes.c
===================================================================
--- linux-2.6.orig/arch/s390/kernel/kprobes.c
+++ linux-2.6/arch/s390/kernel/kprobes.c
@@ -167,7 +167,7 @@ static int __kprobes swap_instruction(vo
 	 * shall not cross any page boundaries (vmalloc area!) when writing
 	 * the new instruction.
 	 */
-	addr = (u32 *)ALIGN((unsigned long)args->ptr, 4);
+	addr = (u32 *)((unsigned long)args->ptr & -4UL);
 	if ((unsigned long)args->ptr & 2)
 		instr = ((*addr) & 0xffff0000) | args->new;
 	else

-- 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [patch 4/6] cio: Device status validity.
  2007-03-26 20:52 [patch 0/6] s390 bug fixes for 2.6.21 Heiko Carstens
                   ` (2 preceding siblings ...)
  2007-03-26 20:52 ` [patch 3/6] kprobes: Align probe address Heiko Carstens
@ 2007-03-26 20:52 ` Heiko Carstens
  2007-03-26 20:52 ` [patch 5/6] zcrypt: Fix possible dead lock in AP bus module Heiko Carstens
  2007-03-26 20:52 ` [patch 6/6] zcrypt: Fix ap_poll_requests counter in lost requests error path Heiko Carstens
  5 siblings, 0 replies; 7+ messages in thread
From: Heiko Carstens @ 2007-03-26 20:52 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Martin Schwidefsky, Cornelia Huck

[-- Attachment #1: 004-cio-devstatus.diff --]
[-- Type: text/plain, Size: 1188 bytes --]

From: Cornelia Huck <cornelia.huck@de.ibm.com>

Only accumulate device status field in irb if it is valid.

Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
---

 drivers/s390/cio/device_status.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletion(-)

Index: linux-2.6/drivers/s390/cio/device_status.c
===================================================================
--- linux-2.6.orig/drivers/s390/cio/device_status.c
+++ linux-2.6/drivers/s390/cio/device_status.c
@@ -263,7 +263,11 @@ ccw_device_accumulate_irb(struct ccw_dev
 		cdev_irb->scsw.cpa = irb->scsw.cpa;
 	/* Accumulate device status, but not the device busy flag. */
 	cdev_irb->scsw.dstat &= ~DEV_STAT_BUSY;
-	cdev_irb->scsw.dstat |= irb->scsw.dstat;
+	/* dstat is not always valid. */
+	if (irb->scsw.stctl &
+	    (SCSW_STCTL_PRIM_STATUS | SCSW_STCTL_SEC_STATUS
+	     | SCSW_STCTL_INTER_STATUS | SCSW_STCTL_ALERT_STATUS))
+		cdev_irb->scsw.dstat |= irb->scsw.dstat;
 	/* Accumulate subchannel status. */
 	cdev_irb->scsw.cstat |= irb->scsw.cstat;
 	/* Copy residual count if it is valid. */

-- 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [patch 5/6] zcrypt: Fix possible dead lock in AP bus module.
  2007-03-26 20:52 [patch 0/6] s390 bug fixes for 2.6.21 Heiko Carstens
                   ` (3 preceding siblings ...)
  2007-03-26 20:52 ` [patch 4/6] cio: Device status validity Heiko Carstens
@ 2007-03-26 20:52 ` Heiko Carstens
  2007-03-26 20:52 ` [patch 6/6] zcrypt: Fix ap_poll_requests counter in lost requests error path Heiko Carstens
  5 siblings, 0 replies; 7+ messages in thread
From: Heiko Carstens @ 2007-03-26 20:52 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Martin Schwidefsky, Ralph Wuerthner

[-- Attachment #1: 005-zcrypt-deadlock.diff --]
[-- Type: text/plain, Size: 2123 bytes --]

From: Ralph Wuerthner <rwuerthn@de.ibm.com>

If a AP device is unconfigured __ap_poll_all() will call
device_unregister() in software interrupt context which can cause
dead locks. To fix this the device will be only marked as unconfigured
and the device_unregister() call will be done later by either
ap_scan_bus() or ap_queue_message() in process context.

Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Ralph Wuerthner <rwuerthn@de.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
---

 drivers/s390/crypto/ap_bus.c |   26 +++++++++++++-------------
 1 files changed, 13 insertions(+), 13 deletions(-)

Index: linux-2.6/drivers/s390/crypto/ap_bus.c
===================================================================
--- linux-2.6.orig/drivers/s390/crypto/ap_bus.c
+++ linux-2.6/drivers/s390/crypto/ap_bus.c
@@ -757,10 +757,16 @@ static void ap_scan_bus(struct work_stru
 				      (void *)(unsigned long)qid,
 				      __ap_scan_bus);
 		rc = ap_query_queue(qid, &queue_depth, &device_type);
-		if (dev && rc) {
-			put_device(dev);
-			device_unregister(dev);
-			continue;
+		if (dev) {
+			ap_dev = to_ap_dev(dev);
+			spin_lock_bh(&ap_dev->lock);
+			if (rc || ap_dev->unregistered) {
+				spin_unlock_bh(&ap_dev->lock);
+				put_device(dev);
+				device_unregister(dev);
+				continue;
+			} else
+				spin_unlock_bh(&ap_dev->lock);
 		}
 		if (dev) {
 			put_device(dev);
@@ -994,7 +1000,7 @@ void ap_queue_message(struct ap_device *
 			ap_dev->unregistered = 1;
 	} else {
 		ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
-		rc = 0;
+		rc = -ENODEV;
 	}
 	spin_unlock_bh(&ap_dev->lock);
 	if (rc == -ENODEV)
@@ -1044,18 +1050,12 @@ static void ap_poll_timeout(unsigned lon
  */
 static int __ap_poll_all(struct ap_device *ap_dev, unsigned long *flags)
 {
-	int rc;
-
 	spin_lock(&ap_dev->lock);
 	if (!ap_dev->unregistered) {
-		rc = ap_poll_queue(ap_dev, flags);
-		if (rc)
+		if (ap_poll_queue(ap_dev, flags))
 			ap_dev->unregistered = 1;
-	} else
-		rc = 0;
+	}
 	spin_unlock(&ap_dev->lock);
-	if (rc)
-		device_unregister(&ap_dev->device);
 	return 0;
 }
 

-- 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [patch 6/6] zcrypt: Fix ap_poll_requests counter in lost requests error path.
  2007-03-26 20:52 [patch 0/6] s390 bug fixes for 2.6.21 Heiko Carstens
                   ` (4 preceding siblings ...)
  2007-03-26 20:52 ` [patch 5/6] zcrypt: Fix possible dead lock in AP bus module Heiko Carstens
@ 2007-03-26 20:52 ` Heiko Carstens
  5 siblings, 0 replies; 7+ messages in thread
From: Heiko Carstens @ 2007-03-26 20:52 UTC (permalink / raw)
  To: linux-kernel, linux-s390; +Cc: Martin Schwidefsky, Ralph Wuerthner

[-- Attachment #1: 006-zcrypt-req.diff --]
[-- Type: text/plain, Size: 1384 bytes --]

From: Ralph Wuerthner <rwuerthn@de.ibm.com>

In the unlikely event that an AP device lost requests, don't forget to
update the ap_poll_requests counter too. Same must happen in case an AP
device is removed while there are still outstanding requests.

Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Ralph Wuerthner <rwuerthn@de.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
---

 drivers/s390/crypto/ap_bus.c |    4 ++++
 1 files changed, 4 insertions(+)

Index: linux-2.6/drivers/s390/crypto/ap_bus.c
===================================================================
--- linux-2.6.orig/drivers/s390/crypto/ap_bus.c
+++ linux-2.6/drivers/s390/crypto/ap_bus.c
@@ -505,6 +505,9 @@ static int ap_device_remove(struct devic
 	spin_lock_bh(&ap_device_lock);
 	list_del_init(&ap_dev->list);
 	spin_unlock_bh(&ap_device_lock);
+	spin_lock_bh(&ap_dev->lock);
+	atomic_sub(ap_dev->queue_count, &ap_poll_requests);
+	spin_unlock_bh(&ap_dev->lock);
 	return 0;
 }
 
@@ -867,6 +870,7 @@ static int ap_poll_read(struct ap_device
 	case AP_RESPONSE_NO_PENDING_REPLY:
 		if (status.queue_empty) {
 			/* The card shouldn't forget requests but who knows. */
+			atomic_sub(ap_dev->queue_count, &ap_poll_requests);
 			ap_dev->queue_count = 0;
 			list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
 			ap_dev->requestq_count += ap_dev->pendingq_count;

-- 

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2007-03-26 20:54 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-03-26 20:52 [patch 0/6] s390 bug fixes for 2.6.21 Heiko Carstens
2007-03-26 20:52 ` [patch 1/6] dasd: Work around gcc bug Heiko Carstens
2007-03-26 20:52 ` [patch 2/6] Fix TCP/UDP pseudo header checksum computation Heiko Carstens
2007-03-26 20:52 ` [patch 3/6] kprobes: Align probe address Heiko Carstens
2007-03-26 20:52 ` [patch 4/6] cio: Device status validity Heiko Carstens
2007-03-26 20:52 ` [patch 5/6] zcrypt: Fix possible dead lock in AP bus module Heiko Carstens
2007-03-26 20:52 ` [patch 6/6] zcrypt: Fix ap_poll_requests counter in lost requests error path Heiko Carstens

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox