aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>2006-03-31 17:44:26 +0100
committercl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>2006-03-31 17:44:26 +0100
commit05c8070bb4eac07ff52203ef090b8881bd56560b (patch)
tree5b746ab983e9180ccc8314aa2a1c38f18e944f9f
parente5829dcbe18cb47ca3c55b589289bbb67dd41213 (diff)
downloadxen-05c8070bb4eac07ff52203ef090b8881bd56560b.tar.gz
xen-05c8070bb4eac07ff52203ef090b8881bd56560b.tar.bz2
xen-05c8070bb4eac07ff52203ef090b8881bd56560b.zip
Fix do_IRQ high bit masking.
Instead of setting the highest bit (which isn't easily done on native x86_64), negate the interrupt vector stored in orig_{e,r}ax. Also add patch for native build. Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
-rw-r--r--linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S4
-rw-r--r--linux-2.6-xen-sparse/arch/i386/kernel/irq-xen.c2
-rw-r--r--linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S2
-rw-r--r--linux-2.6-xen-sparse/arch/x86_64/kernel/irq-xen.c2
-rw-r--r--linux-2.6-xen-sparse/drivers/xen/core/evtchn.c6
-rw-r--r--patches/linux-2.6.16/x86-increase-interrupt-vector-range.patch107
6 files changed, 115 insertions, 8 deletions
diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S b/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S
index c1784979e3..072172cda7 100644
--- a/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S
@@ -461,7 +461,7 @@ vector=0
ENTRY(irq_entries_start)
.rept NR_IRQS
ALIGN
-1: pushl 0x80000000+$vector
+1: pushl $~(vector)
jmp common_interrupt
.data
.long 1b
@@ -478,7 +478,7 @@ common_interrupt:
#define BUILD_INTERRUPT(name, nr) \
ENTRY(name) \
- pushl 0x80000000+$nr; \
+ pushl $~(nr); \
SAVE_ALL \
movl %esp,%eax; \
call smp_/**/name; \
diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/irq-xen.c b/linux-2.6-xen-sparse/arch/i386/kernel/irq-xen.c
index b1d8634bd6..b4a38e4d92 100644
--- a/linux-2.6-xen-sparse/arch/i386/kernel/irq-xen.c
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/irq-xen.c
@@ -54,7 +54,7 @@ static union irq_ctx *softirq_ctx[NR_CPUS];
fastcall unsigned int do_IRQ(struct pt_regs *regs)
{
/* high bit used in ret_from_ code */
- int irq = regs->orig_eax & __IRQ_MASK(BITS_PER_LONG - 1);
+ int irq = ~regs->orig_eax;
#ifdef CONFIG_4KSTACKS
union irq_ctx *curctx, *irqctx;
u32 *isp;
diff --git a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S
index 604365dec3..2930d58da2 100644
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S
@@ -584,7 +584,7 @@ retint_kernel:
*/
.macro apicinterrupt num,func
INTR_FRAME
- pushq 0x8000000000000000+$\num
+ pushq $~(\num)
CFI_ADJUST_CFA_OFFSET 8
interrupt \func
jmp error_entry
diff --git a/linux-2.6-xen-sparse/arch/x86_64/kernel/irq-xen.c b/linux-2.6-xen-sparse/arch/x86_64/kernel/irq-xen.c
index 663e890c94..268f8cd6dc 100644
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/irq-xen.c
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/irq-xen.c
@@ -97,7 +97,7 @@ skip:
asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
{
/* high bit used in ret_from_ code */
- int irq = regs->orig_rax & __IRQ_MASK(BITS_PER_LONG - 1);
+ unsigned irq = ~regs->orig_rax;
exit_idle();
irq_enter();
diff --git a/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c b/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c
index 6dee25cab7..820ce89069 100644
--- a/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c
+++ b/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c
@@ -170,9 +170,9 @@ static inline void exit_idle(void) {}
#include <asm/idle.h>
#define IRQ_REG orig_rax
#endif
-#define do_IRQ(irq, regs) do { \
- (regs)->IRQ_REG = (irq) | (1UL << (BITS_PER_LONG - 1)); \
- do_IRQ((regs)); \
+#define do_IRQ(irq, regs) do { \
+ (regs)->IRQ_REG = ~(irq); \
+ do_IRQ((regs)); \
} while (0)
#endif
diff --git a/patches/linux-2.6.16/x86-increase-interrupt-vector-range.patch b/patches/linux-2.6.16/x86-increase-interrupt-vector-range.patch
new file mode 100644
index 0000000000..c79abfc274
--- /dev/null
+++ b/patches/linux-2.6.16/x86-increase-interrupt-vector-range.patch
@@ -0,0 +1,107 @@
+Subject: Increase x86 interrupt vector range
+
+Remove the limit of 256 interrupt vectors by changing the value
+stored in orig_{e,r}ax to be the negated interrupt vector.
+The orig_{e,r}ax needs to be < 0 to allow the signal code to
+distinguish between return from interrupt and return from syscall.
+With this change applied, NR_IRQS can be > 256.
+
+Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
+---
+ arch/i386/kernel/entry.S | 4 ++--
+ arch/i386/kernel/irq.c | 4 ++--
+ arch/x86_64/kernel/entry.S | 2 +-
+ arch/x86_64/kernel/irq.c | 4 ++--
+ arch/x86_64/kernel/smp.c | 4 ++--
+ include/asm-x86_64/hw_irq.h | 2 +-
+ 6 files changed, 10 insertions(+), 10 deletions(-)
+
+diff -r 7d239c83edea arch/i386/kernel/entry.S
+--- a/arch/i386/kernel/entry.S Mon Mar 20 06:00:20 2006 +0000
++++ b/arch/i386/kernel/entry.S Fri Mar 31 17:01:35 2006 +0100
+@@ -406,7 +406,7 @@ ENTRY(irq_entries_start)
+ ENTRY(irq_entries_start)
+ .rept NR_IRQS
+ ALIGN
+-1: pushl $vector-256
++1: pushl $~(vector)
+ jmp common_interrupt
+ .data
+ .long 1b
+@@ -423,7 +423,7 @@ common_interrupt:
+
+ #define BUILD_INTERRUPT(name, nr) \
+ ENTRY(name) \
+- pushl $nr-256; \
++ pushl $~(nr); \
+ SAVE_ALL \
+ movl %esp,%eax; \
+ call smp_/**/name; \
+diff -r 7d239c83edea arch/i386/kernel/irq.c
+--- a/arch/i386/kernel/irq.c Mon Mar 20 06:00:20 2006 +0000
++++ b/arch/i386/kernel/irq.c Fri Mar 31 17:01:35 2006 +0100
+@@ -53,8 +53,8 @@ static union irq_ctx *softirq_ctx[NR_CPU
+ */
+ fastcall unsigned int do_IRQ(struct pt_regs *regs)
+ {
+- /* high bits used in ret_from_ code */
+- int irq = regs->orig_eax & 0xff;
++ /* high bit used in ret_from_ code */
++ int irq = ~regs->orig_eax;
+ #ifdef CONFIG_4KSTACKS
+ union irq_ctx *curctx, *irqctx;
+ u32 *isp;
+diff -r 7d239c83edea arch/x86_64/kernel/entry.S
+--- a/arch/x86_64/kernel/entry.S Mon Mar 20 06:00:20 2006 +0000
++++ b/arch/x86_64/kernel/entry.S Fri Mar 31 17:01:35 2006 +0100
+@@ -609,7 +609,7 @@ retint_kernel:
+ */
+ .macro apicinterrupt num,func
+ INTR_FRAME
+- pushq $\num-256
++ pushq $~(\num)
+ CFI_ADJUST_CFA_OFFSET 8
+ interrupt \func
+ jmp ret_from_intr
+diff -r 7d239c83edea arch/x86_64/kernel/irq.c
+--- a/arch/x86_64/kernel/irq.c Mon Mar 20 06:00:20 2006 +0000
++++ b/arch/x86_64/kernel/irq.c Fri Mar 31 17:01:35 2006 +0100
+@@ -96,8 +96,8 @@ skip:
+ */
+ asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
+ {
+- /* high bits used in ret_from_ code */
+- unsigned irq = regs->orig_rax & 0xff;
++ /* high bit used in ret_from_ code */
++ unsigned irq = ~regs->orig_rax;
+
+ exit_idle();
+ irq_enter();
+diff -r 7d239c83edea arch/x86_64/kernel/smp.c
+--- a/arch/x86_64/kernel/smp.c Mon Mar 20 06:00:20 2006 +0000
++++ b/arch/x86_64/kernel/smp.c Fri Mar 31 17:01:35 2006 +0100
+@@ -135,10 +135,10 @@ asmlinkage void smp_invalidate_interrupt
+
+ cpu = smp_processor_id();
+ /*
+- * orig_rax contains the interrupt vector - 256.
++ * orig_rax contains the negated interrupt vector.
+ * Use that to determine where the sender put the data.
+ */
+- sender = regs->orig_rax + 256 - INVALIDATE_TLB_VECTOR_START;
++ sender = ~regs->orig_rax - INVALIDATE_TLB_VECTOR_START;
+ f = &per_cpu(flush_state, sender);
+
+ if (!cpu_isset(cpu, f->flush_cpumask))
+diff -r 7d239c83edea include/asm-x86_64/hw_irq.h
+--- a/include/asm-x86_64/hw_irq.h Mon Mar 20 06:00:20 2006 +0000
++++ b/include/asm-x86_64/hw_irq.h Fri Mar 31 17:01:35 2006 +0100
+@@ -127,7 +127,7 @@ __asm__( \
+ __asm__( \
+ "\n.p2align\n" \
+ "IRQ" #nr "_interrupt:\n\t" \
+- "push $" #nr "-256 ; " \
++ "push $~(" #nr ") ; " \
+ "jmp common_interrupt");
+
+ #if defined(CONFIG_X86_IO_APIC)