static inline void setup_percpu_segment(int cpu) { #ifdef CONFIG_X86_32 struct desc_struct gdt; pack_descriptor(&gdt, per_cpu_offset(cpu), 0xFFFFF, 0x2 | DESCTYPE_S, 0x8); gdt.s = 1; write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S); pack_descriptor(&gdt, per_cpu_offset(cpu), 0xFFFFF, 0x2 | DESCTYPE_S | 0x40 , 0x8); gdt.s = 1; write_gdt_entry (get_cpu_gdt_table(cpu), GDT_MODULE_PERCPU, &gdt, DESCTYPE_S); #endif }
/* Initialize the CPU's GDT. This is either the boot CPU doing itself (still using the master per-cpu area), or a CPU doing it for a secondary which will soon come up. */ __cpuinit void init_gdt(int cpu) { struct desc_struct *gdt = get_cpu_gdt_table(cpu); pack_descriptor(&gdt[GDT_ENTRY_PERCPU], __per_cpu_offset[cpu], 0xFFFFF, 0x2 | DESCTYPE_S, 0x8); gdt[GDT_ENTRY_PERCPU].s = 1; per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu]; per_cpu(cpu_number, cpu) = cpu; }
unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp) { unsigned long base = (kesp - uesp) & -THREAD_SIZE; unsigned long new_kesp = kesp - base; unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT; struct desc_struct ss; /* Set up base for espfix segment */ pack_descriptor(&ss, base, lim_pages, 0x93, 0xC); write_gdt_entry(get_cpu_gdt_table(smp_processor_id()), GDT_ENTRY_ESPFIX_SS, &ss, DESCTYPE_S); return new_kesp; }
static inline void setup_percpu_segment(int cpu, unsigned long base) { #ifdef CONFIG_X86_32 struct desc_struct gdt; pack_descriptor(&gdt, base, 0xFFFFF, 0x2 | DESCTYPE_S, 0x8); gdt.s = 1; write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S); #else #error "x86 not defined" #endif }
void __init efi_call_phys_prolog(void) { struct desc_ptr gdt_descr; #ifdef CONFIG_PAX_KERNEXEC struct desc_struct d; #endif local_irq_save(efi_rt_eflags); load_cr3(initial_page_table); __flush_tlb_all(); #ifdef CONFIG_PAX_KERNEXEC pack_descriptor(&d, 0, 0xFFFFF, 0x9B, 0xC); write_gdt_entry(get_cpu_gdt_table(0), GDT_ENTRY_KERNEXEC_EFI_CS, &d, DESCTYPE_S); pack_descriptor(&d, 0, 0xFFFFF, 0x93, 0xC); write_gdt_entry(get_cpu_gdt_table(0), GDT_ENTRY_KERNEXEC_EFI_DS, &d, DESCTYPE_S); #endif gdt_descr.address = __pa(get_cpu_gdt_table(0)); gdt_descr.size = GDT_SIZE - 1; load_gdt(&gdt_descr); }
/* * Initialize the CPU's GDT. This is either the boot CPU doing itself * (still using the master per-cpu area), or a CPU doing it for a * secondary which will soon come up. */ __cpuinit void init_gdt(int cpu) { struct desc_struct d, *gdt = get_cpu_gdt_table(cpu); unsigned long base, limit; base = per_cpu_offset(cpu); limit = PERCPU_ENOUGH_ROOM - 1; if (limit < 64*1024) pack_descriptor(&d, base, limit, 0x80 | DESCTYPE_S | 0x3, 0x4); else pack_descriptor(&d, base, limit >> PAGE_SHIFT, 0x80 | DESCTYPE_S | 0x3, 0xC); write_gdt_entry(gdt, GDT_ENTRY_PERCPU, &d, DESCTYPE_S); per_cpu(this_cpu_off, cpu) = base; per_cpu(cpu_number, cpu) = cpu; }