|
@@ -15,12 +15,10 @@
|
|
|
/* Simple and small GDT entries for booting only */
|
|
|
|
|
|
#define GDT_ENTRY_BOOT_CS 2
|
|
|
+#define GDT_ENTRY_BOOT_DS 3
|
|
|
+#define GDT_ENTRY_BOOT_TSS 4
|
|
|
#define __BOOT_CS (GDT_ENTRY_BOOT_CS * 8)
|
|
|
-
|
|
|
-#define GDT_ENTRY_BOOT_DS (GDT_ENTRY_BOOT_CS + 1)
|
|
|
#define __BOOT_DS (GDT_ENTRY_BOOT_DS * 8)
|
|
|
-
|
|
|
-#define GDT_ENTRY_BOOT_TSS (GDT_ENTRY_BOOT_CS + 2)
|
|
|
#define __BOOT_TSS (GDT_ENTRY_BOOT_TSS * 8)
|
|
|
|
|
|
#define SEGMENT_RPL_MASK 0x3 /*
|
|
@@ -80,97 +78,86 @@
|
|
|
#define GDT_ENTRY_TLS_MIN 6
|
|
|
#define GDT_ENTRY_TLS_MAX (GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1)
|
|
|
|
|
|
+#define GDT_ENTRY_KERNEL_CS 12
|
|
|
+#define GDT_ENTRY_KERNEL_DS 13
|
|
|
#define GDT_ENTRY_DEFAULT_USER_CS 14
|
|
|
-
|
|
|
#define GDT_ENTRY_DEFAULT_USER_DS 15
|
|
|
+#define GDT_ENTRY_TSS 16
|
|
|
+#define GDT_ENTRY_LDT 17
|
|
|
+#define GDT_ENTRY_PNPBIOS_CS32 18
|
|
|
+#define GDT_ENTRY_PNPBIOS_CS16 19
|
|
|
+#define GDT_ENTRY_PNPBIOS_DS 20
|
|
|
+#define GDT_ENTRY_PNPBIOS_TS1 21
|
|
|
+#define GDT_ENTRY_PNPBIOS_TS2 22
|
|
|
+#define GDT_ENTRY_APMBIOS_BASE 23
|
|
|
+
|
|
|
+#define GDT_ENTRY_ESPFIX_SS 26
|
|
|
+#define GDT_ENTRY_PERCPU 27
|
|
|
+#define GDT_ENTRY_STACK_CANARY 28
|
|
|
|
|
|
-#define GDT_ENTRY_KERNEL_BASE (12)
|
|
|
-
|
|
|
-#define GDT_ENTRY_KERNEL_CS (GDT_ENTRY_KERNEL_BASE+0)
|
|
|
-
|
|
|
-#define GDT_ENTRY_KERNEL_DS (GDT_ENTRY_KERNEL_BASE+1)
|
|
|
-
|
|
|
-#define GDT_ENTRY_TSS (GDT_ENTRY_KERNEL_BASE+4)
|
|
|
-#define GDT_ENTRY_LDT (GDT_ENTRY_KERNEL_BASE+5)
|
|
|
-
|
|
|
-#define GDT_ENTRY_PNPBIOS_BASE (GDT_ENTRY_KERNEL_BASE+6)
|
|
|
-#define GDT_ENTRY_APMBIOS_BASE (GDT_ENTRY_KERNEL_BASE+11)
|
|
|
+#define GDT_ENTRY_DOUBLEFAULT_TSS 31
|
|
|
|
|
|
-#define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE+14)
|
|
|
+#define __KERNEL_CS (GDT_ENTRY_KERNEL_CS*8)
|
|
|
+#define __KERNEL_DS (GDT_ENTRY_KERNEL_DS*8)
|
|
|
+#define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS*8+3)
|
|
|
+#define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS*8+3)
|
|
|
#define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS*8)
|
|
|
-
|
|
|
-#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE+15)
|
|
|
+#define PNP_CS32 (GDT_ENTRY_PNPBIOS_CS32 * 8) /* segment for calling fn */
|
|
|
+#define PNP_CS16 (GDT_ENTRY_PNPBIOS_CS16 * 8) /* code segment for BIOS */
|
|
|
+/* "Is this PNP code selector (PNP_CS32 or PNP_CS16)?" */
|
|
|
+#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == PNP_CS32)
|
|
|
+#define PNP_DS (GDT_ENTRY_PNPBIOS_DS * 8) /* data segment for BIOS */
|
|
|
+#define PNP_TS1 (GDT_ENTRY_PNPBIOS_TS1 * 8) /* transfer data segment */
|
|
|
+#define PNP_TS2 (GDT_ENTRY_PNPBIOS_TS2 * 8) /* another data segment */
|
|
|
#ifdef CONFIG_SMP
|
|
|
-#define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
|
|
|
+#define __KERNEL_PERCPU (GDT_ENTRY_PERCPU*8)
|
|
|
#else
|
|
|
-#define __KERNEL_PERCPU 0
|
|
|
+#define __KERNEL_PERCPU 0
|
|
|
#endif
|
|
|
-
|
|
|
-#define GDT_ENTRY_STACK_CANARY (GDT_ENTRY_KERNEL_BASE+16)
|
|
|
#ifdef CONFIG_CC_STACKPROTECTOR
|
|
|
#define __KERNEL_STACK_CANARY (GDT_ENTRY_STACK_CANARY*8)
|
|
|
#else
|
|
|
#define __KERNEL_STACK_CANARY 0
|
|
|
#endif
|
|
|
|
|
|
-#define GDT_ENTRY_DOUBLEFAULT_TSS 31
|
|
|
-
|
|
|
-/*
|
|
|
- * The GDT has 32 entries
|
|
|
- */
|
|
|
#define GDT_ENTRIES 32
|
|
|
|
|
|
-/* The PnP BIOS entries in the GDT */
|
|
|
-#define GDT_ENTRY_PNPBIOS_CS32 (GDT_ENTRY_PNPBIOS_BASE + 0)
|
|
|
-#define GDT_ENTRY_PNPBIOS_CS16 (GDT_ENTRY_PNPBIOS_BASE + 1)
|
|
|
-#define GDT_ENTRY_PNPBIOS_DS (GDT_ENTRY_PNPBIOS_BASE + 2)
|
|
|
-#define GDT_ENTRY_PNPBIOS_TS1 (GDT_ENTRY_PNPBIOS_BASE + 3)
|
|
|
-#define GDT_ENTRY_PNPBIOS_TS2 (GDT_ENTRY_PNPBIOS_BASE + 4)
|
|
|
-
|
|
|
-/* The PnP BIOS selectors */
|
|
|
-#define PNP_CS32 (GDT_ENTRY_PNPBIOS_CS32 * 8) /* segment for calling fn */
|
|
|
-#define PNP_CS16 (GDT_ENTRY_PNPBIOS_CS16 * 8) /* code segment for BIOS */
|
|
|
-#define PNP_DS (GDT_ENTRY_PNPBIOS_DS * 8) /* data segment for BIOS */
|
|
|
-#define PNP_TS1 (GDT_ENTRY_PNPBIOS_TS1 * 8) /* transfer data segment */
|
|
|
-#define PNP_TS2 (GDT_ENTRY_PNPBIOS_TS2 * 8) /* another data segment */
|
|
|
+#else /* 64-bit: */
|
|
|
|
|
|
-
|
|
|
-/*
|
|
|
- * Matching rules for certain types of segments.
|
|
|
- */
|
|
|
-
|
|
|
-/* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
|
|
|
-#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
|
|
|
-
|
|
|
-
|
|
|
-#else
|
|
|
#include <asm/cache.h>
|
|
|
|
|
|
-#define GDT_ENTRY_KERNEL32_CS 1
|
|
|
-#define GDT_ENTRY_KERNEL_CS 2
|
|
|
-#define GDT_ENTRY_KERNEL_DS 3
|
|
|
-
|
|
|
-#define __KERNEL32_CS (GDT_ENTRY_KERNEL32_CS * 8)
|
|
|
-
|
|
|
+#define GDT_ENTRY_KERNEL32_CS 1
|
|
|
+#define GDT_ENTRY_KERNEL_CS 2
|
|
|
+#define GDT_ENTRY_KERNEL_DS 3
|
|
|
/*
|
|
|
* we cannot use the same code segment descriptor for user and kernel
|
|
|
* -- not even in the long flat mode, because of different DPL /kkeil
|
|
|
- * The segment offset needs to contain a RPL. Grr. -AK
|
|
|
- * GDT layout to get 64bit syscall right (sysret hardcodes gdt offsets)
|
|
|
+ * GDT layout to get 64bit syscall/sysret right. sysret hardcodes selectors:
|
|
|
+ * if returning to 32-bit userspace: cs = STAR.SYSRET_CS,
|
|
|
+ * if returning to 64-bit userspace: cs = STAR.SYSRET_CS+16,
|
|
|
+ * ss = STAR.SYSRET_CS+8 (in either case)
|
|
|
+ * thus USER_DS should be between 32-bit and 64-bit code selectors:
|
|
|
*/
|
|
|
#define GDT_ENTRY_DEFAULT_USER32_CS 4
|
|
|
#define GDT_ENTRY_DEFAULT_USER_DS 5
|
|
|
#define GDT_ENTRY_DEFAULT_USER_CS 6
|
|
|
-#define __USER32_CS (GDT_ENTRY_DEFAULT_USER32_CS*8+3)
|
|
|
-#define __USER32_DS __USER_DS
|
|
|
|
|
|
-#define GDT_ENTRY_TSS 8 /* needs two entries */
|
|
|
-#define GDT_ENTRY_LDT 10 /* needs two entries */
|
|
|
-#define GDT_ENTRY_TLS_MIN 12
|
|
|
-#define GDT_ENTRY_TLS_MAX 14
|
|
|
+#define GDT_ENTRY_TSS 8 /* needs two entries */
|
|
|
+#define GDT_ENTRY_LDT 10 /* needs two entries */
|
|
|
+#define GDT_ENTRY_TLS_MIN 12
|
|
|
+#define GDT_ENTRY_TLS_MAX 14
|
|
|
|
|
|
-#define GDT_ENTRY_PER_CPU 15 /* Abused to load per CPU data from limit */
|
|
|
-#define __PER_CPU_SEG (GDT_ENTRY_PER_CPU * 8 + 3)
|
|
|
+#define GDT_ENTRY_PER_CPU 15 /* abused to load per CPU data from limit */
|
|
|
+
|
|
|
+/* Selectors need to also have a correct RPL (+3 thingy) */
|
|
|
+#define __KERNEL_CS (GDT_ENTRY_KERNEL_CS*8)
|
|
|
+#define __KERNEL_DS (GDT_ENTRY_KERNEL_DS*8)
|
|
|
+#define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS*8+3)
|
|
|
+#define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS*8+3)
|
|
|
+#define __KERNEL32_CS (GDT_ENTRY_KERNEL32_CS*8)
|
|
|
+#define __USER32_CS (GDT_ENTRY_DEFAULT_USER32_CS*8+3)
|
|
|
+#define __USER32_DS __USER_DS
|
|
|
+#define __PER_CPU_SEG (GDT_ENTRY_PER_CPU*8+3)
|
|
|
|
|
|
/* TLS indexes for 64bit - hardcoded in arch_prctl */
|
|
|
#define FS_TLS 0
|
|
@@ -183,10 +170,6 @@
|
|
|
|
|
|
#endif
|
|
|
|
|
|
-#define __KERNEL_CS (GDT_ENTRY_KERNEL_CS*8)
|
|
|
-#define __KERNEL_DS (GDT_ENTRY_KERNEL_DS*8)
|
|
|
-#define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS*8+3)
|
|
|
-#define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS*8+3)
|
|
|
#ifndef CONFIG_PARAVIRT
|
|
|
#define get_kernel_rpl() 0
|
|
|
#endif
|