arch/x86/include/asm/uaccess.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index 5838fa911aa0..33597722cfc1 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -411,6 +411,24 @@ struct __large_struct { unsigned long buf[100]; }; * we do not write to any memory gcc knows about, so there are no * aliasing issues. */ +#ifdef CC_HAVE_ASM_GOTO +#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \ +do { __label__ error_label; \ + asm goto(ASM_STAC "\n" \ + "1: mov"itype" %"rtype"0,%1\n" \ + " " ASM_CLAC "\n" \ + _ASM_EXTABLE(1b,%l[error_label]) \ + : /* no outputs */ \ + : ltype(x), "m" (__m(addr)) \ + : /* no clobbers */ \ + : error_label); \ + err = 0; \ + break; \ +error_label: \ + asm volatile(ASM_CLAC); \ + err = errret; \ +} while (0) +#else #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \ asm volatile(ASM_STAC "\n" \ "1: mov"itype" %"rtype"1,%2\n" \ @@ -422,6 +440,7 @@ struct __large_struct { unsigned long buf[100]; }; _ASM_EXTABLE(1b, 3b) \ : "=r"(err) \ : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err)) +#endif #define __put_user_asm_ex(x, addr, itype, rtype, ltype) \ asm volatile("1: mov"itype" %"rtype"0,%1\n" \