[kvm-unit-tests PATCH v1] x86: efi: set up the IDT before accessing MSRs.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux