WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH 10 of 38] x86: add handle_irq() to allow interrupt in

To: Ingo Molnar <mingo@xxxxxxx>
Subject: [Xen-devel] [PATCH 10 of 38] x86: add handle_irq() to allow interrupt injection
From: Jeremy Fitzhardinge <jeremy@xxxxxxxx>
Date: Thu, 13 Nov 2008 11:10:08 -0800
Cc: the arch/x86 maintainers <x86@xxxxxxxxxx>, Xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxx>, linux-kernel@xxxxxxxxxxxxxxx, Ian Campbell <ian.campbell@xxxxxxxxxx>
Delivery-date: Thu, 13 Nov 2008 11:41:05 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <patchbomb.1226603398@xxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Xen uses a different interrupt path, so introduce handle_irq() to
allow interrupts to be inserted into the normal interrupt path.  This
is handled slightly differently on 32 and 64-bit.

Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@xxxxxxxxxx>
---
 arch/x86/include/asm/irq.h |    1 +
 arch/x86/kernel/irq_32.c   |   34 +++++++++++++++++++++-------------
 arch/x86/kernel/irq_64.c   |   27 ++++++++++++++++++---------
 3 files changed, 40 insertions(+), 22 deletions(-)

diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h
--- a/arch/x86/include/asm/irq.h
+++ b/arch/x86/include/asm/irq.h
@@ -39,6 +39,7 @@
 extern unsigned int do_IRQ(struct pt_regs *regs);
 extern void init_IRQ(void);
 extern void native_init_IRQ(void);
+extern bool handle_irq(unsigned irq, struct pt_regs *regs);
 
 /* Interrupt vector management */
 extern DECLARE_BITMAP(used_vectors, NR_VECTORS);
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
--- a/arch/x86/kernel/irq_32.c
+++ b/arch/x86/kernel/irq_32.c
@@ -191,6 +191,26 @@
 execute_on_irq_stack(int overflow, struct irq_desc *desc, int irq) { return 0; 
}
 #endif
 
+bool handle_irq(unsigned irq, struct pt_regs *regs)
+{
+       struct irq_desc *desc;
+       int overflow;
+
+       overflow = check_stack_overflow();
+
+       desc = irq_to_desc(irq);
+       if (unlikely(!desc))
+               return false;
+
+       if (!execute_on_irq_stack(overflow, desc, irq)) {
+               if (unlikely(overflow))
+                       print_stack_overflow();
+               desc->handle_irq(irq, desc);
+       }
+
+       return true;
+}
+
 /*
  * do_IRQ handles all normal device IRQ's (the special
  * SMP cross-CPU interrupts have their own specific
@@ -200,31 +220,19 @@
 {
        struct pt_regs *old_regs;
        /* high bit used in ret_from_ code */
-       int overflow;
        unsigned vector = ~regs->orig_ax;
-       struct irq_desc *desc;
        unsigned irq;
 
-
        old_regs = set_irq_regs(regs);
        irq_enter();
        irq = __get_cpu_var(vector_irq)[vector];
 
-       overflow = check_stack_overflow();
-
-       desc = irq_to_desc(irq);
-       if (unlikely(!desc)) {
+       if (!handle_irq(irq, regs)) {
                printk(KERN_EMERG "%s: cannot handle IRQ %d vector %#x cpu 
%d\n",
                                        __func__, irq, vector, 
smp_processor_id());
                BUG();
        }
 
-       if (!execute_on_irq_stack(overflow, desc, irq)) {
-               if (unlikely(overflow))
-                       print_stack_overflow();
-               desc->handle_irq(irq, desc);
-       }
-
        irq_exit();
        set_irq_regs(old_regs);
        return 1;
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -42,6 +42,22 @@
 }
 #endif
 
+bool handle_irq(unsigned irq, struct pt_regs *regs)
+{
+       struct irq_desc *desc;
+
+#ifdef CONFIG_DEBUG_STACKOVERFLOW
+       stack_overflow_check(regs);
+#endif
+
+       desc = irq_to_desc(irq);
+       if (unlikely(!desc))
+               return false;
+
+       generic_handle_irq_desc(irq, desc);
+       return true;
+}
+
 /*
  * do_IRQ handles all normal device IRQ's (the special
  * SMP cross-CPU interrupts have their own specific
@@ -50,7 +66,6 @@
 asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
 {
        struct pt_regs *old_regs = set_irq_regs(regs);
-       struct irq_desc *desc;
 
        /* high bit used in ret_from_ code  */
        unsigned vector = ~regs->orig_ax;
@@ -58,16 +73,10 @@
 
        exit_idle();
        irq_enter();
+
        irq = __get_cpu_var(vector_irq)[vector];
 
-#ifdef CONFIG_DEBUG_STACKOVERFLOW
-       stack_overflow_check(regs);
-#endif
-
-       desc = irq_to_desc(irq);
-       if (likely(desc))
-               generic_handle_irq_desc(irq, desc);
-       else {
+       if (!handle_irq(irq, regs)) {
                if (!disable_apic)
                        ack_APIC_irq();
 



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

<Prev in Thread] Current Thread [Next in Thread>