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 <jgross@suse.com> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20221125063248.30256-2-jgross@suse.com Signed-off-by: Juergen Gross <jgross@suse.com>
This commit is contained in:
parent
415dab3c17
commit
336f560a89
|
@ -21,6 +21,8 @@ void xen_smp_send_reschedule(int cpu);
|
|||
void xen_smp_send_call_function_ipi(const struct cpumask *mask);
|
||||
void xen_smp_send_call_function_single_ipi(int cpu);
|
||||
|
||||
void xen_cpu_bringup_again(unsigned long stack);
|
||||
|
||||
struct xen_common_irq {
|
||||
int irq;
|
||||
char *name;
|
||||
|
|
|
@ -385,17 +385,8 @@ static void xen_pv_play_dead(void) /* used only with HOTPLUG_CPU */
|
|||
{
|
||||
play_dead_common();
|
||||
HYPERVISOR_vcpu_op(VCPUOP_down, xen_vcpu_nr(smp_processor_id()), NULL);
|
||||
cpu_bringup();
|
||||
/*
|
||||
* commit 4b0c0f294 (tick: Cleanup NOHZ per cpu data on cpu down)
|
||||
* clears certain data that the cpu_idle loop (which called us
|
||||
* and that we return from) expects. The only way to get that
|
||||
* data back is to call:
|
||||
*/
|
||||
tick_nohz_idle_enter();
|
||||
tick_nohz_idle_stop_tick_protected();
|
||||
|
||||
cpuhp_online_idle(CPUHP_AP_ONLINE_IDLE);
|
||||
xen_cpu_bringup_again((unsigned long)task_pt_regs(current));
|
||||
BUG();
|
||||
}
|
||||
|
||||
#else /* !CONFIG_HOTPLUG_CPU */
|
||||
|
|
|
@ -76,6 +76,13 @@ SYM_CODE_START(asm_cpu_bringup_and_idle)
|
|||
|
||||
call cpu_bringup_and_idle
|
||||
SYM_CODE_END(asm_cpu_bringup_and_idle)
|
||||
|
||||
SYM_CODE_START(xen_cpu_bringup_again)
|
||||
UNWIND_HINT_FUNC
|
||||
mov %rdi, %rsp
|
||||
UNWIND_HINT_REGS
|
||||
call cpu_bringup_and_idle
|
||||
SYM_CODE_END(xen_cpu_bringup_again)
|
||||
.popsection
|
||||
#endif
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue