Commit | Line | Data |
---|---|---|
51ae4a2d PA |
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 ; \ | |
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 ; \ | |
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 | ||
63bcff2a | 61 | static __always_inline void clac(void) |
51ae4a2d PA |
62 | { |
63 | /* Note: a barrier is implicit in alternative() */ | |
64 | alternative(ASM_NOP3, __stringify(__ASM_CLAC), X86_FEATURE_SMAP); | |
65 | } | |
66 | ||
63bcff2a | 67 | static __always_inline void stac(void) |
51ae4a2d PA |
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 */ |