diff -urpN -X /home/fletch/.diff.exclude 631-lotsa_sds/arch/i386/kernel/cpu/common.c 640-per_node_idt/arch/i386/kernel/cpu/common.c
--- 631-lotsa_sds/arch/i386/kernel/cpu/common.c	Sun Apr 20 19:34:56 2003
+++ 640-per_node_idt/arch/i386/kernel/cpu/common.c	Fri May 30 21:58:44 2003
@@ -433,9 +433,9 @@ void __init early_cpu_init(void)
 }
 /*
  * cpu_init() initializes state that is per-CPU. Some data is already
- * initialized (naturally) in the bootstrap process, such as the GDT
- * and IDT. We reload them nevertheless, this function acts as a
- * 'CPU state barrier', nothing should get across.
+ * initialized (naturally) in the bootstrap process, such as the GDT.
+ * We reload them nevertheless, this function acts as a 'CPU state barrier',
+ * nothing should get across.
  */
 void __init cpu_init (void)
 {
@@ -459,8 +459,8 @@ void __init cpu_init (void)
 	}
 
 	/*
-	 * Initialize the per-CPU GDT with the boot GDT,
-	 * and set up the GDT descriptor:
+	 * Initialize the per-CPU GDTs with the boot equivalents,
+	 * and set up the descriptors:
 	 */
 	if (cpu) {
 		memcpy(cpu_gdt_table[cpu], cpu_gdt_table[0], GDT_SIZE);
@@ -473,7 +473,6 @@ void __init cpu_init (void)
 	memcpy(thread->tls_array, cpu_gdt_table[cpu], GDT_ENTRY_TLS_ENTRIES * 8);
 
 	__asm__ __volatile__("lgdt %0": "=m" (cpu_gdt_descr[cpu]));
-	__asm__ __volatile__("lidt %0": "=m" (idt_descr));
 
 	/*
 	 * Delete NT
@@ -517,3 +516,31 @@ void __init cpu_init (void)
 	current->used_math = 0;
 	stts();
 }
+
+/*
+ * copy over the boot node idt across all nodes, we currently only have
+ * non-unique idt entries for device io interrupts.
+ */
+void __init setup_node_idts(void)
+{
+	int node = MAX_NUMNODES;
+
+	/* we can skip setting up node0 since it's done in head.S */
+	while (--node) {
+		memcpy(node_idt_table[node], node_idt_table[0], IDT_SIZE);
+		node_idt_descr[node].size = IDT_SIZE - 1;
+		node_idt_descr[node].address = (unsigned long)node_idt_table[node];
+	}
+}
+
+void __init setup_cpu_idt(void)
+{
+	int cpu = smp_processor_id(), node =  cpu_to_node(cpu);
+
+	printk(KERN_DEBUG "CPU%d IDT at 0x%08lx\n", 
+		cpu, node_idt_descr[node].address);
+
+	/* reload the idt on all processors as they come up */
+	__asm__ __volatile__("lidt %0": "=m" (node_idt_descr[node]));
+}
+
diff -urpN -X /home/fletch/.diff.exclude 631-lotsa_sds/arch/i386/kernel/doublefault.c 640-per_node_idt/arch/i386/kernel/doublefault.c
--- 631-lotsa_sds/arch/i386/kernel/doublefault.c	Tue Feb 25 23:03:43 2003
+++ 640-per_node_idt/arch/i386/kernel/doublefault.c	Fri May 30 21:58:44 2003
@@ -16,7 +16,7 @@ static unsigned long doublefault_stack[D
 
 static void doublefault_fn(void)
 {
-	struct Xgt_desc_struct gdt_desc = {0, 0};
+	struct Xdt_desc_struct gdt_desc = {0, 0};
 	unsigned long gdt, tss;
 
 	__asm__ __volatile__("sgdt %0": "=m" (gdt_desc): :"memory");
diff -urpN -X /home/fletch/.diff.exclude 631-lotsa_sds/arch/i386/kernel/head.S 640-per_node_idt/arch/i386/kernel/head.S
--- 631-lotsa_sds/arch/i386/kernel/head.S	Fri May 30 19:23:02 2003
+++ 640-per_node_idt/arch/i386/kernel/head.S	Fri May 30 21:58:44 2003
@@ -250,7 +250,7 @@ is386:	movl $2,%ecx		# set MP
 	call check_x87
 	incb ready
 	lgdt cpu_gdt_descr
-	lidt idt_descr
+	lidt node_idt_descr		# we switch to the per-node IDTs later
 	ljmp $(__KERNEL_CS),$1f
 1:	movl $(__KERNEL_DS),%eax	# reload all the segment registers
 	movl %eax,%ss			# after changing gdt.
@@ -315,7 +315,7 @@ setup_idt:
 	movw %dx,%ax		/* selector = 0x0010 = cs */
 	movw $0x8E00,%dx	/* interrupt gate - dpl=0, present */
 
-	lea idt_table,%edi
+	lea node_idt_table,%edi
 	mov $256,%ecx
 rp_sidt:
 	movl %eax,(%edi)
@@ -360,14 +360,16 @@ ignore_int:
  * segment size, and 32-bit linear address value:
  */
 
-.globl idt_descr
+.globl node_idt_descr
 .globl cpu_gdt_descr
 
 	ALIGN
 	.word 0				# 32-bit align idt_desc.address
-idt_descr:
+node_idt_descr:
 	.word IDT_ENTRIES*8-1		# idt contains 256 entries
-	.long idt_table
+	.long node_idt_table
+	
+	.fill MAX_NUMNODES-1,8,0
 
 # boot GDT descriptor (later on used by CPU#0):
 	.word 0				# 32 bit align gdt_desc.address
diff -urpN -X /home/fletch/.diff.exclude 631-lotsa_sds/arch/i386/kernel/io_apic.c 640-per_node_idt/arch/i386/kernel/io_apic.c
--- 631-lotsa_sds/arch/i386/kernel/io_apic.c	Fri May 30 19:01:59 2003
+++ 640-per_node_idt/arch/i386/kernel/io_apic.c	Fri May 30 21:58:44 2003
@@ -1117,24 +1117,59 @@ static inline int IO_APIC_irq_trigger(in
 }
 
 int irq_vector[NR_IRQS] = { FIRST_DEVICE_VECTOR , 0 };
+int __initdata vector_allocated[MAX_NUMNODES][FIRST_SYSTEM_VECTOR];
 
-static int __init assign_irq_vector(int irq)
+/*
+ * This is the per node vector allocator, it will only work for systems which 
+ * have ioapics which can only deliver vectors to cpus on the same node and 
+ * thus have hardware enforced ioapic/irq node affinity. 
+ *
+ * However currently the only i386 systems which have this interrupt 
+ * dispatching/servicing architecture are NUMAQ and x440. We try and 'share' 
+ * vectors where possible to simplify cases where an irq can be serviced on 
+ * multiple nodes due to it being present on multiple busses/nodes. 
+ * The first pass on node0 will ensure we catch these node 'shared' irqs.
+ */
+static int __init assign_irq_vector(int irq, int node)
 {
-	static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
-	if (IO_APIC_VECTOR(irq) > 0)
-		return IO_APIC_VECTOR(irq);
+	static int offset[MAX_NUMNODES];
+	static int nr_assigned[MAX_NUMNODES] = {[0 ... MAX_NUMNODES-1] = 1};
+	static int current_vector[MAX_NUMNODES] = 
+				{[0 ... MAX_NUMNODES-1] = FIRST_DEVICE_VECTOR};
+
+	int vector;
+
+	Dprintk("requesting vector for node%d/irq%d\n", node, irq);
+	vector = IO_APIC_VECTOR(irq);
+	if (vector > 0) {
+		Dprintk("returning previous allocation vector0x%x\n", vector);
+		vector_allocated[node][vector]++;
+		return vector;
+	}
+
+	if (++nr_assigned[node] > NR_IRQ_VECTORS)
+		return -ENOSPC;
+	
 next:
-	current_vector += 8;
-	if (current_vector == SYSCALL_VECTOR)
+	current_vector[node] += 8;
+	if (current_vector[node] == SYSCALL_VECTOR)
 		goto next;
 
-	if (current_vector >= FIRST_SYSTEM_VECTOR) {
-		offset = (offset + 1) & 7;
-		current_vector = FIRST_DEVICE_VECTOR + offset;
+	if (current_vector[node] > FIRST_SYSTEM_VECTOR) {
+		offset[node] = (offset[node]+1) & 7;
+		current_vector[node] = FIRST_DEVICE_VECTOR + offset[node];
 	}
 
-	IO_APIC_VECTOR(irq) = current_vector;
-	return current_vector;
+	vector = current_vector[node];
+	if (vector_allocated[node][vector])
+		goto next;
+
+	vector_allocated[node][vector]++;
+	IO_APIC_VECTOR(irq) = vector;
+	Dprintk("returning new allocation node%d/irq%d -> vector0x%x\n",
+		node, irq, vector);
+
+	return vector;
 }
 
 static struct hw_interrupt_type ioapic_level_irq_type;
@@ -1143,7 +1178,7 @@ static struct hw_interrupt_type ioapic_e
 void __init setup_IO_APIC_irqs(void)
 {
 	struct IO_APIC_route_entry entry;
-	int apic, pin, idx, irq, first_notcon = 1, vector;
+	int apic, pin, idx, irq, first_notcon = 1, vector, bus, node;
 	unsigned long flags;
 
 	printk(KERN_DEBUG "init IO_APIC IRQs\n");
@@ -1160,11 +1195,12 @@ void __init setup_IO_APIC_irqs(void)
 		entry.dest_mode = INT_DEST_MODE;
 		entry.mask = 0;				/* enable IRQ */
 		entry.dest.logical.logical_dest = TARGET_CPUS;
-
+		
 		idx = find_irq_entry(apic,pin,mp_INT);
 		if (idx == -1) {
 			if (first_notcon) {
-				printk(KERN_DEBUG " IO-APIC (apicid-pin) %d-%d", mp_ioapics[apic].mpc_apicid, pin);
+				printk(KERN_DEBUG " IO-APIC (apicid-pin) %d-%d",
+					mp_ioapics[apic].mpc_apicid, pin);
 				first_notcon = 0;
 			} else
 				printk(", %d-%d", mp_ioapics[apic].mpc_apicid, pin);
@@ -1174,12 +1210,21 @@ void __init setup_IO_APIC_irqs(void)
 		entry.trigger = irq_trigger(idx);
 		entry.polarity = irq_polarity(idx);
 
+		bus = mp_irqs[idx].mpc_srcbus;
+		node = mp_bus_id_to_node[bus];
+
 		if (irq_trigger(idx)) {
 			entry.trigger = 1;
 			entry.mask = 1;
 		}
 
 		irq = pin_2_irq(idx, apic, pin);
+		if (irq >= NR_IRQS) {
+			printk("skipping irq%d on node%d/bus%d/ioapic%d out of IRQs!\n",
+				irq, node, bus, apic);
+			continue;
+		}
+		
 		/*
 		 * skip adding the timer int on secondary nodes, which causes
 		 * a small but painful rift in the time-space continuum
@@ -1193,7 +1238,10 @@ void __init setup_IO_APIC_irqs(void)
 			continue;
 
 		if (IO_APIC_IRQ(irq)) {
-			vector = assign_irq_vector(irq);
+			vector = assign_irq_vector(irq, node);
+			if (vector < 0)
+				continue;
+
 			entry.vector = vector;
 
 			if (IO_APIC_irq_trigger(irq))
@@ -1201,11 +1249,15 @@ void __init setup_IO_APIC_irqs(void)
 			else
 				irq_desc[irq].handler = &ioapic_edge_irq_type;
 
-			set_intr_gate(vector, interrupt[irq]);
-		
+			Dprintk("irq_setup: node%d/bus%d/ioapic%d/vector0x%x - irq%d %p\n",
+				node, bus, apic, vector, irq, interrupt[irq]);
+
+			node_set_intr_gate(node, vector, interrupt[irq]);
+	
 			if (!apic && (irq < 16))
 				disable_8259A_irq(irq);
 		}
+		
 		spin_lock_irqsave(&ioapic_lock, flags);
 		io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1));
 		io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0));
@@ -1896,6 +1948,7 @@ static inline void init_IO_APIC_traps(vo
 			 * so default to an old-fashioned 8259
 			 * interrupt if we can..
 			 */
+			printk(KERN_DEBUG "irq%d not serviced by IOAPIC\n", irq);
 			if (irq < 16)
 				make_8259A_irq(irq);
 			else
@@ -2034,9 +2087,10 @@ static inline void check_timer(void)
 	 * get/set the timer IRQ vector:
 	 */
 	disable_8259A_irq(0);
-	vector = assign_irq_vector(0);
+	vector = assign_irq_vector(0, cpu_to_node(smp_processor_id()));
+	/* This gets reserved on all nodes as FIRST_DEVICE_VECTOR */
 	set_intr_gate(vector, interrupt[0]);
-
+	
 	/*
 	 * Subtle, code in do_timer_interrupt() expects an AEOI
 	 * mode for the 8259A whenever interrupts are routed
@@ -2291,10 +2345,13 @@ int io_apic_set_pci_routing (int ioapic,
 {
 	struct IO_APIC_route_entry entry;
 	unsigned long flags;
+	int node, bus, vector;
+
+	if (irq >= NR_IRQS)
+		return -ENOSPC;
 
 	if (!IO_APIC_IRQ(irq)) {
-		printk(KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0/n", 
-			ioapic);
+		printk(KERN_ERR "ioapic%d invalid reference to IRQ0/n", ioapic);
 		return -EINVAL;
 	}
 
@@ -2314,17 +2371,26 @@ int io_apic_set_pci_routing (int ioapic,
 	entry.polarity = 1;					/* Low active */
 
 	add_pin_to_irq(irq, ioapic, pin);
+	
+	/* XXX verify this with an x440 and plain ACPI/SMP -zwane */
+	bus = mp_irqs[pin].mpc_srcbus;
+	node = mp_bus_id_to_node[bus];
+
+	vector = assign_irq_vector(irq, node);
+	if (vector < 0)
+		return -ENOSPC;
 
-	entry.vector = assign_irq_vector(irq);
-
-	printk(KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry (%d-%d -> 0x%x -> "
-		"IRQ %d)\n", ioapic, 
+	entry.vector = vector;
+	printk(KERN_DEBUG "NODE[%d] IOAPIC[%d]: Set PCI routing entry (%d-%d -> 0x%x -> "
+		"IRQ %d)\n", node, ioapic, 
 		mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq);
 
 	irq_desc[irq].handler = &ioapic_level_irq_type;
 
-	set_intr_gate(entry.vector, interrupt[irq]);
-
+	printk(KERN_DEBUG "irq_route: node%d/bus%d/ioapic%d/vector0x%x - irq%d %p\n",
+		node, bus, ioapic, entry.vector, irq, interrupt[irq]);
+	node_set_intr_gate(node, entry.vector, interrupt[irq]);
+	
 	if (!ioapic && (irq < 16))
 		disable_8259A_irq(irq);
 
diff -urpN -X /home/fletch/.diff.exclude 631-lotsa_sds/arch/i386/kernel/smpboot.c 640-per_node_idt/arch/i386/kernel/smpboot.c
--- 631-lotsa_sds/arch/i386/kernel/smpboot.c	Fri May 30 19:24:56 2003
+++ 640-per_node_idt/arch/i386/kernel/smpboot.c	Fri May 30 21:58:44 2003
@@ -45,6 +45,7 @@
 
 #include <linux/delay.h>
 #include <linux/mc146818rtc.h>
+#include <asm/cpu.h>
 #include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
 #include <asm/desc.h>
@@ -450,6 +451,7 @@ int __init start_secondary(void *unused)
 	 */
 	cpu_init();
 	smp_callin();
+	setup_cpu_idt();
 	while (!test_bit(smp_processor_id(), &smp_commenced_mask))
 		rep_nop();
 	setup_secondary_APIC_clock();
@@ -980,7 +982,7 @@ static void __init smp_boot_cpus(unsigne
 
 	current_thread_info()->cpu = 0;
 	smp_tune_scheduling();
-
+	
 	/*
 	 * If we couldn't find an SMP configuration at boot time,
 	 * get out of here now!
diff -urpN -X /home/fletch/.diff.exclude 631-lotsa_sds/arch/i386/kernel/traps.c 640-per_node_idt/arch/i386/kernel/traps.c
--- 631-lotsa_sds/arch/i386/kernel/traps.c	Fri May 30 19:24:56 2003
+++ 640-per_node_idt/arch/i386/kernel/traps.c	Fri May 30 21:58:44 2003
@@ -31,6 +31,7 @@
 #include <linux/ioport.h>
 #endif
 
+#include <asm/cpu.h>
 #ifdef CONFIG_MCA
 #include <linux/mca.h>
 #include <asm/processor.h>
@@ -88,7 +89,9 @@ char ignore_fpu_irq = 0;
  * F0 0F bug workaround.. We have a special link segment
  * for this.
  */
-struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
+
+struct desc_struct node_idt_table[MAX_NUMNODES][IDT_ENTRIES] __attribute__((__section__(".data.idt"))) = 
+	{[0 ... MAX_NUMNODES-1] = { {0, 0}, }};
 
 asmlinkage void divide_error(void);
 asmlinkage void debug(void);
@@ -859,14 +862,16 @@ asmlinkage void math_emulate(long arg)
 #ifdef CONFIG_X86_F00F_BUG
 void __init trap_init_f00f_bug(void)
 {
-	__set_fixmap(FIX_F00F_IDT, __pa(&idt_table), PAGE_KERNEL_RO);
+	int node = cpu_to_node(smp_processor_id());
+
+	__set_fixmap(FIX_F00F_IDT, __pa(&node_idt_table[node]), PAGE_KERNEL_RO);
 
 	/*
 	 * Update the IDT descriptor and reload the IDT so that
 	 * it uses the read-only mapped virtual address.
 	 */
-	idt_descr.address = fix_to_virt(FIX_F00F_IDT);
-	__asm__ __volatile__("lidt %0": "=m" (idt_descr));
+	node_idt_descr[node].address = fix_to_virt(FIX_F00F_IDT);
+	__asm__ __volatile__("lidt %0": "=m" (node_idt_descr[node]));
 }
 #endif
 
@@ -918,24 +923,36 @@ do { \
 
 
 /*
- * This needs to use 'idt_table' rather than 'idt', and
+ * This needs to use 'node_idt_table' rather than 'idt', and
  * thus use the _nonmapped_ version of the IDT, as the
  * Pentium F0 0F bugfix can have resulted in the mapped
  * IDT being write-protected.
  */
+
+void node_set_intr_gate(unsigned int node, unsigned int n, void *addr)
+{
+	_set_gate(&node_idt_table[node][n],14,0,addr,__KERNEL_CS);
+}
+
 void set_intr_gate(unsigned int n, void *addr)
 {
-	_set_gate(idt_table+n,14,0,addr,__KERNEL_CS);
+	int node;
+	for (node = 0; node < MAX_NUMNODES; node++)
+ 		node_set_intr_gate(node, n, addr);
 }
 
 static void __init set_trap_gate(unsigned int n, void *addr)
 {
-	_set_gate(idt_table+n,15,0,addr,__KERNEL_CS);
+	int node;
+	for (node = 0; node < MAX_NUMNODES; node++)
+		_set_gate(&node_idt_table[node][n],15,0,addr,__KERNEL_CS);
 }
 
 static void __init set_system_gate(unsigned int n, void *addr)
 {
-	_set_gate(idt_table+n,15,3,addr,__KERNEL_CS);
+	int node;
+	for (node = 0; node < MAX_NUMNODES; node++)
+		_set_gate(&node_idt_table[node][n],15,3,addr,__KERNEL_CS);
 }
 
 static void __init set_call_gate(void *a, void *addr)
@@ -945,7 +962,9 @@ static void __init set_call_gate(void *a
 
 static void __init set_task_gate(unsigned int n, unsigned int gdt_entry)
 {
-	_set_gate(idt_table+n,5,0,0,(gdt_entry<<3));
+	int node;
+	for (node = 0; node < MAX_NUMNODES; node++)
+		_set_gate(&node_idt_table[node][n],5,0,0,(gdt_entry<<3));
 }
 
 
@@ -966,9 +985,17 @@ void __init trap_init(void)
 #endif
 
 	set_trap_gate(0,&divide_error);
-	_set_gate(idt_table+1,14,3,&debug,__KERNEL_CS); /* debug trap for kprobes */
+	
+	/* debug trap for kprobes */
+	/* _set_gate(idt_table+1,14,3,&debug,__KERNEL_CS); */
+	_set_gate(&node_idt_table[0][1],14,3,&debug,__KERNEL_CS);
+
 	set_intr_gate(2,&nmi);
-	_set_gate(idt_table+3,14,3,&int3,__KERNEL_CS); /* int3-5 can be called from all */
+
+	/* int3-5 can be called from all */
+	/* _set_gate(idt_table+3,14,3,&int3,__KERNEL_CS); */
+	_set_gate(&node_idt_table[0][3],14,3,&int3,__KERNEL_CS);
+
 	set_system_gate(4,&overflow);
 	set_system_gate(5,&bounds);
 	set_trap_gate(6,&invalid_op);
@@ -996,6 +1023,9 @@ void __init trap_init(void)
 	 */
 	set_call_gate(&default_ldt[0],lcall7);
 	set_call_gate(&default_ldt[4],lcall27);
+
+	/* setup the pernode idt tables */
+	setup_node_idts();
 
 	notify_die(DIE_TRAPINIT, "traps initialized", 0, 0); 
 	/*
diff -urpN -X /home/fletch/.diff.exclude 631-lotsa_sds/arch/i386/mm/fault.c 640-per_node_idt/arch/i386/mm/fault.c
--- 631-lotsa_sds/arch/i386/mm/fault.c	Fri May 30 19:24:56 2003
+++ 640-per_node_idt/arch/i386/mm/fault.c	Fri May 30 21:58:44 2003
@@ -257,9 +257,9 @@ bad_area:
 	 * Pentium F0 0F C7 C8 bug workaround.
 	 */
 	if (boot_cpu_data.f00f_bug) {
-		unsigned long nr;
-		
-		nr = (address - idt_descr.address) >> 3;
+		unsigned long nr, node;
+		node = cpu_to_node(smp_processor_id());
+		nr = (address - node_idt_descr[node].address) >> 3;
 
 		if (nr == 6) {
 			do_invalid_op(regs, 0);
diff -urpN -X /home/fletch/.diff.exclude 631-lotsa_sds/include/asm-i386/cpu.h 640-per_node_idt/include/asm-i386/cpu.h
--- 631-lotsa_sds/include/asm-i386/cpu.h	Thu Feb 13 11:08:13 2003
+++ 640-per_node_idt/include/asm-i386/cpu.h	Fri May 30 21:58:44 2003
@@ -23,4 +23,6 @@ static inline int arch_register_cpu(int 
 	return register_cpu(&cpu_devices[num].cpu, num, parent);
 }
 
+extern void setup_cpu_idt(void);
+extern void setup_node_idts(void);
 #endif /* _ASM_I386_CPU_H_ */
diff -urpN -X /home/fletch/.diff.exclude 631-lotsa_sds/include/asm-i386/desc.h 640-per_node_idt/include/asm-i386/desc.h
--- 631-lotsa_sds/include/asm-i386/desc.h	Tue Feb 25 23:03:50 2003
+++ 640-per_node_idt/include/asm-i386/desc.h	Fri May 30 21:58:44 2003
@@ -2,6 +2,7 @@
 #define __ARCH_DESC_H
 
 #include <asm/ldt.h>
+#include <asm/numnodes.h>
 #include <asm/segment.h>
 
 #ifndef __ASSEMBLY__
@@ -12,14 +13,15 @@
 #include <asm/mmu.h>
 
 extern struct desc_struct cpu_gdt_table[NR_CPUS][GDT_ENTRIES];
+extern struct desc_struct node_idt_table[MAX_NUMNODES][IDT_ENTRIES];
 
-struct Xgt_desc_struct {
+struct Xdt_desc_struct {
 	unsigned short size;
 	unsigned long address __attribute__((packed));
 	unsigned short pad;
 } __attribute__ ((packed));
 
-extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS];
+extern struct Xdt_desc_struct node_idt_descr[MAX_NUMNODES], cpu_gdt_descr[NR_CPUS]; 
 
 #define load_TR_desc() __asm__ __volatile__("ltr %%ax"::"a" (GDT_ENTRY_TSS*8))
 #define load_LDT_desc() __asm__ __volatile__("lldt %%ax"::"a" (GDT_ENTRY_LDT*8))
@@ -29,7 +31,8 @@ extern struct Xgt_desc_struct idt_descr,
  * something other than this.
  */
 extern struct desc_struct default_ldt[];
-extern void set_intr_gate(unsigned int irq, void * addr);
+extern void node_set_intr_gate(unsigned int node, unsigned int vector, void * addr);
+extern void set_intr_gate(unsigned int n, void *addr);
 
 #define _set_tssldt_desc(n,addr,limit,type) \
 __asm__ __volatile__ ("movw %w3,0(%2)\n\t" \
diff -urpN -X /home/fletch/.diff.exclude 631-lotsa_sds/include/asm-i386/mach-default/irq_vectors.h 640-per_node_idt/include/asm-i386/mach-default/irq_vectors.h
--- 631-lotsa_sds/include/asm-i386/mach-default/irq_vectors.h	Fri May 30 19:24:56 2003
+++ 640-per_node_idt/include/asm-i386/mach-default/irq_vectors.h	Fri May 30 21:58:44 2003
@@ -69,15 +69,22 @@
 #define TIMER_IRQ 0
 
 /*
- * 16 8259A IRQ's, 208 potential APIC interrupt sources.
- * Right now the APIC is mostly only used for SMP.
- * 256 vectors is an architectural limit. (we can have
- * more than 256 devices theoretically, but they will
- * have to use shared interrupts)
+ * 16 8259A IRQ's, MAX_IRQ_SOURCES-16 potential APIC
+ * interrupt sources. Right now the APIC is mostly only
+ * used for SMP. 256 vectors is an architectural limit.
+ * (we can have more than 256 devices theoretically, but
+ * they will have to use shared interrupts)
  * Since vectors 0x00-0x1f are used/reserved for the CPU,
  * the usable vector space is 0x20-0xff (224 vectors)
+ * Linux currently makes 190 vectors available for io interrupts
+ * starting at FIRST_DEVICE_VECTOR till FIRST_SYSTEM_VECTOR
+ *
+ * 0________0x31__________________________0xef_________0xff
+ *   system           io interrupts           resvd/smp
+ *
  */
 #ifdef CONFIG_X86_IO_APIC
+#define NR_IRQ_VECTORS 190
 #define NR_IRQS 224
 #else
 #define NR_IRQS 16
diff -urpN -X /home/fletch/.diff.exclude 631-lotsa_sds/include/asm-i386/numaq.h 640-per_node_idt/include/asm-i386/numaq.h
--- 631-lotsa_sds/include/asm-i386/numaq.h	Mon Mar 17 21:43:48 2003
+++ 640-per_node_idt/include/asm-i386/numaq.h	Fri May 30 21:58:44 2003
@@ -29,6 +29,8 @@
 #ifdef CONFIG_X86_NUMAQ
 
 #define MAX_NUMNODES		8
+
+#ifndef __ASSEMBLY__
 extern void get_memcfg_numaq(void);
 #define get_memcfg_numa() get_memcfg_numaq()
 
@@ -161,6 +163,7 @@ static inline unsigned long *get_zholes_
 {
 	return 0;
 }
+#endif /* __ASSEMBLY__ */
 #endif /* CONFIG_X86_NUMAQ */
 #endif /* NUMAQ_H */
 
diff -urpN -X /home/fletch/.diff.exclude 631-lotsa_sds/include/asm-i386/segment.h 640-per_node_idt/include/asm-i386/segment.h
--- 631-lotsa_sds/include/asm-i386/segment.h	Tue Feb 25 23:03:50 2003
+++ 640-per_node_idt/include/asm-i386/segment.h	Fri May 30 21:58:44 2003
@@ -94,5 +94,5 @@
  * of tasks we can have..
  */
 #define IDT_ENTRIES 256
-
+#define IDT_SIZE (IDT_ENTRIES * 8)
 #endif
diff -urpN -X /home/fletch/.diff.exclude 631-lotsa_sds/include/asm-i386/srat.h 640-per_node_idt/include/asm-i386/srat.h
--- 631-lotsa_sds/include/asm-i386/srat.h	Mon Mar 17 21:43:48 2003
+++ 640-per_node_idt/include/asm-i386/srat.h	Fri May 30 21:58:44 2003
@@ -28,8 +28,9 @@
 #define _ASM_SRAT_H_
 
 #define MAX_NUMNODES		8
+#ifndef __ASSEMBLY__
 extern void get_memcfg_from_srat(void);
 extern unsigned long *get_zholes_size(int);
 #define get_memcfg_numa() get_memcfg_from_srat()
-
+#endif
 #endif /* _ASM_SRAT_H_ */