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

[Xen-changelog] [xen master] xen/arm: Handle platforms with edge-triggered virtual timer



commit f688aec47c452d6aef382739d0781735672ef995
Author:     Julien Grall <julien.grall@xxxxxxxxxx>
AuthorDate: Fri Nov 28 15:17:06 2014 +0000
Commit:     Ian Campbell <ian.campbell@xxxxxxxxxx>
CommitDate: Thu Dec 4 12:10:45 2014 +0000

    xen/arm: Handle platforms with edge-triggered virtual timer
    
    Some platforms (such as Xgene and ARMv8 models) use an edge-triggered 
interrupt
    for the virtual timer. Even if the timer output signal is masked in the
    context switch, the GIC will keep track that of any interrupts raised
    while IRQs are disabled. As soon as IRQs are re-enabled, the virtual
    interrupt timer will be injected to Xen.
    
    If an idle vVCPU was scheduled next then the interrupt handler doesn't
    expect to the receive the IRQ and will crash:
    
    (XEN)    [<0000000000228388>] _spin_lock_irqsave+0x28/0x94 (PC)
    (XEN)    [<0000000000228380>] _spin_lock_irqsave+0x20/0x94 (LR)
    (XEN)    [<0000000000250510>] vgic_vcpu_inject_irq+0x40/0x1b0
    (XEN)    [<000000000024bcd0>] vtimer_interrupt+0x4c/0x54
    (XEN)    [<0000000000247010>] do_IRQ+0x1a4/0x220
    (XEN)    [<0000000000244864>] gic_interrupt+0x50/0xec
    (XEN)    [<000000000024fbac>] do_trap_irq+0x20/0x2c
    (XEN)    [<0000000000255240>] hyp_irq+0x5c/0x60
    (XEN)    [<0000000000241084>] context_switch+0xb8/0xc4
    (XEN)    [<000000000022482c>] schedule+0x684/0x6d0
    (XEN)    [<000000000022785c>] __do_softirq+0xcc/0xe8
    (XEN)    [<00000000002278d4>] do_softirq+0x14/0x1c
    (XEN)    [<0000000000240fac>] idle_loop+0x134/0x154
    (XEN)    [<000000000024c160>] start_secondary+0x14c/0x15c
    (XEN)    [<0000000000000001>] 0000000000000001
    
    The proper solution is to context switch the virtual interrupt state at
    the GIC level. This would also avoid masking the output signal which
    requires specific handling in the guest OS and more complex code in Xen
    to deal with EOIs, and so is desirable for that reason too.
    
    Sadly, this solution requires some refactoring which would not be
    suitable for a freeze exception for the Xen 4.5 release.
    
    For now implement a temporary solution which ignores the virtual timer
    interrupt when the idle VCPU is running.
    
    Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx>
    Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
    [ ijc -- tweaked some wording in the comment ]
---
 xen/arch/arm/time.c |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/xen/arch/arm/time.c b/xen/arch/arm/time.c
index a6436f1..0add494 100644
--- a/xen/arch/arm/time.c
+++ b/xen/arch/arm/time.c
@@ -169,6 +169,19 @@ static void timer_interrupt(int irq, void *dev_id, struct 
cpu_user_regs *regs)
 
 static void vtimer_interrupt(int irq, void *dev_id, struct cpu_user_regs *regs)
 {
+    /*
+     * Edge-triggered interrupts can be used for the virtual timer. Even
+     * if the timer output signal is masked in the context switch, the
+     * GIC will keep track that of any interrupts raised while IRQS are
+     * disabled. As soon as IRQs are re-enabled, the virtual interrupt
+     * will be injected to Xen.
+     *
+     * If an IDLE vCPU was scheduled next then we should ignore the
+     * interrupt.
+     */
+    if ( unlikely(is_idle_vcpu(current)) )
+        return;
+
     current->arch.virt_timer.ctl = READ_SYSREG32(CNTV_CTL_EL0);
     WRITE_SYSREG32(current->arch.virt_timer.ctl | CNTx_CTL_MASK, CNTV_CTL_EL0);
     vgic_vcpu_inject_irq(current, current->arch.virt_timer.irq);
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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