From 5158383de04d9662f049c33d35f3d6c783930a1d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 12 Mar 2009 23:20:29 -0700 Subject: [PATCH] more .28 patches --- ...roken-usage-of-acpi_ut_get_node_name.patch | 39 +++ .../acpi-fix-broken-usage-of-name.ascii.patch | 43 +++ ...dd-i2c_board_info-for-riscpc-pcf8583.patch | 69 +++++ ...-race-that-broke-aead-initialisation.patch | 62 ++++ ...-definitions-for-gem-init-execbuffer.patch | 30 ++ ...xt4-add-fallback-for-find_group_flex.patch | 49 +++ ..._write_begin-and-ext4_da_write_begin.patch | 62 ++++ queue-2.6.28/ext4-fix-lockdep-warning.patch | 79 +++++ ...in-ext4_ext_migrate-s-error-handling.patch | 56 ++++ ...ty-directory-blocks-correctly-in-64k.patch | 47 +++ ...tepages-instead-of-write_cache_pages.patch | 101 ++++++ ...e-preallocation-list_head-s-properly.patch | 45 +++ ...evices-from-ignore_list-to-blacklist.patch | 68 +++++ .../hwmon-hide-misleading-error-message.patch | 38 +++ .../i2c-fix-misplaced-parentheses.patch | 35 +++ queue-2.6.28/i2c-timeouts-reach-1.patch | 60 ++++ ...s-fix-odd-length-atapi-pio-transfers.patch | 32 ++ ...-jbd2_journal_begin_ordered_truncate.patch | 142 +++++++++ ...n-value-of-jbd2_journal_start_commit.patch | 103 +++++++ ...-all-pending-commits-in-ext4_sync_fs.patch | 58 ++++ queue-2.6.28/series | 24 ++ ...6-fix-math_emu-register-frame-access.patch | 287 ++++++++++++++++++ ...x86-hpet-fix-for-ls21-hpet-boot-hang.patch | 55 ++++ queue-2.6.28/x86-math_emu-info-cleanup.patch | 244 +++++++++++++++ ...lush_lazy_mmu-cpu-disable-preemption.patch | 97 ++++++ 25 files changed, 1925 insertions(+) create mode 100644 queue-2.6.28/acpi-fix-broken-usage-of-acpi_ut_get_node_name.patch create mode 100644 queue-2.6.28/acpi-fix-broken-usage-of-name.ascii.patch create mode 100644 queue-2.6.28/arm-add-i2c_board_info-for-riscpc-pcf8583.patch create mode 100644 queue-2.6.28/crypto-api-fix-algorithm-test-race-that-broke-aead-initialisation.patch create mode 100644 queue-2.6.28/drm-i915-add-missing-userland-definitions-for-gem-init-execbuffer.patch create mode 100644 queue-2.6.28/ext4-add-fallback-for-find_group_flex.patch create mode 100644 queue-2.6.28/ext4-fix-deadlock-in-ext4_write_begin-and-ext4_da_write_begin.patch create mode 100644 queue-2.6.28/ext4-fix-lockdep-warning.patch create mode 100644 queue-2.6.28/ext4-fix-null-dereference-in-ext4_ext_migrate-s-error-handling.patch create mode 100644 queue-2.6.28/ext4-fix-to-read-empty-directory-blocks-correctly-in-64k.patch create mode 100644 queue-2.6.28/ext4-implement-range_cyclic-in-ext4_da_writepages-instead-of-write_cache_pages.patch create mode 100644 queue-2.6.28/ext4-initialize-preallocation-list_head-s-properly.patch create mode 100644 queue-2.6.28/hid-move-tmff-and-zpff-devices-from-ignore_list-to-blacklist.patch create mode 100644 queue-2.6.28/hwmon-hide-misleading-error-message.patch create mode 100644 queue-2.6.28/i2c-fix-misplaced-parentheses.patch create mode 100644 queue-2.6.28/i2c-timeouts-reach-1.patch create mode 100644 queue-2.6.28/ide-iops-fix-odd-length-atapi-pio-transfers.patch create mode 100644 queue-2.6.28/jbd2-avoid-possible-null-dereference-in-jbd2_journal_begin_ordered_truncate.patch create mode 100644 queue-2.6.28/jbd2-fix-return-value-of-jbd2_journal_start_commit.patch create mode 100644 queue-2.6.28/revert-ext4-wait-on-all-pending-commits-in-ext4_sync_fs.patch create mode 100644 queue-2.6.28/x86-fix-math_emu-register-frame-access.patch create mode 100644 queue-2.6.28/x86-hpet-fix-for-ls21-hpet-boot-hang.patch create mode 100644 queue-2.6.28/x86-math_emu-info-cleanup.patch create mode 100644 queue-2.6.28/x86-paravirt-make-arch_flush_lazy_mmu-cpu-disable-preemption.patch diff --git a/queue-2.6.28/acpi-fix-broken-usage-of-acpi_ut_get_node_name.patch b/queue-2.6.28/acpi-fix-broken-usage-of-acpi_ut_get_node_name.patch new file mode 100644 index 00000000000..c462b93f1ad --- /dev/null +++ b/queue-2.6.28/acpi-fix-broken-usage-of-acpi_ut_get_node_name.patch @@ -0,0 +1,39 @@ +From hmh@hmh.eng.br Thu Mar 12 23:12:43 2009 +From: Henrique de Moraes Holschuh +Date: Tue, 24 Feb 2009 11:48:18 -0300 +Subject: ACPI: fix broken usage of acpi_ut_get_node_name() +To: Len Brown +Cc: linux-acpi@vger.kernel.org, Lin Ming , stable@kernel.org, Henrique de Moraes Holschuh +Message-ID: <1235486898-27756-2-git-send-email-hmh@hmh.eng.br> + +From: Henrique de Moraes Holschuh + +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 +Cc: stable@kernel.org +Acked-by: Lin Ming +Cc: Len Brown +Signed-off-by: Greg Kroah-Hartman + +--- + 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")); + diff --git a/queue-2.6.28/acpi-fix-broken-usage-of-name.ascii.patch b/queue-2.6.28/acpi-fix-broken-usage-of-name.ascii.patch new file mode 100644 index 00000000000..8c28ac5c7bd --- /dev/null +++ b/queue-2.6.28/acpi-fix-broken-usage-of-name.ascii.patch @@ -0,0 +1,43 @@ +From hmh@hmh.eng.br Thu Mar 12 23:11:32 2009 +From: Henrique de Moraes Holschuh +Date: Tue, 24 Feb 2009 11:48:17 -0300 +Subject: ACPI: fix broken usage of name.ascii +To: Len Brown +Cc: linux-acpi@vger.kernel.org, Lin Ming , stable@kernel.org, Henrique de Moraes Holschuh +Message-ID: <1235486898-27756-1-git-send-email-hmh@hmh.eng.br> + +From: Henrique de Moraes Holschuh + +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 +Cc: Lin Ming +Cc: Len Brown +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } + diff --git a/queue-2.6.28/arm-add-i2c_board_info-for-riscpc-pcf8583.patch b/queue-2.6.28/arm-add-i2c_board_info-for-riscpc-pcf8583.patch new file mode 100644 index 00000000000..1ee076b838c --- /dev/null +++ b/queue-2.6.28/arm-add-i2c_board_info-for-riscpc-pcf8583.patch @@ -0,0 +1,69 @@ +From khali@linux-fr.org Thu Mar 12 23:08:53 2009 +From: Jean Delvare +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 +Message-ID: <20090225213407.4a932f92@hyperion.delvare> + + +From: Russell King + +commit 531660ef5604c75de6fdead9da1304051af17c09 upstream + +Add the necessary i2c_board_info structure to fix the lack of PCF8583 +RTC on RiscPC. + +Signed-off-by: Russell King +Signed-off-by: Jean Delvare +Cc: Alessandro Zummo +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + #include + #include ++#include + + #include + #include +@@ -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); diff --git a/queue-2.6.28/crypto-api-fix-algorithm-test-race-that-broke-aead-initialisation.patch b/queue-2.6.28/crypto-api-fix-algorithm-test-race-that-broke-aead-initialisation.patch new file mode 100644 index 00000000000..77b349f8338 --- /dev/null +++ b/queue-2.6.28/crypto-api-fix-algorithm-test-race-that-broke-aead-initialisation.patch @@ -0,0 +1,62 @@ +From b8e15992b420d09dae831125a623c474c8637cee Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Wed, 28 Jan 2009 14:09:59 +1100 +Subject: crypto: api - Fix algorithm test race that broke aead initialisation + +From: Herbert Xu + +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 +Signed-off-by: Herbert Xu +Cc: Kerin Millar +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-2.6.28/drm-i915-add-missing-userland-definitions-for-gem-init-execbuffer.patch b/queue-2.6.28/drm-i915-add-missing-userland-definitions-for-gem-init-execbuffer.patch new file mode 100644 index 00000000000..01b5099543e --- /dev/null +++ b/queue-2.6.28/drm-i915-add-missing-userland-definitions-for-gem-init-execbuffer.patch @@ -0,0 +1,30 @@ +From 8d391aa410ecb230fc4c3147b94eec25b9f3c20f Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Wed, 17 Dec 2008 22:32:14 -0800 +Subject: drm/i915: Add missing userland definitions for gem init/execbuffer. + +From: Eric Anholt + +commit 8d391aa410ecb230fc4c3147b94eec25b9f3c20f upstream. + +fdo bug #19132. + +Signed-off-by: Eric Anholt +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + 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) diff --git a/queue-2.6.28/ext4-add-fallback-for-find_group_flex.patch b/queue-2.6.28/ext4-add-fallback-for-find_group_flex.patch new file mode 100644 index 00000000000..3d52d294b7a --- /dev/null +++ b/queue-2.6.28/ext4-add-fallback-for-find_group_flex.patch @@ -0,0 +1,49 @@ +From tytso@mit.edu Thu Mar 12 22:52:01 2009 +From: "Theodore Ts'o" +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 , "Theodore Ts'o" +Message-ID: <1236238515-8479-1-git-send-email-tytso@mit.edu> + +From: "Theodore Ts'o" + +(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" +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } + diff --git a/queue-2.6.28/ext4-fix-deadlock-in-ext4_write_begin-and-ext4_da_write_begin.patch b/queue-2.6.28/ext4-fix-deadlock-in-ext4_write_begin-and-ext4_da_write_begin.patch new file mode 100644 index 00000000000..4084a3eca63 --- /dev/null +++ b/queue-2.6.28/ext4-fix-deadlock-in-ext4_write_begin-and-ext4_da_write_begin.patch @@ -0,0 +1,62 @@ +From tytso@mit.edu Thu Mar 12 22:52:20 2009 +From: "Theodore Ts'o" +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" , Ext4 Developers List , Jan Kara +Message-ID: <1236238515-8479-2-git-send-email-tytso@mit.edu> + + +From: Jan Kara + +(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 +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + 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) { diff --git a/queue-2.6.28/ext4-fix-lockdep-warning.patch b/queue-2.6.28/ext4-fix-lockdep-warning.patch new file mode 100644 index 00000000000..67697137b40 --- /dev/null +++ b/queue-2.6.28/ext4-fix-lockdep-warning.patch @@ -0,0 +1,79 @@ +From tytso@mit.edu Thu Mar 12 22:50:38 2009 +From: Aneesh Kumar K.V +Date: Tue, 24 Feb 2009 12:14:45 -0500 +Subject: ext4: Fix lockdep warning +To: stable@kernel.org +Cc: "Theodore Ts'o" , "Aneesh Kumar K.V" +Message-ID: <1235495688-8044-5-git-send-email-tytso@mit.edu> + + +From: Aneesh Kumar K.V + +(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: [] + ext4_mb_load_buddy+0xd2/0x343 + + but task is already holding lock: + (&meta_group_info[i]->alloc_sem){----}, at: [] + ext4_mb_load_buddy+0xd2/0x343 + +http://bugzilla.kernel.org/show_bug.cgi?id=12672 + +Signed-off-by: Aneesh Kumar K.V +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + 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) diff --git a/queue-2.6.28/ext4-fix-null-dereference-in-ext4_ext_migrate-s-error-handling.patch b/queue-2.6.28/ext4-fix-null-dereference-in-ext4_ext_migrate-s-error-handling.patch new file mode 100644 index 00000000000..a8e5ff056c4 --- /dev/null +++ b/queue-2.6.28/ext4-fix-null-dereference-in-ext4_ext_migrate-s-error-handling.patch @@ -0,0 +1,56 @@ +From tytso@mit.edu Thu Mar 12 22:51:42 2009 +From: Dan Carpenter +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" , Dan Carpenter +Message-ID: <1235495688-8044-8-git-send-email-tytso@mit.edu> + + +From: Dan Carpenter + +(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 +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } diff --git a/queue-2.6.28/ext4-fix-to-read-empty-directory-blocks-correctly-in-64k.patch b/queue-2.6.28/ext4-fix-to-read-empty-directory-blocks-correctly-in-64k.patch new file mode 100644 index 00000000000..6fe137bc804 --- /dev/null +++ b/queue-2.6.28/ext4-fix-to-read-empty-directory-blocks-correctly-in-64k.patch @@ -0,0 +1,47 @@ +From tytso@mit.edu Thu Mar 12 22:50:20 2009 +From: Wei Yongjun +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" , Wei Yongjun +Message-ID: <1235495688-8044-4-git-send-email-tytso@mit.edu> + + +From: Wei Yongjun + +(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 +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } diff --git a/queue-2.6.28/ext4-implement-range_cyclic-in-ext4_da_writepages-instead-of-write_cache_pages.patch b/queue-2.6.28/ext4-implement-range_cyclic-in-ext4_da_writepages-instead-of-write_cache_pages.patch new file mode 100644 index 00000000000..dfc1bf48511 --- /dev/null +++ b/queue-2.6.28/ext4-implement-range_cyclic-in-ext4_da_writepages-instead-of-write_cache_pages.patch @@ -0,0 +1,101 @@ +From tytso@mit.edu Thu Mar 12 22:51:22 2009 +From: Aneesh Kumar K.V +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" , "Aneesh Kumar K.V" +Message-ID: <1235495688-8044-7-git-send-email-tytso@mit.edu> + + +From: Aneesh Kumar K.V + +(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 +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + 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 diff --git a/queue-2.6.28/ext4-initialize-preallocation-list_head-s-properly.patch b/queue-2.6.28/ext4-initialize-preallocation-list_head-s-properly.patch new file mode 100644 index 00000000000..ffefe3f8934 --- /dev/null +++ b/queue-2.6.28/ext4-initialize-preallocation-list_head-s-properly.patch @@ -0,0 +1,45 @@ +From tytso@mit.edu Thu Mar 12 22:51:02 2009 +From: Aneesh Kumar K.V +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" , "Aneesh Kumar K.V" +Message-ID: <1235495688-8044-6-git-send-email-tytso@mit.edu> + + +From: Aneesh Kumar K.V + +(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 +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + diff --git a/queue-2.6.28/hid-move-tmff-and-zpff-devices-from-ignore_list-to-blacklist.patch b/queue-2.6.28/hid-move-tmff-and-zpff-devices-from-ignore_list-to-blacklist.patch new file mode 100644 index 00000000000..3012f016888 --- /dev/null +++ b/queue-2.6.28/hid-move-tmff-and-zpff-devices-from-ignore_list-to-blacklist.patch @@ -0,0 +1,68 @@ +From jkosina@suse.cz Thu Mar 12 23:07:31 2009 +From: Jiri Kosina +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 +Message-ID: + + +From: Jiri Kosina + +[ upstream commit daedb3d6a91f9626ab4c921378ac52e44de833d5 ] + +From: Anssi Hannula +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 +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + 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) }, + { } + }; + diff --git a/queue-2.6.28/hwmon-hide-misleading-error-message.patch b/queue-2.6.28/hwmon-hide-misleading-error-message.patch new file mode 100644 index 00000000000..f69d625cf94 --- /dev/null +++ b/queue-2.6.28/hwmon-hide-misleading-error-message.patch @@ -0,0 +1,38 @@ +From khali@linux-fr.org Thu Mar 12 23:16:17 2009 +From: Jean Delvare +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 + +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 +Acked-by: Hans de Goede + + +--- + 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; + } + diff --git a/queue-2.6.28/i2c-fix-misplaced-parentheses.patch b/queue-2.6.28/i2c-fix-misplaced-parentheses.patch new file mode 100644 index 00000000000..60e9d85c8e9 --- /dev/null +++ b/queue-2.6.28/i2c-fix-misplaced-parentheses.patch @@ -0,0 +1,35 @@ +From khali@linux-fr.org Thu Mar 12 23:10:15 2009 +From: Roel Kluin +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 + +commit f29d2e0275a4f03ef2fd158e484508dcb0c64efb upstream + +Fix misplaced parentheses. + +Signed-off-by: Roel Kluin +Signed-off-by: Jean Delvare +Signed-off-by: Greg Kroah-Hartman + + +--- + 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: diff --git a/queue-2.6.28/i2c-timeouts-reach-1.patch b/queue-2.6.28/i2c-timeouts-reach-1.patch new file mode 100644 index 00000000000..a682babfaf3 --- /dev/null +++ b/queue-2.6.28/i2c-timeouts-reach-1.patch @@ -0,0 +1,60 @@ +From khali@linux-fr.org Thu Mar 12 23:09:33 2009 +From: Roel Kluin +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 + +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 +Signed-off-by: Jean Delvare +Signed-off-by: Greg Kroah-Hartman + + +--- + 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); + } diff --git a/queue-2.6.28/ide-iops-fix-odd-length-atapi-pio-transfers.patch b/queue-2.6.28/ide-iops-fix-odd-length-atapi-pio-transfers.patch new file mode 100644 index 00000000000..98f0d48c4e6 --- /dev/null +++ b/queue-2.6.28/ide-iops-fix-odd-length-atapi-pio-transfers.patch @@ -0,0 +1,32 @@ +From a509538d4fb4f99cdf0a095213d57cc3b2347615 Mon Sep 17 00:00:00 2001 +From: Sergei Shtylyov +Date: Thu, 5 Mar 2009 16:10:56 +0100 +Subject: ide-iops: fix odd-length ATAPI PIO transfers + +From: Sergei Shtylyov + +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 +Signed-off-by: Bartlomiej Zolnierkiewicz +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + diff --git a/queue-2.6.28/jbd2-avoid-possible-null-dereference-in-jbd2_journal_begin_ordered_truncate.patch b/queue-2.6.28/jbd2-avoid-possible-null-dereference-in-jbd2_journal_begin_ordered_truncate.patch new file mode 100644 index 00000000000..6d20602429e --- /dev/null +++ b/queue-2.6.28/jbd2-avoid-possible-null-dereference-in-jbd2_journal_begin_ordered_truncate.patch @@ -0,0 +1,142 @@ +From tytso@mit.edu Thu Mar 12 22:49:54 2009 +From: Jan Kara +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" , Dan Carpenter , mfasheh@suse.de, Jan Kara , linux-ext4@vger.kernel.org, ocfs2-devel@oss.oracle.com +Message-ID: <1235495688-8044-3-git-send-email-tytso@mit.edu> + + +From: Jan Kara + +(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 for pointing to the +suspitious code. + +Signed-off-by: Jan Kara +Signed-off-by: "Theodore Ts'o" +Acked-by: Joel Becker +CC: linux-ext4@vger.kernel.org +CC: ocfs2-devel@oss.oracle.com +CC: mfasheh@suse.de +CC: Dan Carpenter +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + diff --git a/queue-2.6.28/jbd2-fix-return-value-of-jbd2_journal_start_commit.patch b/queue-2.6.28/jbd2-fix-return-value-of-jbd2_journal_start_commit.patch new file mode 100644 index 00000000000..d5c3d342b3d --- /dev/null +++ b/queue-2.6.28/jbd2-fix-return-value-of-jbd2_journal_start_commit.patch @@ -0,0 +1,103 @@ +From tytso@mit.edu Thu Mar 12 22:49:00 2009 +From: Jan Kara +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" , linux-ext4@vger.kernel.org, Jan Kara , Eric Sandeen +Message-ID: <1235495688-8044-1-git-send-email-tytso@mit.edu> + + +From: Jan Kara + +(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 +: + + #!/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 +Signed-off-by: "Theodore Ts'o" +CC: Eric Sandeen +CC: linux-ext4@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-2.6.28/revert-ext4-wait-on-all-pending-commits-in-ext4_sync_fs.patch b/queue-2.6.28/revert-ext4-wait-on-all-pending-commits-in-ext4_sync_fs.patch new file mode 100644 index 00000000000..4dd70d7e68f --- /dev/null +++ b/queue-2.6.28/revert-ext4-wait-on-all-pending-commits-in-ext4_sync_fs.patch @@ -0,0 +1,58 @@ +From tytso@mit.edu Thu Mar 12 22:49:29 2009 +From: Jan Kara +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" , linux-ext4@vger.kernel.org, Jan Kara , Eric Sandeen +Message-ID: <1235495688-8044-2-git-send-email-tytso@mit.edu> + + +From: Jan Kara + +(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 +Signed-off-by: "Theodore Ts'o" +Cc: Eric Sandeen +Cc: linux-ext4@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } + + /* diff --git a/queue-2.6.28/series b/queue-2.6.28/series index de774bac5d5..e4d1c0db3bb 100644 --- a/queue-2.6.28/series +++ b/queue-2.6.28/series @@ -85,3 +85,27 @@ pipe_rdwr_fasync-fix-the-error-handling-to-prevent-the-leak-crash.patch 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 diff --git a/queue-2.6.28/x86-fix-math_emu-register-frame-access.patch b/queue-2.6.28/x86-fix-math_emu-register-frame-access.patch new file mode 100644 index 00000000000..da0cf1376eb --- /dev/null +++ b/queue-2.6.28/x86-fix-math_emu-register-frame-access.patch @@ -0,0 +1,287 @@ +From d315760ffa261c15ff92699ac6f514112543d7ca Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Mon, 9 Feb 2009 22:17:39 +0900 +Subject: x86: fix math_emu register frame access + +From: Tejun Heo + +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 +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + #include + +-/* 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; + } + diff --git a/queue-2.6.28/x86-hpet-fix-for-ls21-hpet-boot-hang.patch b/queue-2.6.28/x86-hpet-fix-for-ls21-hpet-boot-hang.patch new file mode 100644 index 00000000000..f31c9ecc47d --- /dev/null +++ b/queue-2.6.28/x86-hpet-fix-for-ls21-hpet-boot-hang.patch @@ -0,0 +1,55 @@ +From b13e24644c138d0ddbc451403c30a96b09bfd556 Mon Sep 17 00:00:00 2001 +From: john stultz +Date: Thu, 12 Feb 2009 18:48:53 -0800 +Subject: x86, hpet: fix for LS21 + HPET = boot hang + +From: john stultz + +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 +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + 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)); diff --git a/queue-2.6.28/x86-math_emu-info-cleanup.patch b/queue-2.6.28/x86-math_emu-info-cleanup.patch new file mode 100644 index 00000000000..f05f11251aa --- /dev/null +++ b/queue-2.6.28/x86-math_emu-info-cleanup.patch @@ -0,0 +1,244 @@ +From ae6af41f5a4841f06eb92bc86ad020ad44ae2a30 Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Mon, 9 Feb 2009 22:17:39 +0900 +Subject: x86: math_emu info cleanup + +From: Tejun Heo + +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 +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + 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 ++#include ++ + /* 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; + } + diff --git a/queue-2.6.28/x86-paravirt-make-arch_flush_lazy_mmu-cpu-disable-preemption.patch b/queue-2.6.28/x86-paravirt-make-arch_flush_lazy_mmu-cpu-disable-preemption.patch new file mode 100644 index 00000000000..e90276e34d5 --- /dev/null +++ b/queue-2.6.28/x86-paravirt-make-arch_flush_lazy_mmu-cpu-disable-preemption.patch @@ -0,0 +1,97 @@ +From d85cf93da66977dbc645352be1b2084a659d8a0b Mon Sep 17 00:00:00 2001 +From: Jeremy Fitzhardinge +Date: Thu, 12 Feb 2009 10:02:56 -0800 +Subject: x86/paravirt: make arch_flush_lazy_mmu/cpu disable preemption + +From: Jeremy Fitzhardinge + +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 +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman + +--- + 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, -- 2.47.3