aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/xen/time.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/xen/time.c')
-rw-r--r--arch/x86/xen/time.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
index 0296a9522501..3d88bfdf9e1c 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -377,7 +377,7 @@ static const struct clock_event_device xen_vcpuop_clockevent = {
377 377
378static const struct clock_event_device *xen_clockevent = 378static const struct clock_event_device *xen_clockevent =
379 &xen_timerop_clockevent; 379 &xen_timerop_clockevent;
380static DEFINE_PER_CPU(struct clock_event_device, xen_clock_events); 380static DEFINE_PER_CPU(struct clock_event_device, xen_clock_events) = { .irq = -1 };
381 381
382static irqreturn_t xen_timer_interrupt(int irq, void *dev_id) 382static irqreturn_t xen_timer_interrupt(int irq, void *dev_id)
383{ 383{
@@ -401,6 +401,9 @@ void xen_setup_timer(int cpu)
401 struct clock_event_device *evt; 401 struct clock_event_device *evt;
402 int irq; 402 int irq;
403 403
404 evt = &per_cpu(xen_clock_events, cpu);
405 WARN(evt->irq >= 0, "IRQ%d for CPU%d is already allocated\n", evt->irq, cpu);
406
404 printk(KERN_INFO "installing Xen timer for CPU %d\n", cpu); 407 printk(KERN_INFO "installing Xen timer for CPU %d\n", cpu);
405 408
406 name = kasprintf(GFP_KERNEL, "timer%d", cpu); 409 name = kasprintf(GFP_KERNEL, "timer%d", cpu);
@@ -413,7 +416,6 @@ void xen_setup_timer(int cpu)
413 IRQF_FORCE_RESUME, 416 IRQF_FORCE_RESUME,
414 name, NULL); 417 name, NULL);
415 418
416 evt = &per_cpu(xen_clock_events, cpu);
417 memcpy(evt, xen_clockevent, sizeof(*evt)); 419 memcpy(evt, xen_clockevent, sizeof(*evt));
418 420
419 evt->cpumask = cpumask_of(cpu); 421 evt->cpumask = cpumask_of(cpu);
@@ -426,6 +428,7 @@ void xen_teardown_timer(int cpu)
426 BUG_ON(cpu == 0); 428 BUG_ON(cpu == 0);
427 evt = &per_cpu(xen_clock_events, cpu); 429 evt = &per_cpu(xen_clock_events, cpu);
428 unbind_from_irqhandler(evt->irq, NULL); 430 unbind_from_irqhandler(evt->irq, NULL);
431 evt->irq = -1;
429} 432}
430 433
431void xen_setup_cpu_clockevents(void) 434void xen_setup_cpu_clockevents(void)
@@ -497,7 +500,11 @@ static void xen_hvm_setup_cpu_clockevents(void)
497{ 500{
498 int cpu = smp_processor_id(); 501 int cpu = smp_processor_id();
499 xen_setup_runstate_info(cpu); 502 xen_setup_runstate_info(cpu);
500 xen_setup_timer(cpu); 503 /*
504 * xen_setup_timer(cpu) - snprintf is bad in atomic context. Hence
505 * doing it xen_hvm_cpu_notify (which gets called by smp_init during
506 * early bootup and also during CPU hotplug events).
507 */
501 xen_setup_cpu_clockevents(); 508 xen_setup_cpu_clockevents();
502} 509}
503 510