The ll/sc constructs in the kernel use ".set noat" to inhibit use of $at, and proceed to use it themselves. This is fine, except for one problem: the constraints on memory operands are "o" and "=o", which means offsettable memory references. If I'm not mistaken, the assembler will (always?) turn these into uses of $at if the offset is not 0 - at least, it certainly seems to do that here (gcc 2.95.3, binutils 2.10.91.0.2). Just being honest with the compiler and asking for a real memory reference does the trick. Does this patch look right? -- Daniel Jacobowitz Debian GNU/Linux Developer Monta Vista Software Debian Security Team
Index: arch/mips/kernel/sysmips.c =================================================================== RCS file: /cvs/linux/arch/mips/kernel/sysmips.c,v retrieving revision 1.18 diff -u -r1.18 sysmips.c --- arch/mips/kernel/sysmips.c 2001/04/08 13:24:27 1.18 +++ arch/mips/kernel/sysmips.c 2001/05/23 21:49:29 @@ -99,8 +99,8 @@ ".word\t1b, 3b\n\t" ".word\t2b, 3b\n\t" ".previous\n\t" - : "=&r" (tmp), "=o" (* (u32 *) p), "=r" (errno) - : "r" (arg2), "o" (* (u32 *) p), "2" (errno) + : "=&r" (tmp), "=m" (* (u32 *) p), "=r" (errno) + : "r" (arg2), "m" (* (u32 *) p), "2" (errno) : "$1"); if (errno) Index: include/asm-mips/system.h =================================================================== RCS file: /cvs/linux/include/asm-mips/system.h,v retrieving revision 1.27 diff -u -r1.27 system.h --- include/asm-mips/system.h 2001/03/28 01:35:12 1.27 +++ include/asm-mips/system.h 2001/05/23 21:49:29 @@ -219,8 +219,8 @@ " ll\t%0, %3\n\t" ".set\tat\n\t" ".set\treorder" - : "=r" (val), "=o" (*m), "=r" (dummy) - : "o" (*m), "2" (val) + : "=r" (val), "=m" (*m), "=r" (dummy) + : "m" (*m), "2" (val) : "memory"); return val;