From 5e88353d8b5f483bc1c873ad24ac2b59a6b66c73 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 21 Sep 2012 12:43:15 -0700 Subject: x86, smap: Reduce the SMAP overhead for signal handling Signal handling contains a bunch of accesses to individual user space items, which causes an excessive number of STAC and CLAC instructions. Instead, let get/put_user_try ... get/put_user_catch() contain the STAC and CLAC instructions. This means that get/put_user_try no longer nests, and furthermore that it is no longer legal to use user space access functions other than __get/put_user_ex() inside those blocks. However, these macros are x86-specific anyway and are only used in the signal-handling paths; a simple reordering of moving the larger subroutine calls out of the try...catch blocks resolves that problem. Signed-off-by: H. Peter Anvin Link: http://lkml.kernel.org/r/1348256595-29119-12-git-send-email-hpa@linux.intel.com --- arch/x86/include/asm/uaccess.h | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'arch/x86/include/asm/uaccess.h') diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index b92ece13c238..a91acfbb1a98 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -416,9 +416,8 @@ do { \ } while (0) #define __get_user_asm_ex(x, addr, itype, rtype, ltype) \ - asm volatile(ASM_STAC "\n" \ - "1: mov"itype" %1,%"rtype"0\n" \ - "2: " ASM_CLAC "\n" \ + asm volatile("1: mov"itype" %1,%"rtype"0\n" \ + "2:\n" \ _ASM_EXTABLE_EX(1b, 2b) \ : ltype(x) : "m" (__m(addr))) @@ -460,9 +459,8 @@ struct __large_struct { unsigned long buf[100]; }; : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err)) #define __put_user_asm_ex(x, addr, itype, rtype, ltype) \ - asm volatile(ASM_STAC "\n" \ - "1: mov"itype" %"rtype"0,%1\n" \ - "2: " ASM_CLAC "\n" \ + asm volatile("1: mov"itype" %"rtype"0,%1\n" \ + "2:\n" \ _ASM_EXTABLE_EX(1b, 2b) \ : : ltype(x), "m" (__m(addr))) @@ -470,13 +468,13 @@ struct __large_struct { unsigned long buf[100]; }; * uaccess_try and catch */ #define uaccess_try do { \ - int prev_err = current_thread_info()->uaccess_err; \ current_thread_info()->uaccess_err = 0; \ + stac(); \ barrier(); #define uaccess_catch(err) \ + clac(); \ (err) |= (current_thread_info()->uaccess_err ? -EFAULT : 0); \ - current_thread_info()->uaccess_err = prev_err; \ } while (0) /** -- cgit v1.2.3