• R
    [MIPS] More uaccess.h fixes with gcc >= 4.0.1. · 3218357c
    Ralf Baechle 提交于
        
    From Richard Sandiford <richard@codesourcery.com>:
        
    This patch caused a miscompilation of the restore_gp_regs() block
    in restore_sigcontext().  This was in a 32-bit kernel compiled with
    GCC CVS head.
        
    restore_gp_regs() copies 64-bit user fields into 32-bit variables,
    and in this combination, the new __get_user_asm_ll32() clobbers too
    many registers.  It says:
        
    /*
     * Get a long long 64 using 32 bit registers.
     */
    {									\
    	__asm__ __volatile__(						\
    	"1:	lw	%1, (%3)				\n"	\
    	"2:	lw	%D1, 4(%3)				\n"	\
    	"	move	%0, $0					\n"	\
    	"3:	.section	.fixup,\"ax\"			\n"	\
    	"4:	li	%0, %4					\n"	\
    	"	move	%1, $0					\n"	\
    	"	move	%D1, $0					\n"	\
    	"	j	3b					\n"	\
    	"	.previous					\n"	\
    	"	.section	__ex_table,\"a\"		\n"	\
    	"	" __UA_ADDR "	1b, 4b				\n"	\
    	"	" __UA_ADDR "	2b, 4b				\n"	\
    	"	.previous					\n"	\
    	: "=r" (__gu_err), "=&r" (val)					\
    	: "0" (0), "r" (addr), "i" (-EFAULT));				\
    }
    
    and this requires val (%1) to be a 64-bit value.  In the case I saw,
    gcc was using $3 for the 32-bit val, and wasn't expecting $4 to be
    clobbered.
    Signed-off-by: NRalf Baechle <ralf@linux-mips.org>
    3218357c
uaccess.h 22.0 KB