void __init efi_call_phys_epilog(void) { struct desc_ptr gdt_descr; #ifdef CONFIG_PAX_KERNEXEC struct desc_struct d; memset(&d, 0, sizeof d); write_gdt_entry(get_cpu_gdt_table(0), GDT_ENTRY_KERNEXEC_EFI_CS, &d, DESCTYPE_S); write_gdt_entry(get_cpu_gdt_table(0), GDT_ENTRY_KERNEXEC_EFI_DS, &d, DESCTYPE_S); #endif gdt_descr.address = (unsigned long)get_cpu_gdt_table(0); gdt_descr.size = GDT_SIZE - 1; load_gdt(&gdt_descr); #ifdef CONFIG_PAX_PER_CPU_PGD load_cr3(get_cpu_pgd(smp_processor_id(), kernel)); #else load_cr3(swapper_pg_dir); #endif __flush_tlb_all(); local_irq_restore(efi_rt_eflags); }
static inline void setup_percpu_segment(int cpu) { #ifdef CONFIG_X86_32 struct desc_struct d = GDT_ENTRY_INIT(0x8092, per_cpu_offset(cpu), 0xFFFFF); write_gdt_entry(get_cpu_gdt_rw(cpu), GDT_ENTRY_PERCPU, &d, DESCTYPE_S); #endif }
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 }
static inline void setup_percpu_segment(int cpu) { #ifdef CONFIG_X86_32 struct desc_struct gdt; unsigned long base = per_cpu_offset(cpu); pack_descriptor(&gdt, base, (VMALLOC_END - base - 1) >> PAGE_SHIFT, 0x83 | DESCTYPE_S, 0xC); write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S); #endif }
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; }
/* * Assume __initcall executes before all user space. Hopefully kmod * doesn't violate that. We'll find out if it does. */ static void vsyscall_set_cpu(int cpu) { unsigned long d; unsigned long node = 0; #ifdef CONFIG_NUMA node = cpu_to_node(cpu); #endif if (cpu_has(&cpu_data(cpu), X86_FEATURE_RDTSCP)) write_rdtscp_aux((node << 12) | cpu); /* * Store cpu number in limit so that it can be loaded quickly * in user space in vgetcpu. (12 bits for the CPU and 8 bits for the node) */ d = 0x0f40000000000ULL; d |= cpu; d |= (node & 0xf) << 12; d |= (node >> 4) << 48; write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_PER_CPU, &d, DESCTYPE_S); }