--- /dev/null
+From stable-bounces@linux.kernel.org Mon Jun 2 15:14:58 2008
+Date: Wed, 28 May 2008 12:49:59 +0200 (CEST)
+From: Jiri Kosina <jkosina@suse.cz>
+To: stable@kernel.org
+Message-ID: <Pine.LNX.4.64.0805281248430.6718@jikos.suse.cz>
+Subject: HID: split Numlock emulation quirk from HID_QUIRK_APPLE_HAS_FN.
+
+From: Diego 'Flameeyes' Petteno <flameeyes@gmail.com>
+
+upstream commit: 6e7045990f35ef9250804b3fd85e855b8c2aaeb6.
+
+[jkosina@suse.cz: Needed to fix apple aluminium keyboard regression]
+
+Since 2.6.25 the HID_QUIRK_APPLE_HAS_FN quirk is enabled even for
+non-laptop Apple keyboards of the Aluminium series. The USB version of
+these don't need Numlock emulation, like the laptop (and Aluminium
+Wireless) do, as they have a proper keypad.
+
+This patch splits the Numlock emulation for Apple keyboards in a
+different quirk flag, so that it can be enabled for all the keyboards
+but the Aluminium USB ones.
+
+If the Numlock emulation is enabled for Aluminium USB keyboards, the
+JKL and UIO keys become the numeric pad, and the rest of the keyboard
+is disabled, included the key used to disable Numlock.
+
+Additionally, these keyboard should not have a Numlock at all, as the
+Numlock key is instead replaced by the 'Clear' key as usual for Apple
+USB keyboards.
+
+Signed-off-by: Diego 'Flameeyes' Petteno <flameeyes@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+ drivers/hid/hid-input.c | 5 +++--
+ drivers/hid/usbhid/hid-quirks.c | 38 +++++++++++++++++++-------------------
+ include/linux/hid.h | 1 +
+ 3 files changed, 23 insertions(+), 21 deletions(-)
+
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -218,8 +218,9 @@ int hidinput_apple_event(struct hid_devi
+ }
+ }
+
+- if (test_bit(usage->code, hid->pb_pressed_numlock) ||
+- test_bit(LED_NUML, input->led)) {
++ if (hid->quirks & HID_QUIRK_APPLE_NUMLOCK_EMULATION && (
++ test_bit(usage->code, hid->pb_pressed_numlock) ||
++ test_bit(LED_NUML, input->led))) {
+ trans = find_translation(powerbook_numlock_keys, usage->code);
+
+ if (trans) {
+--- a/drivers/hid/usbhid/hid-quirks.c
++++ b/drivers/hid/usbhid/hid-quirks.c
+@@ -613,28 +613,28 @@ static const struct hid_blacklist {
+
+ { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
+
+- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
+- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
+- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
+- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD},
+- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
+- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
+- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD},
+- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
+- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
+- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD},
+- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
++ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
++ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
++ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
++ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD},
++ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
++ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
++ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD},
++ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
++ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
++ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD},
++ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
+ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI, HID_QUIRK_APPLE_HAS_FN },
+ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD },
+ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS, HID_QUIRK_APPLE_HAS_FN },
+- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
+- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
+- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
+- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI, HID_QUIRK_APPLE_HAS_FN },
+- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD },
+- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS, HID_QUIRK_APPLE_HAS_FN },
+- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
+- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
++ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
++ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
++ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
++ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN },
++ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD },
++ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN },
++ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
++ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
+
+ { USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD, HID_QUIRK_RESET_LEDS },
+--- a/include/linux/hid.h
++++ b/include/linux/hid.h
+@@ -284,6 +284,7 @@ struct hid_item {
+ #define HID_QUIRK_2WHEEL_MOUSE_HACK_B8 0x02000000
+ #define HID_QUIRK_HWHEEL_WHEEL_INVERT 0x04000000
+ #define HID_QUIRK_MICROSOFT_KEYS 0x08000000
++#define HID_QUIRK_APPLE_NUMLOCK_EMULATION 0x10000000
+
+ /*
+ * Separate quirks for runtime report descriptor fixup
--- /dev/null
+From e56a727b023d40d1adf660168883f30f2e6abe0a Mon Sep 17 00:00:00 2001
+Message-Id: <1211375286.29901.7.camel@queen.suse.de>
+From: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+Date: Mon, 28 Apr 2008 15:13:43 -0400
+Subject: CPUFREQ: Make acpi-cpufreq more robust against BIOS freq changes behind our back.
+
+From: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+
+upstream commit: e56a727b023d40d1adf660168883f30f2e6abe0a
+
+We checked the hardware freq with OS cached freq value in get_cur_freqon_cpu().
+
+Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+Signed-off-by: Thomas Renninger <trenn@suse.de>
+Signed-off-by: Dave Jones <davej@redhat.com>
+Cc: Thomas Renninger <trenn@suse.de>
+Cc: "Anthony L. Awtrey" <tony@awtrey.com>
+[chrisw: backport to 2.6.25.4]
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
++++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+@@ -339,6 +339,7 @@ static unsigned int get_cur_freq_on_cpu(
+ {
+ struct acpi_cpufreq_data *data = per_cpu(drv_data, cpu);
+ unsigned int freq;
++ unsigned int cached_freq;
+
+ dprintk("get_cur_freq_on_cpu (%d)\n", cpu);
+
+@@ -347,7 +348,16 @@ static unsigned int get_cur_freq_on_cpu(
+ return 0;
+ }
+
++ cached_freq = data->freq_table[data->acpi_data->state].frequency;
+ freq = extract_freq(get_cur_val(cpumask_of_cpu(cpu)), data);
++ if (freq != cached_freq) {
++ /*
++ * The dreaded BIOS frequency change behind our back.
++ * Force set the frequency on next target call.
++ */
++ data->resume = 1;
++ }
++
+ dprintk("cur freq = %u\n", freq);
+
+ return freq;
--- /dev/null
+From 01b7a314291b2ef56ad718ee1374a1bac4768b29 Mon Sep 17 00:00:00 2001
+Message-ID: <4832C080.4030203@trash.net>
+From: Phil Oester <kernel@linuxace.com>
+Date: Tue, 13 May 2008 23:27:48 -0700
+Subject: netfilter: xt_iprange: module aliases for xt_iprange
+
+From: Phil Oester <kernel@linuxace.com>
+
+upstream commit: 01b7a314291b2ef56ad718ee1374a1bac4768b29
+
+Using iptables 1.3.8 with kernel 2.6.25, rules which include '-m
+iprange' don't automatically pull in xt_iprange module. Below patch
+adds module aliases to fix that. Patch against latest -git, but seems
+like a good candidate for -stable also.
+
+Signed-off-by: Phil Oester <kernel@linuxace.com>
+Signed-off-by: Patrick McHardy <kaber@trash.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ net/netfilter/xt_iprange.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/netfilter/xt_iprange.c
++++ b/net/netfilter/xt_iprange.c
+@@ -179,3 +179,5 @@ module_exit(iprange_mt_exit);
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>, Jan Engelhardt <jengelh@computergmbh.de>");
+ MODULE_DESCRIPTION("Xtables: arbitrary IPv4 range matching");
++MODULE_ALIAS("ipt_iprange");
++MODULE_ALIAS("ip6t_iprange");
--- /dev/null
+From 6fc7431dc0775f21ad7a7a39c2ad0290291a56ea Mon Sep 17 00:00:00 2001
+Message-ID: <484041FE.7050909@am.sony.com>
+From: Masakazu Mokuno <mokuno@sm.sony.co.jp>
+Date: Mon, 12 May 2008 13:50:28 +0900
+Subject: PS3: gelic: fix memory leak
+
+From: Masakazu Mokuno <mokuno@sm.sony.co.jp>
+
+upstream commit: 6fc7431dc0775f21ad7a7a39c2ad0290291a56ea
+
+This fixes the bug that the I/O buffer is not freed at the driver removal.
+
+Signed-off-by: Masakazu Mokuno <mokuno@sm.sony.co.jp>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ drivers/net/ps3_gelic_wireless.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/ps3_gelic_wireless.c
++++ b/drivers/net/ps3_gelic_wireless.c
+@@ -2474,6 +2474,8 @@ static void gelic_wl_free(struct gelic_w
+
+ pr_debug("%s: <-\n", __func__);
+
++ free_page((unsigned long)wl->buf);
++
+ pr_debug("%s: destroy queues\n", __func__);
+ destroy_workqueue(wl->eurus_cmd_queue);
+ destroy_workqueue(wl->event_queue);
--- /dev/null
+From stable-bounces@linux.kernel.org Mon Jun 2 13:09:29 2008
+Message-ID: <483DD13C.7090501@redhat.com>
+Date: Wed, 28 May 2008 17:40:12 -0400
+From: Chuck Ebbert <cebbert@redhat.com>
+To: linux-stable <stable@kernel.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Subject: Revert "PCI: remove default PCI expansion ROM memory allocation"
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+upstream commit: 8d539108560ec121d59eee05160236488266221c
+
+This reverts commit 9f8daccaa05c14e5643bdd4faf5aed9cc8e6f11e, which was
+reported to break X startup (xf86-video-ati-6.8.0). See
+
+ http://bugs.freedesktop.org/show_bug.cgi?id=15523
+
+for details.
+
+Reported-by: Laurence Withers <l@lwithers.me.uk>
+Cc: Gary Hade <garyhade@us.ibm.com>
+Cc: Greg KH <greg@kroah.com>
+Cc: Jan Beulich <jbeulich@novell.com>
+Cc: "Jun'ichi Nomura" <j-nomura@ce.jp.nec.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+[cebbert@redhat.com: backport, remove first hunk to make port easier]
+[chrisw@sous-sol.org: add back first hunk]
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ arch/x86/pci/common.c | 17 -----------------
+ 1 file changed, 17 deletions(-)
+
+--- a/arch/x86/pci/common.c
++++ b/arch/x86/pci/common.c
+@@ -130,19 +130,6 @@ static void __devinit pcibios_fixup_ghos
+ }
+ }
+
+-static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
+-{
+- struct resource *rom_r = &dev->resource[PCI_ROM_RESOURCE];
+-
+- if (rom_r->parent)
+- return;
+- if (rom_r->start)
+- /* we deal with BIOS assigned ROM later */
+- return;
+- if (!(pci_probe & PCI_ASSIGN_ROMS))
+- rom_r->start = rom_r->end = rom_r->flags = 0;
+-}
+-
+ /*
+ * Called after each bus is probed, but before its children
+ * are examined.
+@@ -150,12 +137,8 @@ static void __devinit pcibios_fixup_devi
+
+ void __devinit pcibios_fixup_bus(struct pci_bus *b)
+ {
+- struct pci_dev *dev;
+-
+ pcibios_fixup_ghosts(b);
+ pci_read_bridge_bases(b);
+- list_for_each_entry(dev, &b->devices, bus_list)
+- pcibios_fixup_device_resources(dev);
+ }
+
+ /*
x86-if-we-cannot-calibrate-the-tsc-we-panic.patch
x86-distangle-user-disabled-tsc-from-unstable.patch
x86-disable-tsc-for-sched_clock-when-calibration-failed.patch
+xfs-fix-memory-corruption-with-small-buffer-reads.patch
+x86-prevent-pge-flush-from-interruption-preemption.patch
+revert-pci-remove-default-pci-expansion-rom-memory-allocation.patch
+ps3-gelic-fix-memory-leak.patch
+netfilter-xt_iprange-module-aliases-for-xt_iprange.patch
+hid-split-numlock-emulation-quirk-from-hid_quirk_apple_has_fn.patch
+make-acpi-cpufreq-more-robust-against-bios-freq-changes-behind-our-back.patch
--- /dev/null
+From stable-bounces@linux.kernel.org Mon Jun 2 13:08:28 2008
+Message-ID: <483DCFBA.2040504@redhat.com>
+Date: Wed, 28 May 2008 17:33:46 -0400
+From: Chuck Ebbert <cebbert@redhat.com>
+To: linux-stable <stable@kernel.org>
+Cc: Ingo Molnar <mingo@elte.hu>
+Subject: x86: prevent PGE flush from interruption/preemption
+
+From: Ingo Molnar <mingo@elte.hu>
+
+upstream commit: b1979a5fda7869a790f4fd83fb06c78498d26ba1
+
+CR4 manipulation is not protected against interrupts and preemption,
+but KVM uses smp_function_call to manipulate the X86_CR4_VMXE bit
+either from the CPU hotplug code or from the kvm_init call.
+
+We need to protect the CR4 manipulation from both interrupts and
+preemption.
+
+Original bug report: http://lkml.org/lkml/2008/5/7/48
+Bugzilla entry: http://bugzilla.kernel.org/show_bug.cgi?id=10642
+
+This is not a regression from 2.6.25, it's a long standing and hard to
+trigger bug.
+
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ include/asm-x86/tlbflush.h | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+--- a/include/asm-x86/tlbflush.h
++++ b/include/asm-x86/tlbflush.h
+@@ -22,12 +22,23 @@ static inline void __native_flush_tlb(vo
+
+ static inline void __native_flush_tlb_global(void)
+ {
+- unsigned long cr4 = read_cr4();
++ unsigned long flags;
++ unsigned long cr4;
+
++ /*
++ * Read-modify-write to CR4 - protect it from preemption and
++ * from interrupts. (Use the raw variant because this code can
++ * be called from deep inside debugging code.)
++ */
++ raw_local_irq_save(flags);
++
++ cr4 = read_cr4();
+ /* clear PGE */
+ write_cr4(cr4 & ~X86_CR4_PGE);
+ /* write old PGE again and flush TLBs */
+ write_cr4(cr4);
++
++ raw_local_irq_restore(flags);
+ }
+
+ static inline void __native_flush_tlb_single(unsigned long addr)
--- /dev/null
+From stable-bounces@linux.kernel.org Mon Jun 2 13:06:59 2008
+Message-ID: <483DCEC8.7070906@redhat.com>
+Date: Wed, 28 May 2008 17:29:44 -0400
+From: Chuck Ebbert <cebbert@redhat.com>
+To: linux-stable <stable@kernel.org>
+Cc: David Chinner <dgc@sgi.com>
+Subject: XFS: Fix memory corruption with small buffer reads
+
+From: Christoph Hellwig <hch@infradead.org>
+
+upstream commit: 6ab455eeaff6893cd06da33843e840d888cdc04a
+
+When we have multiple buffers in a single page for a blocksize == pagesize
+filesystem we might overwrite the page contents if two callers hit it
+shortly after each other. To prevent that we need to keep the page locked
+until I/O is completed and the page marked uptodate.
+
+Thanks to Eric Sandeen for triaging this bug and finding a reproducible
+testcase and Dave Chinner for additional advice.
+
+This should fix kernel.org bz #10421.
+
+Tested-by: Eric Sandeen <sandeen@sandeen.net>
+
+SGI-PV: 981813
+SGI-Modid: xfs-linux-melb:xfs-kern:31173a
+
+Signed-off-by: Christoph Hellwig <hch@infradead.org>
+Signed-off-by: David Chinner <dgc@sgi.com>
+Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ fs/xfs/linux-2.6/xfs_buf.c | 24 ++++++++++++++++++++----
+ fs/xfs/linux-2.6/xfs_buf.h | 19 +++++++++++++++++++
+ 2 files changed, 39 insertions(+), 4 deletions(-)
+
+--- a/fs/xfs/linux-2.6/xfs_buf.c
++++ b/fs/xfs/linux-2.6/xfs_buf.c
+@@ -387,6 +387,8 @@ _xfs_buf_lookup_pages(
+ if (unlikely(page == NULL)) {
+ if (flags & XBF_READ_AHEAD) {
+ bp->b_page_count = i;
++ for (i = 0; i < bp->b_page_count; i++)
++ unlock_page(bp->b_pages[i]);
+ return -ENOMEM;
+ }
+
+@@ -416,17 +418,24 @@ _xfs_buf_lookup_pages(
+ ASSERT(!PagePrivate(page));
+ if (!PageUptodate(page)) {
+ page_count--;
+- if (blocksize < PAGE_CACHE_SIZE && !PagePrivate(page)) {
++ if (blocksize >= PAGE_CACHE_SIZE) {
++ if (flags & XBF_READ)
++ bp->b_flags |= _XBF_PAGE_LOCKED;
++ } else if (!PagePrivate(page)) {
+ if (test_page_region(page, offset, nbytes))
+ page_count++;
+ }
+ }
+
+- unlock_page(page);
+ bp->b_pages[i] = page;
+ offset = 0;
+ }
+
++ if (!(bp->b_flags & _XBF_PAGE_LOCKED)) {
++ for (i = 0; i < bp->b_page_count; i++)
++ unlock_page(bp->b_pages[i]);
++ }
++
+ if (page_count == bp->b_page_count)
+ bp->b_flags |= XBF_DONE;
+
+@@ -746,6 +755,7 @@ xfs_buf_associate_memory(
+ bp->b_count_desired = len;
+ bp->b_buffer_length = buflen;
+ bp->b_flags |= XBF_MAPPED;
++ bp->b_flags &= ~_XBF_PAGE_LOCKED;
+
+ return 0;
+ }
+@@ -1093,8 +1103,10 @@ _xfs_buf_ioend(
+ xfs_buf_t *bp,
+ int schedule)
+ {
+- if (atomic_dec_and_test(&bp->b_io_remaining) == 1)
++ if (atomic_dec_and_test(&bp->b_io_remaining) == 1) {
++ bp->b_flags &= ~_XBF_PAGE_LOCKED;
+ xfs_buf_ioend(bp, schedule);
++ }
+ }
+
+ STATIC void
+@@ -1125,6 +1137,9 @@ xfs_buf_bio_end_io(
+
+ if (--bvec >= bio->bi_io_vec)
+ prefetchw(&bvec->bv_page->flags);
++
++ if (bp->b_flags & _XBF_PAGE_LOCKED)
++ unlock_page(page);
+ } while (bvec >= bio->bi_io_vec);
+
+ _xfs_buf_ioend(bp, 1);
+@@ -1163,7 +1178,8 @@ _xfs_buf_ioapply(
+ * filesystem block size is not smaller than the page size.
+ */
+ if ((bp->b_buffer_length < PAGE_CACHE_SIZE) &&
+- (bp->b_flags & XBF_READ) &&
++ ((bp->b_flags & (XBF_READ|_XBF_PAGE_LOCKED)) ==
++ (XBF_READ|_XBF_PAGE_LOCKED)) &&
+ (blocksize >= PAGE_CACHE_SIZE)) {
+ bio = bio_alloc(GFP_NOIO, 1);
+
+--- a/fs/xfs/linux-2.6/xfs_buf.h
++++ b/fs/xfs/linux-2.6/xfs_buf.h
+@@ -66,6 +66,25 @@ typedef enum {
+ _XBF_PAGES = (1 << 18), /* backed by refcounted pages */
+ _XBF_RUN_QUEUES = (1 << 19),/* run block device task queue */
+ _XBF_DELWRI_Q = (1 << 21), /* buffer on delwri queue */
++
++ /*
++ * Special flag for supporting metadata blocks smaller than a FSB.
++ *
++ * In this case we can have multiple xfs_buf_t on a single page and
++ * need to lock out concurrent xfs_buf_t readers as they only
++ * serialise access to the buffer.
++ *
++ * If the FSB size >= PAGE_CACHE_SIZE case, we have no serialisation
++ * between reads of the page. Hence we can have one thread read the
++ * page and modify it, but then race with another thread that thinks
++ * the page is not up-to-date and hence reads it again.
++ *
++ * The result is that the first modifcation to the page is lost.
++ * This sort of AGF/AGI reading race can happen when unlinking inodes
++ * that require truncation and results in the AGI unlinked list
++ * modifications being lost.
++ */
++ _XBF_PAGE_LOCKED = (1 << 22),
+ } xfs_buf_flags_t;
+
+ typedef enum {