Message ID | 20230316222109.1940300-5-usama.arif@bytedance.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Parallel CPU bringup for x86_64 | expand |
On Thu, Mar 16, 2023 at 10:21:01PM +0000, Usama Arif wrote: > From: David Woodhouse <dwmw@amazon.co.uk> > > When bringing up a secondary CPU from do_boot_cpu(), the warm reset flag > is set in CMOS and the starting IP for the trampoline written inside the > BDA at 0x467. Once the CPU is running, the CMOS flag is unset and the > value in the BDA cleared. > > To allow for parallel bringup of CPUs, add a reference count to track the > number of CPUs currently bring brought up, and clear the state only when s/bring // > the count reaches zero.
On 21 March 2023 11:41:15 GMT, Borislav Petkov <bp@alien8.de> wrote: >On Thu, Mar 16, 2023 at 10:21:01PM +0000, Usama Arif wrote: >> From: David Woodhouse <dwmw@amazon.co.uk> >> >> When bringing up a secondary CPU from do_boot_cpu(), the warm reset flag >> is set in CMOS and the starting IP for the trampoline written inside the >> BDA at 0x467. Once the CPU is running, the CMOS flag is unset and the >> value in the BDA cleared. >> >> To allow for parallel bringup of CPUs, add a reference count to track the >> number of CPUs currently bring brought up, and clear the state only when > >s/bring // "being", I think.
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 55cad72715d9..3a793772a2aa 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -121,17 +121,20 @@ int arch_update_cpu_topology(void) return retval; } + +static unsigned int smpboot_warm_reset_vector_count; + static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip) { unsigned long flags; spin_lock_irqsave(&rtc_lock, flags); - CMOS_WRITE(0xa, 0xf); + if (!smpboot_warm_reset_vector_count++) { + CMOS_WRITE(0xa, 0xf); + *((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_HIGH)) = start_eip >> 4; + *((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_LOW)) = start_eip & 0xf; + } spin_unlock_irqrestore(&rtc_lock, flags); - *((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_HIGH)) = - start_eip >> 4; - *((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_LOW)) = - start_eip & 0xf; } static inline void smpboot_restore_warm_reset_vector(void) @@ -143,10 +146,12 @@ static inline void smpboot_restore_warm_reset_vector(void) * to default values. */ spin_lock_irqsave(&rtc_lock, flags); - CMOS_WRITE(0, 0xf); + if (!--smpboot_warm_reset_vector_count) { + CMOS_WRITE(0, 0xf); + *((volatile u32 *)phys_to_virt(TRAMPOLINE_PHYS_LOW)) = 0; + } spin_unlock_irqrestore(&rtc_lock, flags); - *((volatile u32 *)phys_to_virt(TRAMPOLINE_PHYS_LOW)) = 0; } /*