From: Greg Kroah-Hartman Date: Mon, 26 Apr 2010 22:17:10 +0000 (-0700) Subject: .33 patches X-Git-Tag: v2.6.32.13~25 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=957fdf94714e97d36240e28278d43f1cd2b33b2f;p=thirdparty%2Fkernel%2Fstable-queue.git .33 patches --- diff --git a/queue-2.6.33/drm-i915-fix-tiling-limits-for-i915-class-hw-v2.patch b/queue-2.6.33/drm-i915-fix-tiling-limits-for-i915-class-hw-v2.patch new file mode 100644 index 00000000000..fd588ce2e38 --- /dev/null +++ b/queue-2.6.33/drm-i915-fix-tiling-limits-for-i915-class-hw-v2.patch @@ -0,0 +1,100 @@ +From c36a2a6de59e4a141a68b7575de837d3b0bd96b3 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Sat, 17 Apr 2010 15:12:03 +0200 +Subject: drm/i915: fix tiling limits for i915 class hw v2 + +From: Daniel Vetter + +commit c36a2a6de59e4a141a68b7575de837d3b0bd96b3 upstream. + +Current code is definitely crap: Largest pitch allowed spills into +the TILING_Y bit of the fence registers ... :( + +I've rewritten the limits check under the assumption that 3rd gen hw +has a 3d pitch limit of 8kb (like 2nd gen). This is supported by an +otherwise totally misleading XXX comment. + +This bug mostly resulted in tiling-corrupted pixmaps because the kernel +allowed too wide buffers to be tiled. Bug brought to the light by the +xf86-video-intel 2.11 release because that unconditionally enabled +tiling for pixmaps, relying on the kernel to check things. Tiling for +the framebuffer was not affected because the ddx does some additional +checks there ensure the buffer is within hw-limits. + +v2: Instead of computing the value that would be written into the +hw fence registers and then checking the limits simply check whether +the stride is above the 8kb limit. To better document the hw, add +some WARN_ONs in i915_write_fence_reg like I've done for the i830 +case (using the right limits). + +Signed-off-by: Daniel Vetter +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=27449 +Tested-by: Alexander Lam +Signed-off-by: Eric Anholt +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/i915_gem.c | 6 ++++++ + drivers/gpu/drm/i915/i915_gem_tiling.c | 22 +++++++++------------- + drivers/gpu/drm/i915/i915_reg.h | 2 +- + 3 files changed, 16 insertions(+), 14 deletions(-) + +--- a/drivers/gpu/drm/i915/i915_gem.c ++++ b/drivers/gpu/drm/i915/i915_gem.c +@@ -2316,6 +2316,12 @@ static void i915_write_fence_reg(struct + pitch_val = obj_priv->stride / tile_width; + pitch_val = ffs(pitch_val) - 1; + ++ if (obj_priv->tiling_mode == I915_TILING_Y && ++ HAS_128_BYTE_Y_TILING(dev)) ++ WARN_ON(pitch_val > I830_FENCE_MAX_PITCH_VAL); ++ else ++ WARN_ON(pitch_val > I915_FENCE_MAX_PITCH_VAL); ++ + val = obj_priv->gtt_offset; + if (obj_priv->tiling_mode == I915_TILING_Y) + val |= 1 << I830_FENCE_TILING_Y_SHIFT; +--- a/drivers/gpu/drm/i915/i915_gem_tiling.c ++++ b/drivers/gpu/drm/i915/i915_gem_tiling.c +@@ -357,21 +357,17 @@ i915_tiling_ok(struct drm_device *dev, i + * reg, so dont bother to check the size */ + if (stride / 128 > I965_FENCE_MAX_PITCH_VAL) + return false; +- } else if (IS_I9XX(dev)) { +- uint32_t pitch_val = ffs(stride / tile_width) - 1; +- +- /* XXX: For Y tiling, FENCE_MAX_PITCH_VAL is actually 6 (8KB) +- * instead of 4 (2KB) on 945s. +- */ +- if (pitch_val > I915_FENCE_MAX_PITCH_VAL || +- size > (I830_FENCE_MAX_SIZE_VAL << 20)) ++ } else if (IS_GEN3(dev) || IS_GEN2(dev)) { ++ if (stride > 8192) + return false; +- } else { +- uint32_t pitch_val = ffs(stride / tile_width) - 1; + +- if (pitch_val > I830_FENCE_MAX_PITCH_VAL || +- size > (I830_FENCE_MAX_SIZE_VAL << 19)) +- return false; ++ if (IS_GEN3(dev)) { ++ if (size > I830_FENCE_MAX_SIZE_VAL << 20) ++ return false; ++ } else { ++ if (size > I830_FENCE_MAX_SIZE_VAL << 19) ++ return false; ++ } + } + + /* 965+ just needs multiples of tile width */ +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -221,7 +221,7 @@ + #define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8) + #define I830_FENCE_PITCH_SHIFT 4 + #define I830_FENCE_REG_VALID (1<<0) +-#define I915_FENCE_MAX_PITCH_VAL 0x10 ++#define I915_FENCE_MAX_PITCH_VAL 4 + #define I830_FENCE_MAX_PITCH_VAL 6 + #define I830_FENCE_MAX_SIZE_VAL (1<<8) + diff --git a/queue-2.6.33/flex_array-fix-the-panic-when-calling-flex_array_alloc-without-__gfp_zero.patch b/queue-2.6.33/flex_array-fix-the-panic-when-calling-flex_array_alloc-without-__gfp_zero.patch new file mode 100644 index 00000000000..1b50090d69e --- /dev/null +++ b/queue-2.6.33/flex_array-fix-the-panic-when-calling-flex_array_alloc-without-__gfp_zero.patch @@ -0,0 +1,33 @@ +From e59464c735db19619cde2aa331609adb02005f5b Mon Sep 17 00:00:00 2001 +From: Changli Gao +Date: Fri, 23 Apr 2010 13:17:45 -0400 +Subject: flex_array: fix the panic when calling flex_array_alloc() without __GFP_ZERO + +From: Changli Gao + +commit e59464c735db19619cde2aa331609adb02005f5b upstream. + +memset() is called with the wrong address and the kernel panics. + +Signed-off-by: Changli Gao +Cc: Patrick McHardy +Acked-by: David Rientjes +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + lib/flex_array.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/lib/flex_array.c ++++ b/lib/flex_array.c +@@ -99,7 +99,7 @@ struct flex_array *flex_array_alloc(int + ret->element_size = element_size; + ret->total_nr_elements = total; + if (elements_fit_in_base(ret) && !(flags & __GFP_ZERO)) +- memset(ret->parts[0], FLEX_ARRAY_FREE, ++ memset(&ret->parts[0], FLEX_ARRAY_FREE, + FLEX_ARRAY_BASE_BYTES_LEFT); + return ret; + } diff --git a/queue-2.6.33/hugetlb-fix-infinite-loop-in-get_futex_key-when-backed-by-huge-pages.patch b/queue-2.6.33/hugetlb-fix-infinite-loop-in-get_futex_key-when-backed-by-huge-pages.patch new file mode 100644 index 00000000000..531d362ecb9 --- /dev/null +++ b/queue-2.6.33/hugetlb-fix-infinite-loop-in-get_futex_key-when-backed-by-huge-pages.patch @@ -0,0 +1,78 @@ +From 23be7468e8802a2ac1de6ee3eecb3ec7f14dc703 Mon Sep 17 00:00:00 2001 +From: Mel Gorman +Date: Fri, 23 Apr 2010 13:17:56 -0400 +Subject: hugetlb: fix infinite loop in get_futex_key() when backed by huge pages + +From: Mel Gorman + +commit 23be7468e8802a2ac1de6ee3eecb3ec7f14dc703 upstream. + +If a futex key happens to be located within a huge page mapped +MAP_PRIVATE, get_futex_key() can go into an infinite loop waiting for a +page->mapping that will never exist. + +See https://bugzilla.redhat.com/show_bug.cgi?id=552257 for more details +about the problem. + +This patch makes page->mapping a poisoned value that includes +PAGE_MAPPING_ANON mapped MAP_PRIVATE. This is enough for futex to +continue but because of PAGE_MAPPING_ANON, the poisoned value is not +dereferenced or used by futex. No other part of the VM should be +dereferencing the page->mapping of a hugetlbfs page as its page cache is +not on the LRU. + +This patch fixes the problem with the test case described in the bugzilla. + +[akpm@linux-foundation.org: mel cant spel] +Signed-off-by: Mel Gorman +Acked-by: Peter Zijlstra +Acked-by: Darren Hart +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/poison.h | 9 +++++++++ + mm/hugetlb.c | 5 ++++- + 2 files changed, 13 insertions(+), 1 deletion(-) + +--- a/include/linux/poison.h ++++ b/include/linux/poison.h +@@ -48,6 +48,15 @@ + #define POISON_FREE 0x6b /* for use-after-free poisoning */ + #define POISON_END 0xa5 /* end-byte of poisoning */ + ++/********** mm/hugetlb.c **********/ ++/* ++ * Private mappings of hugetlb pages use this poisoned value for ++ * page->mapping. The core VM should not be doing anything with this mapping ++ * but futex requires the existence of some page->mapping value even though it ++ * is unused if PAGE_MAPPING_ANON is set. ++ */ ++#define HUGETLB_POISON ((void *)(0x00300300 + POISON_POINTER_DELTA + PAGE_MAPPING_ANON)) ++ + /********** arch/$ARCH/mm/init.c **********/ + #define POISON_FREE_INITMEM 0xcc + +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -546,6 +546,7 @@ static void free_huge_page(struct page * + + mapping = (struct address_space *) page_private(page); + set_page_private(page, 0); ++ page->mapping = NULL; + BUG_ON(page_count(page)); + INIT_LIST_HEAD(&page->lru); + +@@ -2447,8 +2448,10 @@ retry: + spin_lock(&inode->i_lock); + inode->i_blocks += blocks_per_huge_page(h); + spin_unlock(&inode->i_lock); +- } else ++ } else { + lock_page(page); ++ page->mapping = HUGETLB_POISON; ++ } + } + + /* diff --git a/queue-2.6.33/libata-ensure-ncq-error-result-taskfile-is-fully-initialized.patch b/queue-2.6.33/libata-ensure-ncq-error-result-taskfile-is-fully-initialized.patch new file mode 100644 index 00000000000..383cf508215 --- /dev/null +++ b/queue-2.6.33/libata-ensure-ncq-error-result-taskfile-is-fully-initialized.patch @@ -0,0 +1,27 @@ +From a09bf4cd53b8ab000197ef81f15d50f29ecf973c Mon Sep 17 00:00:00 2001 +From: Jeff Garzik +Date: Thu, 22 Apr 2010 21:59:13 -0400 +Subject: libata: ensure NCQ error result taskfile is fully initialized + before returning it via qc->result_tf. + +From: Jeff Garzik + +commit a09bf4cd53b8ab000197ef81f15d50f29ecf973c upstream. + +Signed-off-by: Jeff Garzik +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/ata/libata-eh.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/ata/libata-eh.c ++++ b/drivers/ata/libata-eh.c +@@ -1628,6 +1628,7 @@ void ata_eh_analyze_ncq_error(struct ata + } + + /* okay, this error is ours */ ++ memset(&tf, 0, sizeof(tf)); + rc = ata_eh_read_log_10h(dev, &tag, &tf); + if (rc) { + ata_link_printk(link, KERN_ERR, "failed to read log page 10h " diff --git a/queue-2.6.33/libata-fix-locking-around-blk_abort_request.patch b/queue-2.6.33/libata-fix-locking-around-blk_abort_request.patch new file mode 100644 index 00000000000..4e9198da80e --- /dev/null +++ b/queue-2.6.33/libata-fix-locking-around-blk_abort_request.patch @@ -0,0 +1,45 @@ +From fa41efdae7de61191a7bda3a00e88ef69afb5bb9 Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Thu, 15 Apr 2010 08:57:37 +0900 +Subject: libata: fix locking around blk_abort_request() + +From: Tejun Heo + +commit fa41efdae7de61191a7bda3a00e88ef69afb5bb9 upstream. + +blk_abort_request() expectes queue lock to be held by the caller. +Grab it before calling the function. + +Lack of this synchronization led to infinite loop on corrupt +q->timeout_list. + +Signed-off-by: Tejun Heo +Cc: Jens Axboe +Signed-off-by: Jeff Garzik +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/ata/libata-eh.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/ata/libata-eh.c ++++ b/drivers/ata/libata-eh.c +@@ -879,6 +879,8 @@ static void ata_eh_set_pending(struct at + void ata_qc_schedule_eh(struct ata_queued_cmd *qc) + { + struct ata_port *ap = qc->ap; ++ struct request_queue *q = qc->scsicmd->device->request_queue; ++ unsigned long flags; + + WARN_ON(!ap->ops->error_handler); + +@@ -890,7 +892,9 @@ void ata_qc_schedule_eh(struct ata_queue + * Note that ATA_QCFLAG_FAILED is unconditionally set after + * this function completes. + */ ++ spin_lock_irqsave(q->queue_lock, flags); + blk_abort_request(qc->scsicmd->request); ++ spin_unlock_irqrestore(q->queue_lock, flags); + } + + /** diff --git a/queue-2.6.33/mac80211-remove-bogus-tx-agg-state-assignment.patch b/queue-2.6.33/mac80211-remove-bogus-tx-agg-state-assignment.patch new file mode 100644 index 00000000000..4cee47d6f8f --- /dev/null +++ b/queue-2.6.33/mac80211-remove-bogus-tx-agg-state-assignment.patch @@ -0,0 +1,32 @@ +From b4bb5c3fd9333024044362df67e23e96158489ed Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Mon, 19 Apr 2010 10:48:38 +0200 +Subject: mac80211: remove bogus TX agg state assignment + +From: Johannes Berg + +commit b4bb5c3fd9333024044362df67e23e96158489ed upstream. + +When the addba timer expires but has no work to do, +it should not affect the state machine. If it does, +TX will not see the successfully established and we +can also crash trying to re-establish the session. + +Signed-off-by: Johannes Berg +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/agg-tx.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/net/mac80211/agg-tx.c ++++ b/net/mac80211/agg-tx.c +@@ -183,7 +183,6 @@ static void sta_addba_resp_timer_expired + HT_AGG_STATE_REQ_STOP_BA_MSK)) != + HT_ADDBA_REQUESTED_MSK) { + spin_unlock_bh(&sta->lock); +- *state = HT_AGG_STATE_IDLE; + #ifdef CONFIG_MAC80211_HT_DEBUG + printk(KERN_DEBUG "timer expired on tid %d but we are not " + "(or no longer) expecting addBA response there", diff --git a/queue-2.6.33/md-raid5-allow-for-more-than-2-31-chunks.patch b/queue-2.6.33/md-raid5-allow-for-more-than-2-31-chunks.patch new file mode 100644 index 00000000000..f8b37ba34ae --- /dev/null +++ b/queue-2.6.33/md-raid5-allow-for-more-than-2-31-chunks.patch @@ -0,0 +1,80 @@ +From 35f2a591192d0a5d9f7fc696869c76f0b8e49c3d Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Tue, 20 Apr 2010 14:13:34 +1000 +Subject: md/raid5: allow for more than 2^31 chunks. + +From: NeilBrown + +commit 35f2a591192d0a5d9f7fc696869c76f0b8e49c3d upstream. + +With many large drives and small chunk sizes it is possible +to create a RAID5 with more than 2^31 chunks. Make sure this +works. + +Reported-by: Brett King +Signed-off-by: NeilBrown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/raid5.c | 19 +++++++------------ + 1 file changed, 7 insertions(+), 12 deletions(-) + +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -1649,8 +1649,8 @@ static sector_t raid5_compute_sector(rai + int previous, int *dd_idx, + struct stripe_head *sh) + { +- long stripe; +- unsigned long chunk_number; ++ sector_t stripe; ++ sector_t chunk_number; + unsigned int chunk_offset; + int pd_idx, qd_idx; + int ddf_layout = 0; +@@ -1670,17 +1670,12 @@ static sector_t raid5_compute_sector(rai + */ + chunk_offset = sector_div(r_sector, sectors_per_chunk); + chunk_number = r_sector; +- BUG_ON(r_sector != chunk_number); + + /* + * Compute the stripe number + */ +- stripe = chunk_number / data_disks; +- +- /* +- * Compute the data disk and parity disk indexes inside the stripe +- */ +- *dd_idx = chunk_number % data_disks; ++ stripe = chunk_number; ++ *dd_idx = sector_div(stripe, data_disks); + + /* + * Select the parity disk based on the user selected algorithm. +@@ -1869,14 +1864,14 @@ static sector_t compute_blocknr(struct s + : conf->algorithm; + sector_t stripe; + int chunk_offset; +- int chunk_number, dummy1, dd_idx = i; ++ sector_t chunk_number; ++ int dummy1, dd_idx = i; + sector_t r_sector; + struct stripe_head sh2; + + + chunk_offset = sector_div(new_sector, sectors_per_chunk); + stripe = new_sector; +- BUG_ON(new_sector != stripe); + + if (i == sh->pd_idx) + return 0; +@@ -1969,7 +1964,7 @@ static sector_t compute_blocknr(struct s + } + + chunk_number = stripe * data_disks + i; +- r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset; ++ r_sector = chunk_number * sectors_per_chunk + chunk_offset; + + check = raid5_compute_sector(conf, r_sector, + previous, &dummy1, &sh2); diff --git a/queue-2.6.33/md-raid5-fix-previous-patch.patch b/queue-2.6.33/md-raid5-fix-previous-patch.patch new file mode 100644 index 00000000000..8f65ca1635d --- /dev/null +++ b/queue-2.6.33/md-raid5-fix-previous-patch.patch @@ -0,0 +1,162 @@ +From 6e3b96ed610e5a1838e62ddae9fa0c3463f235fa Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Fri, 23 Apr 2010 07:08:28 +1000 +Subject: md/raid5: fix previous patch. + +From: NeilBrown + +commit 6e3b96ed610e5a1838e62ddae9fa0c3463f235fa upstream. + +Previous patch changes stripe and chunk_number to sector_t but +mistakenly did not update all of the divisions to use sector_dev(). + +This patch changes all the those divisions (actually the '%' operator) +to sector_div. + +Signed-off-by: NeilBrown +Tested-by: Stefan Lippers-Hollmann +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/raid5.c | 35 ++++++++++++++++++----------------- + 1 file changed, 18 insertions(+), 17 deletions(-) + +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -1649,7 +1649,7 @@ static sector_t raid5_compute_sector(rai + int previous, int *dd_idx, + struct stripe_head *sh) + { +- sector_t stripe; ++ sector_t stripe, stripe2; + sector_t chunk_number; + unsigned int chunk_offset; + int pd_idx, qd_idx; +@@ -1676,7 +1676,7 @@ static sector_t raid5_compute_sector(rai + */ + stripe = chunk_number; + *dd_idx = sector_div(stripe, data_disks); +- ++ stripe2 = stripe; + /* + * Select the parity disk based on the user selected algorithm. + */ +@@ -1688,21 +1688,21 @@ static sector_t raid5_compute_sector(rai + case 5: + switch (algorithm) { + case ALGORITHM_LEFT_ASYMMETRIC: +- pd_idx = data_disks - stripe % raid_disks; ++ pd_idx = data_disks - sector_div(stripe2, raid_disks); + if (*dd_idx >= pd_idx) + (*dd_idx)++; + break; + case ALGORITHM_RIGHT_ASYMMETRIC: +- pd_idx = stripe % raid_disks; ++ pd_idx = sector_div(stripe2, raid_disks); + if (*dd_idx >= pd_idx) + (*dd_idx)++; + break; + case ALGORITHM_LEFT_SYMMETRIC: +- pd_idx = data_disks - stripe % raid_disks; ++ pd_idx = data_disks - sector_div(stripe2, raid_disks); + *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks; + break; + case ALGORITHM_RIGHT_SYMMETRIC: +- pd_idx = stripe % raid_disks; ++ pd_idx = sector_div(stripe2, raid_disks); + *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks; + break; + case ALGORITHM_PARITY_0: +@@ -1722,7 +1722,7 @@ static sector_t raid5_compute_sector(rai + + switch (algorithm) { + case ALGORITHM_LEFT_ASYMMETRIC: +- pd_idx = raid_disks - 1 - (stripe % raid_disks); ++ pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks); + qd_idx = pd_idx + 1; + if (pd_idx == raid_disks-1) { + (*dd_idx)++; /* Q D D D P */ +@@ -1731,7 +1731,7 @@ static sector_t raid5_compute_sector(rai + (*dd_idx) += 2; /* D D P Q D */ + break; + case ALGORITHM_RIGHT_ASYMMETRIC: +- pd_idx = stripe % raid_disks; ++ pd_idx = sector_div(stripe2, raid_disks); + qd_idx = pd_idx + 1; + if (pd_idx == raid_disks-1) { + (*dd_idx)++; /* Q D D D P */ +@@ -1740,12 +1740,12 @@ static sector_t raid5_compute_sector(rai + (*dd_idx) += 2; /* D D P Q D */ + break; + case ALGORITHM_LEFT_SYMMETRIC: +- pd_idx = raid_disks - 1 - (stripe % raid_disks); ++ pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks); + qd_idx = (pd_idx + 1) % raid_disks; + *dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks; + break; + case ALGORITHM_RIGHT_SYMMETRIC: +- pd_idx = stripe % raid_disks; ++ pd_idx = sector_div(stripe2, raid_disks); + qd_idx = (pd_idx + 1) % raid_disks; + *dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks; + break; +@@ -1764,7 +1764,7 @@ static sector_t raid5_compute_sector(rai + /* Exactly the same as RIGHT_ASYMMETRIC, but or + * of blocks for computing Q is different. + */ +- pd_idx = stripe % raid_disks; ++ pd_idx = sector_div(stripe2, raid_disks); + qd_idx = pd_idx + 1; + if (pd_idx == raid_disks-1) { + (*dd_idx)++; /* Q D D D P */ +@@ -1779,7 +1779,8 @@ static sector_t raid5_compute_sector(rai + * D D D P Q rather than + * Q D D D P + */ +- pd_idx = raid_disks - 1 - ((stripe + 1) % raid_disks); ++ stripe2 += 1; ++ pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks); + qd_idx = pd_idx + 1; + if (pd_idx == raid_disks-1) { + (*dd_idx)++; /* Q D D D P */ +@@ -1791,7 +1792,7 @@ static sector_t raid5_compute_sector(rai + + case ALGORITHM_ROTATING_N_CONTINUE: + /* Same as left_symmetric but Q is before P */ +- pd_idx = raid_disks - 1 - (stripe % raid_disks); ++ pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks); + qd_idx = (pd_idx + raid_disks - 1) % raid_disks; + *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks; + ddf_layout = 1; +@@ -1799,27 +1800,27 @@ static sector_t raid5_compute_sector(rai + + case ALGORITHM_LEFT_ASYMMETRIC_6: + /* RAID5 left_asymmetric, with Q on last device */ +- pd_idx = data_disks - stripe % (raid_disks-1); ++ pd_idx = data_disks - sector_div(stripe2, raid_disks-1); + if (*dd_idx >= pd_idx) + (*dd_idx)++; + qd_idx = raid_disks - 1; + break; + + case ALGORITHM_RIGHT_ASYMMETRIC_6: +- pd_idx = stripe % (raid_disks-1); ++ pd_idx = sector_div(stripe2, raid_disks-1); + if (*dd_idx >= pd_idx) + (*dd_idx)++; + qd_idx = raid_disks - 1; + break; + + case ALGORITHM_LEFT_SYMMETRIC_6: +- pd_idx = data_disks - stripe % (raid_disks-1); ++ pd_idx = data_disks - sector_div(stripe2, raid_disks-1); + *dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1); + qd_idx = raid_disks - 1; + break; + + case ALGORITHM_RIGHT_SYMMETRIC_6: +- pd_idx = stripe % (raid_disks-1); ++ pd_idx = sector_div(stripe2, raid_disks-1); + *dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1); + qd_idx = raid_disks - 1; + break; diff --git a/queue-2.6.33/memcg-fix-prepare-migration.patch b/queue-2.6.33/memcg-fix-prepare-migration.patch new file mode 100644 index 00000000000..c5c2420883c --- /dev/null +++ b/queue-2.6.33/memcg-fix-prepare-migration.patch @@ -0,0 +1,54 @@ +From 93d5c9be1ddd57d4063ce463c9ac2be1e5ee14f1 Mon Sep 17 00:00:00 2001 +From: Andrea Arcangeli +Date: Fri, 23 Apr 2010 13:17:39 -0400 +Subject: memcg: fix prepare migration + +From: Andrea Arcangeli + +commit 93d5c9be1ddd57d4063ce463c9ac2be1e5ee14f1 upstream. + +If a signal is pending (task being killed by sigkill) +__mem_cgroup_try_charge will write NULL into &mem, and css_put will oops +on null pointer dereference. + + BUG: unable to handle kernel NULL pointer dereference at 0000000000000010 + IP: [] mem_cgroup_prepare_migration+0x7c/0xc0 + PGD a5d89067 PUD a5d8a067 PMD 0 + Oops: 0000 [#1] SMP + last sysfs file: /sys/devices/platform/microcode/firmware/microcode/loading + CPU 0 + Modules linked in: nfs lockd nfs_acl auth_rpcgss sunrpc acpi_cpufreq pcspkr sg [last unloaded: microcode] + + Pid: 5299, comm: largepages Tainted: G W 2.6.34-rc3 #3 Penryn1600SLI-110dB/To Be Filled By O.E.M. + RIP: 0010:[] [] mem_cgroup_prepare_migration+0x7c/0xc0 + +[nishimura@mxp.nes.nec.co.jp: fix merge issues] +Signed-off-by: Andrea Arcangeli +Acked-by: KAMEZAWA Hiroyuki +Cc: Balbir Singh +Signed-off-by: Daisuke Nishimura +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/memcontrol.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -2215,12 +2215,12 @@ int mem_cgroup_prepare_migration(struct + } + unlock_page_cgroup(pc); + ++ *ptr = mem; + if (mem) { +- ret = __mem_cgroup_try_charge(NULL, GFP_KERNEL, &mem, false, ++ ret = __mem_cgroup_try_charge(NULL, GFP_KERNEL, ptr, false + page); + css_put(&mem->css); + } +- *ptr = mem; + return ret; + } + diff --git a/queue-2.6.33/p54usb-add-usbid-for-corega-cg-wlusb2gt.patch b/queue-2.6.33/p54usb-add-usbid-for-corega-cg-wlusb2gt.patch new file mode 100644 index 00000000000..a6aac464444 --- /dev/null +++ b/queue-2.6.33/p54usb-add-usbid-for-corega-cg-wlusb2gt.patch @@ -0,0 +1,29 @@ +From 15a69a81731d337a3d9db51692ff8704c1114f43 Mon Sep 17 00:00:00 2001 +From: Shimada Hirofumi +Date: Sun, 14 Feb 2010 04:16:16 +0900 +Subject: p54usb: Add usbid for Corega CG-WLUSB2GT. + +From: Shimada Hirofumi + +commit 15a69a81731d337a3d9db51692ff8704c1114f43 upstream. + +Signed-off-by: Shimada Hirofumi +Signed-off-by: YOSHIFUJI Hideaki +Signed-off-by: John W. Linville +Cc: maximilian attems +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/p54/p54usb.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/p54/p54usb.c ++++ b/drivers/net/wireless/p54/p54usb.c +@@ -36,6 +36,7 @@ static struct usb_device_id p54u_table[] + /* Version 1 devices (pci chip + net2280) */ + {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */ + {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */ ++ {USB_DEVICE(0x07aa, 0x001c)}, /* Corega CG-WLUSB2GT */ + {USB_DEVICE(0x083a, 0x4501)}, /* Accton 802.11g WN4501 USB */ + {USB_DEVICE(0x083a, 0x4502)}, /* Siemens Gigaset USB Adapter */ + {USB_DEVICE(0x083a, 0x5501)}, /* Phillips CPWUA054 */ diff --git a/queue-2.6.33/reiserfs-fix-corruption-during-shrinking-of-xattrs.patch b/queue-2.6.33/reiserfs-fix-corruption-during-shrinking-of-xattrs.patch new file mode 100644 index 00000000000..9184051eab4 --- /dev/null +++ b/queue-2.6.33/reiserfs-fix-corruption-during-shrinking-of-xattrs.patch @@ -0,0 +1,52 @@ +From fb2162df74bb19552db3d988fd11c787cf5fad56 Mon Sep 17 00:00:00 2001 +From: Jeff Mahoney +Date: Fri, 23 Apr 2010 13:17:41 -0400 +Subject: reiserfs: fix corruption during shrinking of xattrs + +From: Jeff Mahoney + +commit fb2162df74bb19552db3d988fd11c787cf5fad56 upstream. + +Commit 48b32a3553a54740d236b79a90f20147a25875e3 ("reiserfs: use generic +xattr handlers") introduced a problem that causes corruption when extended +attributes are replaced with a smaller value. + +The issue is that the reiserfs_setattr to shrink the xattr file was moved +from before the write to after the write. + +The root issue has always been in the reiserfs xattr code, but was papered +over by the fact that in the shrink case, the file would just be expanded +again while the xattr was written. + +The end result is that the last 8 bytes of xattr data are lost. + +This patch fixes it to use new_size. + +Addresses https://bugzilla.kernel.org/show_bug.cgi?id=14826 + +Signed-off-by: Jeff Mahoney +Reported-by: Christian Kujau +Tested-by: Christian Kujau +Cc: Edward Shishkin +Cc: Jethro Beekman +Cc: Greg Surbey +Cc: Marco Gatti +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/reiserfs/xattr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/reiserfs/xattr.c ++++ b/fs/reiserfs/xattr.c +@@ -557,7 +557,7 @@ reiserfs_xattr_set_handle(struct reiserf + if (!err && new_size < i_size_read(dentry->d_inode)) { + struct iattr newattrs = { + .ia_ctime = current_fs_time(inode->i_sb), +- .ia_size = buffer_size, ++ .ia_size = new_size, + .ia_valid = ATTR_SIZE | ATTR_CTIME, + }; + diff --git a/queue-2.6.33/reiserfs-fix-permissions-on-.reiserfs_priv.patch b/queue-2.6.33/reiserfs-fix-permissions-on-.reiserfs_priv.patch new file mode 100644 index 00000000000..51ec5c5d8fa --- /dev/null +++ b/queue-2.6.33/reiserfs-fix-permissions-on-.reiserfs_priv.patch @@ -0,0 +1,91 @@ +From cac36f707119b792b2396aed371d6b5cdc194890 Mon Sep 17 00:00:00 2001 +From: Jeff Mahoney +Date: Fri, 23 Apr 2010 13:17:37 -0400 +Subject: reiserfs: fix permissions on .reiserfs_priv + +From: Jeff Mahoney + +commit cac36f707119b792b2396aed371d6b5cdc194890 upstream. + +Commit 677c9b2e393a0cd203bd54e9c18b012b2c73305a ("reiserfs: remove +privroot hiding in lookup") removed the magic from the lookup code to hide +the .reiserfs_priv directory since it was getting loaded at mount-time +instead. The intent was that the entry would be hidden from the user via +a poisoned d_compare, but this was faulty. + +This introduced a security issue where unprivileged users could access and +modify extended attributes or ACLs belonging to other users, including +root. + +This patch resolves the issue by properly hiding .reiserfs_priv. This was +the intent of the xattr poisoning code, but it appears to have never +worked as expected. This is fixed by using d_revalidate instead of +d_compare. + +This patch makes -oexpose_privroot a no-op. I'm fine leaving it this way. +The effort involved in working out the corner cases wrt permissions and +caching outweigh the benefit of the feature. + +Signed-off-by: Jeff Mahoney +Acked-by: Edward Shishkin +Reported-by: Matt McCutchen +Tested-by: Matt McCutchen +Cc: Frederic Weisbecker +Cc: Al Viro +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/reiserfs/dir.c | 2 -- + fs/reiserfs/xattr.c | 17 ++++------------- + 2 files changed, 4 insertions(+), 15 deletions(-) + +--- a/fs/reiserfs/dir.c ++++ b/fs/reiserfs/dir.c +@@ -45,8 +45,6 @@ static inline bool is_privroot_deh(struc + struct reiserfs_de_head *deh) + { + struct dentry *privroot = REISERFS_SB(dir->d_sb)->priv_root; +- if (reiserfs_expose_privroot(dir->d_sb)) +- return 0; + return (dir == dir->d_parent && privroot->d_inode && + deh->deh_objectid == INODE_PKEY(privroot->d_inode)->k_objectid); + } +--- a/fs/reiserfs/xattr.c ++++ b/fs/reiserfs/xattr.c +@@ -976,21 +976,13 @@ int reiserfs_permission(struct inode *in + return generic_permission(inode, mask, NULL); + } + +-/* This will catch lookups from the fs root to .reiserfs_priv */ +-static int +-xattr_lookup_poison(struct dentry *dentry, struct qstr *q1, struct qstr *name) ++static int xattr_hide_revalidate(struct dentry *dentry, struct nameidata *nd) + { +- struct dentry *priv_root = REISERFS_SB(dentry->d_sb)->priv_root; +- if (container_of(q1, struct dentry, d_name) == priv_root) +- return -ENOENT; +- if (q1->len == name->len && +- !memcmp(q1->name, name->name, name->len)) +- return 0; +- return 1; ++ return -EPERM; + } + + static const struct dentry_operations xattr_lookup_poison_ops = { +- .d_compare = xattr_lookup_poison, ++ .d_revalidate = xattr_hide_revalidate, + }; + + int reiserfs_lookup_privroot(struct super_block *s) +@@ -1004,8 +996,7 @@ int reiserfs_lookup_privroot(struct supe + strlen(PRIVROOT_NAME)); + if (!IS_ERR(dentry)) { + REISERFS_SB(s)->priv_root = dentry; +- if (!reiserfs_expose_privroot(s)) +- s->s_root->d_op = &xattr_lookup_poison_ops; ++ dentry->d_op = &xattr_lookup_poison_ops; + if (dentry->d_inode) + dentry->d_inode->i_flags |= S_PRIVATE; + } else diff --git a/queue-2.6.33/series b/queue-2.6.33/series new file mode 100644 index 00000000000..85e1b0c4388 --- /dev/null +++ b/queue-2.6.33/series @@ -0,0 +1,14 @@ +usb-ehci-defer-reclamation-of-sitds.patch +p54usb-add-usbid-for-corega-cg-wlusb2gt.patch +drm-i915-fix-tiling-limits-for-i915-class-hw-v2.patch +md-raid5-allow-for-more-than-2-31-chunks.patch +md-raid5-fix-previous-patch.patch +libata-fix-locking-around-blk_abort_request.patch +libata-ensure-ncq-error-result-taskfile-is-fully-initialized.patch +w1-w1-temp-fix-negative-termperature-calculation.patch +memcg-fix-prepare-migration.patch +mac80211-remove-bogus-tx-agg-state-assignment.patch +flex_array-fix-the-panic-when-calling-flex_array_alloc-without-__gfp_zero.patch +hugetlb-fix-infinite-loop-in-get_futex_key-when-backed-by-huge-pages.patch +reiserfs-fix-permissions-on-.reiserfs_priv.patch +reiserfs-fix-corruption-during-shrinking-of-xattrs.patch diff --git a/queue-2.6.33/usb-ehci-defer-reclamation-of-sitds.patch b/queue-2.6.33/usb-ehci-defer-reclamation-of-sitds.patch new file mode 100644 index 00000000000..c83e1c60a84 --- /dev/null +++ b/queue-2.6.33/usb-ehci-defer-reclamation-of-sitds.patch @@ -0,0 +1,151 @@ +From 0e5f231bc16ff9910882fa5b9d64d80e7691cfab Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Thu, 8 Apr 2010 16:56:37 -0400 +Subject: USB: EHCI: defer reclamation of siTDs + +From: Alan Stern + +commit 0e5f231bc16ff9910882fa5b9d64d80e7691cfab upstream. + +This patch (as1369) fixes a problem in ehci-hcd. Some controllers +occasionally run into trouble when the driver reclaims siTDs too +quickly. This can happen while streaming audio; it causes the +controller to crash. + +The patch changes siTD reclamation to work the same way as iTD +reclamation: Completed siTDs are stored on a list and not reused until +at least one frame has passed. + +Signed-off-by: Alan Stern +Tested-by: Nate Case +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/ehci-hcd.c | 1 + + drivers/usb/host/ehci-mem.c | 2 +- + drivers/usb/host/ehci-sched.c | 38 ++++++++++++++++++++++++++++++-------- + drivers/usb/host/ehci.h | 5 +++-- + 4 files changed, 35 insertions(+), 11 deletions(-) + +--- a/drivers/usb/host/ehci-hcd.c ++++ b/drivers/usb/host/ehci-hcd.c +@@ -543,6 +543,7 @@ static int ehci_init(struct usb_hcd *hcd + */ + ehci->periodic_size = DEFAULT_I_TDPS; + INIT_LIST_HEAD(&ehci->cached_itd_list); ++ INIT_LIST_HEAD(&ehci->cached_sitd_list); + if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0) + return retval; + +--- a/drivers/usb/host/ehci-mem.c ++++ b/drivers/usb/host/ehci-mem.c +@@ -136,7 +136,7 @@ static inline void qh_put (struct ehci_q + + static void ehci_mem_cleanup (struct ehci_hcd *ehci) + { +- free_cached_itd_list(ehci); ++ free_cached_lists(ehci); + if (ehci->async) + qh_put (ehci->async); + ehci->async = NULL; +--- a/drivers/usb/host/ehci-sched.c ++++ b/drivers/usb/host/ehci-sched.c +@@ -2137,13 +2137,27 @@ sitd_complete ( + (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); + } + iso_stream_put (ehci, stream); +- /* OK to recycle this SITD now that its completion callback ran. */ ++ + done: + sitd->urb = NULL; +- sitd->stream = NULL; +- list_move(&sitd->sitd_list, &stream->free_list); +- iso_stream_put(ehci, stream); +- ++ if (ehci->clock_frame != sitd->frame) { ++ /* OK to recycle this SITD now. */ ++ sitd->stream = NULL; ++ list_move(&sitd->sitd_list, &stream->free_list); ++ iso_stream_put(ehci, stream); ++ } else { ++ /* HW might remember this SITD, so we can't recycle it yet. ++ * Move it to a safe place until a new frame starts. ++ */ ++ list_move(&sitd->sitd_list, &ehci->cached_sitd_list); ++ if (stream->refcount == 2) { ++ /* If iso_stream_put() were called here, stream ++ * would be freed. Instead, just prevent reuse. ++ */ ++ stream->ep->hcpriv = NULL; ++ stream->ep = NULL; ++ } ++ } + return retval; + } + +@@ -2209,9 +2223,10 @@ done: + + /*-------------------------------------------------------------------------*/ + +-static void free_cached_itd_list(struct ehci_hcd *ehci) ++static void free_cached_lists(struct ehci_hcd *ehci) + { + struct ehci_itd *itd, *n; ++ struct ehci_sitd *sitd, *sn; + + list_for_each_entry_safe(itd, n, &ehci->cached_itd_list, itd_list) { + struct ehci_iso_stream *stream = itd->stream; +@@ -2219,6 +2234,13 @@ static void free_cached_itd_list(struct + list_move(&itd->itd_list, &stream->free_list); + iso_stream_put(ehci, stream); + } ++ ++ list_for_each_entry_safe(sitd, sn, &ehci->cached_sitd_list, sitd_list) { ++ struct ehci_iso_stream *stream = sitd->stream; ++ sitd->stream = NULL; ++ list_move(&sitd->sitd_list, &stream->free_list); ++ iso_stream_put(ehci, stream); ++ } + } + + /*-------------------------------------------------------------------------*/ +@@ -2245,7 +2267,7 @@ scan_periodic (struct ehci_hcd *ehci) + clock_frame = -1; + } + if (ehci->clock_frame != clock_frame) { +- free_cached_itd_list(ehci); ++ free_cached_lists(ehci); + ehci->clock_frame = clock_frame; + } + clock %= mod; +@@ -2408,7 +2430,7 @@ restart: + clock = now; + clock_frame = clock >> 3; + if (ehci->clock_frame != clock_frame) { +- free_cached_itd_list(ehci); ++ free_cached_lists(ehci); + ehci->clock_frame = clock_frame; + } + } else { +--- a/drivers/usb/host/ehci.h ++++ b/drivers/usb/host/ehci.h +@@ -87,8 +87,9 @@ struct ehci_hcd { /* one per controlle + int next_uframe; /* scan periodic, start here */ + unsigned periodic_sched; /* periodic activity count */ + +- /* list of itds completed while clock_frame was still active */ ++ /* list of itds & sitds completed while clock_frame was still active */ + struct list_head cached_itd_list; ++ struct list_head cached_sitd_list; + unsigned clock_frame; + + /* per root hub port */ +@@ -195,7 +196,7 @@ timer_action_done (struct ehci_hcd *ehci + clear_bit (action, &ehci->actions); + } + +-static void free_cached_itd_list(struct ehci_hcd *ehci); ++static void free_cached_lists(struct ehci_hcd *ehci); + + /*-------------------------------------------------------------------------*/ + diff --git a/queue-2.6.33/w1-w1-temp-fix-negative-termperature-calculation.patch b/queue-2.6.33/w1-w1-temp-fix-negative-termperature-calculation.patch new file mode 100644 index 00000000000..4d9186de9b9 --- /dev/null +++ b/queue-2.6.33/w1-w1-temp-fix-negative-termperature-calculation.patch @@ -0,0 +1,44 @@ +From 9a6a1ecd9e9b5d046a236da2f7eb6b6812f04229 Mon Sep 17 00:00:00 2001 +From: Ian Dall +Date: Fri, 23 Apr 2010 13:17:53 -0400 +Subject: w1: w1 temp: fix negative termperature calculation + +From: Ian Dall + +commit 9a6a1ecd9e9b5d046a236da2f7eb6b6812f04229 upstream. + +Fix regression caused by commit 507e2fbaaacb6f164b4125b87c5002f95143174b +("w1: w1 temp calculation overflow fix") whereby negative temperatures for +the DS18B20 are not converted properly. + +When the temperature exceeds 32767 milli-degrees the temperature overflows +to -32768 millidegrees. These are both well within the -55 - +125 degree +range for the sensor. + +Addresses https://bugzilla.kernel.org/show_bug.cgi?id=12646 + +Signed-of-by: Ian Dall +Cc: Evgeniy Polyakov +Tested-by: Karsten Elfenbein +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/w1/slaves/w1_therm.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/w1/slaves/w1_therm.c ++++ b/drivers/w1/slaves/w1_therm.c +@@ -115,9 +115,8 @@ static struct w1_therm_family_converter + + static inline int w1_DS18B20_convert_temp(u8 rom[9]) + { +- int t = ((s16)rom[1] << 8) | rom[0]; +- t = t*1000/16; +- return t; ++ s16 t = le16_to_cpup((__le16 *)rom); ++ return t*1000/16; + } + + static inline int w1_DS18S20_convert_temp(u8 rom[9])