Commit c3881eb5 authored by Miroslav Benes's avatar Miroslav Benes Committed by Juergen Gross

x86/xen: Make the secondary CPU idle tasks reliable

The unwinder reports the secondary CPU idle tasks' stack on XEN PV as
unreliable, which affects at least live patching.
cpu_initialize_context() sets up the context of the CPU through
VCPUOP_initialise hypercall. After it is woken up, the idle task starts
in cpu_bringup_and_idle() function and its stack starts at the offset
right below pt_regs. The unwinder correctly detects the end of stack
there but it is confused by NULL return address in the last frame.

Introduce a wrapper in assembly, which just calls
cpu_bringup_and_idle(). The return address is thus pushed on the stack
and the wrapper contains the annotation hint for the unwinder regarding
the stack state.
Signed-off-by: default avatarMiroslav Benes <mbenes@suse.cz>
Reviewed-by: default avatarJuergen Gross <jgross@suse.com>
Signed-off-by: default avatarJuergen Gross <jgross@suse.com>
parent 2f62f36e
...@@ -53,6 +53,7 @@ static DEFINE_PER_CPU(struct xen_common_irq, xen_irq_work) = { .irq = -1 }; ...@@ -53,6 +53,7 @@ static DEFINE_PER_CPU(struct xen_common_irq, xen_irq_work) = { .irq = -1 };
static DEFINE_PER_CPU(struct xen_common_irq, xen_pmu_irq) = { .irq = -1 }; static DEFINE_PER_CPU(struct xen_common_irq, xen_pmu_irq) = { .irq = -1 };
static irqreturn_t xen_irq_work_interrupt(int irq, void *dev_id); static irqreturn_t xen_irq_work_interrupt(int irq, void *dev_id);
void asm_cpu_bringup_and_idle(void);
static void cpu_bringup(void) static void cpu_bringup(void)
{ {
...@@ -309,7 +310,7 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle) ...@@ -309,7 +310,7 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
* pointing just below where pt_regs would be if it were a normal * pointing just below where pt_regs would be if it were a normal
* kernel entry. * kernel entry.
*/ */
ctxt->user_regs.eip = (unsigned long)cpu_bringup_and_idle; ctxt->user_regs.eip = (unsigned long)asm_cpu_bringup_and_idle;
ctxt->flags = VGCF_IN_KERNEL; ctxt->flags = VGCF_IN_KERNEL;
ctxt->user_regs.eflags = 0x1000; /* IOPL_RING1 */ ctxt->user_regs.eflags = 0x1000; /* IOPL_RING1 */
ctxt->user_regs.ds = __USER_DS; ctxt->user_regs.ds = __USER_DS;
......
...@@ -58,6 +58,16 @@ SYM_CODE_START(startup_xen) ...@@ -58,6 +58,16 @@ SYM_CODE_START(startup_xen)
call xen_start_kernel call xen_start_kernel
SYM_CODE_END(startup_xen) SYM_CODE_END(startup_xen)
__FINIT __FINIT
#ifdef CONFIG_XEN_PV_SMP
.pushsection .text
SYM_CODE_START(asm_cpu_bringup_and_idle)
UNWIND_HINT_EMPTY
call cpu_bringup_and_idle
SYM_CODE_END(asm_cpu_bringup_and_idle)
.popsection
#endif
#endif #endif
.pushsection .text .pushsection .text
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment