[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [RFC][PATCH 07/10] xen/hybrid: Add PV timer support



If we have event channel, we can use VIRQ_TIMER to deliver timer interrupt,
otherwise we would reuse IRQ0.

Signed-off-by: Sheng Yang <sheng@xxxxxxxxxxxxxxx>
---
 arch/x86/xen/enlighten.c |   14 ++++++++++++++
 arch/x86/xen/time.c      |   18 +++++++++++++++---
 2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index b6751ed..18aba22 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -53,6 +53,8 @@
 #include <asm/tlbflush.h>
 #include <asm/reboot.h>
 
+#include <xen/hvm.h>
+
 #include "xen-ops.h"
 #include "mmu.h"
 #include "multicalls.h"
@@ -1050,6 +1052,9 @@ static void __init xen_hybrid_banner(void)
        printk(KERN_INFO "Booting hybrid kernel on %s\n", pv_info.name);
        printk(KERN_INFO "Xen version: %d.%d%s\n",
               version >> 16, version & 0xffff, extra.extraversion);
+
+       if (xen_hybrid_timer_enabled())
+               printk(KERN_INFO "Hybrid feature: PV Timer enabled\n");
 }
 
 static int xen_para_available(void)
@@ -1093,6 +1098,10 @@ static int init_hybrid_info(void)
                return -ENODEV;
 
        xen_hybrid_status = XEN_HYBRID_ENABLED;
+       if (edx & XEN_CPUID_FEAT2_HYBRID_TIMER) {
+               xen_hybrid_status |= XEN_HYBRID_TIMER_ENABLED;
+               flags |= HVM_HYBRID_TIMER;
+       }
 
        /* We only support 1 page of hypercall for now */
        if (pages != 1)
@@ -1149,5 +1158,10 @@ void __init xen_start_hybrid(void)
        xen_hybrid_init_irq_ops();
 
        init_shared_info();
+
+       if (xen_hybrid_timer_enabled()) {
+               pv_time_ops = xen_time_ops;
+               pv_apic_ops = xen_apic_ops;
+       }
 }
 
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
index 0a5aa44..381f135 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -421,6 +421,13 @@ static irqreturn_t xen_timer_interrupt(int irq, void 
*dev_id)
        return ret;
 }
 
+static struct irqaction xen_timer_irq0 = {
+       .handler        = xen_timer_interrupt,
+       .flags          = IRQF_DISABLED | IRQF_IRQPOLL |
+                         IRQF_NOBALANCING | IRQF_TIMER,
+       .name           = "timer"
+};
+
 void xen_setup_timer(int cpu)
 {
        const char *name;
@@ -433,9 +440,14 @@ void xen_setup_timer(int cpu)
        if (!name)
                name = "<timer kasprintf failed>";
 
-       irq = bind_virq_to_irqhandler(VIRQ_TIMER, cpu, xen_timer_interrupt,
-                                     
IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING,
-                                     name, NULL);
+       if (xen_hybrid_timer_enabled() && !xen_hybrid_evtchn_enabled()) {
+               irq = 0;
+               setup_irq(0, &xen_timer_irq0);
+       } else
+               irq = bind_virq_to_irqhandler(VIRQ_TIMER, cpu,
+                               xen_timer_interrupt,
+                               IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING,
+                               name, NULL);
 
        evt = &per_cpu(xen_clock_events, cpu);
        memcpy(evt, xen_clockevent, sizeof(*evt));
-- 
1.5.4.5


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.