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 \ 31*669f8a90SBorislav Petkov ALTERNATIVE "", __stringify(__ASM_CLAC), X86_FEATURE_SMAP 3251ae4a2dSH. Peter Anvin 3351ae4a2dSH. Peter Anvin #define ASM_STAC \ 34*669f8a90SBorislav Petkov ALTERNATIVE "", __stringify(__ASM_STAC), X86_FEATURE_SMAP 3551ae4a2dSH. Peter Anvin 3651ae4a2dSH. Peter Anvin #else /* CONFIG_X86_SMAP */ 3751ae4a2dSH. Peter Anvin 3851ae4a2dSH. Peter Anvin #define ASM_CLAC 3951ae4a2dSH. Peter Anvin #define ASM_STAC 4051ae4a2dSH. Peter Anvin 4151ae4a2dSH. Peter Anvin #endif /* CONFIG_X86_SMAP */ 4251ae4a2dSH. Peter Anvin 4351ae4a2dSH. Peter Anvin #else /* __ASSEMBLY__ */ 4451ae4a2dSH. Peter Anvin 4551ae4a2dSH. Peter Anvin #include <asm/alternative.h> 4651ae4a2dSH. Peter Anvin 4751ae4a2dSH. Peter Anvin #ifdef CONFIG_X86_SMAP 4851ae4a2dSH. Peter Anvin 4963bcff2aSH. Peter Anvin static __always_inline void clac(void) 5051ae4a2dSH. Peter Anvin { 5151ae4a2dSH. Peter Anvin /* Note: a barrier is implicit in alternative() */ 52*669f8a90SBorislav Petkov alternative("", __stringify(__ASM_CLAC), X86_FEATURE_SMAP); 5351ae4a2dSH. Peter Anvin } 5451ae4a2dSH. Peter Anvin 5563bcff2aSH. Peter Anvin static __always_inline void stac(void) 5651ae4a2dSH. Peter Anvin { 5751ae4a2dSH. Peter Anvin /* Note: a barrier is implicit in alternative() */ 58*669f8a90SBorislav Petkov alternative("", __stringify(__ASM_STAC), X86_FEATURE_SMAP); 5951ae4a2dSH. Peter Anvin } 6051ae4a2dSH. Peter Anvin 6151ae4a2dSH. Peter Anvin /* These macros can be used in asm() statements */ 6251ae4a2dSH. Peter Anvin #define ASM_CLAC \ 63*669f8a90SBorislav Petkov ALTERNATIVE("", __stringify(__ASM_CLAC), X86_FEATURE_SMAP) 6451ae4a2dSH. Peter Anvin #define ASM_STAC \ 65*669f8a90SBorislav Petkov ALTERNATIVE("", __stringify(__ASM_STAC), X86_FEATURE_SMAP) 6651ae4a2dSH. Peter Anvin 6751ae4a2dSH. Peter Anvin #else /* CONFIG_X86_SMAP */ 6851ae4a2dSH. Peter Anvin 6951ae4a2dSH. Peter Anvin static inline void clac(void) { } 7051ae4a2dSH. Peter Anvin static inline void stac(void) { } 7151ae4a2dSH. Peter Anvin 7251ae4a2dSH. Peter Anvin #define ASM_CLAC 7351ae4a2dSH. Peter Anvin #define ASM_STAC 7451ae4a2dSH. Peter Anvin 7551ae4a2dSH. Peter Anvin #endif /* CONFIG_X86_SMAP */ 7651ae4a2dSH. Peter Anvin 7751ae4a2dSH. Peter Anvin #endif /* __ASSEMBLY__ */ 7851ae4a2dSH. Peter Anvin 7951ae4a2dSH. Peter Anvin #endif /* _ASM_X86_SMAP_H */ 80