1 /* 2 * Supervisor Mode Access Prevention support 3 * 4 * Copyright (C) 2012 Intel Corporation 5 * Author: H. Peter Anvin <hpa@linux.intel.com> 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; version 2 10 * of the License. 11 */ 12 13 #ifndef _ASM_X86_SMAP_H 14 #define _ASM_X86_SMAP_H 15 16 #include <linux/stringify.h> 17 #include <asm/nops.h> 18 #include <asm/cpufeature.h> 19 20 /* "Raw" instruction opcodes */ 21 #define __ASM_CLAC .byte 0x0f,0x01,0xca 22 #define __ASM_STAC .byte 0x0f,0x01,0xcb 23 24 #ifdef __ASSEMBLY__ 25 26 #include <asm/alternative-asm.h> 27 28 #ifdef CONFIG_X86_SMAP 29 30 #define ASM_CLAC \ 31 661: ASM_NOP3 ; \ 32 .pushsection .altinstr_replacement, "ax" ; \ 33 662: __ASM_CLAC ; \ 34 .popsection ; \ 35 .pushsection .altinstructions, "a" ; \ 36 altinstruction_entry 661b, 662b, X86_FEATURE_SMAP, 3, 3, 0 ; \ 37 .popsection 38 39 #define ASM_STAC \ 40 661: ASM_NOP3 ; \ 41 .pushsection .altinstr_replacement, "ax" ; \ 42 662: __ASM_STAC ; \ 43 .popsection ; \ 44 .pushsection .altinstructions, "a" ; \ 45 altinstruction_entry 661b, 662b, X86_FEATURE_SMAP, 3, 3, 0 ; \ 46 .popsection 47 48 #else /* CONFIG_X86_SMAP */ 49 50 #define ASM_CLAC 51 #define ASM_STAC 52 53 #endif /* CONFIG_X86_SMAP */ 54 55 #else /* __ASSEMBLY__ */ 56 57 #include <asm/alternative.h> 58 59 #ifdef CONFIG_X86_SMAP 60 61 static __always_inline void clac(void) 62 { 63 /* Note: a barrier is implicit in alternative() */ 64 alternative(ASM_NOP3, __stringify(__ASM_CLAC), X86_FEATURE_SMAP); 65 } 66 67 static __always_inline void stac(void) 68 { 69 /* Note: a barrier is implicit in alternative() */ 70 alternative(ASM_NOP3, __stringify(__ASM_STAC), X86_FEATURE_SMAP); 71 } 72 73 /* These macros can be used in asm() statements */ 74 #define ASM_CLAC \ 75 ALTERNATIVE(ASM_NOP3, __stringify(__ASM_CLAC), X86_FEATURE_SMAP) 76 #define ASM_STAC \ 77 ALTERNATIVE(ASM_NOP3, __stringify(__ASM_STAC), X86_FEATURE_SMAP) 78 79 #else /* CONFIG_X86_SMAP */ 80 81 static inline void clac(void) { } 82 static inline void stac(void) { } 83 84 #define ASM_CLAC 85 #define ASM_STAC 86 87 #endif /* CONFIG_X86_SMAP */ 88 89 #endif /* __ASSEMBLY__ */ 90 91 #endif /* _ASM_X86_SMAP_H */ 92