On Tue, Jul 26, 2011 at 01:52:14PM +0200, Olaf Hering wrote:
> The kexec kernel will crash because the timer interrupt is already
> registerd with EVTCHNOP_bind_virq. Unbind the event channel during
> shutdown so that the kexec kernel can reregister the interrupt.
>
> Signed-off-by: Olaf Hering <olaf@xxxxxxxxx>
>
> ---
> arch/x86/xen/time.c | 27 ++++++++++++++++++++++++---
> 1 file changed, 24 insertions(+), 3 deletions(-)
>
> Index: linux-3.0/arch/x86/xen/time.c
> ===================================================================
> --- linux-3.0.orig/arch/x86/xen/time.c
> +++ linux-3.0/arch/x86/xen/time.c
> @@ -14,6 +14,7 @@
> #include <linux/kernel_stat.h>
> #include <linux/math64.h>
> #include <linux/gfp.h>
> +#include <linux/syscore_ops.h>
>
> #include <asm/pvclock.h>
> #include <asm/xen/hypervisor.h>
> @@ -405,12 +406,20 @@ void xen_setup_timer(int cpu)
> evt->irq = irq;
> }
>
> -void xen_teardown_timer(int cpu)
> +static void xen_unbind_timer(int cpu)
> {
> struct clock_event_device *evt;
> - BUG_ON(cpu == 0);
> evt = &per_cpu(xen_clock_events, cpu);
> - unbind_from_irqhandler(evt->irq, NULL);
> + if (evt->irq >= 0) {
> + unbind_from_irqhandler(evt->irq, NULL);
> + evt->irq = -1;
> + }
> +}
> +
> +void xen_teardown_timer(int cpu)
> +{
> + BUG_ON(cpu == 0);
Why the BUG? Ah you just copied it from xen_unbind_timer.
Hm, I wonder if we actually need that BUG_ON.
> + xen_unbind_timer(cpu);
> }
>
> void xen_setup_cpu_clockevents(void)
> @@ -478,6 +487,17 @@ void __init xen_init_time_ops(void)
> }
>
> #ifdef CONFIG_XEN_PVHVM
> +static void xen_hvmtimer_shutdown(void)
> +{
> + int cpu;
> + for_each_online_cpu(cpu)
> + xen_unbind_timer(cpu);
> +}
> +
> +static struct syscore_ops xen_hvmtimer_syscore_ops = {
> + .shutdown = xen_hvmtimer_shutdown,
> +};
> +
> static void xen_hvm_setup_cpu_clockevents(void)
> {
> int cpu = smp_processor_id();
> @@ -506,5 +526,6 @@ void __init xen_hvm_init_time_ops(void)
> x86_platform.calibrate_tsc = xen_tsc_khz;
> x86_platform.get_wallclock = xen_get_wallclock;
> x86_platform.set_wallclock = xen_set_wallclock;
> + register_syscore_ops(&xen_hvmtimer_syscore_ops);
> }
> #endif
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@xxxxxxxxxxxxxxxxxxx
> http://lists.xensource.com/xen-devel
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|