The in-place byteswap functions are broken on sparc64. Code like the following fails because the assignment before the byteswap call is optimized away by gcc: v = 2; __swab32s(&v); printf("x: %x\n", v); /* v = 2 is lost */ Insert a memory barrier before each byteswap operation in __arch_swab{16,32,64}p(). Signed-off-by: Jose E. Marchesi <jose.marchesi@xxxxxxxxxx> Signed-off-by: Martin K. Petersen <martin.petersen@xxxxxxxxxx> Cc: stable@xxxxxxxxxxxxxxx --- A different approach would be to use the "w" constraint. However, this was not introduced until gcc 4.7.0. swab.h is also used by userland so we don't have access to things like GCC_VERSION and would either have to pull that macro in or open code the version checks. Furthermore, the output generated by gcc is the same with either approach. And consequently inserting the barrier seems like the simplest solution. diff --git a/arch/sparc/include/uapi/asm/swab.h b/arch/sparc/include/uapi/asm/swab.h index a34ad079487e..64e603a13801 100644 --- a/arch/sparc/include/uapi/asm/swab.h +++ b/arch/sparc/include/uapi/asm/swab.h @@ -9,6 +9,7 @@ static inline __u16 __arch_swab16p(const __u16 *addr) { __u16 ret; + __asm__ __volatile__ ("": : :"memory"); __asm__ __volatile__ ("lduha [%1] %2, %0" : "=r" (ret) : "r" (addr), "i" (ASI_PL)); @@ -20,6 +21,7 @@ static inline __u32 __arch_swab32p(const __u32 *addr) { __u32 ret; + __asm__ __volatile__ ("": : :"memory"); __asm__ __volatile__ ("lduwa [%1] %2, %0" : "=r" (ret) : "r" (addr), "i" (ASI_PL)); @@ -31,6 +33,7 @@ static inline __u64 __arch_swab64p(const __u64 *addr) { __u64 ret; + __asm__ __volatile__ ("": : :"memory"); __asm__ __volatile__ ("ldxa [%1] %2, %0" : "=r" (ret) : "r" (addr), "i" (ASI_PL)); -- To unsubscribe from this list: send the line "unsubscribe sparclinux" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html