diff options
author | Ingo Molnar <mingo@kernel.org> | 2015-03-24 15:45:42 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2015-03-24 16:13:38 -0400 |
commit | 72d64cc76941cde45e65e2a5b9fb81d527963645 (patch) | |
tree | ceec49f6c4243249121fd6264f7bbd97cfa575e5 /arch | |
parent | dca5b52ad76b10c3adc29e2a006d4b1721c44a8d (diff) |
x86/asm: Further improve segment.h readability
- extend/clarify explanations where necessary
- move comments from macro values to before the macro, to
make them more consistent, and to reduce preprocessor overhead
- sort GDT index and selector values likewise by number
- use consistent, modern kernel coding style across the file
- capitalize consistently
- use consistent vertical spacing
- remove the unused get_limit() method (noticed by Andy Lutomirski)
No change in code (verified with objdump -d):
64-bit defconfig+kvmconfig:
815a129bc1f80de6445c1d8ca5b97cad vmlinux.o.before.asm
815a129bc1f80de6445c1d8ca5b97cad vmlinux.o.after.asm
32-bit defconfig+kvmconfig:
e659ef045159ddf41a0771b33a34aae5 vmlinux.o.before.asm
e659ef045159ddf41a0771b33a34aae5 vmlinux.o.after.asm
Acked-by: Andy Lutomirski <luto@amacapital.net>
Cc: Alexei Starovoitov <ast@plumgrid.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Will Drewry <wad@chromium.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/include/asm/segment.h | 242 |
1 files changed, 141 insertions, 101 deletions
diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h index 117028f58882..d394899e055c 100644 --- a/arch/x86/include/asm/segment.h +++ b/arch/x86/include/asm/segment.h | |||
@@ -3,8 +3,10 @@ | |||
3 | 3 | ||
4 | #include <linux/const.h> | 4 | #include <linux/const.h> |
5 | 5 | ||
6 | /* Constructor for a conventional segment GDT (or LDT) entry */ | 6 | /* |
7 | /* This is a macro so it can be used in initializers */ | 7 | * Constructor for a conventional segment GDT (or LDT) entry. |
8 | * This is a macro so it can be used in initializers. | ||
9 | */ | ||
8 | #define GDT_ENTRY(flags, base, limit) \ | 10 | #define GDT_ENTRY(flags, base, limit) \ |
9 | ((((base) & _AC(0xff000000,ULL)) << (56-24)) | \ | 11 | ((((base) & _AC(0xff000000,ULL)) << (56-24)) | \ |
10 | (((flags) & _AC(0x0000f0ff,ULL)) << 40) | \ | 12 | (((flags) & _AC(0x0000f0ff,ULL)) << 40) | \ |
@@ -12,71 +14,78 @@ | |||
12 | (((base) & _AC(0x00ffffff,ULL)) << 16) | \ | 14 | (((base) & _AC(0x00ffffff,ULL)) << 16) | \ |
13 | (((limit) & _AC(0x0000ffff,ULL)))) | 15 | (((limit) & _AC(0x0000ffff,ULL)))) |
14 | 16 | ||
15 | /* Simple and small GDT entries for booting only */ | 17 | /* Simple and small GDT entries for booting only: */ |
16 | 18 | ||
17 | #define GDT_ENTRY_BOOT_CS 2 | 19 | #define GDT_ENTRY_BOOT_CS 2 |
18 | #define GDT_ENTRY_BOOT_DS 3 | 20 | #define GDT_ENTRY_BOOT_DS 3 |
19 | #define GDT_ENTRY_BOOT_TSS 4 | 21 | #define GDT_ENTRY_BOOT_TSS 4 |
20 | #define __BOOT_CS (GDT_ENTRY_BOOT_CS * 8) | 22 | #define __BOOT_CS (GDT_ENTRY_BOOT_CS*8) |
21 | #define __BOOT_DS (GDT_ENTRY_BOOT_DS * 8) | 23 | #define __BOOT_DS (GDT_ENTRY_BOOT_DS*8) |
22 | #define __BOOT_TSS (GDT_ENTRY_BOOT_TSS * 8) | 24 | #define __BOOT_TSS (GDT_ENTRY_BOOT_TSS*8) |
23 | 25 | ||
24 | #define SEGMENT_RPL_MASK 0x3 /* | 26 | /* |
25 | * Bottom two bits of selector give the ring | 27 | * Bottom two bits of selector give the ring |
26 | * privilege level | 28 | * privilege level |
27 | */ | 29 | */ |
28 | #define SEGMENT_TI_MASK 0x4 /* Bit 2 is table indicator (LDT/GDT) */ | 30 | #define SEGMENT_RPL_MASK 0x3 |
29 | #define USER_RPL 0x3 /* User mode is privilege level 3 */ | 31 | |
30 | #define SEGMENT_LDT 0x4 /* LDT segment has TI set... */ | 32 | /* User mode is privilege level 3: */ |
31 | #define SEGMENT_GDT 0x0 /* ... GDT has it cleared */ | 33 | #define USER_RPL 0x3 |
34 | |||
35 | /* Bit 2 is Table Indicator (TI): selects between LDT or GDT */ | ||
36 | #define SEGMENT_TI_MASK 0x4 | ||
37 | /* LDT segment has TI set ... */ | ||
38 | #define SEGMENT_LDT 0x4 | ||
39 | /* ... GDT has it cleared */ | ||
40 | #define SEGMENT_GDT 0x0 | ||
32 | 41 | ||
33 | #ifdef CONFIG_X86_32 | 42 | #ifdef CONFIG_X86_32 |
34 | /* | 43 | /* |
35 | * The layout of the per-CPU GDT under Linux: | 44 | * The layout of the per-CPU GDT under Linux: |
36 | * | 45 | * |
37 | * 0 - null | 46 | * 0 - null <=== cacheline #1 |
38 | * 1 - reserved | 47 | * 1 - reserved |
39 | * 2 - reserved | 48 | * 2 - reserved |
40 | * 3 - reserved | 49 | * 3 - reserved |
41 | * | 50 | * |
42 | * 4 - unused <==== new cacheline | 51 | * 4 - unused <=== cacheline #2 |
43 | * 5 - unused | 52 | * 5 - unused |
44 | * | 53 | * |
45 | * ------- start of TLS (Thread-Local Storage) segments: | 54 | * ------- start of TLS (Thread-Local Storage) segments: |
46 | * | 55 | * |
47 | * 6 - TLS segment #1 [ glibc's TLS segment ] | 56 | * 6 - TLS segment #1 [ glibc's TLS segment ] |
48 | * 7 - TLS segment #2 [ Wine's %fs Win32 segment ] | 57 | * 7 - TLS segment #2 [ Wine's %fs Win32 segment ] |
49 | * 8 - TLS segment #3 | 58 | * 8 - TLS segment #3 <=== cacheline #3 |
50 | * 9 - reserved | 59 | * 9 - reserved |
51 | * 10 - reserved | 60 | * 10 - reserved |
52 | * 11 - reserved | 61 | * 11 - reserved |
53 | * | 62 | * |
54 | * ------- start of kernel segments: | 63 | * ------- start of kernel segments: |
55 | * | 64 | * |
56 | * 12 - kernel code segment <==== new cacheline | 65 | * 12 - kernel code segment <=== cacheline #4 |
57 | * 13 - kernel data segment | 66 | * 13 - kernel data segment |
58 | * 14 - default user CS | 67 | * 14 - default user CS |
59 | * 15 - default user DS | 68 | * 15 - default user DS |
60 | * 16 - TSS | 69 | * 16 - TSS <=== cacheline #5 |
61 | * 17 - LDT | 70 | * 17 - LDT |
62 | * 18 - PNPBIOS support (16->32 gate) | 71 | * 18 - PNPBIOS support (16->32 gate) |
63 | * 19 - PNPBIOS support | 72 | * 19 - PNPBIOS support |
64 | * 20 - PNPBIOS support | 73 | * 20 - PNPBIOS support <=== cacheline #6 |
65 | * 21 - PNPBIOS support | 74 | * 21 - PNPBIOS support |
66 | * 22 - PNPBIOS support | 75 | * 22 - PNPBIOS support |
67 | * 23 - APM BIOS support | 76 | * 23 - APM BIOS support |
68 | * 24 - APM BIOS support | 77 | * 24 - APM BIOS support <=== cacheline #7 |
69 | * 25 - APM BIOS support | 78 | * 25 - APM BIOS support |
70 | * | 79 | * |
71 | * 26 - ESPFIX small SS | 80 | * 26 - ESPFIX small SS |
72 | * 27 - per-cpu [ offset to per-cpu data area ] | 81 | * 27 - per-cpu [ offset to per-cpu data area ] |
73 | * 28 - stack_canary-20 [ for stack protector ] | 82 | * 28 - stack_canary-20 [ for stack protector ] <=== cacheline #8 |
74 | * 29 - unused | 83 | * 29 - unused |
75 | * 30 - unused | 84 | * 30 - unused |
76 | * 31 - TSS for double fault handler | 85 | * 31 - TSS for double fault handler |
77 | */ | 86 | */ |
78 | #define GDT_ENTRY_TLS_MIN 6 | 87 | #define GDT_ENTRY_TLS_MIN 6 |
79 | #define GDT_ENTRY_TLS_MAX (GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1) | 88 | #define GDT_ENTRY_TLS_MAX (GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1) |
80 | 89 | ||
81 | #define GDT_ENTRY_KERNEL_CS 12 | 90 | #define GDT_ENTRY_KERNEL_CS 12 |
82 | #define GDT_ENTRY_KERNEL_DS 13 | 91 | #define GDT_ENTRY_KERNEL_DS 13 |
@@ -97,96 +106,134 @@ | |||
97 | 106 | ||
98 | #define GDT_ENTRY_DOUBLEFAULT_TSS 31 | 107 | #define GDT_ENTRY_DOUBLEFAULT_TSS 31 |
99 | 108 | ||
109 | /* | ||
110 | * Number of entries in the GDT table: | ||
111 | */ | ||
112 | #define GDT_ENTRIES 32 | ||
113 | |||
114 | /* | ||
115 | * Segment selector values corresponding to the above entries: | ||
116 | */ | ||
117 | |||
100 | #define __KERNEL_CS (GDT_ENTRY_KERNEL_CS*8) | 118 | #define __KERNEL_CS (GDT_ENTRY_KERNEL_CS*8) |
101 | #define __KERNEL_DS (GDT_ENTRY_KERNEL_DS*8) | 119 | #define __KERNEL_DS (GDT_ENTRY_KERNEL_DS*8) |
102 | #define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS*8+3) | 120 | #define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS*8 + 3) |
103 | #define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS*8+3) | 121 | #define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS*8 + 3) |
104 | #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS*8) | 122 | #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS*8) |
105 | #define PNP_CS32 (GDT_ENTRY_PNPBIOS_CS32 * 8) /* segment for calling fn */ | 123 | |
106 | #define PNP_CS16 (GDT_ENTRY_PNPBIOS_CS16 * 8) /* code segment for BIOS */ | 124 | /* segment for calling fn: */ |
125 | #define PNP_CS32 (GDT_ENTRY_PNPBIOS_CS32*8) | ||
126 | /* code segment for BIOS: */ | ||
127 | #define PNP_CS16 (GDT_ENTRY_PNPBIOS_CS16*8) | ||
128 | |||
107 | /* "Is this PNP code selector (PNP_CS32 or PNP_CS16)?" */ | 129 | /* "Is this PNP code selector (PNP_CS32 or PNP_CS16)?" */ |
108 | #define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == PNP_CS32) | 130 | #define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == PNP_CS32) |
109 | #define PNP_DS (GDT_ENTRY_PNPBIOS_DS * 8) /* data segment for BIOS */ | 131 | |
110 | #define PNP_TS1 (GDT_ENTRY_PNPBIOS_TS1 * 8) /* transfer data segment */ | 132 | /* data segment for BIOS: */ |
111 | #define PNP_TS2 (GDT_ENTRY_PNPBIOS_TS2 * 8) /* another data segment */ | 133 | #define PNP_DS (GDT_ENTRY_PNPBIOS_DS*8) |
134 | /* transfer data segment: */ | ||
135 | #define PNP_TS1 (GDT_ENTRY_PNPBIOS_TS1*8) | ||
136 | /* another data segment: */ | ||
137 | #define PNP_TS2 (GDT_ENTRY_PNPBIOS_TS2*8) | ||
138 | |||
112 | #ifdef CONFIG_SMP | 139 | #ifdef CONFIG_SMP |
113 | #define __KERNEL_PERCPU (GDT_ENTRY_PERCPU*8) | 140 | # define __KERNEL_PERCPU (GDT_ENTRY_PERCPU*8) |
114 | #else | 141 | #else |
115 | #define __KERNEL_PERCPU 0 | 142 | # define __KERNEL_PERCPU 0 |
116 | #endif | 143 | #endif |
144 | |||
117 | #ifdef CONFIG_CC_STACKPROTECTOR | 145 | #ifdef CONFIG_CC_STACKPROTECTOR |
118 | #define __KERNEL_STACK_CANARY (GDT_ENTRY_STACK_CANARY*8) | 146 | # define __KERNEL_STACK_CANARY (GDT_ENTRY_STACK_CANARY*8) |
119 | #else | 147 | #else |
120 | #define __KERNEL_STACK_CANARY 0 | 148 | # define __KERNEL_STACK_CANARY 0 |
121 | #endif | 149 | #endif |
122 | 150 | ||
123 | #define GDT_ENTRIES 32 | ||
124 | |||
125 | #else /* 64-bit: */ | 151 | #else /* 64-bit: */ |
126 | 152 | ||
127 | #include <asm/cache.h> | 153 | #include <asm/cache.h> |
128 | 154 | ||
129 | #define GDT_ENTRY_KERNEL32_CS 1 | 155 | #define GDT_ENTRY_KERNEL32_CS 1 |
130 | #define GDT_ENTRY_KERNEL_CS 2 | 156 | #define GDT_ENTRY_KERNEL_CS 2 |
131 | #define GDT_ENTRY_KERNEL_DS 3 | 157 | #define GDT_ENTRY_KERNEL_DS 3 |
158 | |||
132 | /* | 159 | /* |
133 | * we cannot use the same code segment descriptor for user and kernel | 160 | * We cannot use the same code segment descriptor for user and kernel mode, |
134 | * -- not even in the long flat mode, because of different DPL /kkeil | 161 | * not even in long flat mode, because of different DPL. |
135 | * GDT layout to get 64bit syscall/sysret right. sysret hardcodes selectors: | 162 | * |
136 | * if returning to 32-bit userspace: cs = STAR.SYSRET_CS, | 163 | * GDT layout to get 64-bit SYSCALL/SYSRET support right. SYSRET hardcodes |
137 | * if returning to 64-bit userspace: cs = STAR.SYSRET_CS+16, | 164 | * selectors: |
165 | * | ||
166 | * if returning to 32-bit userspace: cs = STAR.SYSRET_CS, | ||
167 | * if returning to 64-bit userspace: cs = STAR.SYSRET_CS+16, | ||
168 | * | ||
138 | * ss = STAR.SYSRET_CS+8 (in either case) | 169 | * ss = STAR.SYSRET_CS+8 (in either case) |
170 | * | ||
139 | * thus USER_DS should be between 32-bit and 64-bit code selectors: | 171 | * thus USER_DS should be between 32-bit and 64-bit code selectors: |
140 | */ | 172 | */ |
141 | #define GDT_ENTRY_DEFAULT_USER32_CS 4 | 173 | #define GDT_ENTRY_DEFAULT_USER32_CS 4 |
142 | #define GDT_ENTRY_DEFAULT_USER_DS 5 | 174 | #define GDT_ENTRY_DEFAULT_USER_DS 5 |
143 | #define GDT_ENTRY_DEFAULT_USER_CS 6 | 175 | #define GDT_ENTRY_DEFAULT_USER_CS 6 |
176 | |||
177 | /* Needs two entries */ | ||
178 | #define GDT_ENTRY_TSS 8 | ||
179 | /* Needs two entries */ | ||
180 | #define GDT_ENTRY_LDT 10 | ||
144 | 181 | ||
145 | #define GDT_ENTRY_TSS 8 /* needs two entries */ | 182 | #define GDT_ENTRY_TLS_MIN 12 |
146 | #define GDT_ENTRY_LDT 10 /* needs two entries */ | 183 | #define GDT_ENTRY_TLS_MAX 14 |
147 | #define GDT_ENTRY_TLS_MIN 12 | ||
148 | #define GDT_ENTRY_TLS_MAX 14 | ||
149 | 184 | ||
150 | #define GDT_ENTRY_PER_CPU 15 /* abused to load per CPU data from limit */ | 185 | /* Abused to load per CPU data from limit */ |
186 | #define GDT_ENTRY_PER_CPU 15 | ||
151 | 187 | ||
152 | /* Selectors need to also have a correct RPL (+3 thingy) */ | 188 | /* |
153 | #define __KERNEL_CS (GDT_ENTRY_KERNEL_CS*8) | 189 | * Number of entries in the GDT table: |
154 | #define __KERNEL_DS (GDT_ENTRY_KERNEL_DS*8) | 190 | */ |
155 | #define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS*8+3) | 191 | #define GDT_ENTRIES 16 |
156 | #define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS*8+3) | ||
157 | #define __KERNEL32_CS (GDT_ENTRY_KERNEL32_CS*8) | ||
158 | #define __USER32_CS (GDT_ENTRY_DEFAULT_USER32_CS*8+3) | ||
159 | #define __USER32_DS __USER_DS | ||
160 | #define __PER_CPU_SEG (GDT_ENTRY_PER_CPU*8+3) | ||
161 | 192 | ||
162 | /* TLS indexes for 64bit - hardcoded in arch_prctl */ | 193 | /* |
163 | #define FS_TLS 0 | 194 | * Segment selector values corresponding to the above entries: |
164 | #define GS_TLS 1 | 195 | * |
196 | * Note, selectors also need to have a correct RPL, | ||
197 | * expressed with the +3 value for user-space selectors: | ||
198 | */ | ||
199 | #define __KERNEL32_CS (GDT_ENTRY_KERNEL32_CS*8) | ||
200 | #define __KERNEL_CS (GDT_ENTRY_KERNEL_CS*8) | ||
201 | #define __KERNEL_DS (GDT_ENTRY_KERNEL_DS*8) | ||
202 | #define __USER32_CS (GDT_ENTRY_DEFAULT_USER32_CS*8 + 3) | ||
203 | #define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS*8 + 3) | ||
204 | #define __USER32_DS __USER_DS | ||
205 | #define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS*8 + 3) | ||
206 | #define __PER_CPU_SEG (GDT_ENTRY_PER_CPU*8 + 3) | ||
165 | 207 | ||
166 | #define GS_TLS_SEL ((GDT_ENTRY_TLS_MIN+GS_TLS)*8 + 3) | 208 | /* TLS indexes for 64-bit - hardcoded in arch_prctl(): */ |
167 | #define FS_TLS_SEL ((GDT_ENTRY_TLS_MIN+FS_TLS)*8 + 3) | 209 | #define FS_TLS 0 |
210 | #define GS_TLS 1 | ||
168 | 211 | ||
169 | #define GDT_ENTRIES 16 | 212 | #define GS_TLS_SEL ((GDT_ENTRY_TLS_MIN+GS_TLS)*8 + 3) |
213 | #define FS_TLS_SEL ((GDT_ENTRY_TLS_MIN+FS_TLS)*8 + 3) | ||
170 | 214 | ||
171 | #endif | 215 | #endif |
172 | 216 | ||
173 | #ifndef CONFIG_PARAVIRT | 217 | #ifndef CONFIG_PARAVIRT |
174 | #define get_kernel_rpl() 0 | 218 | # define get_kernel_rpl() 0 |
175 | #endif | 219 | #endif |
176 | 220 | ||
177 | #define IDT_ENTRIES 256 | 221 | #define IDT_ENTRIES 256 |
178 | #define NUM_EXCEPTION_VECTORS 32 | 222 | #define NUM_EXCEPTION_VECTORS 32 |
179 | /* Bitmask of exception vectors which push an error code on the stack */ | 223 | |
180 | #define EXCEPTION_ERRCODE_MASK 0x00027d00 | 224 | /* Bitmask of exception vectors which push an error code on the stack: */ |
181 | #define GDT_SIZE (GDT_ENTRIES * 8) | 225 | #define EXCEPTION_ERRCODE_MASK 0x00027d00 |
182 | #define GDT_ENTRY_TLS_ENTRIES 3 | 226 | |
183 | #define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES * 8) | 227 | #define GDT_SIZE (GDT_ENTRIES*8) |
228 | #define GDT_ENTRY_TLS_ENTRIES 3 | ||
229 | #define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES* 8) | ||
184 | 230 | ||
185 | #ifdef __KERNEL__ | 231 | #ifdef __KERNEL__ |
186 | #ifndef __ASSEMBLY__ | 232 | #ifndef __ASSEMBLY__ |
233 | |||
187 | extern const char early_idt_handlers[NUM_EXCEPTION_VECTORS][2+2+5]; | 234 | extern const char early_idt_handlers[NUM_EXCEPTION_VECTORS][2+2+5]; |
188 | #ifdef CONFIG_TRACING | 235 | #ifdef CONFIG_TRACING |
189 | #define trace_early_idt_handlers early_idt_handlers | 236 | # define trace_early_idt_handlers early_idt_handlers |
190 | #endif | 237 | #endif |
191 | 238 | ||
192 | /* | 239 | /* |
@@ -211,37 +258,30 @@ do { \ | |||
211 | } while (0) | 258 | } while (0) |
212 | 259 | ||
213 | /* | 260 | /* |
214 | * Save a segment register away | 261 | * Save a segment register away: |
215 | */ | 262 | */ |
216 | #define savesegment(seg, value) \ | 263 | #define savesegment(seg, value) \ |
217 | asm("mov %%" #seg ",%0":"=r" (value) : : "memory") | 264 | asm("mov %%" #seg ",%0":"=r" (value) : : "memory") |
218 | 265 | ||
219 | /* | 266 | /* |
220 | * x86_32 user gs accessors. | 267 | * x86-32 user GS accessors: |
221 | */ | 268 | */ |
222 | #ifdef CONFIG_X86_32 | 269 | #ifdef CONFIG_X86_32 |
223 | #ifdef CONFIG_X86_32_LAZY_GS | 270 | # ifdef CONFIG_X86_32_LAZY_GS |
224 | #define get_user_gs(regs) (u16)({unsigned long v; savesegment(gs, v); v;}) | 271 | # define get_user_gs(regs) (u16)({ unsigned long v; savesegment(gs, v); v; }) |
225 | #define set_user_gs(regs, v) loadsegment(gs, (unsigned long)(v)) | 272 | # define set_user_gs(regs, v) loadsegment(gs, (unsigned long)(v)) |
226 | #define task_user_gs(tsk) ((tsk)->thread.gs) | 273 | # define task_user_gs(tsk) ((tsk)->thread.gs) |
227 | #define lazy_save_gs(v) savesegment(gs, (v)) | 274 | # define lazy_save_gs(v) savesegment(gs, (v)) |
228 | #define lazy_load_gs(v) loadsegment(gs, (v)) | 275 | # define lazy_load_gs(v) loadsegment(gs, (v)) |
229 | #else /* X86_32_LAZY_GS */ | 276 | # else /* X86_32_LAZY_GS */ |
230 | #define get_user_gs(regs) (u16)((regs)->gs) | 277 | # define get_user_gs(regs) (u16)((regs)->gs) |
231 | #define set_user_gs(regs, v) do { (regs)->gs = (v); } while (0) | 278 | # define set_user_gs(regs, v) do { (regs)->gs = (v); } while (0) |
232 | #define task_user_gs(tsk) (task_pt_regs(tsk)->gs) | 279 | # define task_user_gs(tsk) (task_pt_regs(tsk)->gs) |
233 | #define lazy_save_gs(v) do { } while (0) | 280 | # define lazy_save_gs(v) do { } while (0) |
234 | #define lazy_load_gs(v) do { } while (0) | 281 | # define lazy_load_gs(v) do { } while (0) |
235 | #endif /* X86_32_LAZY_GS */ | 282 | # endif /* X86_32_LAZY_GS */ |
236 | #endif /* X86_32 */ | 283 | #endif /* X86_32 */ |
237 | 284 | ||
238 | static inline unsigned long get_limit(unsigned long segment) | ||
239 | { | ||
240 | unsigned long __limit; | ||
241 | asm("lsll %1,%0" : "=r" (__limit) : "r" (segment)); | ||
242 | return __limit + 1; | ||
243 | } | ||
244 | |||
245 | #endif /* !__ASSEMBLY__ */ | 285 | #endif /* !__ASSEMBLY__ */ |
246 | #endif /* __KERNEL__ */ | 286 | #endif /* __KERNEL__ */ |
247 | 287 | ||