Green shading in the line number column means the source is part of the translation unit, red means it is conditionally excluded. Highlighted line numbers link to the translation unit page. Highlighted macros link to the macro page.
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 */ 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: /* Simple and small GDT entries for booting only */ 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: * The layout of the per-CPU GDT under Linux: 29: * 30: * 0 - null 31: * 1 - reserved 32: * 2 - reserved 33: * 3 - reserved 34: * 35: * 4 - unused <==== new cacheline 36: * 5 - unused 37: * 38: * ------- start of TLS (Thread-Local Storage) segments: 39: * 40: * 6 - TLS segment #1 [ glibc's TLS segment ] 41: * 7 - TLS segment #2 [ Wine's %fs Win32 segment ] 42: * 8 - TLS segment #3 43: * 9 - reserved 44: * 10 - reserved 45: * 11 - reserved 46: * 47: * ------- start of kernel segments: 48: * 49: * 12 - kernel code segment <==== new cacheline 50: * 13 - kernel data segment 51: * 14 - default user CS 52: * 15 - default user DS 53: * 16 - TSS 54: * 17 - LDT 55: * 18 - PNPBIOS support (16->32 gate) 56: * 19 - PNPBIOS support 57: * 20 - PNPBIOS support 58: * 21 - PNPBIOS support 59: * 22 - PNPBIOS support 60: * 23 - APM BIOS support 61: * 24 - APM BIOS support 62: * 25 - APM BIOS support 63: * 64: * 26 - ESPFIX small SS 65: * 27 - per-cpu [ offset to per-cpu data area ] 66: * 28 - stack_canary-20 [ for stack protector ] 67: * 29 - unused 68: * 30 - unused 69: * 31 - TSS for double fault handler 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: * The GDT has 32 entries 111: */ 112: #define GDT_ENTRIES 32 113: 114: /* The PnP BIOS entries in the GDT */ 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: /* The PnP BIOS selectors */ 122: #define PNP_CS32 (GDT_ENTRY_PNPBIOS_CS32 * 8) /* segment for calling fn */ 123: #define PNP_CS16 (GDT_ENTRY_PNPBIOS_CS16 * 8) /* code segment for BIOS */ 124: #define PNP_DS (GDT_ENTRY_PNPBIOS_DS * 8) /* data segment for BIOS */ 125: #define PNP_TS1 (GDT_ENTRY_PNPBIOS_TS1 * 8) /* transfer data segment */ 126: #define PNP_TS2 (GDT_ENTRY_PNPBIOS_TS2 * 8) /* another data segment */ 127: 128: /* Bottom two bits of selector give the ring privilege level */ 129: #define SEGMENT_RPL_MASK 0x3 130: /* Bit 2 is table indicator (LDT/GDT) */ 131: #define SEGMENT_TI_MASK 0x4 132: 133: /* User mode is privilege level 3 */ 134: #define USER_RPL 0x3 135: /* LDT segment has TI set, GDT has it cleared */ 136: #define SEGMENT_LDT 0x4 137: #define SEGMENT_GDT 0x0 138: 139: /* 140: * Matching rules for certain types of segments. 141: */ 142: 143: /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */ 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: * we cannot use the same code segment descriptor for user and kernel 158: * -- not even in the long flat mode, because of different DPL /kkeil 159: * The segment offset needs to contain a RPL. Grr. -AK 160: * GDT layout to get 64bit syscall right (sysret hardcodes gdt offsets) 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 /* needs two entries */ 169: #define GDT_ENTRY_LDT 10 /* needs two entries */ 170: #define GDT_ENTRY_TLS_MIN 12 171: #define GDT_ENTRY_TLS_MAX 14 172: 173: #define GDT_ENTRY_PER_CPU 15 /* Abused to load per CPU data from limit */ 174: #define __PER_CPU_SEG (GDT_ENTRY_PER_CPU * 8 + 3) 175: 176: /* TLS indexes for 64bit - hardcoded in arch_prctl */ 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: /* User mode is privilege level 3 */ 196: #define USER_RPL 0x3 197: /* LDT segment has TI set, GDT has it cleared */ 198: #define SEGMENT_LDT 0x4 199: #define SEGMENT_GDT 0x0 200: 201: /* Bottom two bits of selector give the ring privilege level */ 202: #define SEGMENT_RPL_MASK 0x3 203: /* Bit 2 is table indicator (LDT/GDT) */ 204: #define SEGMENT_TI_MASK 0x4 205: 206: #define IDT_ENTRIES 256 207: #define NUM_EXCEPTION_VECTORS 32 208: /* Bitmask of exception vectors which push an error code on the stack */ 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__ 216: extern const char early_idt_handlers[NUM_EXCEPTION_VECTORS][2+2+5]; 217: #ifdef CONFIG_TRACING 218: #define trace_early_idt_handlers early_idt_handlers 219: #endif 220: 221: /* 222: * Load a segment. Fall back on loading the zero 223: * segment if something goes wrong.. 224: */ 225: #define loadsegment(seg, value) \ 226: do { \ 227: unsigned short __val = (value); \ 228: \ 229: asm volatile(" \n" \ 230: "1: movl %k0,%%" #seg " \n" \ 231: \ 232: ".section .fixup,\"ax\" \n" \ 233: "2: xorl %k0,%k0 \n" \ 234: " jmp 1b \n" \ 235: ".previous \n" \ 236: \ 237: _ASM_EXTABLE(1b, 2b) \ 238: \ 239: : "+r" (__val) : : "memory"); \ 240: } while (0) 241: 242: /* 243: * Save a segment register away 244: */ 245: #define savesegment(seg, value) \ 246: asm("mov %%" #seg ",%0":"=r" (value) : : "memory") 247: 248: /* 249: * x86_32 user gs accessors. 250: */ 251: #ifdef CONFIG_X86_32 252: #ifdef CONFIG_X86_32_LAZY_GS 253: #define get_user_gs(regs) (u16)({unsigned long v; savesegment(gs, v); v;}) 254: #define set_user_gs(regs, v) loadsegment(gs, (unsigned long)(v)) 255: #define task_user_gs(tsk) ((tsk)->thread.gs) 256: #define lazy_save_gs(v) savesegment(gs, (v)) 257: #define lazy_load_gs(v) loadsegment(gs, (v)) 258: #else /* X86_32_LAZY_GS */ 259: #define get_user_gs(regs) (u16)((regs)->gs) 260: #define set_user_gs(regs, v) do { (regs)->gs = (v); } while (0) 261: #define task_user_gs(tsk) (task_pt_regs(tsk)->gs) 262: #define lazy_save_gs(v) do { } while (0) 263: #define lazy_load_gs(v) do { } while (0) 264: #endif /* X86_32_LAZY_GS */ 265: #endif /* X86_32 */ 266: 267: static inline unsigned long get_limit(unsigned long segment) 268: { 269: unsigned long __limit; 270: asm("lsll %1,%0" : "=r" (__limit) : "r" (segment)); 271: return __limit + 1; 272: } 273: 274: #endif /* !__ASSEMBLY__ */ 275: #endif /* __KERNEL__ */ 276: 277: #endif /* _ASM_X86_SEGMENT_H */ 278: