--- /dev/null
+From hmh@hmh.eng.br Thu Mar 12 23:12:43 2009
+From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
+Date: Tue, 24 Feb 2009 11:48:18 -0300
+Subject: ACPI: fix broken usage of acpi_ut_get_node_name()
+To: Len Brown <lenb@kernel.org>
+Cc: linux-acpi@vger.kernel.org, Lin Ming <ming.m.lin@intel.com>, stable@kernel.org, Henrique de Moraes Holschuh <hmh@hmh.eng.br>
+Message-ID: <1235486898-27756-2-git-send-email-hmh@hmh.eng.br>
+
+From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
+
+This issue was fixed indirectly in mainline by commit
+60a4ce7f4148155d3f28eea4a213f7ee47cd57b7.
+
+acpi_ut_get_node_name() returns a four char fixed-size array, not
+NULL-terminated.
+
+This is the minimal fix for stable 2.6.28.
+
+Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
+Cc: stable@kernel.org
+Acked-by: Lin Ming <ming.m.lin@intel.com>
+Cc: Len Brown <lenb@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/acpi/power.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/acpi/power.c
++++ b/drivers/acpi/power.c
+@@ -151,7 +151,7 @@ static int acpi_power_get_state(acpi_han
+ *state = (sta & 0x01)?ACPI_POWER_RESOURCE_STATE_ON:
+ ACPI_POWER_RESOURCE_STATE_OFF;
+
+- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n",
++ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%4.4s] is %s\n",
+ acpi_ut_get_node_name(handle),
+ *state ? "on" : "off"));
+
--- /dev/null
+From hmh@hmh.eng.br Thu Mar 12 23:11:32 2009
+From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
+Date: Tue, 24 Feb 2009 11:48:17 -0300
+Subject: ACPI: fix broken usage of name.ascii
+To: Len Brown <lenb@kernel.org>
+Cc: linux-acpi@vger.kernel.org, Lin Ming <ming.m.lin@intel.com>, stable@kernel.org, Henrique de Moraes Holschuh <hmh@hmh.eng.br>
+Message-ID: <1235486898-27756-1-git-send-email-hmh@hmh.eng.br>
+
+From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
+
+This issue was fixed indirectly in mainline by commit
+0175d562a29ad052c510782c7e76bc63d5155b9b.
+
+acpi_namespace_node's name.ascii field is four chars, and not NULL-
+terminated except by pure luck. So, it cannot be used by sscanf() without
+a length restriction.
+
+This is the minimal fix for both stable 2.6.27 and 2.6.28.
+
+Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
+Cc: Lin Ming <ming.m.lin@intel.com>
+Cc: Len Brown <lenb@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/acpi/ec.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -759,9 +759,10 @@ acpi_ec_register_query_methods(acpi_hand
+ struct acpi_namespace_node *node = handle;
+ struct acpi_ec *ec = context;
+ int value = 0;
+- if (sscanf(node->name.ascii, "_Q%x", &value) == 1) {
++
++ if (sscanf(node->name.ascii, "_Q%2x", &value) == 1)
+ acpi_ec_add_query_handler(ec, value, handle, NULL, NULL);
+- }
++
+ return AE_OK;
+ }
+
--- /dev/null
+From khali@linux-fr.org Thu Mar 12 23:08:53 2009
+From: Jean Delvare <khali@linux-fr.org>
+Date: Wed, 25 Feb 2009 21:34:07 +0100
+Subject: ARM: Add i2c_board_info for RiscPC PCF8583
+To: stable@kernel.org
+Cc: Russell King <rmk+kernel@arm.linux.org.uk>
+Message-ID: <20090225213407.4a932f92@hyperion.delvare>
+
+
+From: Russell King <rmk+kernel@arm.linux.org.uk>
+
+commit 531660ef5604c75de6fdead9da1304051af17c09 upstream
+
+Add the necessary i2c_board_info structure to fix the lack of PCF8583
+RTC on RiscPC.
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Cc: Alessandro Zummo <a.zummo@towertech.it>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/arm/mach-rpc/riscpc.c | 6 ++++++
+ drivers/i2c/busses/i2c-acorn.c | 3 ++-
+ 2 files changed, 8 insertions(+), 1 deletion(-)
+
+--- a/arch/arm/mach-rpc/riscpc.c
++++ b/arch/arm/mach-rpc/riscpc.c
+@@ -19,6 +19,7 @@
+ #include <linux/serial_8250.h>
+ #include <linux/ata_platform.h>
+ #include <linux/io.h>
++#include <linux/i2c.h>
+
+ #include <asm/elf.h>
+ #include <asm/mach-types.h>
+@@ -201,8 +202,13 @@ static struct platform_device *devs[] __
+ &pata_device,
+ };
+
++static struct i2c_board_info i2c_rtc = {
++ I2C_BOARD_INFO("pcf8583", 0x50)
++};
++
+ static int __init rpc_init(void)
+ {
++ i2c_register_board_info(0, &i2c_rtc, 1);
+ return platform_add_devices(devs, ARRAY_SIZE(devs));
+ }
+
+--- a/drivers/i2c/busses/i2c-acorn.c
++++ b/drivers/i2c/busses/i2c-acorn.c
+@@ -84,6 +84,7 @@ static struct i2c_algo_bit_data ioc_data
+
+ static struct i2c_adapter ioc_ops = {
+ .id = I2C_HW_B_IOC,
++ .nr = 0,
+ .algo_data = &ioc_data,
+ };
+
+@@ -91,7 +92,7 @@ static int __init i2c_ioc_init(void)
+ {
+ force_ones = FORCE_ONES | SCL | SDA;
+
+- return i2c_bit_add_bus(&ioc_ops);
++ return i2c_bit_add_numbered_bus(&ioc_ops);
+ }
+
+ module_init(i2c_ioc_init);
--- /dev/null
+From b8e15992b420d09dae831125a623c474c8637cee Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Date: Wed, 28 Jan 2009 14:09:59 +1100
+Subject: crypto: api - Fix algorithm test race that broke aead initialisation
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+commit b8e15992b420d09dae831125a623c474c8637cee upstream.
+
+When we complete a test we'll notify everyone waiting on it, drop
+the mutex, and then remove the test larval (after reacquiring the
+mutex). If one of the notified parties tries to register another
+algorithm with the same driver name prior to the removal of the
+test larval, they will fail with EEXIST as only one algorithm of
+a given name can be tested at any time.
+
+This broke the initialisation of aead and givcipher algorithms as
+they will register two algorithms with the same driver name, in
+sequence.
+
+This patch fixes the problem by marking the larval as dead before
+we drop the mutex, and also ignoring all dead or dying algorithms
+on the registration path.
+
+Tested-by: Andreas Steffen <andreas.steffen@strongswan.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: Kerin Millar <kerframil@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ crypto/algapi.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/crypto/algapi.c
++++ b/crypto/algapi.c
+@@ -149,6 +149,9 @@ static struct crypto_larval *__crypto_re
+ if (q == alg)
+ goto err;
+
++ if (crypto_is_moribund(q))
++ continue;
++
+ if (crypto_is_larval(q)) {
+ if (!strcmp(alg->cra_driver_name, q->cra_driver_name))
+ goto err;
+@@ -197,7 +200,7 @@ void crypto_alg_tested(const char *name,
+
+ down_write(&crypto_alg_sem);
+ list_for_each_entry(q, &crypto_alg_list, cra_list) {
+- if (!crypto_is_larval(q))
++ if (crypto_is_moribund(q) || !crypto_is_larval(q))
+ continue;
+
+ test = (struct crypto_larval *)q;
+@@ -210,6 +213,7 @@ void crypto_alg_tested(const char *name,
+ goto unlock;
+
+ found:
++ q->cra_flags |= CRYPTO_ALG_DEAD;
+ alg = test->adult;
+ if (err || list_empty(&alg->cra_list))
+ goto complete;
--- /dev/null
+From 8d391aa410ecb230fc4c3147b94eec25b9f3c20f Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Wed, 17 Dec 2008 22:32:14 -0800
+Subject: drm/i915: Add missing userland definitions for gem init/execbuffer.
+
+From: Eric Anholt <eric@anholt.net>
+
+commit 8d391aa410ecb230fc4c3147b94eec25b9f3c20f upstream.
+
+fdo bug #19132.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/drm/i915_drm.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/include/drm/i915_drm.h
++++ b/include/drm/i915_drm.h
+@@ -177,6 +177,8 @@ typedef struct _drm_i915_sarea {
+ #define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
+ #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
+ #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t)
++#define DRM_IOCTL_I915_GEM_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_INIT, struct drm_i915_gem_init)
++#define DRM_IOCTL_I915_GEM_EXECBUFFER DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER, struct drm_i915_gem_execbuffer)
+ #define DRM_IOCTL_I915_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_PIN, struct drm_i915_gem_pin)
+ #define DRM_IOCTL_I915_GEM_UNPIN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_UNPIN, struct drm_i915_gem_unpin)
+ #define DRM_IOCTL_I915_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_BUSY, struct drm_i915_gem_busy)
--- /dev/null
+From tytso@mit.edu Thu Mar 12 22:52:01 2009
+From: "Theodore Ts'o" <tytso@mit.edu>
+Date: Thu, 5 Mar 2009 02:35:14 -0500
+Subject: ext4: Add fallback for find_group_flex
+To: stable@kernel.org
+Cc: Ext4 Developers List <linux-ext4@vger.kernel.org>, "Theodore Ts'o" <tytso@mit.edu>
+Message-ID: <1236238515-8479-1-git-send-email-tytso@mit.edu>
+
+From: "Theodore Ts'o" <tytso@mit.edu>
+
+(cherry picked from commit 05bf9e839d9de4e8a094274a0a2fd07beb47eaf1)
+
+This is a workaround for find_group_flex() which badly needs to be
+replaced. One of its problems (besides ignoring the Orlov algorithm)
+is that it is a bit hyperactive about returning failure under
+suspicious circumstances. This can lead to spurious ENOSPC failures
+even when there are inodes still available.
+
+Work around this for now by retrying the search using
+find_group_other() if find_group_flex() returns -1. If
+find_group_other() succeeds when find_group_flex() has failed, log a
+warning message.
+
+A better block/inode allocator that will fix this problem for real has
+been queued up for the next merge window.
+
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ext4/ialloc.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/fs/ext4/ialloc.c
++++ b/fs/ext4/ialloc.c
+@@ -703,6 +703,13 @@ struct inode *ext4_new_inode(handle_t *h
+
+ if (sbi->s_log_groups_per_flex) {
+ ret2 = find_group_flex(sb, dir, &group);
++ if (ret2 == -1) {
++ ret2 = find_group_other(sb, dir, &group);
++ if (ret2 == 0 && printk_ratelimit())
++ printk(KERN_NOTICE "ext4: find_group_flex "
++ "failed, fallback succeeded dir %lu\n",
++ dir->i_ino);
++ }
+ goto got_group;
+ }
+
--- /dev/null
+From tytso@mit.edu Thu Mar 12 22:52:20 2009
+From: "Theodore Ts'o" <tytso@mit.edu>
+Date: Thu, 5 Mar 2009 02:35:15 -0500
+Subject: ext4: Fix deadlock in ext4_write_begin() and ext4_da_write_begin()
+To: stable@kernel.org
+Cc: "Theodore Ts'o" <tytso@mit.edu>, Ext4 Developers List <linux-ext4@vger.kernel.org>, Jan Kara <jack@suse.cz>
+Message-ID: <1236238515-8479-2-git-send-email-tytso@mit.edu>
+
+
+From: Jan Kara <jack@suse.cz>
+
+(cherry picked from commit ebd3610b110bbb18ea6f9f2aeed1e1068c537227)
+
+Functions ext4_write_begin() and ext4_da_write_begin() call
+grab_cache_page_write_begin() without AOP_FLAG_NOFS. Thus it
+can happen that page reclaim is triggered in that function
+and it recurses back into the filesystem (or some other filesystem).
+But this can lead to various problems as a transaction is already
+started at that point. Add the necessary flag.
+
+http://bugzilla.kernel.org/show_bug.cgi?id=11688
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ext4/inode.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -1347,6 +1347,10 @@ retry:
+ goto out;
+ }
+
++ /* We cannot recurse into the filesystem as the transaction is already
++ * started */
++ flags |= AOP_FLAG_NOFS;
++
+ page = grab_cache_page_write_begin(mapping, index, flags);
+ if (!page) {
+ ext4_journal_stop(handle);
+@@ -1356,7 +1360,7 @@ retry:
+ *pagep = page;
+
+ ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+- ext4_get_block);
++ ext4_get_block);
+
+ if (!ret && ext4_should_journal_data(inode)) {
+ ret = walk_page_buffers(handle, page_buffers(page),
+@@ -2603,6 +2607,9 @@ retry:
+ ret = PTR_ERR(handle);
+ goto out;
+ }
++ /* We cannot recurse into the filesystem as the transaction is already
++ * started */
++ flags |= AOP_FLAG_NOFS;
+
+ page = grab_cache_page_write_begin(mapping, index, flags);
+ if (!page) {
--- /dev/null
+From tytso@mit.edu Thu Mar 12 22:50:38 2009
+From: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+Date: Tue, 24 Feb 2009 12:14:45 -0500
+Subject: ext4: Fix lockdep warning
+To: stable@kernel.org
+Cc: "Theodore Ts'o" <tytso@mit.edu>, "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
+Message-ID: <1235495688-8044-5-git-send-email-tytso@mit.edu>
+
+
+From: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+
+(cherry picked from commit ba4439165f0f0d25b2fe065cf0c1ff8130b802eb)
+
+We should not call ext4_mb_add_n_trim while holding alloc_semp.
+
+ =============================================
+ [ INFO: possible recursive locking detected ]
+ 2.6.29-rc4-git1-dirty #124
+ ---------------------------------------------
+ ffsb/3116 is trying to acquire lock:
+ (&meta_group_info[i]->alloc_sem){----}, at: [<ffffffff8035a6e8>]
+ ext4_mb_load_buddy+0xd2/0x343
+
+ but task is already holding lock:
+ (&meta_group_info[i]->alloc_sem){----}, at: [<ffffffff8035a6e8>]
+ ext4_mb_load_buddy+0xd2/0x343
+
+http://bugzilla.kernel.org/show_bug.cgi?id=12672
+
+Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ext4/mballoc.c | 29 ++++++++++++++++-------------
+ 1 file changed, 16 insertions(+), 13 deletions(-)
+
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -4456,23 +4456,26 @@ static int ext4_mb_release_context(struc
+ pa->pa_free -= ac->ac_b_ex.fe_len;
+ pa->pa_len -= ac->ac_b_ex.fe_len;
+ spin_unlock(&pa->pa_lock);
+- /*
+- * We want to add the pa to the right bucket.
+- * Remove it from the list and while adding
+- * make sure the list to which we are adding
+- * doesn't grow big.
+- */
+- if (likely(pa->pa_free)) {
+- spin_lock(pa->pa_obj_lock);
+- list_del_rcu(&pa->pa_inode_list);
+- spin_unlock(pa->pa_obj_lock);
+- ext4_mb_add_n_trim(ac);
+- }
+ }
+- ext4_mb_put_pa(ac, ac->ac_sb, pa);
+ }
+ if (ac->alloc_semp)
+ up_read(ac->alloc_semp);
++ if (pa) {
++ /*
++ * We want to add the pa to the right bucket.
++ * Remove it from the list and while adding
++ * make sure the list to which we are adding
++ * doesn't grow big. We need to release
++ * alloc_semp before calling ext4_mb_add_n_trim()
++ */
++ if (pa->pa_linear && likely(pa->pa_free)) {
++ spin_lock(pa->pa_obj_lock);
++ list_del_rcu(&pa->pa_inode_list);
++ spin_unlock(pa->pa_obj_lock);
++ ext4_mb_add_n_trim(ac);
++ }
++ ext4_mb_put_pa(ac, ac->ac_sb, pa);
++ }
+ if (ac->ac_bitmap_page)
+ page_cache_release(ac->ac_bitmap_page);
+ if (ac->ac_buddy_page)
--- /dev/null
+From tytso@mit.edu Thu Mar 12 22:51:42 2009
+From: Dan Carpenter <error27@gmail.com>
+Date: Tue, 24 Feb 2009 12:14:48 -0500
+Subject: ext4: Fix NULL dereference in ext4_ext_migrate()'s error handling
+To: stable@kernel.org
+Cc: "Theodore Ts'o" <tytso@mit.edu>, Dan Carpenter <error27@gmail.com>
+Message-ID: <1235495688-8044-8-git-send-email-tytso@mit.edu>
+
+
+From: Dan Carpenter <error27@gmail.com>
+
+(cherry picked from commit 090542641de833c6f756895fc2f139f046e298f9)
+
+This was found through a code checker (http://repo.or.cz/w/smatch.git/).
+It looks like you might be able to trigger the error by trying to migrate
+a readonly file system.
+
+Signed-off-by: Dan Carpenter <error27@gmail.com>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ext4/migrate.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+--- a/fs/ext4/migrate.c
++++ b/fs/ext4/migrate.c
+@@ -480,7 +480,7 @@ int ext4_ext_migrate(struct inode *inode
+ + 1);
+ if (IS_ERR(handle)) {
+ retval = PTR_ERR(handle);
+- goto err_out;
++ return retval;
+ }
+ tmp_inode = ext4_new_inode(handle,
+ inode->i_sb->s_root->d_inode,
+@@ -488,8 +488,7 @@ int ext4_ext_migrate(struct inode *inode
+ if (IS_ERR(tmp_inode)) {
+ retval = -ENOMEM;
+ ext4_journal_stop(handle);
+- tmp_inode = NULL;
+- goto err_out;
++ return retval;
+ }
+ i_size_write(tmp_inode, i_size_read(inode));
+ /*
+@@ -617,8 +616,7 @@ err_out:
+
+ ext4_journal_stop(handle);
+
+- if (tmp_inode)
+- iput(tmp_inode);
++ iput(tmp_inode);
+
+ return retval;
+ }
--- /dev/null
+From tytso@mit.edu Thu Mar 12 22:50:20 2009
+From: Wei Yongjun <yjwei@cn.fujitsu.com>
+Date: Tue, 24 Feb 2009 12:14:44 -0500
+Subject: ext4: Fix to read empty directory blocks correctly in 64k
+To: stable@kernel.org
+Cc: "Theodore Ts'o" <tytso@mit.edu>, Wei Yongjun <yjwei@cn.fujitsu.com>
+Message-ID: <1235495688-8044-4-git-send-email-tytso@mit.edu>
+
+
+From: Wei Yongjun <yjwei@cn.fujitsu.com>
+
+(cherry picked from commit 7be2baaa0322c59ba888aa5260a8c130666acd41)
+
+The rec_len field in the directory entry is 16 bits, so there was a
+problem representing rec_len for filesystems with a 64k block size in
+the case where the directory entry takes the entire 64k block.
+Unfortunately, there were two schemes that were proposed; one where
+all zeros meant 65536 and one where all ones (65535) meant 65536.
+E2fsprogs used 0, whereas the kernel used 65535. Oops. Fortunately
+this case happens extremely rarely, with the most common case being
+the lost+found directory, created by mke2fs.
+
+So we will be liberal in what we accept, and accept both encodings,
+but we will continue to encode 65536 as 65535. This will require a
+change in e2fsprogs, but with fortunately ext4 filesystems normally
+have the dir_index feature enabled, which precludes having a
+completely empty directory block.
+
+Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ext4/ext4.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -862,7 +862,7 @@ static inline unsigned ext4_rec_len_from
+ {
+ unsigned len = le16_to_cpu(dlen);
+
+- if (len == EXT4_MAX_REC_LEN)
++ if (len == EXT4_MAX_REC_LEN || len == 0)
+ return 1 << 16;
+ return len;
+ }
--- /dev/null
+From tytso@mit.edu Thu Mar 12 22:51:22 2009
+From: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+Date: Tue, 24 Feb 2009 12:14:47 -0500
+Subject: ext4: Implement range_cyclic in ext4_da_writepages instead of write_cache_pages
+To: stable@kernel.org
+Cc: "Theodore Ts'o" <tytso@mit.edu>, "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
+Message-ID: <1235495688-8044-7-git-send-email-tytso@mit.edu>
+
+
+From: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+
+(cherry picked from commit 2acf2c261b823d9d9ed954f348b97620297a36b5)
+
+With delayed allocation we lock the page in write_cache_pages() and
+try to build an in memory extent of contiguous blocks. This is needed
+so that we can get large contiguous blocks request. If range_cyclic
+mode is enabled, write_cache_pages() will loop back to the 0 index if
+no I/O has been done yet, and try to start writing from the beginning
+of the range. That causes an attempt to take the page lock of lower
+index page while holding the page lock of higher index page, which can
+cause a dead lock with another writeback thread.
+
+The solution is to implement the range_cyclic behavior in
+ext4_da_writepages() instead.
+
+http://bugzilla.kernel.org/show_bug.cgi?id=12579
+
+Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ext4/inode.c | 21 +++++++++++++++++++--
+ 1 file changed, 19 insertions(+), 2 deletions(-)
+
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -2402,6 +2402,7 @@ static int ext4_da_writepages(struct add
+ struct inode *inode = mapping->host;
+ int no_nrwrite_index_update;
+ long pages_written = 0, pages_skipped;
++ int range_cyclic, cycled = 1, io_done = 0;
+ int needed_blocks, ret = 0, nr_to_writebump = 0;
+ struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb);
+
+@@ -2439,9 +2440,15 @@ static int ext4_da_writepages(struct add
+ if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
+ range_whole = 1;
+
+- if (wbc->range_cyclic)
++ range_cyclic = wbc->range_cyclic;
++ if (wbc->range_cyclic) {
+ index = mapping->writeback_index;
+- else
++ if (index)
++ cycled = 0;
++ wbc->range_start = index << PAGE_CACHE_SHIFT;
++ wbc->range_end = LLONG_MAX;
++ wbc->range_cyclic = 0;
++ } else
+ index = wbc->range_start >> PAGE_CACHE_SHIFT;
+
+ mpd.wbc = wbc;
+@@ -2455,6 +2462,7 @@ static int ext4_da_writepages(struct add
+ wbc->no_nrwrite_index_update = 1;
+ pages_skipped = wbc->pages_skipped;
+
++retry:
+ while (!ret && wbc->nr_to_write > 0) {
+
+ /*
+@@ -2497,6 +2505,7 @@ static int ext4_da_writepages(struct add
+ pages_written += mpd.pages_written;
+ wbc->pages_skipped = pages_skipped;
+ ret = 0;
++ io_done = 1;
+ } else if (wbc->nr_to_write)
+ /*
+ * There is no more writeout needed
+@@ -2505,6 +2514,13 @@ static int ext4_da_writepages(struct add
+ */
+ break;
+ }
++ if (!io_done && !cycled) {
++ cycled = 1;
++ index = 0;
++ wbc->range_start = index << PAGE_CACHE_SHIFT;
++ wbc->range_end = mapping->writeback_index - 1;
++ goto retry;
++ }
+ if (pages_skipped != wbc->pages_skipped)
+ printk(KERN_EMERG "This should not happen leaving %s "
+ "with nr_to_write = %ld ret = %d\n",
+@@ -2512,6 +2528,7 @@ static int ext4_da_writepages(struct add
+
+ /* Update index */
+ index += pages_written;
++ wbc->range_cyclic = range_cyclic;
+ if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
+ /*
+ * set the writeback_index so that range_cyclic
--- /dev/null
+From tytso@mit.edu Thu Mar 12 22:51:02 2009
+From: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+Date: Tue, 24 Feb 2009 12:14:46 -0500
+Subject: ext4: Initialize preallocation list_head's properly
+To: stable@kernel.org
+Cc: "Theodore Ts'o" <tytso@mit.edu>, "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
+Message-ID: <1235495688-8044-6-git-send-email-tytso@mit.edu>
+
+
+From: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+
+(cherry picked from commit d794bf8e0936dce45104565cd48c571061f4c1e3)
+
+When creating a new ext4_prealloc_space structure, we have to
+initialize its list_head pointers before we add them to any prealloc
+lists. Otherwise, with list debug enabled, we will get list
+corruption warnings.
+
+Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ext4/mballoc.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -3690,6 +3690,8 @@ ext4_mb_new_inode_pa(struct ext4_allocat
+ pa->pa_free = pa->pa_len;
+ atomic_set(&pa->pa_count, 1);
+ spin_lock_init(&pa->pa_lock);
++ INIT_LIST_HEAD(&pa->pa_inode_list);
++ INIT_LIST_HEAD(&pa->pa_group_list);
+ pa->pa_deleted = 0;
+ pa->pa_linear = 0;
+
+@@ -3748,6 +3750,7 @@ ext4_mb_new_group_pa(struct ext4_allocat
+ atomic_set(&pa->pa_count, 1);
+ spin_lock_init(&pa->pa_lock);
+ INIT_LIST_HEAD(&pa->pa_inode_list);
++ INIT_LIST_HEAD(&pa->pa_group_list);
+ pa->pa_deleted = 0;
+ pa->pa_linear = 1;
+
--- /dev/null
+From jkosina@suse.cz Thu Mar 12 23:07:31 2009
+From: Jiri Kosina <jkosina@suse.cz>
+Date: Mon, 2 Mar 2009 16:16:10 +0100 (CET)
+Subject: HID: move tmff and zpff devices from ignore_list to blacklist
+To: stable@kernel.org
+Cc: Anssi Hannula <anssi.hannula@gmail.com>
+Message-ID: <alpine.LNX.1.10.0903021614570.11667@jikos.suse.cz>
+
+
+From: Jiri Kosina <jkosina@suse.cz>
+
+[ upstream commit daedb3d6a91f9626ab4c921378ac52e44de833d5 ]
+
+From: Anssi Hannula <anssi.hannula@gmail.com>
+Subject: HID: move tmff and zpff devices from ignore_list to blacklist
+
+The devices handled by hid-tmff and hid-zpff were added in the
+hid_ignore_list[] instead of hid_blacklist[] in hid-core.c, thus
+disabling them completely.
+
+hid_ignore_list[] causes hid layer to skip the device, while
+hid_blacklist[] indicates there is a specific driver in hid bus.
+
+Re-enable the devices by moving them to the correct list.
+
+Signed-off-by: Anssi Hannula <anssi.hannula@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/hid/hid-core.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/hid/hid-core.c
++++ b/drivers/hid/hid-core.c
+@@ -1302,6 +1302,12 @@ static const struct hid_device_id hid_bl
+ { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },
++ { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
++ { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
++ { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
++ { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
++ { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
++ { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
+
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
+@@ -1529,10 +1535,6 @@ static const struct hid_device_id hid_ig
+ { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY1) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY2) },
+- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
+- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
+- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
+- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) },
+@@ -1543,8 +1545,6 @@ static const struct hid_device_id hid_ig
+ { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) },
+- { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
+- { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
+ { }
+ };
+
--- /dev/null
+From khali@linux-fr.org Thu Mar 12 23:16:17 2009
+From: Jean Delvare <khali@linux-fr.org>
+Date: Sat, 21 Feb 2009 12:00:20 +0100
+Subject: hwmon: (f71882fg) Hide misleading error message
+To: stable@kernel.org
+Message-ID: <20090221120020.35dafe74@hyperion.delvare>
+
+From: Jean Delvare <khali@linux-fr.org>
+
+commit 603eaa1bdd3e0402085e815cc531bb0a32827a9e upstream
+
+If the F71882FG chip is at address 0x4e, then the probe at 0x2e will
+fail with the following message in the logs:
+f71882fg: Not a Fintek device
+
+This is misleading because there is a Fintek device, just at a
+different address. So I propose to degrade this message to a debug
+message.
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Acked-by: Hans de Goede <hdegoede@redhat.com>
+
+
+---
+ drivers/hwmon/f71882fg.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/hwmon/f71882fg.c
++++ b/drivers/hwmon/f71882fg.c
+@@ -837,7 +837,7 @@ static int __init f71882fg_find(int sioa
+
+ devid = superio_inw(sioaddr, SIO_REG_MANID);
+ if (devid != SIO_FINTEK_ID) {
+- printk(KERN_INFO DRVNAME ": Not a Fintek device\n");
++ pr_debug(DRVNAME ": Not a Fintek device\n");
+ goto exit;
+ }
+
--- /dev/null
+From khali@linux-fr.org Thu Mar 12 23:10:15 2009
+From: Roel Kluin <roel.kluin@gmail.com>
+Date: Wed, 25 Feb 2009 21:24:40 +0100
+Subject: i2c: Fix misplaced parentheses
+To: stable@kernel.org
+Message-ID: <20090225212440.3b6d0001@hyperion.delvare>
+
+
+From: Roel Kluin <roel.kluin@gmail.com>
+
+commit f29d2e0275a4f03ef2fd158e484508dcb0c64efb upstream
+
+Fix misplaced parentheses.
+
+Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/i2c/i2c-core.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/i2c/i2c-core.c
++++ b/drivers/i2c/i2c-core.c
+@@ -1831,7 +1831,8 @@ static s32 i2c_smbus_xfer_emulated(struc
+ case I2C_SMBUS_QUICK:
+ msg[0].len = 0;
+ /* Special case: The read/write field is used as data */
+- msg[0].flags = flags | (read_write==I2C_SMBUS_READ)?I2C_M_RD:0;
++ msg[0].flags = flags | (read_write == I2C_SMBUS_READ ?
++ I2C_M_RD : 0);
+ num = 1;
+ break;
+ case I2C_SMBUS_BYTE:
--- /dev/null
+From khali@linux-fr.org Thu Mar 12 23:09:33 2009
+From: Roel Kluin <roel.kluin@gmail.com>
+Date: Wed, 25 Feb 2009 21:26:21 +0100
+Subject: i2c: Timeouts reach -1
+To: stable@kernel.org
+Message-ID: <20090225212621.4714ef35@hyperion.delvare>
+
+
+From: Roel Kluin <roel.kluin@gmail.com>
+
+commit a746b578d8406b2db0e9f0d040061bc1f78433cf upstream
+
+With a postfix decrement these timeouts reach -1 rather than 0, but
+after the loop it is tested whether they have become 0.
+
+As pointed out by Jean Delvare, the condition we are waiting for should
+also be tested before the timeout. With the current order, you could
+exit with a timeout error while the job is actually done.
+
+Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/i2c/busses/i2c-amd8111.c | 4 ++--
+ drivers/i2c/busses/i2c-pxa.c | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/i2c/busses/i2c-amd8111.c
++++ b/drivers/i2c/busses/i2c-amd8111.c
+@@ -72,7 +72,7 @@ static unsigned int amd_ec_wait_write(st
+ {
+ int timeout = 500;
+
+- while (timeout-- && (inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_IBF))
++ while ((inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_IBF) && --timeout)
+ udelay(1);
+
+ if (!timeout) {
+@@ -88,7 +88,7 @@ static unsigned int amd_ec_wait_read(str
+ {
+ int timeout = 500;
+
+- while (timeout-- && (~inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_OBF))
++ while ((~inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_OBF) && --timeout)
+ udelay(1);
+
+ if (!timeout) {
+--- a/drivers/i2c/busses/i2c-pxa.c
++++ b/drivers/i2c/busses/i2c-pxa.c
+@@ -644,7 +644,7 @@ static int i2c_pxa_do_pio_xfer(struct px
+
+ i2c_pxa_start_message(i2c);
+
+- while (timeout-- && i2c->msg_num > 0) {
++ while (i2c->msg_num > 0 && --timeout) {
+ i2c_pxa_handler(0, i2c);
+ udelay(10);
+ }
--- /dev/null
+From a509538d4fb4f99cdf0a095213d57cc3b2347615 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Date: Thu, 5 Mar 2009 16:10:56 +0100
+Subject: ide-iops: fix odd-length ATAPI PIO transfers
+
+From: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+
+commit a509538d4fb4f99cdf0a095213d57cc3b2347615 upstream.
+
+Commit 9567b349f7e7dd7e2483db99ee8e4a6fe0caca38 (ide: merge ->atapi_*put_bytes
+and ->ata_*put_data methods) introduced a regression WRT the odd-length ATAPI
+PIO transfers -- the final word didn't get written (causing command timeouts).
+
+Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/ide/ide-iops.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/ide/ide-iops.c
++++ b/drivers/ide/ide-iops.c
+@@ -324,6 +324,8 @@ void ide_output_data(ide_drive_t *drive,
+ u8 io_32bit = drive->io_32bit;
+ u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+
++ len++;
++
+ if (io_32bit) {
+ unsigned long uninitialized_var(flags);
+
--- /dev/null
+From tytso@mit.edu Thu Mar 12 22:49:54 2009
+From: Jan Kara <jack@suse.cz>
+Date: Tue, 24 Feb 2009 12:14:43 -0500
+Subject: jbd2: Avoid possible NULL dereference in jbd2_journal_begin_ordered_truncate()
+To: stable@kernel.org
+Cc: "Theodore Ts'o" <tytso@mit.edu>, Dan Carpenter <error27@gmail.com>, mfasheh@suse.de, Jan Kara <jack@suse.cz>, linux-ext4@vger.kernel.org, ocfs2-devel@oss.oracle.com
+Message-ID: <1235495688-8044-3-git-send-email-tytso@mit.edu>
+
+
+From: Jan Kara <jack@suse.cz>
+
+(cherry picked from commit 7f5aa215088b817add9c71914b83650bdd49f8a9)
+
+If we race with commit code setting i_transaction to NULL, we could
+possibly dereference it. Proper locking requires the journal pointer
+(to access journal->j_list_lock), which we don't have. So we have to
+change the prototype of the function so that filesystem passes us the
+journal pointer. Also add a more detailed comment about why the
+function jbd2_journal_begin_ordered_truncate() does what it does and
+how it should be used.
+
+Thanks to Dan Carpenter <error27@gmail.com> for pointing to the
+suspitious code.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Acked-by: Joel Becker <joel.becker@oracle.com>
+CC: linux-ext4@vger.kernel.org
+CC: ocfs2-devel@oss.oracle.com
+CC: mfasheh@suse.de
+CC: Dan Carpenter <error27@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ext4/inode.c | 6 ++++--
+ fs/jbd2/transaction.c | 42 +++++++++++++++++++++++++++++++-----------
+ fs/ocfs2/journal.h | 6 ++++--
+ include/linux/jbd2.h | 3 ++-
+ 4 files changed, 41 insertions(+), 16 deletions(-)
+
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -46,8 +46,10 @@
+ static inline int ext4_begin_ordered_truncate(struct inode *inode,
+ loff_t new_size)
+ {
+- return jbd2_journal_begin_ordered_truncate(&EXT4_I(inode)->jinode,
+- new_size);
++ return jbd2_journal_begin_ordered_truncate(
++ EXT4_SB(inode->i_sb)->s_journal,
++ &EXT4_I(inode)->jinode,
++ new_size);
+ }
+
+ static void ext4_invalidatepage(struct page *page, unsigned long offset);
+--- a/fs/jbd2/transaction.c
++++ b/fs/jbd2/transaction.c
+@@ -2050,26 +2050,46 @@ done:
+ }
+
+ /*
+- * This function must be called when inode is journaled in ordered mode
+- * before truncation happens. It starts writeout of truncated part in
+- * case it is in the committing transaction so that we stand to ordered
+- * mode consistency guarantees.
++ * File truncate and transaction commit interact with each other in a
++ * non-trivial way. If a transaction writing data block A is
++ * committing, we cannot discard the data by truncate until we have
++ * written them. Otherwise if we crashed after the transaction with
++ * write has committed but before the transaction with truncate has
++ * committed, we could see stale data in block A. This function is a
++ * helper to solve this problem. It starts writeout of the truncated
++ * part in case it is in the committing transaction.
++ *
++ * Filesystem code must call this function when inode is journaled in
++ * ordered mode before truncation happens and after the inode has been
++ * placed on orphan list with the new inode size. The second condition
++ * avoids the race that someone writes new data and we start
++ * committing the transaction after this function has been called but
++ * before a transaction for truncate is started (and furthermore it
++ * allows us to optimize the case where the addition to orphan list
++ * happens in the same transaction as write --- we don't have to write
++ * any data in such case).
+ */
+-int jbd2_journal_begin_ordered_truncate(struct jbd2_inode *inode,
++int jbd2_journal_begin_ordered_truncate(journal_t *journal,
++ struct jbd2_inode *jinode,
+ loff_t new_size)
+ {
+- journal_t *journal;
+- transaction_t *commit_trans;
++ transaction_t *inode_trans, *commit_trans;
+ int ret = 0;
+
+- if (!inode->i_transaction && !inode->i_next_transaction)
++ /* This is a quick check to avoid locking if not necessary */
++ if (!jinode->i_transaction)
+ goto out;
+- journal = inode->i_transaction->t_journal;
++ /* Locks are here just to force reading of recent values, it is
++ * enough that the transaction was not committing before we started
++ * a transaction adding the inode to orphan list */
+ spin_lock(&journal->j_state_lock);
+ commit_trans = journal->j_committing_transaction;
+ spin_unlock(&journal->j_state_lock);
+- if (inode->i_transaction == commit_trans) {
+- ret = filemap_fdatawrite_range(inode->i_vfs_inode->i_mapping,
++ spin_lock(&journal->j_list_lock);
++ inode_trans = jinode->i_transaction;
++ spin_unlock(&journal->j_list_lock);
++ if (inode_trans == commit_trans) {
++ ret = filemap_fdatawrite_range(jinode->i_vfs_inode->i_mapping,
+ new_size, LLONG_MAX);
+ if (ret)
+ jbd2_journal_abort(journal, ret);
+--- a/fs/ocfs2/journal.h
++++ b/fs/ocfs2/journal.h
+@@ -445,8 +445,10 @@ static inline int ocfs2_jbd2_file_inode(
+ static inline int ocfs2_begin_ordered_truncate(struct inode *inode,
+ loff_t new_size)
+ {
+- return jbd2_journal_begin_ordered_truncate(&OCFS2_I(inode)->ip_jinode,
+- new_size);
++ return jbd2_journal_begin_ordered_truncate(
++ OCFS2_SB(inode->i_sb)->journal->j_journal,
++ &OCFS2_I(inode)->ip_jinode,
++ new_size);
+ }
+
+ #endif /* OCFS2_JOURNAL_H */
+--- a/include/linux/jbd2.h
++++ b/include/linux/jbd2.h
+@@ -1087,7 +1087,8 @@ extern int jbd2_journal_clear_err (j
+ extern int jbd2_journal_bmap(journal_t *, unsigned long, unsigned long long *);
+ extern int jbd2_journal_force_commit(journal_t *);
+ extern int jbd2_journal_file_inode(handle_t *handle, struct jbd2_inode *inode);
+-extern int jbd2_journal_begin_ordered_truncate(struct jbd2_inode *inode, loff_t new_size);
++extern int jbd2_journal_begin_ordered_truncate(journal_t *journal,
++ struct jbd2_inode *inode, loff_t new_size);
+ extern void jbd2_journal_init_jbd_inode(struct jbd2_inode *jinode, struct inode *inode);
+ extern void jbd2_journal_release_jbd_inode(journal_t *journal, struct jbd2_inode *jinode);
+
--- /dev/null
+From tytso@mit.edu Thu Mar 12 22:49:00 2009
+From: Jan Kara <jack@suse.cz>
+Date: Tue, 24 Feb 2009 12:14:41 -0500
+Subject: jbd2: Fix return value of jbd2_journal_start_commit()
+To: stable@kernel.org
+Cc: "Theodore Ts'o" <tytso@mit.edu>, linux-ext4@vger.kernel.org, Jan Kara <jack@suse.cz>, Eric Sandeen <sandeen@redhat.com>
+Message-ID: <1235495688-8044-1-git-send-email-tytso@mit.edu>
+
+
+From: Jan Kara <jack@suse.cz>
+
+(cherry picked from commit c88ccea3143975294f5a52097546bcbb75975f52)
+
+The function jbd2_journal_start_commit() returns 1 if either a
+transaction is committing or the function has queued a transaction
+commit. But it returns 0 if we raced with somebody queueing the
+transaction commit as well. This resulted in ext4_sync_fs() not
+functioning correctly (description from Arthur Jones):
+
+ In the case of a data=ordered umount with pending long symlinks
+ which are delayed due to a long list of other I/O on the backing
+ block device, this causes the buffer associated with the long
+ symlinks to not be moved to the inode dirty list in the second
+ phase of fsync_super. Then, before they can be dirtied again,
+ kjournald exits, seeing the UMOUNT flag and the dirty pages are
+ never written to the backing block device, causing long symlink
+ corruption and exposing new or previously freed block data to
+ userspace.
+
+This can be reproduced with a script created by Eric Sandeen
+<sandeen@redhat.com>:
+
+ #!/bin/bash
+
+ umount /mnt/test2
+ mount /dev/sdb4 /mnt/test2
+ rm -f /mnt/test2/*
+ dd if=/dev/zero of=/mnt/test2/bigfile bs=1M count=512
+ touch /mnt/test2/thisisveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryverylongfilename
+ ln -s /mnt/test2/thisisveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryverylongfilename
+ /mnt/test2/link
+ umount /mnt/test2
+ mount /dev/sdb4 /mnt/test2
+ ls /mnt/test2/
+
+This patch fixes jbd2_journal_start_commit() to always return 1 when
+there's a transaction committing or queued for commit.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+CC: Eric Sandeen <sandeen@redhat.com>
+CC: linux-ext4@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/jbd2/journal.c | 17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+--- a/fs/jbd2/journal.c
++++ b/fs/jbd2/journal.c
+@@ -430,7 +430,7 @@ int __jbd2_log_space_left(journal_t *jou
+ }
+
+ /*
+- * Called under j_state_lock. Returns true if a transaction was started.
++ * Called under j_state_lock. Returns true if a transaction commit was started.
+ */
+ int __jbd2_log_start_commit(journal_t *journal, tid_t target)
+ {
+@@ -498,7 +498,8 @@ int jbd2_journal_force_commit_nested(jou
+
+ /*
+ * Start a commit of the current running transaction (if any). Returns true
+- * if a transaction was started, and fills its tid in at *ptid
++ * if a transaction is going to be committed (or is currently already
++ * committing), and fills its tid in at *ptid
+ */
+ int jbd2_journal_start_commit(journal_t *journal, tid_t *ptid)
+ {
+@@ -508,15 +509,19 @@ int jbd2_journal_start_commit(journal_t
+ if (journal->j_running_transaction) {
+ tid_t tid = journal->j_running_transaction->t_tid;
+
+- ret = __jbd2_log_start_commit(journal, tid);
+- if (ret && ptid)
++ __jbd2_log_start_commit(journal, tid);
++ /* There's a running transaction and we've just made sure
++ * it's commit has been scheduled. */
++ if (ptid)
+ *ptid = tid;
+- } else if (journal->j_committing_transaction && ptid) {
++ ret = 1;
++ } else if (journal->j_committing_transaction) {
+ /*
+ * If ext3_write_super() recently started a commit, then we
+ * have to wait for completion of that transaction
+ */
+- *ptid = journal->j_committing_transaction->t_tid;
++ if (ptid)
++ *ptid = journal->j_committing_transaction->t_tid;
+ ret = 1;
+ }
+ spin_unlock(&journal->j_state_lock);
--- /dev/null
+From tytso@mit.edu Thu Mar 12 22:49:29 2009
+From: Jan Kara <jack@suse.cz>
+Date: Tue, 24 Feb 2009 12:14:42 -0500
+Subject: Revert "ext4: wait on all pending commits in ext4_sync_fs()"
+To: stable@kernel.org
+Cc: "Theodore Ts'o" <tytso@mit.edu>, linux-ext4@vger.kernel.org, Jan Kara <jack@suse.cz>, Eric Sandeen <sandeen@redhat.com>
+Message-ID: <1235495688-8044-2-git-send-email-tytso@mit.edu>
+
+
+From: Jan Kara <jack@suse.cz>
+
+(cherry picked from commit 9eddacf9e9c03578ef2c07c9534423e823d677f8)
+
+This undoes commit 14ce0cb411c88681ab8f3a4c9caa7f42e97a3184.
+
+Since jbd2_journal_start_commit() is now fixed to return 1 when we
+started a transaction commit, there's some transaction waiting to be
+committed or there's a transaction already committing, we don't
+need to call ext4_force_commit() in ext4_sync_fs(). Furthermore
+ext4_force_commit() can unnecessarily create sync transaction which is
+expensive so it's worthwhile to remove it when we can.
+
+http://bugzilla.kernel.org/show_bug.cgi?id=12224
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Cc: Eric Sandeen <sandeen@redhat.com>
+Cc: linux-ext4@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ext4/super.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -2914,15 +2914,15 @@ static void ext4_write_super(struct supe
+
+ static int ext4_sync_fs(struct super_block *sb, int wait)
+ {
+- int ret = 0;
++ tid_t target;
+
+ trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait);
+ sb->s_dirt = 0;
+- if (wait)
+- ret = ext4_force_commit(sb);
+- else
+- jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, NULL);
+- return ret;
++ if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, &target)) {
++ if (wait)
++ jbd2_log_wait_commit(EXT4_SB(sb)->s_journal, target);
++ }
++ return 0;
+ }
+
+ /*
0002-V4L-tda8290-fix-TDA8290-TDA18271-initialization.patch
0003-V4L-saa7127-fix-broken-S-Video-with-saa7129.patch
0004-V4L-ivtv-fix-decoder-crash-regression.patch
+jbd2-fix-return-value-of-jbd2_journal_start_commit.patch
+revert-ext4-wait-on-all-pending-commits-in-ext4_sync_fs.patch
+jbd2-avoid-possible-null-dereference-in-jbd2_journal_begin_ordered_truncate.patch
+ext4-fix-to-read-empty-directory-blocks-correctly-in-64k.patch
+ext4-fix-lockdep-warning.patch
+ext4-initialize-preallocation-list_head-s-properly.patch
+ext4-implement-range_cyclic-in-ext4_da_writepages-instead-of-write_cache_pages.patch
+ext4-fix-null-dereference-in-ext4_ext_migrate-s-error-handling.patch
+ext4-add-fallback-for-find_group_flex.patch
+ext4-fix-deadlock-in-ext4_write_begin-and-ext4_da_write_begin.patch
+x86-paravirt-make-arch_flush_lazy_mmu-cpu-disable-preemption.patch
+x86-hpet-fix-for-ls21-hpet-boot-hang.patch
+x86-math_emu-info-cleanup.patch
+x86-fix-math_emu-register-frame-access.patch
+ide-iops-fix-odd-length-atapi-pio-transfers.patch
+hid-move-tmff-and-zpff-devices-from-ignore_list-to-blacklist.patch
+arm-add-i2c_board_info-for-riscpc-pcf8583.patch
+i2c-timeouts-reach-1.patch
+i2c-fix-misplaced-parentheses.patch
+acpi-fix-broken-usage-of-name.ascii.patch
+acpi-fix-broken-usage-of-acpi_ut_get_node_name.patch
+crypto-api-fix-algorithm-test-race-that-broke-aead-initialisation.patch
+hwmon-hide-misleading-error-message.patch
+drm-i915-add-missing-userland-definitions-for-gem-init-execbuffer.patch
--- /dev/null
+From d315760ffa261c15ff92699ac6f514112543d7ca Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Mon, 9 Feb 2009 22:17:39 +0900
+Subject: x86: fix math_emu register frame access
+
+From: Tejun Heo <tj@kernel.org>
+
+commit d315760ffa261c15ff92699ac6f514112543d7ca upstream.
+
+do_device_not_available() is the handler for #NM and it declares that
+it takes a unsigned long and calls math_emu(), which takes a long
+argument and surprisingly expects the stack frame starting at the zero
+argument would match struct math_emu_info, which isn't true regardless
+of configuration in the current code.
+
+This patch makes do_device_not_available() take struct pt_regs like
+other exception handlers and initialize struct math_emu_info with
+pointer to it and pass pointer to the math_emu_info to math_emulate()
+like normal C functions do. This way, unless gcc makes a copy of
+struct pt_regs in do_device_not_available(), the register frame is
+correctly accessed regardless of kernel configuration or compiler
+used.
+
+This doesn't fix all math_emu problems but it at least gets it
+somewhat working.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86/include/asm/math_emu.h | 4 +-
+ arch/x86/include/asm/traps.h | 4 +-
+ arch/x86/kernel/traps.c | 15 +++++----
+ arch/x86/math-emu/fpu_entry.c | 4 +-
+ arch/x86/math-emu/fpu_proto.h | 2 -
+ arch/x86/math-emu/fpu_system.h | 16 +++------
+ arch/x86/math-emu/get_address.c | 66 ++++++++++++++++++++--------------------
+ 7 files changed, 55 insertions(+), 56 deletions(-)
+
+--- a/arch/x86/include/asm/math_emu.h
++++ b/arch/x86/include/asm/math_emu.h
+@@ -11,8 +11,8 @@
+ struct math_emu_info {
+ long ___orig_eip;
+ union {
+- struct pt_regs regs;
+- struct kernel_vm86_regs vm86;
++ struct pt_regs *regs;
++ struct kernel_vm86_regs *vm86;
+ };
+ };
+ #endif /* _ASM_X86_MATH_EMU_H */
+--- a/arch/x86/include/asm/traps.h
++++ b/arch/x86/include/asm/traps.h
+@@ -41,7 +41,7 @@ dotraplinkage void do_int3(struct pt_reg
+ dotraplinkage void do_overflow(struct pt_regs *, long);
+ dotraplinkage void do_bounds(struct pt_regs *, long);
+ dotraplinkage void do_invalid_op(struct pt_regs *, long);
+-dotraplinkage void do_device_not_available(struct pt_regs *, long);
++dotraplinkage void do_device_not_available(struct pt_regs);
+ dotraplinkage void do_coprocessor_segment_overrun(struct pt_regs *, long);
+ dotraplinkage void do_invalid_TSS(struct pt_regs *, long);
+ dotraplinkage void do_segment_not_present(struct pt_regs *, long);
+@@ -74,8 +74,8 @@ extern int kstack_depth_to_print;
+
+ #ifdef CONFIG_X86_32
+ void math_error(void __user *);
++void math_emulate(struct math_emu_info *);
+ unsigned long patch_espfix_desc(unsigned long, unsigned long);
+-asmlinkage void math_emulate(long);
+ #endif
+
+ #endif /* _ASM_X86_TRAPS_H */
+--- a/arch/x86/kernel/traps.c
++++ b/arch/x86/kernel/traps.c
+@@ -912,7 +912,7 @@ asmlinkage void math_state_restore(void)
+ EXPORT_SYMBOL_GPL(math_state_restore);
+
+ #ifndef CONFIG_MATH_EMULATION
+-asmlinkage void math_emulate(long arg)
++void math_emulate(struct math_emu_info *info)
+ {
+ printk(KERN_EMERG
+ "math-emulation not enabled and no coprocessor found.\n");
+@@ -922,16 +922,19 @@ asmlinkage void math_emulate(long arg)
+ }
+ #endif /* CONFIG_MATH_EMULATION */
+
+-dotraplinkage void __kprobes
+-do_device_not_available(struct pt_regs *regs, long error)
++dotraplinkage void __kprobes do_device_not_available(struct pt_regs regs)
+ {
+ #ifdef CONFIG_X86_32
+ if (read_cr0() & X86_CR0_EM) {
+- conditional_sti(regs);
+- math_emulate(0);
++ struct math_emu_info info = { };
++
++ conditional_sti(®s);
++
++ info.regs = ®s;
++ math_emulate(&info);
+ } else {
+ math_state_restore(); /* interrupts still off */
+- conditional_sti(regs);
++ conditional_sti(®s);
+ }
+ #else
+ math_state_restore();
+--- a/arch/x86/math-emu/fpu_entry.c
++++ b/arch/x86/math-emu/fpu_entry.c
+@@ -131,7 +131,7 @@ u_char emulating = 0;
+ static int valid_prefix(u_char *Byte, u_char __user ** fpu_eip,
+ overrides * override);
+
+-asmlinkage void math_emulate(long arg)
++void math_emulate(struct math_emu_info *info)
+ {
+ u_char FPU_modrm, byte1;
+ unsigned short code;
+@@ -161,7 +161,7 @@ asmlinkage void math_emulate(long arg)
+ RE_ENTRANT_CHECK_ON;
+ #endif /* RE_ENTRANT_CHECKING */
+
+- SETUP_DATA_AREA(arg);
++ FPU_info = info;
+
+ FPU_ORIG_EIP = FPU_EIP;
+
+--- a/arch/x86/math-emu/fpu_proto.h
++++ b/arch/x86/math-emu/fpu_proto.h
+@@ -51,7 +51,7 @@ extern void ffreep(void);
+ extern void fst_i_(void);
+ extern void fstp_i(void);
+ /* fpu_entry.c */
+-asmlinkage extern void math_emulate(long arg);
++extern void math_emulate(struct math_emu_info *info);
+ extern void math_abort(struct math_emu_info *info, unsigned int signal);
+ /* fpu_etc.c */
+ extern void FPU_etc(void);
+--- a/arch/x86/math-emu/fpu_system.h
++++ b/arch/x86/math-emu/fpu_system.h
+@@ -16,10 +16,6 @@
+ #include <linux/kernel.h>
+ #include <linux/mm.h>
+
+-/* This sets the pointer FPU_info to point to the argument part
+- of the stack frame of math_emulate() */
+-#define SETUP_DATA_AREA(arg) FPU_info = (struct math_emu_info *) &arg
+-
+ /* s is always from a cpu register, and the cpu does bounds checking
+ * during register load --> no further bounds checks needed */
+ #define LDT_DESCRIPTOR(s) (((struct desc_struct *)current->mm->context.ldt)[(s) >> 3])
+@@ -38,12 +34,12 @@
+ #define I387 (current->thread.xstate)
+ #define FPU_info (I387->soft.info)
+
+-#define FPU_CS (*(unsigned short *) &(FPU_info->regs.cs))
+-#define FPU_SS (*(unsigned short *) &(FPU_info->regs.ss))
+-#define FPU_DS (*(unsigned short *) &(FPU_info->regs.ds))
+-#define FPU_EAX (FPU_info->regs.ax)
+-#define FPU_EFLAGS (FPU_info->regs.flags)
+-#define FPU_EIP (FPU_info->regs.ip)
++#define FPU_CS (*(unsigned short *) &(FPU_info->regs->cs))
++#define FPU_SS (*(unsigned short *) &(FPU_info->regs->ss))
++#define FPU_DS (*(unsigned short *) &(FPU_info->regs->ds))
++#define FPU_EAX (FPU_info->regs->ax)
++#define FPU_EFLAGS (FPU_info->regs->flags)
++#define FPU_EIP (FPU_info->regs->ip)
+ #define FPU_ORIG_EIP (FPU_info->___orig_eip)
+
+ #define FPU_lookahead (I387->soft.lookahead)
+--- a/arch/x86/math-emu/get_address.c
++++ b/arch/x86/math-emu/get_address.c
+@@ -29,43 +29,43 @@
+ #define FPU_WRITE_BIT 0x10
+
+ static int reg_offset[] = {
+- offsetof(struct math_emu_info, regs.ax),
+- offsetof(struct math_emu_info, regs.cx),
+- offsetof(struct math_emu_info, regs.dx),
+- offsetof(struct math_emu_info, regs.bx),
+- offsetof(struct math_emu_info, regs.sp),
+- offsetof(struct math_emu_info, regs.bp),
+- offsetof(struct math_emu_info, regs.si),
+- offsetof(struct math_emu_info, regs.di)
++ offsetof(struct pt_regs, ax),
++ offsetof(struct pt_regs, cx),
++ offsetof(struct pt_regs, dx),
++ offsetof(struct pt_regs, bx),
++ offsetof(struct pt_regs, sp),
++ offsetof(struct pt_regs, bp),
++ offsetof(struct pt_regs, si),
++ offsetof(struct pt_regs, di)
+ };
+
+-#define REG_(x) (*(long *)(reg_offset[(x)]+(u_char *) FPU_info))
++#define REG_(x) (*(long *)(reg_offset[(x)] + (u_char *)FPU_info->regs))
+
+ static int reg_offset_vm86[] = {
+- offsetof(struct math_emu_info, regs.cs),
+- offsetof(struct math_emu_info, vm86.ds),
+- offsetof(struct math_emu_info, vm86.es),
+- offsetof(struct math_emu_info, vm86.fs),
+- offsetof(struct math_emu_info, vm86.gs),
+- offsetof(struct math_emu_info, regs.ss),
+- offsetof(struct math_emu_info, vm86.ds)
++ offsetof(struct pt_regs, cs),
++ offsetof(struct kernel_vm86_regs, ds),
++ offsetof(struct kernel_vm86_regs, es),
++ offsetof(struct kernel_vm86_regs, fs),
++ offsetof(struct kernel_vm86_regs, gs),
++ offsetof(struct pt_regs, ss),
++ offsetof(struct kernel_vm86_regs, ds)
+ };
+
+ #define VM86_REG_(x) (*(unsigned short *) \
+- (reg_offset_vm86[((unsigned)x)]+(u_char *) FPU_info))
++ (reg_offset_vm86[((unsigned)x)] + (u_char *)FPU_info->regs))
+
+ static int reg_offset_pm[] = {
+- offsetof(struct math_emu_info, regs.cs),
+- offsetof(struct math_emu_info, regs.ds),
+- offsetof(struct math_emu_info, regs.es),
+- offsetof(struct math_emu_info, regs.fs),
+- offsetof(struct math_emu_info, regs.ds), /* dummy, not saved on stack */
+- offsetof(struct math_emu_info, regs.ss),
+- offsetof(struct math_emu_info, regs.ds)
++ offsetof(struct pt_regs, cs),
++ offsetof(struct pt_regs, ds),
++ offsetof(struct pt_regs, es),
++ offsetof(struct pt_regs, fs),
++ offsetof(struct pt_regs, ds), /* dummy, not saved on stack */
++ offsetof(struct pt_regs, ss),
++ offsetof(struct pt_regs, ds)
+ };
+
+ #define PM_REG_(x) (*(unsigned short *) \
+- (reg_offset_pm[((unsigned)x)]+(u_char *) FPU_info))
++ (reg_offset_pm[((unsigned)x)] + (u_char *)FPU_info->regs))
+
+ /* Decode the SIB byte. This function assumes mod != 0 */
+ static int sib(int mod, unsigned long *fpu_eip)
+@@ -346,34 +346,34 @@ void __user *FPU_get_address_16(u_char F
+ }
+ switch (rm) {
+ case 0:
+- address += FPU_info->regs.bx + FPU_info->regs.si;
++ address += FPU_info->regs->bx + FPU_info->regs->si;
+ break;
+ case 1:
+- address += FPU_info->regs.bx + FPU_info->regs.di;
++ address += FPU_info->regs->bx + FPU_info->regs->di;
+ break;
+ case 2:
+- address += FPU_info->regs.bp + FPU_info->regs.si;
++ address += FPU_info->regs->bp + FPU_info->regs->si;
+ if (addr_modes.override.segment == PREFIX_DEFAULT)
+ addr_modes.override.segment = PREFIX_SS_;
+ break;
+ case 3:
+- address += FPU_info->regs.bp + FPU_info->regs.di;
++ address += FPU_info->regs->bp + FPU_info->regs->di;
+ if (addr_modes.override.segment == PREFIX_DEFAULT)
+ addr_modes.override.segment = PREFIX_SS_;
+ break;
+ case 4:
+- address += FPU_info->regs.si;
++ address += FPU_info->regs->si;
+ break;
+ case 5:
+- address += FPU_info->regs.di;
++ address += FPU_info->regs->di;
+ break;
+ case 6:
+- address += FPU_info->regs.bp;
++ address += FPU_info->regs->bp;
+ if (addr_modes.override.segment == PREFIX_DEFAULT)
+ addr_modes.override.segment = PREFIX_SS_;
+ break;
+ case 7:
+- address += FPU_info->regs.bx;
++ address += FPU_info->regs->bx;
+ break;
+ }
+
--- /dev/null
+From b13e24644c138d0ddbc451403c30a96b09bfd556 Mon Sep 17 00:00:00 2001
+From: john stultz <johnstul@us.ibm.com>
+Date: Thu, 12 Feb 2009 18:48:53 -0800
+Subject: x86, hpet: fix for LS21 + HPET = boot hang
+
+From: john stultz <johnstul@us.ibm.com>
+
+commit b13e24644c138d0ddbc451403c30a96b09bfd556 upstream.
+
+Between 2.6.23 and 2.6.24-rc1 a change was made that broke IBM LS21
+systems that had the HPET enabled in the BIOS, resulting in boot hangs
+for x86_64.
+
+Specifically commit b8ce33590687888ebb900d09557b8807c4539022, which
+merges the i386 and x86_64 HPET code.
+
+Prior to this commit, when we setup the HPET timers in x86_64, we did
+the following:
+
+ hpet_writel(HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL |
+ HPET_TN_32BIT, HPET_T0_CFG);
+
+However after the i386/x86_64 HPET merge, we do the following:
+
+ cfg = hpet_readl(HPET_Tn_CFG(timer));
+ cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC |
+ HPET_TN_SETVAL | HPET_TN_32BIT;
+ hpet_writel(cfg, HPET_Tn_CFG(timer));
+
+However on LS21s with HPET enabled in the BIOS, the HPET_T0_CFG register
+boots with Level triggered interrupts (HPET_TN_LEVEL) enabled. This
+causes the periodic interrupt to be not so periodic, and that results in
+the boot time hang I reported earlier in the delay calibration.
+
+My fix: Always disable HPET_TN_LEVEL when setting up periodic mode.
+
+Signed-off-by: John Stultz <johnstul@us.ibm.com>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86/kernel/hpet.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/x86/kernel/hpet.c
++++ b/arch/x86/kernel/hpet.c
+@@ -267,6 +267,8 @@ static void hpet_set_mode(enum clock_eve
+ now = hpet_readl(HPET_COUNTER);
+ cmp = now + (unsigned long) delta;
+ cfg = hpet_readl(HPET_Tn_CFG(timer));
++ /* Make sure we use edge triggered interrupts */
++ cfg &= ~HPET_TN_LEVEL;
+ cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC |
+ HPET_TN_SETVAL | HPET_TN_32BIT;
+ hpet_writel(cfg, HPET_Tn_CFG(timer));
--- /dev/null
+From ae6af41f5a4841f06eb92bc86ad020ad44ae2a30 Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Mon, 9 Feb 2009 22:17:39 +0900
+Subject: x86: math_emu info cleanup
+
+From: Tejun Heo <tj@kernel.org>
+
+commit ae6af41f5a4841f06eb92bc86ad020ad44ae2a30 upstream.
+
+Impact: cleanup
+
+* Come on, struct info? s/struct info/struct math_emu_info/
+
+* Use struct pt_regs and kernel_vm86_regs instead of defining its own
+ register frame structure.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86/include/asm/math_emu.h | 29 ++++-------------
+ arch/x86/include/asm/processor.h | 2 -
+ arch/x86/math-emu/fpu_entry.c | 2 -
+ arch/x86/math-emu/fpu_proto.h | 2 -
+ arch/x86/math-emu/fpu_system.h | 14 ++++----
+ arch/x86/math-emu/get_address.c | 63 ++++++++++++++++++---------------------
+ 6 files changed, 48 insertions(+), 64 deletions(-)
+
+--- a/arch/x86/include/asm/math_emu.h
++++ b/arch/x86/include/asm/math_emu.h
+@@ -1,31 +1,18 @@
+ #ifndef _ASM_X86_MATH_EMU_H
+ #define _ASM_X86_MATH_EMU_H
+
++#include <asm/ptrace.h>
++#include <asm/vm86.h>
++
+ /* This structure matches the layout of the data saved to the stack
+ following a device-not-present interrupt, part of it saved
+ automatically by the 80386/80486.
+ */
+-struct info {
++struct math_emu_info {
+ long ___orig_eip;
+- long ___ebx;
+- long ___ecx;
+- long ___edx;
+- long ___esi;
+- long ___edi;
+- long ___ebp;
+- long ___eax;
+- long ___ds;
+- long ___es;
+- long ___fs;
+- long ___orig_eax;
+- long ___eip;
+- long ___cs;
+- long ___eflags;
+- long ___esp;
+- long ___ss;
+- long ___vm86_es; /* This and the following only in vm86 mode */
+- long ___vm86_ds;
+- long ___vm86_fs;
+- long ___vm86_gs;
++ union {
++ struct pt_regs regs;
++ struct kernel_vm86_regs vm86;
++ };
+ };
+ #endif /* _ASM_X86_MATH_EMU_H */
+--- a/arch/x86/include/asm/processor.h
++++ b/arch/x86/include/asm/processor.h
+@@ -349,7 +349,7 @@ struct i387_soft_struct {
+ u8 no_update;
+ u8 rm;
+ u8 alimit;
+- struct info *info;
++ struct math_emu_info *info;
+ u32 entry_eip;
+ };
+
+--- a/arch/x86/math-emu/fpu_entry.c
++++ b/arch/x86/math-emu/fpu_entry.c
+@@ -659,7 +659,7 @@ static int valid_prefix(u_char *Byte, u_
+ }
+ }
+
+-void math_abort(struct info *info, unsigned int signal)
++void math_abort(struct math_emu_info *info, unsigned int signal)
+ {
+ FPU_EIP = FPU_ORIG_EIP;
+ current->thread.trap_no = 16;
+--- a/arch/x86/math-emu/fpu_proto.h
++++ b/arch/x86/math-emu/fpu_proto.h
+@@ -52,7 +52,7 @@ extern void fst_i_(void);
+ extern void fstp_i(void);
+ /* fpu_entry.c */
+ asmlinkage extern void math_emulate(long arg);
+-extern void math_abort(struct info *info, unsigned int signal);
++extern void math_abort(struct math_emu_info *info, unsigned int signal);
+ /* fpu_etc.c */
+ extern void FPU_etc(void);
+ /* fpu_tags.c */
+--- a/arch/x86/math-emu/fpu_system.h
++++ b/arch/x86/math-emu/fpu_system.h
+@@ -18,7 +18,7 @@
+
+ /* This sets the pointer FPU_info to point to the argument part
+ of the stack frame of math_emulate() */
+-#define SETUP_DATA_AREA(arg) FPU_info = (struct info *) &arg
++#define SETUP_DATA_AREA(arg) FPU_info = (struct math_emu_info *) &arg
+
+ /* s is always from a cpu register, and the cpu does bounds checking
+ * during register load --> no further bounds checks needed */
+@@ -38,12 +38,12 @@
+ #define I387 (current->thread.xstate)
+ #define FPU_info (I387->soft.info)
+
+-#define FPU_CS (*(unsigned short *) &(FPU_info->___cs))
+-#define FPU_SS (*(unsigned short *) &(FPU_info->___ss))
+-#define FPU_DS (*(unsigned short *) &(FPU_info->___ds))
+-#define FPU_EAX (FPU_info->___eax)
+-#define FPU_EFLAGS (FPU_info->___eflags)
+-#define FPU_EIP (FPU_info->___eip)
++#define FPU_CS (*(unsigned short *) &(FPU_info->regs.cs))
++#define FPU_SS (*(unsigned short *) &(FPU_info->regs.ss))
++#define FPU_DS (*(unsigned short *) &(FPU_info->regs.ds))
++#define FPU_EAX (FPU_info->regs.ax)
++#define FPU_EFLAGS (FPU_info->regs.flags)
++#define FPU_EIP (FPU_info->regs.ip)
+ #define FPU_ORIG_EIP (FPU_info->___orig_eip)
+
+ #define FPU_lookahead (I387->soft.lookahead)
+--- a/arch/x86/math-emu/get_address.c
++++ b/arch/x86/math-emu/get_address.c
+@@ -29,42 +29,39 @@
+ #define FPU_WRITE_BIT 0x10
+
+ static int reg_offset[] = {
+- offsetof(struct info, ___eax),
+- offsetof(struct info, ___ecx),
+- offsetof(struct info, ___edx),
+- offsetof(struct info, ___ebx),
+- offsetof(struct info, ___esp),
+- offsetof(struct info, ___ebp),
+- offsetof(struct info, ___esi),
+- offsetof(struct info, ___edi)
++ offsetof(struct math_emu_info, regs.ax),
++ offsetof(struct math_emu_info, regs.cx),
++ offsetof(struct math_emu_info, regs.dx),
++ offsetof(struct math_emu_info, regs.bx),
++ offsetof(struct math_emu_info, regs.sp),
++ offsetof(struct math_emu_info, regs.bp),
++ offsetof(struct math_emu_info, regs.si),
++ offsetof(struct math_emu_info, regs.di)
+ };
+
+ #define REG_(x) (*(long *)(reg_offset[(x)]+(u_char *) FPU_info))
+
+ static int reg_offset_vm86[] = {
+- offsetof(struct info, ___cs),
+- offsetof(struct info, ___vm86_ds),
+- offsetof(struct info, ___vm86_es),
+- offsetof(struct info, ___vm86_fs),
+- offsetof(struct info, ___vm86_gs),
+- offsetof(struct info, ___ss),
+- offsetof(struct info, ___vm86_ds)
++ offsetof(struct math_emu_info, regs.cs),
++ offsetof(struct math_emu_info, vm86.ds),
++ offsetof(struct math_emu_info, vm86.es),
++ offsetof(struct math_emu_info, vm86.fs),
++ offsetof(struct math_emu_info, vm86.gs),
++ offsetof(struct math_emu_info, regs.ss),
++ offsetof(struct math_emu_info, vm86.ds)
+ };
+
+ #define VM86_REG_(x) (*(unsigned short *) \
+ (reg_offset_vm86[((unsigned)x)]+(u_char *) FPU_info))
+
+-/* This dummy, gs is not saved on the stack. */
+-#define ___GS ___ds
+-
+ static int reg_offset_pm[] = {
+- offsetof(struct info, ___cs),
+- offsetof(struct info, ___ds),
+- offsetof(struct info, ___es),
+- offsetof(struct info, ___fs),
+- offsetof(struct info, ___GS),
+- offsetof(struct info, ___ss),
+- offsetof(struct info, ___ds)
++ offsetof(struct math_emu_info, regs.cs),
++ offsetof(struct math_emu_info, regs.ds),
++ offsetof(struct math_emu_info, regs.es),
++ offsetof(struct math_emu_info, regs.fs),
++ offsetof(struct math_emu_info, regs.ds), /* dummy, not saved on stack */
++ offsetof(struct math_emu_info, regs.ss),
++ offsetof(struct math_emu_info, regs.ds)
+ };
+
+ #define PM_REG_(x) (*(unsigned short *) \
+@@ -349,34 +346,34 @@ void __user *FPU_get_address_16(u_char F
+ }
+ switch (rm) {
+ case 0:
+- address += FPU_info->___ebx + FPU_info->___esi;
++ address += FPU_info->regs.bx + FPU_info->regs.si;
+ break;
+ case 1:
+- address += FPU_info->___ebx + FPU_info->___edi;
++ address += FPU_info->regs.bx + FPU_info->regs.di;
+ break;
+ case 2:
+- address += FPU_info->___ebp + FPU_info->___esi;
++ address += FPU_info->regs.bp + FPU_info->regs.si;
+ if (addr_modes.override.segment == PREFIX_DEFAULT)
+ addr_modes.override.segment = PREFIX_SS_;
+ break;
+ case 3:
+- address += FPU_info->___ebp + FPU_info->___edi;
++ address += FPU_info->regs.bp + FPU_info->regs.di;
+ if (addr_modes.override.segment == PREFIX_DEFAULT)
+ addr_modes.override.segment = PREFIX_SS_;
+ break;
+ case 4:
+- address += FPU_info->___esi;
++ address += FPU_info->regs.si;
+ break;
+ case 5:
+- address += FPU_info->___edi;
++ address += FPU_info->regs.di;
+ break;
+ case 6:
+- address += FPU_info->___ebp;
++ address += FPU_info->regs.bp;
+ if (addr_modes.override.segment == PREFIX_DEFAULT)
+ addr_modes.override.segment = PREFIX_SS_;
+ break;
+ case 7:
+- address += FPU_info->___ebx;
++ address += FPU_info->regs.bx;
+ break;
+ }
+
--- /dev/null
+From d85cf93da66977dbc645352be1b2084a659d8a0b Mon Sep 17 00:00:00 2001
+From: Jeremy Fitzhardinge <jeremy@goop.org>
+Date: Thu, 12 Feb 2009 10:02:56 -0800
+Subject: x86/paravirt: make arch_flush_lazy_mmu/cpu disable preemption
+
+From: Jeremy Fitzhardinge <jeremy@goop.org>
+
+commit d85cf93da66977dbc645352be1b2084a659d8a0b upstream.
+
+Impact: avoid access to percpu vars in preempible context
+
+They are intended to be used whenever there's the possibility
+that there's some stale state which is going to be overwritten
+with a queued update, or to force a state change when we may be
+in lazy mode. Either way, we could end up calling it with
+preemption enabled, so wrap the functions in their own little
+preempt-disable section so they can be safely called in any
+context (though preemption should never be enabled if we're actually
+in a lazy state).
+
+(Move out of line to avoid #include dependencies.)
+
+Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86/include/asm/paravirt.h | 17 ++---------------
+ arch/x86/kernel/paravirt.c | 24 ++++++++++++++++++++++++
+ 2 files changed, 26 insertions(+), 15 deletions(-)
+
+--- a/arch/x86/include/asm/paravirt.h
++++ b/arch/x86/include/asm/paravirt.h
+@@ -1352,14 +1352,7 @@ static inline void arch_leave_lazy_cpu_m
+ PVOP_VCALL0(pv_cpu_ops.lazy_mode.leave);
+ }
+
+-static inline void arch_flush_lazy_cpu_mode(void)
+-{
+- if (unlikely(paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU)) {
+- arch_leave_lazy_cpu_mode();
+- arch_enter_lazy_cpu_mode();
+- }
+-}
+-
++void arch_flush_lazy_cpu_mode(void);
+
+ #define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
+ static inline void arch_enter_lazy_mmu_mode(void)
+@@ -1372,13 +1365,7 @@ static inline void arch_leave_lazy_mmu_m
+ PVOP_VCALL0(pv_mmu_ops.lazy_mode.leave);
+ }
+
+-static inline void arch_flush_lazy_mmu_mode(void)
+-{
+- if (unlikely(paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU)) {
+- arch_leave_lazy_mmu_mode();
+- arch_enter_lazy_mmu_mode();
+- }
+-}
++void arch_flush_lazy_mmu_mode(void);
+
+ static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx,
+ unsigned long phys, pgprot_t flags)
+--- a/arch/x86/kernel/paravirt.c
++++ b/arch/x86/kernel/paravirt.c
+@@ -268,6 +268,30 @@ enum paravirt_lazy_mode paravirt_get_laz
+ return __get_cpu_var(paravirt_lazy_mode);
+ }
+
++void arch_flush_lazy_mmu_mode(void)
++{
++ preempt_disable();
++
++ if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) {
++ arch_leave_lazy_mmu_mode();
++ arch_enter_lazy_mmu_mode();
++ }
++
++ preempt_enable();
++}
++
++void arch_flush_lazy_cpu_mode(void)
++{
++ preempt_disable();
++
++ if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU) {
++ arch_leave_lazy_cpu_mode();
++ arch_enter_lazy_cpu_mode();
++ }
++
++ preempt_enable();
++}
++
+ struct pv_info pv_info = {
+ .name = "bare hardware",
+ .paravirt_enabled = 0,