crashes in clear_user_page

Anton Blanchard anton at samba.org
Thu Mar 4 16:24:51 EST 2004


Hi,

> I get crashes in clear_user_page() while building rpms on a p660.
> gcc is 3.2.2, config is arch/ppc64/configs/pseries, plain ameslab tree.
>
> there is lot of IO, 8 processes do unpack rpms in parallel on a reiserfs
> filesystem.

It turns out you got a kernel segment with ks set. Shouldnt ever happen.

We werent zeroing the old contents of the segment table entry before
inserting the new one, if we overwrote a user segment with a kernel one
the ks bit would remain set. Its a POWER3/RS64 only bug.

Give this patch a go. While I was there I modified our vsid calculation
code to match reality (we only use 13 bits of the EA).

Anton

diff -urN ameslab-2.5/arch/ppc64/kernel/head.S foobar2/arch/ppc64/kernel/head.S
--- ameslab-2.5/arch/ppc64/kernel/head.S	2004-03-02 09:06:07.935488713 +1100
+++ foobar2/arch/ppc64/kernel/head.S	2004-03-04 16:17:07.374783850 +1100
@@ -904,12 +904,13 @@

 	/* (((ea >> 28) & 0x1fff) << 15) | (ea >> 60) */
 	mfspr	r21,DAR
-	rldicl  r20,r21,36,32   /* Permits a full 32b of ESID */
-	rldicr  r20,r20,15,48
-	rldicl  r21,r21,4,60
-	or      r20,r20,r21
+	rldicl	r20,r21,36,51
+	sldi	r20,r20,15
+	srdi	r21,r21,60
+	or	r20,r20,r21

-	li      r21,9           /* VSID_RANDOMIZER */
+	/* VSID_RANDOMIZER */
+	li      r21,9
 	sldi    r21,r21,32
 	oris    r21,r21,58231
 	ori     r21,r21,39831
@@ -933,11 +934,11 @@
 	rldicl  r23,r23,57,63
 	cmpwi   r23,0
 	bne     2f
-	ld      r23,8(r21)      /* Get the current vsid part of the ste */
+	li	r23,0
 	rldimi  r23,r20,12,0    /* Insert the new vsid value            */
 	std     r23,8(r21)      /* Put new entry back into the stab     */
 	eieio                  /* Order vsid update                    */
-	ld      r23,0(r21)      /* Get the esid part of the ste         */
+	li	r23,0
 	mfspr	r20,DAR        /* Get the new esid                     */
 	rldicl  r20,r20,36,28  /* Permits a full 36b of ESID           */
 	rldimi  r23,r20,28,0    /* Insert the new esid value            */
@@ -971,13 +972,13 @@
 	std     r23,0(r21)
 	sync

-	ld      r23,8(r21)
+	li	r23,0
 	rldimi  r23,r20,12,0
 	std     r23,8(r21)
 	eieio

-	ld      r23,0(r21)      /* Get the esid part of the ste         */
-	mr      r22,r23
+	ld	r22,0(r21)	/* Get the esid part of the ste         */
+	li	r23,0
 	mfspr	r20,DAR         /* Get the new esid                     */
 	rldicl  r20,r20,36,28   /* Permits a full 32b of ESID           */
 	rldimi  r23,r20,28,0    /* Insert the new esid value            */
diff -urN ameslab-2.5/arch/ppc64/kernel/stab.c foobar2/arch/ppc64/kernel/stab.c
--- ameslab-2.5/arch/ppc64/kernel/stab.c	2004-03-04 10:17:49.350078218 +1100
+++ foobar2/arch/ppc64/kernel/stab.c	2004-03-04 12:51:58.410484312 +1100
@@ -88,6 +88,8 @@
 	for (group = 0; group < 2; group++) {
 		for (entry = 0; entry < 8; entry++, ste++) {
 			if (!(ste->dw0.dw0.v)) {
+				ste->dw0.dword0 = 0;
+				ste->dw1.dword1 = 0;
 				ste->dw1.dw1.vsid = vsid;
 				ste->dw0.dw0.esid = esid;
 				ste->dw0.dw0.kp = 1;
@@ -135,6 +137,9 @@

 	castout_ste->dw0.dw0.v = 0;
 	asm volatile("sync" : : : "memory");    /* Order update */
+
+	castout_ste->dw0.dword0 = 0;
+	castout_ste->dw1.dword1 = 0;
 	castout_ste->dw1.dw1.vsid = vsid;
 	old_esid = castout_ste->dw0.dw0.esid;
 	castout_ste->dw0.dw0.esid = esid;
diff -urN ameslab-2.5/include/asm-ppc64/mmu_context.h foobar2/include/asm-ppc64/mmu_context.h
--- ameslab-2.5/include/asm-ppc64/mmu_context.h	2004-02-25 15:29:53.182417225 +1100
+++ foobar2/include/asm-ppc64/mmu_context.h	2004-03-04 12:49:09.946082835 +1100
@@ -189,7 +189,7 @@
 {
 	unsigned long ordinal, vsid;

-	ordinal = (((ea >> 28) & 0x1fffff) * LAST_USER_CONTEXT) | (ea >> 60);
+	ordinal = (((ea >> 28) & 0x1fff) * LAST_USER_CONTEXT) | (ea >> 60);
 	vsid = (ordinal * VSID_RANDOMIZER) & VSID_MASK;

 	ifppcdebug(PPCDBG_HTABSTRESS) {

** Sent via the linuxppc64-dev mail list. See http://lists.linuxppc.org/





More information about the Linuxppc64-dev mailing list