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

[Xen-changelog] Fix do_IRQ high bit masking.



# HG changeset patch
# User cl349@xxxxxxxxxxxxxxxxxxxx
# Node ID d76a7a40f3a997b7faa1e2e85acbde213aa68a8b
# Parent  dadadf9aeee713bbe2f8dc040a74f7cea2223f41
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@xxxxxxxxxxxx>

diff -r dadadf9aeee7 -r d76a7a40f3a9 
linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S
--- a/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S Fri Mar 31 14:34:52 2006
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S Fri Mar 31 16:44:26 2006
@@ -461,7 +461,7 @@
 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 @@
 
 #define BUILD_INTERRUPT(name, nr)      \
 ENTRY(name)                            \
-       pushl 0x80000000+$nr;           \
+       pushl $~(nr);                   \
        SAVE_ALL                        \
        movl %esp,%eax;                 \
        call smp_/**/name;              \
diff -r dadadf9aeee7 -r d76a7a40f3a9 
linux-2.6-xen-sparse/arch/i386/kernel/irq-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/irq-xen.c   Fri Mar 31 14:34:52 2006
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/irq-xen.c   Fri Mar 31 16:44:26 2006
@@ -54,7 +54,7 @@
 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 -r dadadf9aeee7 -r d76a7a40f3a9 
linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S       Fri Mar 31 
14:34:52 2006
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S       Fri Mar 31 
16:44:26 2006
@@ -584,7 +584,7 @@
  */            
        .macro apicinterrupt num,func
        INTR_FRAME
-       pushq 0x8000000000000000+$\num
+       pushq $~(\num)
        CFI_ADJUST_CFA_OFFSET 8
        interrupt \func
        jmp error_entry
diff -r dadadf9aeee7 -r d76a7a40f3a9 
linux-2.6-xen-sparse/arch/x86_64/kernel/irq-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/irq-xen.c Fri Mar 31 14:34:52 2006
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/irq-xen.c Fri Mar 31 16:44:26 2006
@@ -97,7 +97,7 @@
 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 -r dadadf9aeee7 -r d76a7a40f3a9 
linux-2.6-xen-sparse/drivers/xen/core/evtchn.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c    Fri Mar 31 14:34:52 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c    Fri Mar 31 16:44:26 2006
@@ -170,9 +170,9 @@
 #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 -r dadadf9aeee7 -r d76a7a40f3a9 
patches/linux-2.6.16/x86-increase-interrupt-vector-range.patch
--- /dev/null   Fri Mar 31 14:34:52 2006
+++ b/patches/linux-2.6.16/x86-increase-interrupt-vector-range.patch    Fri Mar 
31 16:44:26 2006
@@ -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@xxxxxxxxxxxx>
+---
+ 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)

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
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®.