xref: /linux/arch/x86/include/asm/smap.h (revision 669f8a900198599d3c2e2e463bafe12d30d96507)
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