Skip to content

Commit 336f560

Browse files
committed
x86/xen: don't let xen_pv_play_dead() return
A function called via the paravirt play_dead() hook should not return to the caller. xen_pv_play_dead() has a problem in this regard, as it currently will return in case an offlined cpu is brought to life again. This can be changed only by doing basically a longjmp() to cpu_bringup_and_idle(), as the hypercall for bringing down the cpu will just return when the cpu is coming up again. Just re-initializing the cpu isn't possible, as the Xen hypervisor will deny that operation. So introduce xen_cpu_bringup_again() resetting the stack and calling cpu_bringup_and_idle(), which can be called after HYPERVISOR_vcpu_op() in xen_pv_play_dead(). Signed-off-by: Juergen Gross <[email protected]> Reviewed-by: Boris Ostrovsky <[email protected]> Acked-by: Peter Zijlstra (Intel) <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Juergen Gross <[email protected]>
1 parent 415dab3 commit 336f560

File tree

3 files changed

+11
-11
lines changed

3 files changed

+11
-11
lines changed

arch/x86/xen/smp.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ void xen_smp_send_reschedule(int cpu);
2121
void xen_smp_send_call_function_ipi(const struct cpumask *mask);
2222
void xen_smp_send_call_function_single_ipi(int cpu);
2323

24+
void xen_cpu_bringup_again(unsigned long stack);
25+
2426
struct xen_common_irq {
2527
int irq;
2628
char *name;

arch/x86/xen/smp_pv.c

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -385,17 +385,8 @@ static void xen_pv_play_dead(void) /* used only with HOTPLUG_CPU */
385385
{
386386
play_dead_common();
387387
HYPERVISOR_vcpu_op(VCPUOP_down, xen_vcpu_nr(smp_processor_id()), NULL);
388-
cpu_bringup();
389-
/*
390-
* commit 4b0c0f294 (tick: Cleanup NOHZ per cpu data on cpu down)
391-
* clears certain data that the cpu_idle loop (which called us
392-
* and that we return from) expects. The only way to get that
393-
* data back is to call:
394-
*/
395-
tick_nohz_idle_enter();
396-
tick_nohz_idle_stop_tick_protected();
397-
398-
cpuhp_online_idle(CPUHP_AP_ONLINE_IDLE);
388+
xen_cpu_bringup_again((unsigned long)task_pt_regs(current));
389+
BUG();
399390
}
400391

401392
#else /* !CONFIG_HOTPLUG_CPU */

arch/x86/xen/xen-head.S

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,13 @@ SYM_CODE_START(asm_cpu_bringup_and_idle)
7676

7777
call cpu_bringup_and_idle
7878
SYM_CODE_END(asm_cpu_bringup_and_idle)
79+
80+
SYM_CODE_START(xen_cpu_bringup_again)
81+
UNWIND_HINT_FUNC
82+
mov %rdi, %rsp
83+
UNWIND_HINT_REGS
84+
call cpu_bringup_and_idle
85+
SYM_CODE_END(xen_cpu_bringup_again)
7986
.popsection
8087
#endif
8188
#endif

0 commit comments

Comments
 (0)