From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758419AbYLPUuW (ORCPT ); Tue, 16 Dec 2008 15:50:22 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1755032AbYLPUuE (ORCPT ); Tue, 16 Dec 2008 15:50:04 -0500 Received: from mx3.mail.elte.hu ([157.181.1.138]:48846 "EHLO mx3.mail.elte.hu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752881AbYLPUuB (ORCPT ); Tue, 16 Dec 2008 15:50:01 -0500 Date: Tue, 16 Dec 2008 21:49:46 +0100 From: Ingo Molnar To: Jeremy Fitzhardinge Cc: the arch/x86 maintainers , Linux Kernel Mailing List Subject: Re: [PATCH] x86: add handle_irq() to allow interrupt injection Message-ID: <20081216204946.GE14787@elte.hu> References: <494810F0.1010101@goop.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <494810F0.1010101@goop.org> User-Agent: Mutt/1.5.18 (2008-05-17) X-ELTE-VirusStatus: clean X-ELTE-SpamScore: -1.5 X-ELTE-SpamLevel: X-ELTE-SpamCheck: no X-ELTE-SpamVersion: ELTE 2.0 X-ELTE-SpamCheck-Details: score=-1.5 required=5.9 tests=BAYES_00 autolearn=no SpamAssassin version=3.2.3 -1.5 BAYES_00 BODY: Bayesian spam probability is 0 to 1% [score: 0.0000] Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org * Jeremy Fitzhardinge wrote: > 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 > --- > arch/x86/include/asm/irq.h | 1 + > arch/x86/kernel/irq_32.c | 34 +++++++++++++++++++++------------- > arch/x86/kernel/irq_64.c | 23 ++++++++++++++++------- > 3 files changed, 38 insertions(+), 20 deletions(-) > > =================================================================== > --- 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); > =================================================================== > --- 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; > =================================================================== > --- a/arch/x86/kernel/irq_64.c > +++ b/arch/x86/kernel/irq_64.c > @@ -40,6 +40,20 @@ > #endif > } > > +bool handle_irq(unsigned irq, struct pt_regs *regs) > +{ > + struct irq_desc *desc; > + > + stack_overflow_check(regs); > + > + 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 > @@ -48,7 +62,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; > @@ -56,14 +69,10 @@ > > exit_idle(); > irq_enter(); > + > irq = __get_cpu_var(vector_irq)[vector]; > > - stack_overflow_check(regs); > - > - 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(); > the changes look rather similar. Could you please look into unifying irq_*.c before adding more logic to it? Ingo