File: /Users/paulross/dev/linux/linux-3.13/arch/x86/include/asm/segment.h

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: