1 #include <xen/init.h> 2 #include <xen/lib.h> 3 #include <xen/mm.h> 4 #include <xen/percpu.h> 5 6 #include <asm/desc.h> 7 8 /* 9 * Native and Compat GDTs used by Xen. 10 * 11 * The R1 and R3 descriptors are fixed in Xen's ABI for PV guests. All other 12 * descriptors are in principle variable, with the following restrictions. 13 * 14 * All R0 descriptors must line up in both GDTs to allow for correct 15 * interrupt/exception handling. 16 * 17 * The SYSCALL/SYSRET GDT layout requires: 18 * - R0 long mode code followed by R0 data. 19 * - R3 compat code, followed by R3 data, followed by R3 long mode code. 20 * 21 * The SYSENTER GDT layout requirements are compatible with SYSCALL. Xen does 22 * not use the SYSEXIT instruction, and does not provide a compatible GDT. 23 * 24 * These tables are used directly by CPU0, and used as the template for the 25 * GDTs of other CPUs. Everything from the TSS onwards is unique per CPU. 26 */ 27 28 #define SEL2GDT(sel) (((sel) >> 3) - FIRST_RESERVED_GDT_ENTRY) 29 30 __section(".data.page_aligned") __aligned(PAGE_SIZE) 31 seg_desc_t boot_gdt[PAGE_SIZE / sizeof(seg_desc_t)] = 32 { 33 /* 0xe008 - Ring 0 code, 64bit mode */ 34 [SEL2GDT(__HYPERVISOR_CS)] = { 0x00af9b000000ffff }, 35 36 /* 0xe010 - Ring 0 data */ 37 [SEL2GDT(__HYPERVISOR_DS32)] = { 0x00cf93000000ffff }, 38 39 /* 0xe018 - reserved */ 40 41 /* 0xe023 - Ring 3 code, compatibility */ 42 [SEL2GDT(FLAT_RING3_CS32)] = { 0x00cffb000000ffff }, 43 44 /* 0xe02b - Ring 3 data */ 45 [SEL2GDT(FLAT_RING3_DS32)] = { 0x00cff3000000ffff }, 46 47 /* 0xe033 - Ring 3 code, 64-bit mode */ 48 [SEL2GDT(FLAT_RING3_CS64)] = { 0x00affb000000ffff }, 49 50 /* 0xe038 - reserved */ 51 /* 0xe040 - TSS */ 52 /* 0xe050 - LDT */ 53 54 /* 0xe060 - per-CPU entry (limit == cpu) */ 55 [SEL2GDT(PER_CPU_SELECTOR)] = { 0x0000910000000000 }, 56 }; 57 58 #ifdef CONFIG_PV32 59 __section(".data.page_aligned") __aligned(PAGE_SIZE) 60 seg_desc_t boot_compat_gdt[PAGE_SIZE / sizeof(seg_desc_t)] = 61 { 62 /* 0xe008 - Ring 0 code, 64bit mode */ 63 [SEL2GDT(__HYPERVISOR_CS)] = { 0x00af9b000000ffff }, 64 65 /* 0xe010 - Ring 0 data */ 66 [SEL2GDT(__HYPERVISOR_DS32)] = { 0x00cf93000000ffff }, 67 68 /* 0xe019 - Ring 1 code, compatibility */ 69 [SEL2GDT(FLAT_COMPAT_RING1_CS)] = { 0x00cfbb000000ffff }, 70 71 /* 0xe021 - Ring 1 data */ 72 [SEL2GDT(FLAT_COMPAT_RING1_DS)] = { 0x00cfb3000000ffff }, 73 74 /* 0xe02b - Ring 3 code, compatibility */ 75 [SEL2GDT(FLAT_COMPAT_RING3_CS)] = { 0x00cffb000000ffff }, 76 77 /* 0xe033 - Ring 3 data */ 78 [SEL2GDT(FLAT_COMPAT_RING3_DS)] = { 0x00cff3000000ffff }, 79 80 /* 0xe038 - reserved */ 81 /* 0xe040 - TSS */ 82 /* 0xe050 - LDT */ 83 84 /* 0xe060 - per-CPU entry (limit == cpu) */ 85 [SEL2GDT(PER_CPU_SELECTOR)] = { 0x0000910000000000 }, 86 }; 87 #endif 88 89 /* 90 * Used by each CPU as it starts up, to enter C with a suitable %cs. 91 * References boot_cpu_gdt_table for a short period, until the CPUs switch 92 * onto their per-CPU GDTs. 93 */ 94 const struct desc_ptr boot_gdtr = { 95 .limit = LAST_RESERVED_GDT_BYTE, 96 .base = (unsigned long)(boot_gdt - FIRST_RESERVED_GDT_ENTRY), 97 }; 98 99 /* 100 * Local variables: 101 * mode: C 102 * c-file-style: "BSD" 103 * c-basic-offset: 4 104 * tab-width: 4 105 * indent-tabs-mode: nil 106 * End: 107 */ 108