--- /dev/null
+From: Suresh Siddha <suresh.b.siddha@intel.com>
+Subject: x64, x2apic/intr-remap: ioapic routines which deal with initial io-apic RTE setup
+References: fate #303948 and fate #303984
+Patch-Mainline: queued for .28
+Commit-ID: 4dc2f96cacd1e74c688f94348a3bfd0a980817d5
+
+Signed-off-by: Thomas Renninger <trenn@suse.de>
+
+Generic ioapic specific routines which be used later during enabling
+interrupt-remapping.
+
+Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
+Cc: akpm@linux-foundation.org
+Cc: arjan@linux.intel.com
+Cc: andi@firstfloor.org
+Cc: ebiederm@xmission.com
+Cc: jbarnes@virtuousgeek.org
+Cc: steiner@sgi.com
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+
+---
+ arch/x86/kernel/io_apic_64.c | 66 +++++++++++++++++++++++++++++++++++++++++++
+ include/asm-x86/io_apic.h | 6 +++
+ 2 files changed, 72 insertions(+)
+
+Index: linux-2.6.26/arch/x86/kernel/io_apic_64.c
+===================================================================
+--- linux-2.6.26.orig/arch/x86/kernel/io_apic_64.c
++++ linux-2.6.26/arch/x86/kernel/io_apic_64.c
+@@ -108,6 +108,9 @@ static DEFINE_SPINLOCK(vector_lock);
+ */
+ int nr_ioapic_registers[MAX_IO_APICS];
+
++/* I/O APIC RTE contents at the OS boot up */
++struct IO_APIC_route_entry *early_ioapic_entries[MAX_IO_APICS];
++
+ /* I/O APIC entries */
+ struct mp_config_ioapic mp_ioapics[MAX_IO_APICS];
+ int nr_ioapics;
+@@ -440,6 +443,69 @@ static void clear_IO_APIC (void)
+ clear_IO_APIC_pin(apic, pin);
+ }
+
++/*
++ * Saves and masks all the unmasked IO-APIC RTE's
++ */
++int save_mask_IO_APIC_setup(void)
++{
++ union IO_APIC_reg_01 reg_01;
++ unsigned long flags;
++ int apic, pin;
++
++ /*
++ * The number of IO-APIC IRQ registers (== #pins):
++ */
++ for (apic = 0; apic < nr_ioapics; apic++) {
++ spin_lock_irqsave(&ioapic_lock, flags);
++ reg_01.raw = io_apic_read(apic, 1);
++ spin_unlock_irqrestore(&ioapic_lock, flags);
++ nr_ioapic_registers[apic] = reg_01.bits.entries+1;
++ }
++
++ for (apic = 0; apic < nr_ioapics; apic++) {
++ early_ioapic_entries[apic] =
++ kzalloc(sizeof(struct IO_APIC_route_entry) *
++ nr_ioapic_registers[apic], GFP_KERNEL);
++ if (!early_ioapic_entries[apic])
++ return -ENOMEM;
++ }
++
++ for (apic = 0; apic < nr_ioapics; apic++)
++ for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
++ struct IO_APIC_route_entry entry;
++
++ entry = early_ioapic_entries[apic][pin] =
++ ioapic_read_entry(apic, pin);
++ if (!entry.mask) {
++ entry.mask = 1;
++ ioapic_write_entry(apic, pin, entry);
++ }
++ }
++ return 0;
++}
++
++void restore_IO_APIC_setup(void)
++{
++ int apic, pin;
++
++ for (apic = 0; apic < nr_ioapics; apic++)
++ for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
++ ioapic_write_entry(apic, pin,
++ early_ioapic_entries[apic][pin]);
++}
++
++void reinit_intr_remapped_IO_APIC(int intr_remapping)
++{
++ /*
++ * for now plain restore of previous settings.
++ * TBD: In the case of OS enabling interrupt-remapping,
++ * IO-APIC RTE's need to be setup to point to interrupt-remapping
++ * table entries. for now, do a plain restore, and wait for
++ * the setup_IO_APIC_irqs() to do proper initialization.
++ */
++ restore_IO_APIC_setup();
++}
++
+ int skip_ioapic_setup;
+ int ioapic_force;
+
+Index: linux-2.6.26/include/asm-x86/io_apic.h
+===================================================================
+--- linux-2.6.26.orig/include/asm-x86/io_apic.h
++++ linux-2.6.26/include/asm-x86/io_apic.h
+@@ -193,6 +193,12 @@ extern int io_apic_set_pci_routing(int i
+ extern int (*ioapic_renumber_irq)(int ioapic, int irq);
+ extern void ioapic_init_mappings(void);
+
++#ifdef CONFIG_X86_64
++extern int save_mask_IO_APIC_setup(void);
++extern void restore_IO_APIC_setup(void);
++extern void reinit_intr_remapped_IO_APIC(int);
++#endif
++
+ #else /* !CONFIG_X86_IO_APIC */
+ #define io_apic_assign_pci_irqs 0
+ static const int timer_through_8259 = 0;