From: Varad Gautam <varad.gautam@xxxxxxxx> UEFI tests do not update MSR_GS_BASE during bringup, and continue using the GS_BASE set up by the UEFI implementation for percpu storage. Update this MSR during setup_segments64() to allow storing percpu data at a sane location reserved by the testcase, and ensure that this happens before any operation that ends up storing to the percpu space. Since apic_ops (touched by reset_apic()) is percpu, move reset_apic() to happen after setup_gdt_tss(). With this, ap_init() can now use percpu apic_ops via apic_icr_write(). Signed-off-by: Varad Gautam <varad.gautam@xxxxxxxx> Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx> --- lib/x86/setup.c | 7 ++++++- lib/x86/smp.c | 14 -------------- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/lib/x86/setup.c b/lib/x86/setup.c index 9724465..c7c0983 100644 --- a/lib/x86/setup.c +++ b/lib/x86/setup.c @@ -169,6 +169,8 @@ void setup_multiboot(struct mbi_bootinfo *bi) #ifdef CONFIG_EFI +static struct percpu_data __percpu_data[MAX_TEST_CPUS]; + static void setup_segments64(void) { /* Update data segments */ @@ -178,6 +180,9 @@ 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 * address, then doing a far return: this will use the new code segment @@ -337,8 +342,8 @@ efi_status_t setup_efi(efi_bootinfo_t *efi_bootinfo) return status; } - reset_apic(); setup_gdt_tss(); + reset_apic(); setup_idt(); load_idt(); mask_pic_interrupts(); diff --git a/lib/x86/smp.c b/lib/x86/smp.c index 81dacef..2f554ce 100644 --- a/lib/x86/smp.c +++ b/lib/x86/smp.c @@ -184,25 +184,11 @@ void ap_init(void) setup_rm_gdt(); -#ifdef CONFIG_EFI - /* - * apic_icr_write() is unusable on CONFIG_EFI until percpu area gets set up. - * Use raw writes to APIC_ICR to send IPIs for time being. - */ - volatile u32 *apic_icr = (volatile u32 *) (APIC_DEFAULT_PHYS_BASE + APIC_ICR); - - /* INIT */ - *apic_icr = APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT; - - /* SIPI */ - *apic_icr = APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP; -#else /* INIT */ apic_icr_write(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT, 0); /* SIPI */ apic_icr_write(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP, 0); -#endif _cpu_count = fwcfg_get_nb_cpus(); -- 2.36.1.476.g0c4daa206d-goog