From mboxrd@z Thu Jan 1 00:00:00 1970 From: Srinivas KANDAGATLA Date: Thu, 07 Apr 2011 12:57:09 +0000 Subject: sh:fixed issue in xchg_u32 function when val==r15. Message-Id: <4D9DB4A5.4010002@st.com> MIME-Version: 1 Content-Type: multipart/mixed; boundary="------------050601090902080206070302" List-Id: To: linux-sh@vger.kernel.org This is a multi-part message in MIME format. --------------050601090902080206070302 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hi All, Recently we have discovered a bug in xchg_u32 function of GUSA_RB feature. This function breaks if one of the input parameter 'val' is r15. Kernel version: Linux 2.6.39-rc2 and previous versions too. Here is the part of disassembly code of exit_mm function in kernel/exit.c which calls xchg_u32 and looks like: (generated by 'sh4-linux-objdump -d kernel/exit.o' ) 168: 02 c7 mova 174 ,r0 16a: 09 00 nop 16c: f3 61 mov r15,r1 16e: fc ef mov #-4,r15 170: 22 67 mov.l @r2,r7 172: f2 22 mov.l r15,@r2 174: 13 6f mov r1,r15 176: 01 e3 mov #1,r3 178: 7f 1b mov.l r7,@(60,r11) 17a: d3 62 mov r13,r2 17c: 02 c7 mova 188 ,r0 in '16e' we can see that r15 was changed to -4 and at '172' we can see it gets assigned to @r2. Originally this bug was discovered as part of stlinux bugzilla triage. This issue can be easily reproduced with a simple multi-threaded test-app attached, the kernel crashes while cleaning up its memory descriptor. Fix is making val an input/output constraint so the compiler cannot pass r15 directly and must use a temporary register. After applying the patch the code in exit_mm() looks like: 168: 02 c7 mova 174 ,r0 16a: 09 00 nop 16c: f3 61 mov r15,r1 16e: fc ef mov #-4,r15 170: 22 67 mov.l @r2,r7 172: 32 22 mov.l r3,@r2 174: 13 6f mov r1,r15 176: 01 e3 mov #1,r3 178: 7f 1b mov.l r7,@(60,r11) 17a: e3 62 mov r14,r2 17c: 02 c7 mova 188 ,r0 Patch is attached Thanks, srini --------------050601090902080206070302 Content-Type: text/x-csrc; name="main.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="main.c" #include #include #define NTHREADS 40 void *dodump(void *threadid) { char *ptr = 0x1212121; printf("DUmp... %s \n", ptr); } void *dowork(void *threadid) { printf("\nThread %d started \n", (int )threadid); while(1); } int main(int argc, char *argv[]) { pthread_t threads[NTHREADS]; int rc; long t; for(t=0; tFrom da8a5909fed9bb801b7d9b175330f4e205b9dd61 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 7 Apr 2011 13:34:43 +0100 Subject: [PATCH sh-2.6.32.y] sh: fixed issue in xchg_u32 function. This patch addresses a use case where input parameter (val) to xchg_u32 inline asm function is equal to r15. If val == r15 then xchg_u32 always sets m to -4(0xfffffffc). In particular code in kernel/exit.c exit_mm() will hit this bug. This patch makes adds val to input/output constraint so that compiler cannot pass r15 directly and must use a temporary register instead. Without this patch a SEGFAULT in multithreaded program will crash the kernel. Originally this bug was discovered as part of stlinux bugzilla##11229 triage. Signed-off-by: Srinivas Kandagatla Reviewed-by: Stuart Menefy --- arch/sh/include/asm/cmpxchg-grb.h | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/sh/include/asm/cmpxchg-grb.h b/arch/sh/include/asm/cmpxchg-grb.h index 4676bf5..fc3deb6 100644 --- a/arch/sh/include/asm/cmpxchg-grb.h +++ b/arch/sh/include/asm/cmpxchg-grb.h @@ -15,8 +15,10 @@ static inline unsigned long xchg_u32(volatile u32 *m, unsigned long val) " mov.l %2, @%1 \n\t" /* store new value */ "1: mov r1, r15 \n\t" /* LOGOUT */ : "=&r" (retval), - "+r" (m) - : "r" (val) + "+r" (m), + "+r" (val) /* when val == r15 this function will not work as expected. + * So val is added to output constriants */ + : : "memory", "r0", "r1"); return retval; -- 1.6.3.3 --------------050601090902080206070302--