diff options
Diffstat (limited to 'arch/x86/include/asm/segment.h')
-rw-r--r-- | arch/x86/include/asm/segment.h | 289 |
1 files changed, 157 insertions, 132 deletions
diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h index db257a58571f..5a9856eb12ba 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,198 +14,228 @@ | |||
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 __BOOT_CS (GDT_ENTRY_BOOT_CS * 8) | 20 | #define GDT_ENTRY_BOOT_DS 3 |
21 | #define GDT_ENTRY_BOOT_TSS 4 | ||
22 | #define __BOOT_CS (GDT_ENTRY_BOOT_CS*8) | ||
23 | #define __BOOT_DS (GDT_ENTRY_BOOT_DS*8) | ||
24 | #define __BOOT_TSS (GDT_ENTRY_BOOT_TSS*8) | ||
25 | |||
26 | /* | ||
27 | * Bottom two bits of selector give the ring | ||
28 | * privilege level | ||
29 | */ | ||
30 | #define SEGMENT_RPL_MASK 0x3 | ||
19 | 31 | ||
20 | #define GDT_ENTRY_BOOT_DS (GDT_ENTRY_BOOT_CS + 1) | 32 | /* User mode is privilege level 3: */ |
21 | #define __BOOT_DS (GDT_ENTRY_BOOT_DS * 8) | 33 | #define USER_RPL 0x3 |
22 | 34 | ||
23 | #define GDT_ENTRY_BOOT_TSS (GDT_ENTRY_BOOT_CS + 2) | 35 | /* Bit 2 is Table Indicator (TI): selects between LDT or GDT */ |
24 | #define __BOOT_TSS (GDT_ENTRY_BOOT_TSS * 8) | 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 | ||
25 | 41 | ||
26 | #define SEGMENT_RPL_MASK 0x3 /* | 42 | #define GDT_ENTRY_INVALID_SEG 0 |
27 | * Bottom two bits of selector give the ring | ||
28 | * privilege level | ||
29 | */ | ||
30 | #define SEGMENT_TI_MASK 0x4 /* Bit 2 is table indicator (LDT/GDT) */ | ||
31 | #define USER_RPL 0x3 /* User mode is privilege level 3 */ | ||
32 | #define SEGMENT_LDT 0x4 /* LDT segment has TI set... */ | ||
33 | #define SEGMENT_GDT 0x0 /* ... GDT has it cleared */ | ||
34 | 43 | ||
35 | #ifdef CONFIG_X86_32 | 44 | #ifdef CONFIG_X86_32 |
36 | /* | 45 | /* |
37 | * The layout of the per-CPU GDT under Linux: | 46 | * The layout of the per-CPU GDT under Linux: |
38 | * | 47 | * |
39 | * 0 - null | 48 | * 0 - null <=== cacheline #1 |
40 | * 1 - reserved | 49 | * 1 - reserved |
41 | * 2 - reserved | 50 | * 2 - reserved |
42 | * 3 - reserved | 51 | * 3 - reserved |
43 | * | 52 | * |
44 | * 4 - unused <==== new cacheline | 53 | * 4 - unused <=== cacheline #2 |
45 | * 5 - unused | 54 | * 5 - unused |
46 | * | 55 | * |
47 | * ------- start of TLS (Thread-Local Storage) segments: | 56 | * ------- start of TLS (Thread-Local Storage) segments: |
48 | * | 57 | * |
49 | * 6 - TLS segment #1 [ glibc's TLS segment ] | 58 | * 6 - TLS segment #1 [ glibc's TLS segment ] |
50 | * 7 - TLS segment #2 [ Wine's %fs Win32 segment ] | 59 | * 7 - TLS segment #2 [ Wine's %fs Win32 segment ] |
51 | * 8 - TLS segment #3 | 60 | * 8 - TLS segment #3 <=== cacheline #3 |
52 | * 9 - reserved | 61 | * 9 - reserved |
53 | * 10 - reserved | 62 | * 10 - reserved |
54 | * 11 - reserved | 63 | * 11 - reserved |
55 | * | 64 | * |
56 | * ------- start of kernel segments: | 65 | * ------- start of kernel segments: |
57 | * | 66 | * |
58 | * 12 - kernel code segment <==== new cacheline | 67 | * 12 - kernel code segment <=== cacheline #4 |
59 | * 13 - kernel data segment | 68 | * 13 - kernel data segment |
60 | * 14 - default user CS | 69 | * 14 - default user CS |
61 | * 15 - default user DS | 70 | * 15 - default user DS |
62 | * 16 - TSS | 71 | * 16 - TSS <=== cacheline #5 |
63 | * 17 - LDT | 72 | * 17 - LDT |
64 | * 18 - PNPBIOS support (16->32 gate) | 73 | * 18 - PNPBIOS support (16->32 gate) |
65 | * 19 - PNPBIOS support | 74 | * 19 - PNPBIOS support |
66 | * 20 - PNPBIOS support | 75 | * 20 - PNPBIOS support <=== cacheline #6 |
67 | * 21 - PNPBIOS support | 76 | * 21 - PNPBIOS support |
68 | * 22 - PNPBIOS support | 77 | * 22 - PNPBIOS support |
69 | * 23 - APM BIOS support | 78 | * 23 - APM BIOS support |
70 | * 24 - APM BIOS support | 79 | * 24 - APM BIOS support <=== cacheline #7 |
71 | * 25 - APM BIOS support | 80 | * 25 - APM BIOS support |
72 | * | 81 | * |
73 | * 26 - ESPFIX small SS | 82 | * 26 - ESPFIX small SS |
74 | * 27 - per-cpu [ offset to per-cpu data area ] | 83 | * 27 - per-cpu [ offset to per-cpu data area ] |
75 | * 28 - stack_canary-20 [ for stack protector ] | 84 | * 28 - stack_canary-20 [ for stack protector ] <=== cacheline #8 |
76 | * 29 - unused | 85 | * 29 - unused |
77 | * 30 - unused | 86 | * 30 - unused |
78 | * 31 - TSS for double fault handler | 87 | * 31 - TSS for double fault handler |
79 | */ | 88 | */ |
80 | #define GDT_ENTRY_TLS_MIN 6 | 89 | #define GDT_ENTRY_TLS_MIN 6 |
81 | #define GDT_ENTRY_TLS_MAX (GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1) | 90 | #define GDT_ENTRY_TLS_MAX (GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1) |
82 | 91 | ||
92 | #define GDT_ENTRY_KERNEL_CS 12 | ||
93 | #define GDT_ENTRY_KERNEL_DS 13 | ||
83 | #define GDT_ENTRY_DEFAULT_USER_CS 14 | 94 | #define GDT_ENTRY_DEFAULT_USER_CS 14 |
84 | |||
85 | #define GDT_ENTRY_DEFAULT_USER_DS 15 | 95 | #define GDT_ENTRY_DEFAULT_USER_DS 15 |
96 | #define GDT_ENTRY_TSS 16 | ||
97 | #define GDT_ENTRY_LDT 17 | ||
98 | #define GDT_ENTRY_PNPBIOS_CS32 18 | ||
99 | #define GDT_ENTRY_PNPBIOS_CS16 19 | ||
100 | #define GDT_ENTRY_PNPBIOS_DS 20 | ||
101 | #define GDT_ENTRY_PNPBIOS_TS1 21 | ||
102 | #define GDT_ENTRY_PNPBIOS_TS2 22 | ||
103 | #define GDT_ENTRY_APMBIOS_BASE 23 | ||
104 | |||
105 | #define GDT_ENTRY_ESPFIX_SS 26 | ||
106 | #define GDT_ENTRY_PERCPU 27 | ||
107 | #define GDT_ENTRY_STACK_CANARY 28 | ||
108 | |||
109 | #define GDT_ENTRY_DOUBLEFAULT_TSS 31 | ||
86 | 110 | ||
87 | #define GDT_ENTRY_KERNEL_BASE (12) | 111 | /* |
112 | * Number of entries in the GDT table: | ||
113 | */ | ||
114 | #define GDT_ENTRIES 32 | ||
88 | 115 | ||
89 | #define GDT_ENTRY_KERNEL_CS (GDT_ENTRY_KERNEL_BASE+0) | 116 | /* |
117 | * Segment selector values corresponding to the above entries: | ||
118 | */ | ||
90 | 119 | ||
91 | #define GDT_ENTRY_KERNEL_DS (GDT_ENTRY_KERNEL_BASE+1) | 120 | #define __KERNEL_CS (GDT_ENTRY_KERNEL_CS*8) |
121 | #define __KERNEL_DS (GDT_ENTRY_KERNEL_DS*8) | ||
122 | #define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS*8 + 3) | ||
123 | #define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS*8 + 3) | ||
124 | #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS*8) | ||
92 | 125 | ||
93 | #define GDT_ENTRY_TSS (GDT_ENTRY_KERNEL_BASE+4) | 126 | /* segment for calling fn: */ |
94 | #define GDT_ENTRY_LDT (GDT_ENTRY_KERNEL_BASE+5) | 127 | #define PNP_CS32 (GDT_ENTRY_PNPBIOS_CS32*8) |
128 | /* code segment for BIOS: */ | ||
129 | #define PNP_CS16 (GDT_ENTRY_PNPBIOS_CS16*8) | ||
95 | 130 | ||
96 | #define GDT_ENTRY_PNPBIOS_BASE (GDT_ENTRY_KERNEL_BASE+6) | 131 | /* "Is this PNP code selector (PNP_CS32 or PNP_CS16)?" */ |
97 | #define GDT_ENTRY_APMBIOS_BASE (GDT_ENTRY_KERNEL_BASE+11) | 132 | #define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == PNP_CS32) |
98 | 133 | ||
99 | #define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE+14) | 134 | /* data segment for BIOS: */ |
100 | #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS*8) | 135 | #define PNP_DS (GDT_ENTRY_PNPBIOS_DS*8) |
136 | /* transfer data segment: */ | ||
137 | #define PNP_TS1 (GDT_ENTRY_PNPBIOS_TS1*8) | ||
138 | /* another data segment: */ | ||
139 | #define PNP_TS2 (GDT_ENTRY_PNPBIOS_TS2*8) | ||
101 | 140 | ||
102 | #define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE+15) | ||
103 | #ifdef CONFIG_SMP | 141 | #ifdef CONFIG_SMP |
104 | #define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8) | 142 | # define __KERNEL_PERCPU (GDT_ENTRY_PERCPU*8) |
105 | #else | 143 | #else |
106 | #define __KERNEL_PERCPU 0 | 144 | # define __KERNEL_PERCPU 0 |
107 | #endif | 145 | #endif |
108 | 146 | ||
109 | #define GDT_ENTRY_STACK_CANARY (GDT_ENTRY_KERNEL_BASE+16) | ||
110 | #ifdef CONFIG_CC_STACKPROTECTOR | 147 | #ifdef CONFIG_CC_STACKPROTECTOR |
111 | #define __KERNEL_STACK_CANARY (GDT_ENTRY_STACK_CANARY*8) | 148 | # define __KERNEL_STACK_CANARY (GDT_ENTRY_STACK_CANARY*8) |
112 | #else | 149 | #else |
113 | #define __KERNEL_STACK_CANARY 0 | 150 | # define __KERNEL_STACK_CANARY 0 |
114 | #endif | 151 | #endif |
115 | 152 | ||
116 | #define GDT_ENTRY_DOUBLEFAULT_TSS 31 | 153 | #else /* 64-bit: */ |
117 | |||
118 | /* | ||
119 | * The GDT has 32 entries | ||
120 | */ | ||
121 | #define GDT_ENTRIES 32 | ||
122 | 154 | ||
123 | /* The PnP BIOS entries in the GDT */ | 155 | #include <asm/cache.h> |
124 | #define GDT_ENTRY_PNPBIOS_CS32 (GDT_ENTRY_PNPBIOS_BASE + 0) | ||
125 | #define GDT_ENTRY_PNPBIOS_CS16 (GDT_ENTRY_PNPBIOS_BASE + 1) | ||
126 | #define GDT_ENTRY_PNPBIOS_DS (GDT_ENTRY_PNPBIOS_BASE + 2) | ||
127 | #define GDT_ENTRY_PNPBIOS_TS1 (GDT_ENTRY_PNPBIOS_BASE + 3) | ||
128 | #define GDT_ENTRY_PNPBIOS_TS2 (GDT_ENTRY_PNPBIOS_BASE + 4) | ||
129 | |||
130 | /* The PnP BIOS selectors */ | ||
131 | #define PNP_CS32 (GDT_ENTRY_PNPBIOS_CS32 * 8) /* segment for calling fn */ | ||
132 | #define PNP_CS16 (GDT_ENTRY_PNPBIOS_CS16 * 8) /* code segment for BIOS */ | ||
133 | #define PNP_DS (GDT_ENTRY_PNPBIOS_DS * 8) /* data segment for BIOS */ | ||
134 | #define PNP_TS1 (GDT_ENTRY_PNPBIOS_TS1 * 8) /* transfer data segment */ | ||
135 | #define PNP_TS2 (GDT_ENTRY_PNPBIOS_TS2 * 8) /* another data segment */ | ||
136 | 156 | ||
157 | #define GDT_ENTRY_KERNEL32_CS 1 | ||
158 | #define GDT_ENTRY_KERNEL_CS 2 | ||
159 | #define GDT_ENTRY_KERNEL_DS 3 | ||
137 | 160 | ||
138 | /* | 161 | /* |
139 | * Matching rules for certain types of segments. | 162 | * We cannot use the same code segment descriptor for user and kernel mode, |
163 | * not even in long flat mode, because of different DPL. | ||
164 | * | ||
165 | * GDT layout to get 64-bit SYSCALL/SYSRET support right. SYSRET hardcodes | ||
166 | * selectors: | ||
167 | * | ||
168 | * if returning to 32-bit userspace: cs = STAR.SYSRET_CS, | ||
169 | * if returning to 64-bit userspace: cs = STAR.SYSRET_CS+16, | ||
170 | * | ||
171 | * ss = STAR.SYSRET_CS+8 (in either case) | ||
172 | * | ||
173 | * thus USER_DS should be between 32-bit and 64-bit code selectors: | ||
140 | */ | 174 | */ |
175 | #define GDT_ENTRY_DEFAULT_USER32_CS 4 | ||
176 | #define GDT_ENTRY_DEFAULT_USER_DS 5 | ||
177 | #define GDT_ENTRY_DEFAULT_USER_CS 6 | ||
141 | 178 | ||
142 | /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */ | 179 | /* Needs two entries */ |
143 | #define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8) | 180 | #define GDT_ENTRY_TSS 8 |
144 | 181 | /* Needs two entries */ | |
182 | #define GDT_ENTRY_LDT 10 | ||
145 | 183 | ||
146 | #else | 184 | #define GDT_ENTRY_TLS_MIN 12 |
147 | #include <asm/cache.h> | 185 | #define GDT_ENTRY_TLS_MAX 14 |
148 | |||
149 | #define GDT_ENTRY_KERNEL32_CS 1 | ||
150 | #define GDT_ENTRY_KERNEL_CS 2 | ||
151 | #define GDT_ENTRY_KERNEL_DS 3 | ||
152 | 186 | ||
153 | #define __KERNEL32_CS (GDT_ENTRY_KERNEL32_CS * 8) | 187 | /* Abused to load per CPU data from limit */ |
188 | #define GDT_ENTRY_PER_CPU 15 | ||
154 | 189 | ||
155 | /* | 190 | /* |
156 | * we cannot use the same code segment descriptor for user and kernel | 191 | * Number of entries in the GDT table: |
157 | * -- not even in the long flat mode, because of different DPL /kkeil | ||
158 | * The segment offset needs to contain a RPL. Grr. -AK | ||
159 | * GDT layout to get 64bit syscall right (sysret hardcodes gdt offsets) | ||
160 | */ | 192 | */ |
161 | #define GDT_ENTRY_DEFAULT_USER32_CS 4 | 193 | #define GDT_ENTRIES 16 |
162 | #define GDT_ENTRY_DEFAULT_USER_DS 5 | ||
163 | #define GDT_ENTRY_DEFAULT_USER_CS 6 | ||
164 | #define __USER32_CS (GDT_ENTRY_DEFAULT_USER32_CS*8+3) | ||
165 | #define __USER32_DS __USER_DS | ||
166 | |||
167 | #define GDT_ENTRY_TSS 8 /* needs two entries */ | ||
168 | #define GDT_ENTRY_LDT 10 /* needs two entries */ | ||
169 | #define GDT_ENTRY_TLS_MIN 12 | ||
170 | #define GDT_ENTRY_TLS_MAX 14 | ||
171 | |||
172 | #define GDT_ENTRY_PER_CPU 15 /* Abused to load per CPU data from limit */ | ||
173 | #define __PER_CPU_SEG (GDT_ENTRY_PER_CPU * 8 + 3) | ||
174 | 194 | ||
175 | /* TLS indexes for 64bit - hardcoded in arch_prctl */ | 195 | /* |
176 | #define FS_TLS 0 | 196 | * Segment selector values corresponding to the above entries: |
177 | #define GS_TLS 1 | 197 | * |
178 | 198 | * Note, selectors also need to have a correct RPL, | |
179 | #define GS_TLS_SEL ((GDT_ENTRY_TLS_MIN+GS_TLS)*8 + 3) | 199 | * expressed with the +3 value for user-space selectors: |
180 | #define FS_TLS_SEL ((GDT_ENTRY_TLS_MIN+FS_TLS)*8 + 3) | 200 | */ |
181 | 201 | #define __KERNEL32_CS (GDT_ENTRY_KERNEL32_CS*8) | |
182 | #define GDT_ENTRIES 16 | 202 | #define __KERNEL_CS (GDT_ENTRY_KERNEL_CS*8) |
203 | #define __KERNEL_DS (GDT_ENTRY_KERNEL_DS*8) | ||
204 | #define __USER32_CS (GDT_ENTRY_DEFAULT_USER32_CS*8 + 3) | ||
205 | #define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS*8 + 3) | ||
206 | #define __USER32_DS __USER_DS | ||
207 | #define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS*8 + 3) | ||
208 | #define __PER_CPU_SEG (GDT_ENTRY_PER_CPU*8 + 3) | ||
209 | |||
210 | /* TLS indexes for 64-bit - hardcoded in arch_prctl(): */ | ||
211 | #define FS_TLS 0 | ||
212 | #define GS_TLS 1 | ||
213 | |||
214 | #define GS_TLS_SEL ((GDT_ENTRY_TLS_MIN+GS_TLS)*8 + 3) | ||
215 | #define FS_TLS_SEL ((GDT_ENTRY_TLS_MIN+FS_TLS)*8 + 3) | ||
183 | 216 | ||
184 | #endif | 217 | #endif |
185 | 218 | ||
186 | #define __KERNEL_CS (GDT_ENTRY_KERNEL_CS*8) | ||
187 | #define __KERNEL_DS (GDT_ENTRY_KERNEL_DS*8) | ||
188 | #define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS*8+3) | ||
189 | #define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS*8+3) | ||
190 | #ifndef CONFIG_PARAVIRT | 219 | #ifndef CONFIG_PARAVIRT |
191 | #define get_kernel_rpl() 0 | 220 | # define get_kernel_rpl() 0 |
192 | #endif | 221 | #endif |
193 | 222 | ||
194 | #define IDT_ENTRIES 256 | 223 | #define IDT_ENTRIES 256 |
195 | #define NUM_EXCEPTION_VECTORS 32 | 224 | #define NUM_EXCEPTION_VECTORS 32 |
196 | /* Bitmask of exception vectors which push an error code on the stack */ | 225 | |
197 | #define EXCEPTION_ERRCODE_MASK 0x00027d00 | 226 | /* Bitmask of exception vectors which push an error code on the stack: */ |
198 | #define GDT_SIZE (GDT_ENTRIES * 8) | 227 | #define EXCEPTION_ERRCODE_MASK 0x00027d00 |
199 | #define GDT_ENTRY_TLS_ENTRIES 3 | 228 | |
200 | #define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES * 8) | 229 | #define GDT_SIZE (GDT_ENTRIES*8) |
230 | #define GDT_ENTRY_TLS_ENTRIES 3 | ||
231 | #define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES* 8) | ||
201 | 232 | ||
202 | #ifdef __KERNEL__ | 233 | #ifdef __KERNEL__ |
203 | #ifndef __ASSEMBLY__ | 234 | #ifndef __ASSEMBLY__ |
235 | |||
204 | extern const char early_idt_handlers[NUM_EXCEPTION_VECTORS][2+2+5]; | 236 | extern const char early_idt_handlers[NUM_EXCEPTION_VECTORS][2+2+5]; |
205 | #ifdef CONFIG_TRACING | 237 | #ifdef CONFIG_TRACING |
206 | #define trace_early_idt_handlers early_idt_handlers | 238 | # define trace_early_idt_handlers early_idt_handlers |
207 | #endif | 239 | #endif |
208 | 240 | ||
209 | /* | 241 | /* |
@@ -228,37 +260,30 @@ do { \ | |||
228 | } while (0) | 260 | } while (0) |
229 | 261 | ||
230 | /* | 262 | /* |
231 | * Save a segment register away | 263 | * Save a segment register away: |
232 | */ | 264 | */ |
233 | #define savesegment(seg, value) \ | 265 | #define savesegment(seg, value) \ |
234 | asm("mov %%" #seg ",%0":"=r" (value) : : "memory") | 266 | asm("mov %%" #seg ",%0":"=r" (value) : : "memory") |
235 | 267 | ||
236 | /* | 268 | /* |
237 | * x86_32 user gs accessors. | 269 | * x86-32 user GS accessors: |
238 | */ | 270 | */ |
239 | #ifdef CONFIG_X86_32 | 271 | #ifdef CONFIG_X86_32 |
240 | #ifdef CONFIG_X86_32_LAZY_GS | 272 | # ifdef CONFIG_X86_32_LAZY_GS |
241 | #define get_user_gs(regs) (u16)({unsigned long v; savesegment(gs, v); v;}) | 273 | # define get_user_gs(regs) (u16)({ unsigned long v; savesegment(gs, v); v; }) |
242 | #define set_user_gs(regs, v) loadsegment(gs, (unsigned long)(v)) | 274 | # define set_user_gs(regs, v) loadsegment(gs, (unsigned long)(v)) |
243 | #define task_user_gs(tsk) ((tsk)->thread.gs) | 275 | # define task_user_gs(tsk) ((tsk)->thread.gs) |
244 | #define lazy_save_gs(v) savesegment(gs, (v)) | 276 | # define lazy_save_gs(v) savesegment(gs, (v)) |
245 | #define lazy_load_gs(v) loadsegment(gs, (v)) | 277 | # define lazy_load_gs(v) loadsegment(gs, (v)) |
246 | #else /* X86_32_LAZY_GS */ | 278 | # else /* X86_32_LAZY_GS */ |
247 | #define get_user_gs(regs) (u16)((regs)->gs) | 279 | # define get_user_gs(regs) (u16)((regs)->gs) |
248 | #define set_user_gs(regs, v) do { (regs)->gs = (v); } while (0) | 280 | # define set_user_gs(regs, v) do { (regs)->gs = (v); } while (0) |
249 | #define task_user_gs(tsk) (task_pt_regs(tsk)->gs) | 281 | # define task_user_gs(tsk) (task_pt_regs(tsk)->gs) |
250 | #define lazy_save_gs(v) do { } while (0) | 282 | # define lazy_save_gs(v) do { } while (0) |
251 | #define lazy_load_gs(v) do { } while (0) | 283 | # define lazy_load_gs(v) do { } while (0) |
252 | #endif /* X86_32_LAZY_GS */ | 284 | # endif /* X86_32_LAZY_GS */ |
253 | #endif /* X86_32 */ | 285 | #endif /* X86_32 */ |
254 | 286 | ||
255 | static inline unsigned long get_limit(unsigned long segment) | ||
256 | { | ||
257 | unsigned long __limit; | ||
258 | asm("lsll %1,%0" : "=r" (__limit) : "r" (segment)); | ||
259 | return __limit + 1; | ||
260 | } | ||
261 | |||
262 | #endif /* !__ASSEMBLY__ */ | 287 | #endif /* !__ASSEMBLY__ */ |
263 | #endif /* __KERNEL__ */ | 288 | #endif /* __KERNEL__ */ |
264 | 289 | ||