1
2#ifndef _ASM_X86_SEGMENT_H
3#define _ASM_X86_SEGMENT_H
4
5#include <linux/const.h>
6#include <asm/alternative.h>
7
8
9
10
11
12#define GDT_ENTRY(flags, base, limit) \
13 ((((base) & _AC(0xff000000,ULL)) << (56-24)) | \
14 (((flags) & _AC(0x0000f0ff,ULL)) << 40) | \
15 (((limit) & _AC(0x000f0000,ULL)) << (48-16)) | \
16 (((base) & _AC(0x00ffffff,ULL)) << 16) | \
17 (((limit) & _AC(0x0000ffff,ULL))))
18
19
20
21#define GDT_ENTRY_BOOT_CS 2
22#define GDT_ENTRY_BOOT_DS 3
23#define GDT_ENTRY_BOOT_TSS 4
24#define __BOOT_CS (GDT_ENTRY_BOOT_CS*8)
25#define __BOOT_DS (GDT_ENTRY_BOOT_DS*8)
26#define __BOOT_TSS (GDT_ENTRY_BOOT_TSS*8)
27
28
29
30
31
32#define SEGMENT_RPL_MASK 0x3
33
34
35#define USER_RPL 0x3
36
37
38#define SEGMENT_TI_MASK 0x4
39
40#define SEGMENT_LDT 0x4
41
42#define SEGMENT_GDT 0x0
43
44#define GDT_ENTRY_INVALID_SEG 0
45
46#ifdef CONFIG_X86_32
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91#define GDT_ENTRY_TLS_MIN 6
92#define GDT_ENTRY_TLS_MAX (GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1)
93
94#define GDT_ENTRY_KERNEL_CS 12
95#define GDT_ENTRY_KERNEL_DS 13
96#define GDT_ENTRY_DEFAULT_USER_CS 14
97#define GDT_ENTRY_DEFAULT_USER_DS 15
98#define GDT_ENTRY_TSS 16
99#define GDT_ENTRY_LDT 17
100#define GDT_ENTRY_PNPBIOS_CS32 18
101#define GDT_ENTRY_PNPBIOS_CS16 19
102#define GDT_ENTRY_PNPBIOS_DS 20
103#define GDT_ENTRY_PNPBIOS_TS1 21
104#define GDT_ENTRY_PNPBIOS_TS2 22
105#define GDT_ENTRY_APMBIOS_BASE 23
106
107#define GDT_ENTRY_ESPFIX_SS 26
108#define GDT_ENTRY_PERCPU 27
109#define GDT_ENTRY_STACK_CANARY 28
110
111#define GDT_ENTRY_DOUBLEFAULT_TSS 31
112
113
114
115
116#define GDT_ENTRIES 32
117
118
119
120
121
122#define __KERNEL_CS (GDT_ENTRY_KERNEL_CS*8)
123#define __KERNEL_DS (GDT_ENTRY_KERNEL_DS*8)
124#define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS*8 + 3)
125#define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS*8 + 3)
126#define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS*8)
127
128
129#define PNP_CS32 (GDT_ENTRY_PNPBIOS_CS32*8)
130
131#define PNP_CS16 (GDT_ENTRY_PNPBIOS_CS16*8)
132
133
134#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == PNP_CS32)
135
136
137#define PNP_DS (GDT_ENTRY_PNPBIOS_DS*8)
138
139#define PNP_TS1 (GDT_ENTRY_PNPBIOS_TS1*8)
140
141#define PNP_TS2 (GDT_ENTRY_PNPBIOS_TS2*8)
142
143#ifdef CONFIG_SMP
144# define __KERNEL_PERCPU (GDT_ENTRY_PERCPU*8)
145#else
146# define __KERNEL_PERCPU 0
147#endif
148
149#ifdef CONFIG_STACKPROTECTOR
150# define __KERNEL_STACK_CANARY (GDT_ENTRY_STACK_CANARY*8)
151#else
152# define __KERNEL_STACK_CANARY 0
153#endif
154
155#else
156
157#include <asm/cache.h>
158
159#define GDT_ENTRY_KERNEL32_CS 1
160#define GDT_ENTRY_KERNEL_CS 2
161#define GDT_ENTRY_KERNEL_DS 3
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177#define GDT_ENTRY_DEFAULT_USER32_CS 4
178#define GDT_ENTRY_DEFAULT_USER_DS 5
179#define GDT_ENTRY_DEFAULT_USER_CS 6
180
181
182#define GDT_ENTRY_TSS 8
183
184#define GDT_ENTRY_LDT 10
185
186#define GDT_ENTRY_TLS_MIN 12
187#define GDT_ENTRY_TLS_MAX 14
188
189
190#define GDT_ENTRY_PER_CPU 15
191
192
193
194
195#define GDT_ENTRIES 16
196
197
198
199
200
201
202
203#define __KERNEL32_CS (GDT_ENTRY_KERNEL32_CS*8)
204#define __KERNEL_CS (GDT_ENTRY_KERNEL_CS*8)
205#define __KERNEL_DS (GDT_ENTRY_KERNEL_DS*8)
206#define __USER32_CS (GDT_ENTRY_DEFAULT_USER32_CS*8 + 3)
207#define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS*8 + 3)
208#define __USER32_DS __USER_DS
209#define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS*8 + 3)
210#define __PER_CPU_SEG (GDT_ENTRY_PER_CPU*8 + 3)
211
212#endif
213
214#ifndef CONFIG_PARAVIRT
215# define get_kernel_rpl() 0
216#endif
217
218#define IDT_ENTRIES 256
219#define NUM_EXCEPTION_VECTORS 32
220
221
222#define EXCEPTION_ERRCODE_MASK 0x00027d00
223
224#define GDT_SIZE (GDT_ENTRIES*8)
225#define GDT_ENTRY_TLS_ENTRIES 3
226#define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES* 8)
227
228#ifdef __KERNEL__
229
230
231
232
233
234
235
236
237#define EARLY_IDT_HANDLER_SIZE 9
238
239
240
241
242
243
244
245#define XEN_EARLY_IDT_HANDLER_SIZE 8
246
247#ifndef __ASSEMBLY__
248
249extern const char early_idt_handler_array[NUM_EXCEPTION_VECTORS][EARLY_IDT_HANDLER_SIZE];
250extern void early_ignore_irq(void);
251
252#if defined(CONFIG_X86_64) && defined(CONFIG_XEN_PV)
253extern const char xen_early_idt_handler_array[NUM_EXCEPTION_VECTORS][XEN_EARLY_IDT_HANDLER_SIZE];
254#endif
255
256
257
258
259
260
261
262
263#define __loadsegment_simple(seg, value) \
264do { \
265 unsigned short __val = (value); \
266 \
267 asm volatile(" \n" \
268 "1: movl %k0,%%" #seg " \n" \
269 \
270 ".section .fixup,\"ax\" \n" \
271 "2: xorl %k0,%k0 \n" \
272 " jmp 1b \n" \
273 ".previous \n" \
274 \
275 _ASM_EXTABLE(1b, 2b) \
276 \
277 : "+r" (__val) : : "memory"); \
278} while (0)
279
280#define __loadsegment_ss(value) __loadsegment_simple(ss, (value))
281#define __loadsegment_ds(value) __loadsegment_simple(ds, (value))
282#define __loadsegment_es(value) __loadsegment_simple(es, (value))
283
284#ifdef CONFIG_X86_32
285
286
287
288
289
290#define __loadsegment_fs(value) __loadsegment_simple(fs, (value))
291#define __loadsegment_gs(value) __loadsegment_simple(gs, (value))
292
293#else
294
295static inline void __loadsegment_fs(unsigned short value)
296{
297 asm volatile(" \n"
298 "1: movw %0, %%fs \n"
299 "2: \n"
300
301 _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_clear_fs)
302
303 : : "rm" (value) : "memory");
304}
305
306
307
308#endif
309
310#define loadsegment(seg, value) __loadsegment_ ## seg (value)
311
312
313
314
315#define savesegment(seg, value) \
316 asm("mov %%" #seg ",%0":"=r" (value) : : "memory")
317
318
319
320
321#ifdef CONFIG_X86_32
322# ifdef CONFIG_X86_32_LAZY_GS
323# define get_user_gs(regs) (u16)({ unsigned long v; savesegment(gs, v); v; })
324# define set_user_gs(regs, v) loadsegment(gs, (unsigned long)(v))
325# define task_user_gs(tsk) ((tsk)->thread.gs)
326# define lazy_save_gs(v) savesegment(gs, (v))
327# define lazy_load_gs(v) loadsegment(gs, (v))
328# else
329# define get_user_gs(regs) (u16)((regs)->gs)
330# define set_user_gs(regs, v) do { (regs)->gs = (v); } while (0)
331# define task_user_gs(tsk) (task_pt_regs(tsk)->gs)
332# define lazy_save_gs(v) do { } while (0)
333# define lazy_load_gs(v) do { } while (0)
334# endif
335#endif
336
337#endif
338#endif
339
340#endif
341