1#ifndef _ASM_X86_SEGMENT_H
2#define _ASM_X86_SEGMENT_H
3
4#include <linux/const.h>
5
6
7
8#define GDT_ENTRY(flags, base, limit) \
9 ((((base) & _AC(0xff000000,ULL)) << (56-24)) | \
10 (((flags) & _AC(0x0000f0ff,ULL)) << 40) | \
11 (((limit) & _AC(0x000f0000,ULL)) << (48-16)) | \
12 (((base) & _AC(0x00ffffff,ULL)) << 16) | \
13 (((limit) & _AC(0x0000ffff,ULL))))
14
15
16
17#define GDT_ENTRY_BOOT_CS 2
18#define __BOOT_CS (GDT_ENTRY_BOOT_CS * 8)
19
20#define GDT_ENTRY_BOOT_DS (GDT_ENTRY_BOOT_CS + 1)
21#define __BOOT_DS (GDT_ENTRY_BOOT_DS * 8)
22
23#define GDT_ENTRY_BOOT_TSS (GDT_ENTRY_BOOT_CS + 2)
24#define __BOOT_TSS (GDT_ENTRY_BOOT_TSS * 8)
25
26#ifdef CONFIG_X86_32
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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#define GDT_ENTRY_TLS_MIN 6
72#define GDT_ENTRY_TLS_MAX (GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1)
73
74#define GDT_ENTRY_DEFAULT_USER_CS 14
75
76#define GDT_ENTRY_DEFAULT_USER_DS 15
77
78#define GDT_ENTRY_KERNEL_BASE (12)
79
80#define GDT_ENTRY_KERNEL_CS (GDT_ENTRY_KERNEL_BASE+0)
81
82#define GDT_ENTRY_KERNEL_DS (GDT_ENTRY_KERNEL_BASE+1)
83
84#define GDT_ENTRY_TSS (GDT_ENTRY_KERNEL_BASE+4)
85#define GDT_ENTRY_LDT (GDT_ENTRY_KERNEL_BASE+5)
86
87#define GDT_ENTRY_PNPBIOS_BASE (GDT_ENTRY_KERNEL_BASE+6)
88#define GDT_ENTRY_APMBIOS_BASE (GDT_ENTRY_KERNEL_BASE+11)
89
90#define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE+14)
91#define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS*8)
92
93#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE+15)
94#ifdef CONFIG_SMP
95#define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
96#else
97#define __KERNEL_PERCPU 0
98#endif
99
100#define GDT_ENTRY_STACK_CANARY (GDT_ENTRY_KERNEL_BASE+16)
101#ifdef CONFIG_CC_STACKPROTECTOR
102#define __KERNEL_STACK_CANARY (GDT_ENTRY_STACK_CANARY*8)
103#else
104#define __KERNEL_STACK_CANARY 0
105#endif
106
107#define GDT_ENTRY_DOUBLEFAULT_TSS 31
108
109
110
111
112#define GDT_ENTRIES 32
113
114
115#define GDT_ENTRY_PNPBIOS_CS32 (GDT_ENTRY_PNPBIOS_BASE + 0)
116#define GDT_ENTRY_PNPBIOS_CS16 (GDT_ENTRY_PNPBIOS_BASE + 1)
117#define GDT_ENTRY_PNPBIOS_DS (GDT_ENTRY_PNPBIOS_BASE + 2)
118#define GDT_ENTRY_PNPBIOS_TS1 (GDT_ENTRY_PNPBIOS_BASE + 3)
119#define GDT_ENTRY_PNPBIOS_TS2 (GDT_ENTRY_PNPBIOS_BASE + 4)
120
121
122#define PNP_CS32 (GDT_ENTRY_PNPBIOS_CS32 * 8)
123#define PNP_CS16 (GDT_ENTRY_PNPBIOS_CS16 * 8)
124#define PNP_DS (GDT_ENTRY_PNPBIOS_DS * 8)
125#define PNP_TS1 (GDT_ENTRY_PNPBIOS_TS1 * 8)
126#define PNP_TS2 (GDT_ENTRY_PNPBIOS_TS2 * 8)
127
128
129#define SEGMENT_RPL_MASK 0x3
130
131#define SEGMENT_TI_MASK 0x4
132
133
134#define USER_RPL 0x3
135
136#define SEGMENT_LDT 0x4
137#define SEGMENT_GDT 0x0
138
139
140
141
142
143
144#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
145
146
147#else
148#include <asm/cache.h>
149
150#define GDT_ENTRY_KERNEL32_CS 1
151#define GDT_ENTRY_KERNEL_CS 2
152#define GDT_ENTRY_KERNEL_DS 3
153
154#define __KERNEL32_CS (GDT_ENTRY_KERNEL32_CS * 8)
155
156
157
158
159
160
161
162#define GDT_ENTRY_DEFAULT_USER32_CS 4
163#define GDT_ENTRY_DEFAULT_USER_DS 5
164#define GDT_ENTRY_DEFAULT_USER_CS 6
165#define __USER32_CS (GDT_ENTRY_DEFAULT_USER32_CS*8+3)
166#define __USER32_DS __USER_DS
167
168#define GDT_ENTRY_TSS 8
169#define GDT_ENTRY_LDT 10
170#define GDT_ENTRY_TLS_MIN 12
171#define GDT_ENTRY_TLS_MAX 14
172
173#define GDT_ENTRY_PER_CPU 15
174#define __PER_CPU_SEG (GDT_ENTRY_PER_CPU * 8 + 3)
175
176
177#define FS_TLS 0
178#define GS_TLS 1
179
180#define GS_TLS_SEL ((GDT_ENTRY_TLS_MIN+GS_TLS)*8 + 3)
181#define FS_TLS_SEL ((GDT_ENTRY_TLS_MIN+FS_TLS)*8 + 3)
182
183#define GDT_ENTRIES 16
184
185#endif
186
187#define __KERNEL_CS (GDT_ENTRY_KERNEL_CS*8)
188#define __KERNEL_DS (GDT_ENTRY_KERNEL_DS*8)
189#define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS*8+3)
190#define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS*8+3)
191#ifndef CONFIG_PARAVIRT
192#define get_kernel_rpl() 0
193#endif
194
195
196#define USER_RPL 0x3
197
198#define SEGMENT_LDT 0x4
199#define SEGMENT_GDT 0x0
200
201
202#define SEGMENT_RPL_MASK 0x3
203
204#define SEGMENT_TI_MASK 0x4
205
206#define IDT_ENTRIES 256
207#define NUM_EXCEPTION_VECTORS 32
208
209#define EXCEPTION_ERRCODE_MASK 0x00027d00
210#define GDT_SIZE (GDT_ENTRIES * 8)
211#define GDT_ENTRY_TLS_ENTRIES 3
212#define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES * 8)
213
214#ifdef __KERNEL__
215#ifndef __ASSEMBLY__
216extern const char early_idt_handlers[NUM_EXCEPTION_VECTORS][2+2+5];
217
218
219
220
221
222#define loadsegment(seg, value) \
223do { \
224 unsigned short __val = (value); \
225 \
226 asm volatile(" \n" \
227 "1: movl %k0,%%" #seg " \n" \
228 \
229 ".section .fixup,\"ax\" \n" \
230 "2: xorl %k0,%k0 \n" \
231 " jmp 1b \n" \
232 ".previous \n" \
233 \
234 _ASM_EXTABLE(1b, 2b) \
235 \
236 : "+r" (__val) : : "memory"); \
237} while (0)
238
239
240
241
242#define savesegment(seg, value) \
243 asm("mov %%" #seg ",%0":"=r" (value) : : "memory")
244
245
246
247
248#ifdef CONFIG_X86_32
249#ifdef CONFIG_X86_32_LAZY_GS
250#define get_user_gs(regs) (u16)({unsigned long v; savesegment(gs, v); v;})
251#define set_user_gs(regs, v) loadsegment(gs, (unsigned long)(v))
252#define task_user_gs(tsk) ((tsk)->thread.gs)
253#define lazy_save_gs(v) savesegment(gs, (v))
254#define lazy_load_gs(v) loadsegment(gs, (v))
255#else
256#define get_user_gs(regs) (u16)((regs)->gs)
257#define set_user_gs(regs, v) do { (regs)->gs = (v); } while (0)
258#define task_user_gs(tsk) (task_pt_regs(tsk)->gs)
259#define lazy_save_gs(v) do { } while (0)
260#define lazy_load_gs(v) do { } while (0)
261#endif
262#endif
263
264static inline unsigned long get_limit(unsigned long segment)
265{
266 unsigned long __limit;
267 asm("lsll %1,%0" : "=r" (__limit) : "r" (segment));
268 return __limit + 1;
269}
270
271#endif
272#endif
273
274#endif
275