Reading or writing MSR_IA32_APICBASE is typically an intercepted operation and causes #VC exception when the test is launched as an SEV-ES guest. So calling pre_boot_apic_id() and reset_apic() before the IDT is set up in setup_idt() and load_idt() might cause problems. Hence move percpu data setup and reset_apic() call after setup_idt() and load_idt(). Fixes: 3c50214c97f173f5e0f82c7f248a7c62707d8748 (x86: efi: Provide percpu storage) Signed-off-by: Vasant Karasulli <vkarasulli@xxxxxxx> --- lib/x86/setup.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/x86/setup.c b/lib/x86/setup.c index 7df0256..712e292 100644 --- a/lib/x86/setup.c +++ b/lib/x86/setup.c @@ -192,8 +192,6 @@ static void setup_segments64(void) write_gs(KERNEL_DS); write_ss(KERNEL_DS); - /* Setup percpu base */ - wrmsr(MSR_GS_BASE, (u64)&__percpu_data[pre_boot_apic_id()]); /* * Update the code segment by putting it on the stack before the return @@ -322,7 +320,7 @@ efi_status_t setup_efi(efi_bootinfo_t *efi_bootinfo) } return status; } - + status = setup_rsdp(efi_bootinfo); if (status != EFI_SUCCESS) { printf("Cannot find RSDP in EFI system table\n"); @@ -344,14 +342,20 @@ efi_status_t setup_efi(efi_bootinfo_t *efi_bootinfo) } setup_gdt_tss(); - /* - * GS.base, which points at the per-vCPU data, must be configured prior - * to resetting the APIC, which sets the per-vCPU APIC ops. - */ setup_segments64(); - reset_apic(); setup_idt(); load_idt(); + /* + * Load GS.base with the per-vCPU data. This must be done after + * loading the IDT as reading the APIC ID may #VC when running + * as an SEV-ES guest + */ + wrmsr(MSR_GS_BASE, (u64)&__percpu_data[pre_boot_apic_id()]); + /* + * Resetting the APIC sets the per-vCPU APIC ops and so must be + * done after loading GS.base with the per-vCPU data. + */ + reset_apic(); mask_pic_interrupts(); setup_page_table(); enable_apic(); -- 2.34.1