Skip to content

Commit 805ae9d

Browse files
dwmw2KAGA-KOKO
authored andcommitted
x86/smpboot: Reference count on smpboot_setup_warm_reset_vector()
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 the count reaches zero. Since the RTC spinlock is required to write to the CMOS, it can be used for mutual exclusion on the refcount too. Signed-off-by: David Woodhouse <[email protected]> Signed-off-by: Usama Arif <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Tested-by: Paul E. McKenney <[email protected]> Tested-by: Kim Phillips <[email protected]> Tested-by: Oleksandr Natalenko <[email protected]> Tested-by: Guilherme G. Piccoli <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 8f6be6d commit 805ae9d

File tree

1 file changed

+12
-7
lines changed

1 file changed

+12
-7
lines changed

arch/x86/kernel/smpboot.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -121,17 +121,20 @@ int arch_update_cpu_topology(void)
121121
return retval;
122122
}
123123

124+
125+
static unsigned int smpboot_warm_reset_vector_count;
126+
124127
static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
125128
{
126129
unsigned long flags;
127130

128131
spin_lock_irqsave(&rtc_lock, flags);
129-
CMOS_WRITE(0xa, 0xf);
132+
if (!smpboot_warm_reset_vector_count++) {
133+
CMOS_WRITE(0xa, 0xf);
134+
*((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_HIGH)) = start_eip >> 4;
135+
*((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_LOW)) = start_eip & 0xf;
136+
}
130137
spin_unlock_irqrestore(&rtc_lock, flags);
131-
*((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_HIGH)) =
132-
start_eip >> 4;
133-
*((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_LOW)) =
134-
start_eip & 0xf;
135138
}
136139

137140
static inline void smpboot_restore_warm_reset_vector(void)
@@ -143,10 +146,12 @@ static inline void smpboot_restore_warm_reset_vector(void)
143146
* to default values.
144147
*/
145148
spin_lock_irqsave(&rtc_lock, flags);
146-
CMOS_WRITE(0, 0xf);
149+
if (!--smpboot_warm_reset_vector_count) {
150+
CMOS_WRITE(0, 0xf);
151+
*((volatile u32 *)phys_to_virt(TRAMPOLINE_PHYS_LOW)) = 0;
152+
}
147153
spin_unlock_irqrestore(&rtc_lock, flags);
148154

149-
*((volatile u32 *)phys_to_virt(TRAMPOLINE_PHYS_LOW)) = 0;
150155
}
151156

152157
/*

0 commit comments

Comments
 (0)