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