151ae4a2dSH. Peter Anvin /* 251ae4a2dSH. Peter Anvin * Supervisor Mode Access Prevention support 351ae4a2dSH. Peter Anvin * 451ae4a2dSH. Peter Anvin * Copyright (C) 2012 Intel Corporation 551ae4a2dSH. Peter Anvin * Author: H. Peter Anvin <hpa@linux.intel.com> 651ae4a2dSH. Peter Anvin * 751ae4a2dSH. Peter Anvin * This program is free software; you can redistribute it and/or 851ae4a2dSH. Peter Anvin * modify it under the terms of the GNU General Public License 951ae4a2dSH. Peter Anvin * as published by the Free Software Foundation; version 2 1051ae4a2dSH. Peter Anvin * of the License. 1151ae4a2dSH. Peter Anvin */ 1251ae4a2dSH. Peter Anvin 1351ae4a2dSH. Peter Anvin #ifndef _ASM_X86_SMAP_H 1451ae4a2dSH. Peter Anvin #define _ASM_X86_SMAP_H 1551ae4a2dSH. Peter Anvin 1651ae4a2dSH. Peter Anvin #include <linux/stringify.h> 1751ae4a2dSH. Peter Anvin #include <asm/nops.h> 1851ae4a2dSH. Peter Anvin #include <asm/cpufeature.h> 1951ae4a2dSH. Peter Anvin 2051ae4a2dSH. Peter Anvin /* "Raw" instruction opcodes */ 2151ae4a2dSH. Peter Anvin #define __ASM_CLAC .byte 0x0f,0x01,0xca 2251ae4a2dSH. Peter Anvin #define __ASM_STAC .byte 0x0f,0x01,0xcb 2351ae4a2dSH. Peter Anvin 2451ae4a2dSH. Peter Anvin #ifdef __ASSEMBLY__ 2551ae4a2dSH. Peter Anvin 2651ae4a2dSH. Peter Anvin #include <asm/alternative-asm.h> 2751ae4a2dSH. Peter Anvin 2851ae4a2dSH. Peter Anvin #ifdef CONFIG_X86_SMAP 2951ae4a2dSH. Peter Anvin 3051ae4a2dSH. Peter Anvin #define ASM_CLAC \ 3151ae4a2dSH. Peter Anvin 661: ASM_NOP3 ; \ 3251ae4a2dSH. Peter Anvin .pushsection .altinstr_replacement, "ax" ; \ 3351ae4a2dSH. Peter Anvin 662: __ASM_CLAC ; \ 3451ae4a2dSH. Peter Anvin .popsection ; \ 3551ae4a2dSH. Peter Anvin .pushsection .altinstructions, "a" ; \ 3651ae4a2dSH. Peter Anvin altinstruction_entry 661b, 662b, X86_FEATURE_SMAP, 3, 3 ; \ 3751ae4a2dSH. Peter Anvin .popsection 3851ae4a2dSH. Peter Anvin 3951ae4a2dSH. Peter Anvin #define ASM_STAC \ 4051ae4a2dSH. Peter Anvin 661: ASM_NOP3 ; \ 4151ae4a2dSH. Peter Anvin .pushsection .altinstr_replacement, "ax" ; \ 4251ae4a2dSH. Peter Anvin 662: __ASM_STAC ; \ 4351ae4a2dSH. Peter Anvin .popsection ; \ 4451ae4a2dSH. Peter Anvin .pushsection .altinstructions, "a" ; \ 4551ae4a2dSH. Peter Anvin altinstruction_entry 661b, 662b, X86_FEATURE_SMAP, 3, 3 ; \ 4651ae4a2dSH. Peter Anvin .popsection 4751ae4a2dSH. Peter Anvin 4851ae4a2dSH. Peter Anvin #else /* CONFIG_X86_SMAP */ 4951ae4a2dSH. Peter Anvin 5051ae4a2dSH. Peter Anvin #define ASM_CLAC 5151ae4a2dSH. Peter Anvin #define ASM_STAC 5251ae4a2dSH. Peter Anvin 5351ae4a2dSH. Peter Anvin #endif /* CONFIG_X86_SMAP */ 5451ae4a2dSH. Peter Anvin 5551ae4a2dSH. Peter Anvin #else /* __ASSEMBLY__ */ 5651ae4a2dSH. Peter Anvin 5751ae4a2dSH. Peter Anvin #include <asm/alternative.h> 5851ae4a2dSH. Peter Anvin 5951ae4a2dSH. Peter Anvin #ifdef CONFIG_X86_SMAP 6051ae4a2dSH. Peter Anvin 6163bcff2aSH. Peter Anvin static __always_inline void clac(void) 6251ae4a2dSH. Peter Anvin { 6351ae4a2dSH. Peter Anvin /* Note: a barrier is implicit in alternative() */ 6451ae4a2dSH. Peter Anvin alternative(ASM_NOP3, __stringify(__ASM_CLAC), X86_FEATURE_SMAP); 6551ae4a2dSH. Peter Anvin } 6651ae4a2dSH. Peter Anvin 6763bcff2aSH. Peter Anvin static __always_inline void stac(void) 6851ae4a2dSH. Peter Anvin { 6951ae4a2dSH. Peter Anvin /* Note: a barrier is implicit in alternative() */ 7051ae4a2dSH. Peter Anvin alternative(ASM_NOP3, __stringify(__ASM_STAC), X86_FEATURE_SMAP); 7151ae4a2dSH. Peter Anvin } 7251ae4a2dSH. Peter Anvin 7351ae4a2dSH. Peter Anvin /* These macros can be used in asm() statements */ 7451ae4a2dSH. Peter Anvin #define ASM_CLAC \ 7551ae4a2dSH. Peter Anvin ALTERNATIVE(ASM_NOP3, __stringify(__ASM_CLAC), X86_FEATURE_SMAP) 7651ae4a2dSH. Peter Anvin #define ASM_STAC \ 7751ae4a2dSH. Peter Anvin ALTERNATIVE(ASM_NOP3, __stringify(__ASM_STAC), X86_FEATURE_SMAP) 7851ae4a2dSH. Peter Anvin 7951ae4a2dSH. Peter Anvin #else /* CONFIG_X86_SMAP */ 8051ae4a2dSH. Peter Anvin 8151ae4a2dSH. Peter Anvin static inline void clac(void) { } 8251ae4a2dSH. Peter Anvin static inline void stac(void) { } 8351ae4a2dSH. Peter Anvin 8451ae4a2dSH. Peter Anvin #define ASM_CLAC 8551ae4a2dSH. Peter Anvin #define ASM_STAC 8651ae4a2dSH. Peter Anvin 8751ae4a2dSH. Peter Anvin #endif /* CONFIG_X86_SMAP */ 8851ae4a2dSH. Peter Anvin 8951ae4a2dSH. Peter Anvin #endif /* __ASSEMBLY__ */ 9051ae4a2dSH. Peter Anvin 9151ae4a2dSH. Peter Anvin #endif /* _ASM_X86_SMAP_H */ 92