From: Ard Biesheuvel <ardb@xxxxxxxxxx> There used to be two separate code paths for programming the IDT early: one that was called via the 1:1 mapping, and one via the kernel virtual mapping, where the former used explicit pointer fixups to obtain 1:1 mapped addresses. That distinction is now gone so the GDT/IDT init code can be unified and simplified accordingly. Signed-off-by: Ard Biesheuvel <ardb@xxxxxxxxxx> --- arch/x86/kernel/head64.c | 59 +++++++------------- 1 file changed, 19 insertions(+), 40 deletions(-) diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index a4a380494703..993d888a3172 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -59,21 +59,12 @@ EXPORT_SYMBOL(vmemmap_base); /* * GDT used on the boot CPU before switching to virtual addresses. */ -static struct desc_struct startup_gdt[GDT_ENTRIES] __initdata = { +static struct desc_struct startup_gdt[GDT_ENTRIES] __initconst = { [GDT_ENTRY_KERNEL32_CS] = GDT_ENTRY_INIT(DESC_CODE32, 0, 0xfffff), [GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(DESC_CODE64, 0, 0xfffff), [GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(DESC_DATA64, 0, 0xfffff), }; -/* - * Address needs to be set at runtime because it references the startup_gdt - * while the kernel still uses a direct mapping. - */ -static struct desc_ptr startup_gdt_descr __initdata = { - .size = sizeof(startup_gdt)-1, - .address = 0, -}; - #define __va_symbol(sym) ({ \ unsigned long __v; \ asm("movq $" __stringify(sym) ", %0":"=r"(__v)); \ @@ -363,7 +354,7 @@ void __init do_early_exception(struct pt_regs *regs, int trapnr) early_fixup_exception(regs, trapnr); } -/* Don't add a printk in there. printk relies on the PDA which is not initialized +/* Don't add a printk in there. printk relies on the PDA which is not initialized yet. */ void __init clear_bss(void) { @@ -517,47 +508,32 @@ void __init __noreturn x86_64_start_reservations(char *real_mode_data) */ static gate_desc bringup_idt_table[NUM_EXCEPTION_VECTORS] __page_aligned_data; -static struct desc_ptr bringup_idt_descr = { - .size = (NUM_EXCEPTION_VECTORS * sizeof(gate_desc)) - 1, - .address = 0, /* Set at runtime */ -}; - -static void set_bringup_idt_handler(gate_desc *idt, int n, void *handler) -{ -#ifdef CONFIG_AMD_MEM_ENCRYPT - struct idt_data data; - gate_desc desc; - - init_idt_data(&data, n, handler); - idt_init_desc(&desc, &data); - native_write_idt_entry(idt, n, &desc); -#endif -} - -/* This runs while still in the direct mapping */ -static void __head startup_64_load_idt(void) +static void early_load_idt(void (*handler)(void)) { gate_desc *idt = bringup_idt_table; + struct desc_ptr bringup_idt_descr; + + if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) { + struct idt_data data; + gate_desc desc; - if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) /* VMM Communication Exception */ - set_bringup_idt_handler(idt, X86_TRAP_VC, vc_no_ghcb); + init_idt_data(&data, X86_TRAP_VC, handler); + idt_init_desc(&desc, &data); + native_write_idt_entry(idt, X86_TRAP_VC, &desc); + } bringup_idt_descr.address = (unsigned long)idt; + bringup_idt_descr.size = sizeof(bringup_idt_table); native_load_idt(&bringup_idt_descr); } -/* This is used when running on kernel addresses */ void early_setup_idt(void) { - /* VMM Communication Exception */ - if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) { + if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) setup_ghcb(); - set_bringup_idt_handler(bringup_idt_table, X86_TRAP_VC, vc_boot_ghcb); - } - bringup_idt_descr.address = (unsigned long)bringup_idt_table; - native_load_idt(&bringup_idt_descr); + early_load_idt(vc_boot_ghcb); } /* @@ -565,8 +541,11 @@ void early_setup_idt(void) */ void __head startup_64_setup_env(void) { + struct desc_ptr startup_gdt_descr; + /* Load GDT */ startup_gdt_descr.address = (unsigned long)startup_gdt; + startup_gdt_descr.size = sizeof(startup_gdt) - 1; native_load_gdt(&startup_gdt_descr); /* New GDT is live - reload data segment registers */ @@ -574,5 +553,5 @@ void __head startup_64_setup_env(void) "movl %%eax, %%ss\n" "movl %%eax, %%es\n" : : "a"(__KERNEL_DS) : "memory"); - startup_64_load_idt(); + early_load_idt(vc_no_ghcb); } -- 2.43.0.429.g432eaa2c6b-goog