From: Jeremy Fitzhardinge <jeremy@goop.org>
To: Ingo Molnar <mingo@elte.hu>
Cc: the arch/x86 maintainers <x86@kernel.org>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] x86: add handle_irq() to allow interrupt injection
Date: Wed, 17 Dec 2008 15:06:09 -0800 [thread overview]
Message-ID: <494985E1.90304@goop.org> (raw)
In-Reply-To: <20081216204946.GE14787@elte.hu>
Ingo Molnar wrote:
> * Jeremy Fitzhardinge <jeremy@goop.org> 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 <jeremy.fitzhardinge@citrix.com>
>> ---
>> 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?
>
I didn't really add more logic - I just hoisted some existing code into
a new function.
It does make do_IRQ() itself trivial to unify now. But the rest looks
non-trivial: fixup_irqs() is quite different, as is the interrupt stack
stuff.
Hm, what does asmlinkage do on x86-64?
J
Subject: x86: unify do_IRQ()
With the differences in interrupt handling hoisted into handle_irq(),
do_IRQ is more or less identical between 32 and 64 bit, so unify it.
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
---
arch/x86/include/asm/irq.h | 1 -
arch/x86/kernel/irq.c | 41 +++++++++++++++++++++++++++++++++++++++++
arch/x86/kernel/irq_32.c | 27 ---------------------------
arch/x86/kernel/irq_64.c | 33 ---------------------------------
4 files changed, 41 insertions(+), 61 deletions(-)
===================================================================
--- a/arch/x86/include/asm/irq.h
+++ b/arch/x86/include/asm/irq.h
@@ -36,7 +36,6 @@
extern void fixup_irqs(cpumask_t map);
#endif
-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);
===================================================================
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -5,10 +5,12 @@
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/seq_file.h>
+#include <linux/ftrace.h>
#include <asm/apic.h>
#include <asm/io_apic.h>
#include <asm/smp.h>
+#include <asm/idle.h>
atomic_t irq_err_count;
@@ -195,3 +197,42 @@
#endif
return sum;
}
+
+
+/*
+ * do_IRQ handles all normal device IRQ's (the special
+ * SMP cross-CPU interrupts have their own specific
+ * handlers).
+ */
+#ifdef CONFIG_X86_64
+asmlinkage
+#endif
+unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
+{
+ struct pt_regs *old_regs = set_irq_regs(regs);
+
+ /* high bit used in ret_from_ code */
+ unsigned vector = ~regs->orig_ax;
+ unsigned irq;
+
+ exit_idle();
+ irq_enter();
+
+ irq = __get_cpu_var(vector_irq)[vector];
+
+ if (!handle_irq(irq, regs)) {
+#ifdef CONFIG_X86_64
+ if (!disable_apic)
+ ack_APIC_irq();
+#endif
+
+ if (printk_ratelimit())
+ printk(KERN_EMERG "%s: %d.%d No irq handler for vector (irq %d)\n",
+ __func__, smp_processor_id(), vector, irq);
+ }
+
+ irq_exit();
+
+ set_irq_regs(old_regs);
+ return 1;
+}
===================================================================
--- a/arch/x86/kernel/irq_32.c
+++ b/arch/x86/kernel/irq_32.c
@@ -211,33 +211,6 @@
return true;
}
-/*
- * do_IRQ handles all normal device IRQ's (the special
- * SMP cross-CPU interrupts have their own specific
- * handlers).
- */
-unsigned int do_IRQ(struct pt_regs *regs)
-{
- struct pt_regs *old_regs;
- /* high bit used in ret_from_ code */
- unsigned vector = ~regs->orig_ax;
- unsigned irq;
-
- old_regs = set_irq_regs(regs);
- irq_enter();
- irq = __get_cpu_var(vector_irq)[vector];
-
- 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();
- }
-
- irq_exit();
- set_irq_regs(old_regs);
- return 1;
-}
-
#ifdef CONFIG_HOTPLUG_CPU
#include <mach_apic.h>
===================================================================
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -55,39 +55,6 @@
return true;
}
-/*
- * do_IRQ handles all normal device IRQ's (the special
- * SMP cross-CPU interrupts have their own specific
- * handlers).
- */
-asmlinkage unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
-{
- struct pt_regs *old_regs = set_irq_regs(regs);
-
- /* high bit used in ret_from_ code */
- unsigned vector = ~regs->orig_ax;
- unsigned irq;
-
- exit_idle();
- irq_enter();
-
- irq = __get_cpu_var(vector_irq)[vector];
-
- if (!handle_irq(irq, regs)) {
- if (!disable_apic)
- ack_APIC_irq();
-
- if (printk_ratelimit())
- printk(KERN_EMERG "%s: %d.%d No irq handler for vector\n",
- __func__, smp_processor_id(), vector);
- }
-
- irq_exit();
-
- set_irq_regs(old_regs);
- return 1;
-}
-
#ifdef CONFIG_HOTPLUG_CPU
void fixup_irqs(cpumask_t map)
{
next prev parent reply other threads:[~2008-12-17 23:06 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-12-16 20:34 [PATCH] x86: add handle_irq() to allow interrupt injection Jeremy Fitzhardinge
2008-12-16 20:49 ` Ingo Molnar
2008-12-17 23:06 ` Jeremy Fitzhardinge [this message]
2008-12-18 5:28 ` Cyrill Gorcunov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=494985E1.90304@goop.org \
--to=jeremy@goop.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.