xref: /linux/arch/x86/include/asm/segment.h (revision f05e798ad4c09255f590f5b2c00a7ca6c172f983)
11965aae3SH. Peter Anvin #ifndef _ASM_X86_SEGMENT_H
21965aae3SH. Peter Anvin #define _ASM_X86_SEGMENT_H
3bb898558SAl Viro 
4014eea51SH. Peter Anvin #include <linux/const.h>
5014eea51SH. Peter Anvin 
6bb898558SAl Viro /* Constructor for a conventional segment GDT (or LDT) entry */
7bb898558SAl Viro /* This is a macro so it can be used in initializers */
8bb898558SAl Viro #define GDT_ENTRY(flags, base, limit)			\
9014eea51SH. Peter Anvin 	((((base)  & _AC(0xff000000,ULL)) << (56-24)) |	\
10014eea51SH. Peter Anvin 	 (((flags) & _AC(0x0000f0ff,ULL)) << 40) |	\
11014eea51SH. Peter Anvin 	 (((limit) & _AC(0x000f0000,ULL)) << (48-16)) |	\
12014eea51SH. Peter Anvin 	 (((base)  & _AC(0x00ffffff,ULL)) << 16) |	\
13014eea51SH. Peter Anvin 	 (((limit) & _AC(0x0000ffff,ULL))))
14bb898558SAl Viro 
15bb898558SAl Viro /* Simple and small GDT entries for booting only */
16bb898558SAl Viro 
17bb898558SAl Viro #define GDT_ENTRY_BOOT_CS	2
18bb898558SAl Viro #define __BOOT_CS		(GDT_ENTRY_BOOT_CS * 8)
19bb898558SAl Viro 
20bb898558SAl Viro #define GDT_ENTRY_BOOT_DS	(GDT_ENTRY_BOOT_CS + 1)
21bb898558SAl Viro #define __BOOT_DS		(GDT_ENTRY_BOOT_DS * 8)
22bb898558SAl Viro 
23bb898558SAl Viro #define GDT_ENTRY_BOOT_TSS	(GDT_ENTRY_BOOT_CS + 2)
24bb898558SAl Viro #define __BOOT_TSS		(GDT_ENTRY_BOOT_TSS * 8)
25bb898558SAl Viro 
26bb898558SAl Viro #ifdef CONFIG_X86_32
27bb898558SAl Viro /*
28bb898558SAl Viro  * The layout of the per-CPU GDT under Linux:
29bb898558SAl Viro  *
30bb898558SAl Viro  *   0 - null
31bb898558SAl Viro  *   1 - reserved
32bb898558SAl Viro  *   2 - reserved
33bb898558SAl Viro  *   3 - reserved
34bb898558SAl Viro  *
35bb898558SAl Viro  *   4 - unused			<==== new cacheline
36bb898558SAl Viro  *   5 - unused
37bb898558SAl Viro  *
38bb898558SAl Viro  *  ------- start of TLS (Thread-Local Storage) segments:
39bb898558SAl Viro  *
40bb898558SAl Viro  *   6 - TLS segment #1			[ glibc's TLS segment ]
41bb898558SAl Viro  *   7 - TLS segment #2			[ Wine's %fs Win32 segment ]
42bb898558SAl Viro  *   8 - TLS segment #3
43bb898558SAl Viro  *   9 - reserved
44bb898558SAl Viro  *  10 - reserved
45bb898558SAl Viro  *  11 - reserved
46bb898558SAl Viro  *
47bb898558SAl Viro  *  ------- start of kernel segments:
48bb898558SAl Viro  *
49bb898558SAl Viro  *  12 - kernel code segment		<==== new cacheline
50bb898558SAl Viro  *  13 - kernel data segment
51bb898558SAl Viro  *  14 - default user CS
52bb898558SAl Viro  *  15 - default user DS
53bb898558SAl Viro  *  16 - TSS
54bb898558SAl Viro  *  17 - LDT
55bb898558SAl Viro  *  18 - PNPBIOS support (16->32 gate)
56bb898558SAl Viro  *  19 - PNPBIOS support
57bb898558SAl Viro  *  20 - PNPBIOS support
58bb898558SAl Viro  *  21 - PNPBIOS support
59bb898558SAl Viro  *  22 - PNPBIOS support
60bb898558SAl Viro  *  23 - APM BIOS support
61bb898558SAl Viro  *  24 - APM BIOS support
62bb898558SAl Viro  *  25 - APM BIOS support
63bb898558SAl Viro  *
64bb898558SAl Viro  *  26 - ESPFIX small SS
65bb898558SAl Viro  *  27 - per-cpu			[ offset to per-cpu data area ]
6660a5317fSTejun Heo  *  28 - stack_canary-20		[ for stack protector ]
67bb898558SAl Viro  *  29 - unused
68bb898558SAl Viro  *  30 - unused
69bb898558SAl Viro  *  31 - TSS for double fault handler
70bb898558SAl Viro  */
71bb898558SAl Viro #define GDT_ENTRY_TLS_MIN	6
72bb898558SAl Viro #define GDT_ENTRY_TLS_MAX 	(GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1)
73bb898558SAl Viro 
74bb898558SAl Viro #define GDT_ENTRY_DEFAULT_USER_CS	14
75bb898558SAl Viro 
76bb898558SAl Viro #define GDT_ENTRY_DEFAULT_USER_DS	15
77bb898558SAl Viro 
783234282fSJan Beulich #define GDT_ENTRY_KERNEL_BASE		(12)
79bb898558SAl Viro 
80bb898558SAl Viro #define GDT_ENTRY_KERNEL_CS		(GDT_ENTRY_KERNEL_BASE+0)
81bb898558SAl Viro 
82bb898558SAl Viro #define GDT_ENTRY_KERNEL_DS		(GDT_ENTRY_KERNEL_BASE+1)
83bb898558SAl Viro 
84bb898558SAl Viro #define GDT_ENTRY_TSS			(GDT_ENTRY_KERNEL_BASE+4)
85bb898558SAl Viro #define GDT_ENTRY_LDT			(GDT_ENTRY_KERNEL_BASE+5)
86bb898558SAl Viro 
87bb898558SAl Viro #define GDT_ENTRY_PNPBIOS_BASE		(GDT_ENTRY_KERNEL_BASE+6)
88bb898558SAl Viro #define GDT_ENTRY_APMBIOS_BASE		(GDT_ENTRY_KERNEL_BASE+11)
89bb898558SAl Viro 
90bb898558SAl Viro #define GDT_ENTRY_ESPFIX_SS		(GDT_ENTRY_KERNEL_BASE+14)
91bb898558SAl Viro #define __ESPFIX_SS			(GDT_ENTRY_ESPFIX_SS*8)
92bb898558SAl Viro 
93bb898558SAl Viro #define GDT_ENTRY_PERCPU		(GDT_ENTRY_KERNEL_BASE+15)
94bb898558SAl Viro #ifdef CONFIG_SMP
95bb898558SAl Viro #define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
96bb898558SAl Viro #else
97bb898558SAl Viro #define __KERNEL_PERCPU 0
98bb898558SAl Viro #endif
99bb898558SAl Viro 
10060a5317fSTejun Heo #define GDT_ENTRY_STACK_CANARY		(GDT_ENTRY_KERNEL_BASE+16)
10160a5317fSTejun Heo #ifdef CONFIG_CC_STACKPROTECTOR
10260a5317fSTejun Heo #define __KERNEL_STACK_CANARY		(GDT_ENTRY_STACK_CANARY*8)
10360a5317fSTejun Heo #else
10460a5317fSTejun Heo #define __KERNEL_STACK_CANARY		0
10560a5317fSTejun Heo #endif
10660a5317fSTejun Heo 
107bb898558SAl Viro #define GDT_ENTRY_DOUBLEFAULT_TSS	31
108bb898558SAl Viro 
109bb898558SAl Viro /*
110bb898558SAl Viro  * The GDT has 32 entries
111bb898558SAl Viro  */
112bb898558SAl Viro #define GDT_ENTRIES 32
113bb898558SAl Viro 
114bb898558SAl Viro /* The PnP BIOS entries in the GDT */
115bb898558SAl Viro #define GDT_ENTRY_PNPBIOS_CS32		(GDT_ENTRY_PNPBIOS_BASE + 0)
116bb898558SAl Viro #define GDT_ENTRY_PNPBIOS_CS16		(GDT_ENTRY_PNPBIOS_BASE + 1)
117bb898558SAl Viro #define GDT_ENTRY_PNPBIOS_DS		(GDT_ENTRY_PNPBIOS_BASE + 2)
118bb898558SAl Viro #define GDT_ENTRY_PNPBIOS_TS1		(GDT_ENTRY_PNPBIOS_BASE + 3)
119bb898558SAl Viro #define GDT_ENTRY_PNPBIOS_TS2		(GDT_ENTRY_PNPBIOS_BASE + 4)
120bb898558SAl Viro 
121bb898558SAl Viro /* The PnP BIOS selectors */
122bb898558SAl Viro #define PNP_CS32   (GDT_ENTRY_PNPBIOS_CS32 * 8)	/* segment for calling fn */
123bb898558SAl Viro #define PNP_CS16   (GDT_ENTRY_PNPBIOS_CS16 * 8)	/* code segment for BIOS */
124bb898558SAl Viro #define PNP_DS     (GDT_ENTRY_PNPBIOS_DS * 8)	/* data segment for BIOS */
125bb898558SAl Viro #define PNP_TS1    (GDT_ENTRY_PNPBIOS_TS1 * 8)	/* transfer data segment */
126bb898558SAl Viro #define PNP_TS2    (GDT_ENTRY_PNPBIOS_TS2 * 8)	/* another data segment */
127bb898558SAl Viro 
128bb898558SAl Viro /* Bottom two bits of selector give the ring privilege level */
129bb898558SAl Viro #define SEGMENT_RPL_MASK	0x3
130bb898558SAl Viro /* Bit 2 is table indicator (LDT/GDT) */
131bb898558SAl Viro #define SEGMENT_TI_MASK		0x4
132bb898558SAl Viro 
133bb898558SAl Viro /* User mode is privilege level 3 */
134bb898558SAl Viro #define USER_RPL		0x3
135bb898558SAl Viro /* LDT segment has TI set, GDT has it cleared */
136bb898558SAl Viro #define SEGMENT_LDT		0x4
137bb898558SAl Viro #define SEGMENT_GDT		0x0
138bb898558SAl Viro 
139bb898558SAl Viro /*
140bb898558SAl Viro  * Matching rules for certain types of segments.
141bb898558SAl Viro  */
142bb898558SAl Viro 
143bb898558SAl Viro /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
144bb898558SAl Viro #define SEGMENT_IS_PNP_CODE(x)   (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
145bb898558SAl Viro 
146bb898558SAl Viro 
147bb898558SAl Viro #else
148bb898558SAl Viro #include <asm/cache.h>
149bb898558SAl Viro 
150bb898558SAl Viro #define GDT_ENTRY_KERNEL32_CS 1
151bb898558SAl Viro #define GDT_ENTRY_KERNEL_CS 2
152bb898558SAl Viro #define GDT_ENTRY_KERNEL_DS 3
153bb898558SAl Viro 
154bb898558SAl Viro #define __KERNEL32_CS   (GDT_ENTRY_KERNEL32_CS * 8)
155bb898558SAl Viro 
156bb898558SAl Viro /*
157bb898558SAl Viro  * we cannot use the same code segment descriptor for user and kernel
158bb898558SAl Viro  * -- not even in the long flat mode, because of different DPL /kkeil
159bb898558SAl Viro  * The segment offset needs to contain a RPL. Grr. -AK
160bb898558SAl Viro  * GDT layout to get 64bit syscall right (sysret hardcodes gdt offsets)
161bb898558SAl Viro  */
162bb898558SAl Viro #define GDT_ENTRY_DEFAULT_USER32_CS 4
163bb898558SAl Viro #define GDT_ENTRY_DEFAULT_USER_DS 5
164bb898558SAl Viro #define GDT_ENTRY_DEFAULT_USER_CS 6
165bb898558SAl Viro #define __USER32_CS   (GDT_ENTRY_DEFAULT_USER32_CS*8+3)
166bb898558SAl Viro #define __USER32_DS	__USER_DS
167bb898558SAl Viro 
168bb898558SAl Viro #define GDT_ENTRY_TSS 8	/* needs two entries */
169bb898558SAl Viro #define GDT_ENTRY_LDT 10 /* needs two entries */
170bb898558SAl Viro #define GDT_ENTRY_TLS_MIN 12
171bb898558SAl Viro #define GDT_ENTRY_TLS_MAX 14
172bb898558SAl Viro 
173bb898558SAl Viro #define GDT_ENTRY_PER_CPU 15	/* Abused to load per CPU data from limit */
174bb898558SAl Viro #define __PER_CPU_SEG	(GDT_ENTRY_PER_CPU * 8 + 3)
175bb898558SAl Viro 
176bb898558SAl Viro /* TLS indexes for 64bit - hardcoded in arch_prctl */
177bb898558SAl Viro #define FS_TLS 0
178bb898558SAl Viro #define GS_TLS 1
179bb898558SAl Viro 
180bb898558SAl Viro #define GS_TLS_SEL ((GDT_ENTRY_TLS_MIN+GS_TLS)*8 + 3)
181bb898558SAl Viro #define FS_TLS_SEL ((GDT_ENTRY_TLS_MIN+FS_TLS)*8 + 3)
182bb898558SAl Viro 
183bb898558SAl Viro #define GDT_ENTRIES 16
184bb898558SAl Viro 
185bb898558SAl Viro #endif
186bb898558SAl Viro 
187bb898558SAl Viro #define __KERNEL_CS	(GDT_ENTRY_KERNEL_CS*8)
188bb898558SAl Viro #define __KERNEL_DS	(GDT_ENTRY_KERNEL_DS*8)
189bb898558SAl Viro #define __USER_DS	(GDT_ENTRY_DEFAULT_USER_DS*8+3)
190bb898558SAl Viro #define __USER_CS	(GDT_ENTRY_DEFAULT_USER_CS*8+3)
191bb898558SAl Viro #ifndef CONFIG_PARAVIRT
192bb898558SAl Viro #define get_kernel_rpl()  0
193bb898558SAl Viro #endif
194bb898558SAl Viro 
195bb898558SAl Viro /* User mode is privilege level 3 */
196bb898558SAl Viro #define USER_RPL		0x3
197bb898558SAl Viro /* LDT segment has TI set, GDT has it cleared */
198bb898558SAl Viro #define SEGMENT_LDT		0x4
199bb898558SAl Viro #define SEGMENT_GDT		0x0
200bb898558SAl Viro 
201bb898558SAl Viro /* Bottom two bits of selector give the ring privilege level */
202bb898558SAl Viro #define SEGMENT_RPL_MASK	0x3
203bb898558SAl Viro /* Bit 2 is table indicator (LDT/GDT) */
204bb898558SAl Viro #define SEGMENT_TI_MASK		0x4
205bb898558SAl Viro 
206bb898558SAl Viro #define IDT_ENTRIES 256
207bb898558SAl Viro #define NUM_EXCEPTION_VECTORS 32
208bb898558SAl Viro #define GDT_SIZE (GDT_ENTRIES * 8)
209bb898558SAl Viro #define GDT_ENTRY_TLS_ENTRIES 3
210bb898558SAl Viro #define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES * 8)
211bb898558SAl Viro 
212bb898558SAl Viro #ifdef __KERNEL__
213bb898558SAl Viro #ifndef __ASSEMBLY__
214bb898558SAl Viro extern const char early_idt_handlers[NUM_EXCEPTION_VECTORS][10];
215*f05e798aSDavid Howells 
216*f05e798aSDavid Howells /*
217*f05e798aSDavid Howells  * Load a segment. Fall back on loading the zero
218*f05e798aSDavid Howells  * segment if something goes wrong..
219*f05e798aSDavid Howells  */
220*f05e798aSDavid Howells #define loadsegment(seg, value)						\
221*f05e798aSDavid Howells do {									\
222*f05e798aSDavid Howells 	unsigned short __val = (value);					\
223*f05e798aSDavid Howells 									\
224*f05e798aSDavid Howells 	asm volatile("						\n"	\
225*f05e798aSDavid Howells 		     "1:	movl %k0,%%" #seg "		\n"	\
226*f05e798aSDavid Howells 									\
227*f05e798aSDavid Howells 		     ".section .fixup,\"ax\"			\n"	\
228*f05e798aSDavid Howells 		     "2:	xorl %k0,%k0			\n"	\
229*f05e798aSDavid Howells 		     "		jmp 1b				\n"	\
230*f05e798aSDavid Howells 		     ".previous					\n"	\
231*f05e798aSDavid Howells 									\
232*f05e798aSDavid Howells 		     _ASM_EXTABLE(1b, 2b)				\
233*f05e798aSDavid Howells 									\
234*f05e798aSDavid Howells 		     : "+r" (__val) : : "memory");			\
235*f05e798aSDavid Howells } while (0)
236*f05e798aSDavid Howells 
237*f05e798aSDavid Howells /*
238*f05e798aSDavid Howells  * Save a segment register away
239*f05e798aSDavid Howells  */
240*f05e798aSDavid Howells #define savesegment(seg, value)				\
241*f05e798aSDavid Howells 	asm("mov %%" #seg ",%0":"=r" (value) : : "memory")
242*f05e798aSDavid Howells 
243*f05e798aSDavid Howells /*
244*f05e798aSDavid Howells  * x86_32 user gs accessors.
245*f05e798aSDavid Howells  */
246*f05e798aSDavid Howells #ifdef CONFIG_X86_32
247*f05e798aSDavid Howells #ifdef CONFIG_X86_32_LAZY_GS
248*f05e798aSDavid Howells #define get_user_gs(regs)	(u16)({unsigned long v; savesegment(gs, v); v;})
249*f05e798aSDavid Howells #define set_user_gs(regs, v)	loadsegment(gs, (unsigned long)(v))
250*f05e798aSDavid Howells #define task_user_gs(tsk)	((tsk)->thread.gs)
251*f05e798aSDavid Howells #define lazy_save_gs(v)		savesegment(gs, (v))
252*f05e798aSDavid Howells #define lazy_load_gs(v)		loadsegment(gs, (v))
253*f05e798aSDavid Howells #else	/* X86_32_LAZY_GS */
254*f05e798aSDavid Howells #define get_user_gs(regs)	(u16)((regs)->gs)
255*f05e798aSDavid Howells #define set_user_gs(regs, v)	do { (regs)->gs = (v); } while (0)
256*f05e798aSDavid Howells #define task_user_gs(tsk)	(task_pt_regs(tsk)->gs)
257*f05e798aSDavid Howells #define lazy_save_gs(v)		do { } while (0)
258*f05e798aSDavid Howells #define lazy_load_gs(v)		do { } while (0)
259*f05e798aSDavid Howells #endif	/* X86_32_LAZY_GS */
260*f05e798aSDavid Howells #endif	/* X86_32 */
261*f05e798aSDavid Howells 
262*f05e798aSDavid Howells static inline unsigned long get_limit(unsigned long segment)
263*f05e798aSDavid Howells {
264*f05e798aSDavid Howells 	unsigned long __limit;
265*f05e798aSDavid Howells 	asm("lsll %1,%0" : "=r" (__limit) : "r" (segment));
266*f05e798aSDavid Howells 	return __limit + 1;
267*f05e798aSDavid Howells }
268*f05e798aSDavid Howells 
269*f05e798aSDavid Howells #endif /* !__ASSEMBLY__ */
270*f05e798aSDavid Howells #endif /* __KERNEL__ */
271bb898558SAl Viro 
2721965aae3SH. Peter Anvin #endif /* _ASM_X86_SEGMENT_H */
273