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); }
/* * Activate a secondary processor. */ notrace static void __cpuinit start_secondary(void *unused) { /* * Don't put *anything* before cpu_init(), SMP booting is too * fragile that we want to limit the things done here to the * most necessary things. */ cpu_init(); x86_cpuinit.early_percpu_clock_init(); preempt_disable(); smp_callin(); enable_start_cpu0 = 0; /* otherwise gcc will move up smp_processor_id before the cpu_init */ barrier(); /* switch away from the initial page table */ #ifdef CONFIG_PAX_PER_CPU_PGD load_cr3(get_cpu_pgd(smp_processor_id(), kernel)); __flush_tlb_all(); #elif defined(CONFIG_X86_32) load_cr3(swapper_pg_dir); __flush_tlb_all(); #endif /* * Check TSC synchronization with the BP: */ check_tsc_sync_target(); /* * We need to hold vector_lock so there the set of online cpus * does not change while we are assigning vectors to cpus. Holding * this lock ensures we don't half assign or remove an irq from a cpu. */ lock_vector_lock(); set_cpu_online(smp_processor_id(), true); unlock_vector_lock(); per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; x86_platform.nmi_init(); /* enable local interrupts */ local_irq_enable(); /* to prevent fake stack check failure in clock setup */ boot_init_stack_canary(); x86_cpuinit.setup_percpu_clockev(); wmb(); cpu_startup_entry(CPUHP_ONLINE); }
void __init init_espfix_bsp(void) { pgd_t *pgd_p; pud_t *pud_p; unsigned long index = pgd_index(ESPFIX_BASE_ADDR); /* Install the espfix pud into the kernel page directory */ pgd_p = &init_level4_pgt[index]; pud_p = espfix_pud_page; paravirt_alloc_pud(&init_mm, __pa(pud_p) >> PAGE_SHIFT); set_pgd(pgd_p, __pgd(PGTABLE_PROT | __pa(pud_p))); #ifdef CONFIG_PAX_PER_CPU_PGD clone_pgd_range(get_cpu_pgd(0, kernel) + index, swapper_pg_dir + index, 1); clone_pgd_range(get_cpu_pgd(0, user) + index, swapper_pg_dir + index, 1); #endif /* Randomize the locations */ init_espfix_random(); /* The rest is the same as for any other processor */ init_espfix_ap(0); }
void __init efi_call_phys_epilog(void) { /* * After the lock is released, the original page table is restored. */ int pgd; int n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT) , PGDIR_SIZE); for (pgd = 0; pgd < n_pgds; pgd++) set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), save_pgd[pgd]); kfree(save_pgd); #ifdef CONFIG_PAX_PER_CPU_PGD load_cr3(get_cpu_pgd(smp_processor_id(), kernel)); #endif __flush_tlb_all(); local_irq_restore(efi_flags); early_code_mapping_set_exec(0); }