Skip to contentSkip to conversation

Fix alignment of i386 interrupt entry stubs

PATCH New Brian Gerst 1 participant 1 message May 2, 2003

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Fix alignment of i386 interrupt entry stubs

This patch provides for improved alignment of the entry stubs, to avoid crossing cache lines. This is accomplished by using a fixed size for each stub (16 bytes for IO-APIC, 8 bytes otherwise). The fixed size allows for removal of the pointer table. Also, subtracting 256 from the irq number is no longer necessary. orig_eax is no longer used by the exit code to distinguish between interrupts and system calls.

--
Brian Gerst

arch/i386/kernel/entry.S +5 -15
diff -ur linux-2.5.68-bk/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
@@ -374,27 +374,17 @@
 	movl $-ENOSYS,EAX(%esp)
 	jmp resume_userspace
 
-/*
- * Build the entry stubs and pointer table with
- * some assembler magic.
- */
-.data
-ENTRY(interrupt)
-.text
-
+/* Build the IRQ entry stubs */
 vector=0
-ENTRY(irq_entries_start)
+	.align IRQ_STUB_SIZE,0x90
+ENTRY(irq_entries)
 .rept NR_IRQS
-	ALIGN
-1:	pushl $vector-256
+1:	pushl $vector
 	jmp common_interrupt
-.data
-	.long 1b
-.text
+	.align IRQ_STUB_SIZE,0x90
 vector=vector+1
 .endr
 
-	ALIGN
 common_interrupt:
 	SAVE_ALL
 	call do_IRQ
arch/i386/kernel/i8259.c +1 -1
diff -ur linux-2.5.68-bk/arch/i386/kernel/i8259.c linux/arch/i386/kernel/i8259.c
@@ -425,7 +425,7 @@
 	for (i = 0; i < NR_IRQS; i++) {
 		int vector = FIRST_EXTERNAL_VECTOR + i;
 		if (vector != SYSCALL_VECTOR) 
-			set_intr_gate(vector, interrupt[i]);
+			set_intr_gate(vector, &irq_entries[i]);
 	}
 
 	/* setup after call gates are initialised (usually add in
arch/i386/kernel/io_apic.c +3 -3
diff -ur linux-2.5.68-bk/arch/i386/kernel/io_apic.c linux/arch/i386/kernel/io_apic.c
@@ -1190,7 +1190,7 @@
 			else
 				irq_desc[irq].handler = &ioapic_edge_irq_type;
 
-			set_intr_gate(vector, interrupt[irq]);
+			set_intr_gate(vector, &irq_entries[irq]);
 		
 			if (!apic && (irq < 16))
 				disable_8259A_irq(irq);
@@ -2024,7 +2024,7 @@
 	 */
 	disable_8259A_irq(0);
 	vector = assign_irq_vector(0);
-	set_intr_gate(vector, interrupt[0]);
+	set_intr_gate(vector, &irq_entries[0]);
 
 	/*
 	 * Subtle, code in do_timer_interrupt() expects an AEOI
@@ -2312,7 +2312,7 @@
 
 	irq_desc[irq].handler = &ioapic_level_irq_type;
 
-	set_intr_gate(entry.vector, interrupt[irq]);
+	set_intr_gate(entry.vector, &irq_entries[irq]);
 
 	if (!ioapic && (irq < 16))
 		disable_8259A_irq(irq);
arch/i386/kernel/irq.c +1 -1
diff -ur linux-2.5.68-bk/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c
@@ -354,7 +354,7 @@
 	 * 0 return value means that this irq is already being
 	 * handled by some other CPU. (or is disabled)
 	 */
-	int irq = regs.orig_eax & 0xff; /* high bits used in ret_from_ code  */
+	int irq = regs.orig_eax;
 	int cpu = smp_processor_id();
 	irq_desc_t *desc = irq_desc + irq;
 	struct irqaction * action;
arch/i386/kernel/smpboot.c +1 -1
diff -ur linux-2.5.68-bk/arch/i386/kernel/smpboot.c linux/arch/i386/kernel/smpboot.c
@@ -1159,7 +1159,7 @@
 	 * IRQ0 must be given a fixed assignment and initialized,
 	 * because it's used before the IO-APIC is set up.
 	 */
-	set_intr_gate(FIRST_DEVICE_VECTOR, interrupt[0]);
+	set_intr_gate(FIRST_DEVICE_VECTOR, &irq_entries[0]);
 
 	/*
 	 * The reschedule interrupt is a CPU-to-CPU reschedule-helper
include/asm-i386/hw_irq.h +1 -1
diff -ur linux-2.5.68-bk/include/asm-i386/hw_irq.h linux/include/asm-i386/hw_irq.h
@@ -27,7 +27,7 @@
 extern int irq_vector[NR_IRQS];
 #define IO_APIC_VECTOR(irq)	irq_vector[irq]
 
-extern void (*interrupt[NR_IRQS])(void);
+extern char irq_entries[NR_IRQS][IRQ_STUB_SIZE];
 
 #ifdef CONFIG_SMP
 extern asmlinkage void reschedule_interrupt(void);
include/asm-i386/mach-default/irq_vectors.h +2 -0
diff -ur linux-2.5.68-bk/include/asm-i386/mach-default/irq_vectors.h linux/include/asm-i386/mach-default/irq_vectors.h
@@ -78,8 +78,10 @@
  */
 #ifdef CONFIG_X86_IO_APIC
 #define NR_IRQS 224
+#define IRQ_STUB_SIZE 16
 #else
 #define NR_IRQS 16
+#define IRQ_STUB_SIZE 8
 #endif
 
 #define FPU_IRQ			13
include/asm-i386/mach-pc9800/irq_vectors.h +2 -0
diff -ur linux-2.5.68-bk/include/asm-i386/mach-pc9800/irq_vectors.h linux/include/asm-i386/mach-pc9800/irq_vectors.h
@@ -78,8 +78,10 @@
  */
 #ifdef CONFIG_X86_IO_APIC
 #define NR_IRQS 224
+#define IRQ_STUB_SIZE 16
 #else
 #define NR_IRQS 16
+#define IRQ_STUB_SIZE 8
 #endif
 
 #define FPU_IRQ			8
include/asm-i386/mach-visws/irq_vectors.h +1 -0
diff -ur linux-2.5.68-bk/include/asm-i386/mach-visws/irq_vectors.h linux/include/asm-i386/mach-visws/irq_vectors.h
@@ -50,6 +50,7 @@
  * 
  */
 #define NR_IRQS 224
+#define IRQ_STUB_SIZE 16
 
 #define FPU_IRQ			13
 
include/asm-i386/mach-voyager/irq_vectors.h +1 -0
diff -ur linux-2.5.68-bk/include/asm-i386/mach-voyager/irq_vectors.h linux/include/asm-i386/mach-voyager/irq_vectors.h
@@ -56,6 +56,7 @@
 #define VIC_CPU_BOOT_ERRATA_CPI		(VIC_CPI_LEVEL0 + 8)
 
 #define NR_IRQS 224
+#define IRQ_STUB_SIZE 16
 
 #define FPU_IRQ				13