diff options
Diffstat (limited to 'arch/x86/include/asm/segment.h')
-rw-r--r-- | arch/x86/include/asm/segment.h | 58 |
1 files changed, 56 insertions, 2 deletions
diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h index 5e641715c3f..165466233ab 100644 --- a/arch/x86/include/asm/segment.h +++ b/arch/x86/include/asm/segment.h | |||
@@ -212,7 +212,61 @@ | |||
212 | #ifdef __KERNEL__ | 212 | #ifdef __KERNEL__ |
213 | #ifndef __ASSEMBLY__ | 213 | #ifndef __ASSEMBLY__ |
214 | extern const char early_idt_handlers[NUM_EXCEPTION_VECTORS][10]; | 214 | extern const char early_idt_handlers[NUM_EXCEPTION_VECTORS][10]; |
215 | #endif | 215 | |
216 | #endif | 216 | /* |
217 | * Load a segment. Fall back on loading the zero | ||
218 | * segment if something goes wrong.. | ||
219 | */ | ||
220 | #define loadsegment(seg, value) \ | ||
221 | do { \ | ||
222 | unsigned short __val = (value); \ | ||
223 | \ | ||
224 | asm volatile(" \n" \ | ||
225 | "1: movl %k0,%%" #seg " \n" \ | ||
226 | \ | ||
227 | ".section .fixup,\"ax\" \n" \ | ||
228 | "2: xorl %k0,%k0 \n" \ | ||
229 | " jmp 1b \n" \ | ||
230 | ".previous \n" \ | ||
231 | \ | ||
232 | _ASM_EXTABLE(1b, 2b) \ | ||
233 | \ | ||
234 | : "+r" (__val) : : "memory"); \ | ||
235 | } while (0) | ||
236 | |||
237 | /* | ||
238 | * Save a segment register away | ||
239 | */ | ||
240 | #define savesegment(seg, value) \ | ||
241 | asm("mov %%" #seg ",%0":"=r" (value) : : "memory") | ||
242 | |||
243 | /* | ||
244 | * x86_32 user gs accessors. | ||
245 | */ | ||
246 | #ifdef CONFIG_X86_32 | ||
247 | #ifdef CONFIG_X86_32_LAZY_GS | ||
248 | #define get_user_gs(regs) (u16)({unsigned long v; savesegment(gs, v); v;}) | ||
249 | #define set_user_gs(regs, v) loadsegment(gs, (unsigned long)(v)) | ||
250 | #define task_user_gs(tsk) ((tsk)->thread.gs) | ||
251 | #define lazy_save_gs(v) savesegment(gs, (v)) | ||
252 | #define lazy_load_gs(v) loadsegment(gs, (v)) | ||
253 | #else /* X86_32_LAZY_GS */ | ||
254 | #define get_user_gs(regs) (u16)((regs)->gs) | ||
255 | #define set_user_gs(regs, v) do { (regs)->gs = (v); } while (0) | ||
256 | #define task_user_gs(tsk) (task_pt_regs(tsk)->gs) | ||
257 | #define lazy_save_gs(v) do { } while (0) | ||
258 | #define lazy_load_gs(v) do { } while (0) | ||
259 | #endif /* X86_32_LAZY_GS */ | ||
260 | #endif /* X86_32 */ | ||
261 | |||
262 | static inline unsigned long get_limit(unsigned long segment) | ||
263 | { | ||
264 | unsigned long __limit; | ||
265 | asm("lsll %1,%0" : "=r" (__limit) : "r" (segment)); | ||
266 | return __limit + 1; | ||
267 | } | ||
268 | |||
269 | #endif /* !__ASSEMBLY__ */ | ||
270 | #endif /* __KERNEL__ */ | ||
217 | 271 | ||
218 | #endif /* _ASM_X86_SEGMENT_H */ | 272 | #endif /* _ASM_X86_SEGMENT_H */ |