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