]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
start some 2.6.23 work
authorGreg Kroah-Hartman <gregkh@suse.de>
Mon, 14 Jan 2008 21:34:37 +0000 (13:34 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 14 Jan 2008 21:34:37 +0000 (13:34 -0800)
queue-2.6.23/acpi-thinkpad-acpi-fix-lenovo-keymap-for-brightness.patch [new file with mode: 0644]
queue-2.6.23/acpi-video_device_list-corruption.patch [new file with mode: 0644]
queue-2.6.23/dm-crypt-fix-write-endio.patch [new file with mode: 0644]
queue-2.6.23/dm-crypt-use-bio_add_page.patch [new file with mode: 0644]
queue-2.6.23/dm-table-detect-io-beyond-device.patch [new file with mode: 0644]
queue-2.6.23/series [new file with mode: 0644]

diff --git a/queue-2.6.23/acpi-thinkpad-acpi-fix-lenovo-keymap-for-brightness.patch b/queue-2.6.23/acpi-thinkpad-acpi-fix-lenovo-keymap-for-brightness.patch
new file mode 100644 (file)
index 0000000..54f6105
--- /dev/null
@@ -0,0 +1,49 @@
+From stable-bounces@linux.kernel.org Thu Dec 13 19:04:09 2007
+From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
+Date: Thu, 13 Dec 2007 22:03:52 -0500
+Subject: ACPI: thinkpad-acpi: fix lenovo keymap for brightness
+To: stable@kernel.org
+Cc: Henrique Holschuh <hmh@hmh.eng.br>
+Message-ID: <200712132203.53013.lenb@kernel.org>
+Content-Disposition: inline
+
+
+From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
+
+upstream  commit 56a185b43be05e48da7428e6a1d3e2585b232b1d
+
+Starting in 2.6.23...
+
+Several reports from X60 users complained that the default Lenovo keymap
+issuing EV_KEY KEY_BRIGHTNESS_UP/DOWN input events caused major issues when
+the proper brightness support through ACPI video.c was loaded.
+
+Therefore, remove the generation of these events by default, which is the
+right thing for T60, X60, R60, T61, X61 and R61 with their latest BIOSes.
+
+Distros that want to misuse these events into OSD reporting (which requires
+an ugly hack from hell in HAL) are welcome to set up the key map they need
+through HAL.  That way, we don't break everyone else's systems.
+
+Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
+Signed-off-by: Len Brown <len.brown@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/misc/thinkpad_acpi.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/misc/thinkpad_acpi.c
++++ b/drivers/misc/thinkpad_acpi.c
+@@ -968,9 +968,9 @@ static int __init hotkey_init(struct ibm
+               KEY_UNKNOWN,    /* 0x0C: FN+BACKSPACE */
+               KEY_UNKNOWN,    /* 0x0D: FN+INSERT */
+               KEY_UNKNOWN,    /* 0x0E: FN+DELETE */
+-              KEY_BRIGHTNESSUP,       /* 0x0F: FN+HOME (brightness up) */
++              KEY_RESERVED,   /* 0x0F: FN+HOME (brightness up) */
+               /* Scan codes 0x10 to 0x1F: Extended ACPI HKEY hot keys */
+-              KEY_BRIGHTNESSDOWN,     /* 0x10: FN+END (brightness down) */
++              KEY_RESERVED,   /* 0x10: FN+END (brightness down) */
+               KEY_RESERVED,   /* 0x11: FN+PGUP (thinklight toggle) */
+               KEY_UNKNOWN,    /* 0x12: FN+PGDOWN */
+               KEY_ZOOM,       /* 0x13: FN+SPACE (zoom) */
diff --git a/queue-2.6.23/acpi-video_device_list-corruption.patch b/queue-2.6.23/acpi-video_device_list-corruption.patch
new file mode 100644 (file)
index 0000000..82df8e1
--- /dev/null
@@ -0,0 +1,48 @@
+From stable-bounces@linux.kernel.org Thu Dec 13 14:41:00 2007
+From: William Lee Irwin III <wli@holomorphy.com>
+Date: Thu, 13 Dec 2007 16:29:16 -0500
+Subject: ACPI: video_device_list corruption
+To: stable@kernel.org
+Message-ID: <200712131629.16257.lenb@kernel.org>
+Content-Disposition: inline
+
+
+From: William Lee Irwin III <wli@holomorphy.com>
+
+The ->cap fields of struct acpi_video_device and struct acpi_video_bus
+are 1B each, not 4B. The oversized memset()'s corrupted the subsequent
+list_head fields. This resulted in silent corruption without
+CONFIG_DEBUG_LIST and BUG's with it. This patch uses sizeof() to pass
+the proper bounds to the memset() calls and thereby correct the bugs.
+
+upstream commit 98934def70b48dac74fac3738b78ab2d1a28edda
+
+Signed-off-by: William Irwin <wli@holomorphy.com>
+Acked-by: Mikael Pettersson <mikpe@it.uu.se>
+Signed-off-by: Len Brown <len.brown@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/acpi/video.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/acpi/video.c
++++ b/drivers/acpi/video.c
+@@ -573,7 +573,7 @@ static void acpi_video_device_find_cap(s
+       struct acpi_video_device_brightness *br = NULL;
+-      memset(&device->cap, 0, 4);
++      memset(&device->cap, 0, sizeof(device->cap));
+       if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_ADR", &h_dummy1))) {
+               device->cap._ADR = 1;
+@@ -693,7 +693,7 @@ static void acpi_video_bus_find_cap(stru
+ {
+       acpi_handle h_dummy1;
+-      memset(&video->cap, 0, 4);
++      memset(&video->cap, 0, sizeof(video->cap));
+       if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) {
+               video->cap._DOS = 1;
+       }
diff --git a/queue-2.6.23/dm-crypt-fix-write-endio.patch b/queue-2.6.23/dm-crypt-fix-write-endio.patch
new file mode 100644 (file)
index 0000000..19714fa
--- /dev/null
@@ -0,0 +1,48 @@
+From stable-bounces@linux.kernel.org Thu Dec 13 06:43:32 2007
+From: Milan Broz <mbroz@redhat.com>
+Date: Thu, 13 Dec 2007 14:43:05 +0000
+Subject: dm crypt: fix write endio
+To: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: dm-crypt@saout.de, stable@kernel.org, dm-devel@redhat.com, linux-kernel@vger.kernel.org, Milan Broz <mbroz@redhat.com>
+Message-ID: <20071213144305.GV24157@agk.fab.redhat.com>
+Content-Disposition: inline
+
+
+From: Milan Broz <mbroz@redhat.com>
+
+patch adfe47702c4726b3e045f9f83178def02833be4c in mainline.
+
+Fix BIO_UPTODATE test for write io.
+
+Signed-off-by: Milan Broz <mbroz@redhat.com>
+Signed-off-by: Alasdair G Kergon <agk@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/md/dm-crypt.c |    7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/md/dm-crypt.c
++++ b/drivers/md/dm-crypt.c
+@@ -515,6 +515,9 @@ static int crypt_endio(struct bio *clone
+       struct crypt_config *cc = io->target->private;
+       unsigned read_io = bio_data_dir(clone) == READ;
++      if (unlikely(!bio_flagged(clone, BIO_UPTODATE) && !error))
++              error = -EIO;
++
+       /*
+        * free the processed pages, even if
+        * it's only a partially completed write
+@@ -529,10 +532,8 @@ static int crypt_endio(struct bio *clone
+       if (!read_io)
+               goto out;
+-      if (unlikely(!bio_flagged(clone, BIO_UPTODATE))) {
+-              error = -EIO;
++      if (unlikely(error))
+               goto out;
+-      }
+       bio_put(clone);
+       io->post_process = 1;
diff --git a/queue-2.6.23/dm-crypt-use-bio_add_page.patch b/queue-2.6.23/dm-crypt-use-bio_add_page.patch
new file mode 100644 (file)
index 0000000..437cd17
--- /dev/null
@@ -0,0 +1,86 @@
+From stable-bounces@linux.kernel.org Thu Dec 13 06:44:53 2007
+From: Milan Broz <mbroz@redhat.com>
+Date: Thu, 13 Dec 2007 14:44:18 +0000
+Subject: dm crypt: use bio_add_page
+To: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: dm-crypt@saout.de, stable@kernel.org, dm-devel@redhat.com, linux-kernel@vger.kernel.org, Milan Broz <mbroz@redhat.com>
+Message-ID: <20071213144418.GY24157@agk.fab.redhat.com>
+Content-Disposition: inline
+
+
+From: Milan Broz <mbroz@redhat.com>
+
+patch 91e106259214b40e992a58fb9417da46868e19b2 in mainline.
+
+Fix possible max_phys_segments violation in cloned dm-crypt bio.
+
+In write operation dm-crypt needs to allocate new bio request
+and run crypto operation on this clone. Cloned request has always
+the same size, but number of physical segments can be increased
+and violate max_phys_segments restriction.
+
+This can lead to data corruption and serious hardware malfunction.
+This was observed when using XFS over dm-crypt and at least
+two HBA controller drivers (arcmsr, cciss) recently.
+
+Fix it by using bio_add_page() call (which tests for other
+restrictions too) instead of constructing own biovec.
+
+All versions of dm-crypt are affected by this bug.
+
+Signed-off-by: Milan Broz <mbroz@redhat.com>
+Signed-off-by: Alasdair G Kergon <agk@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/md/dm-crypt.c |   24 +++++++++++-------------
+ 1 file changed, 11 insertions(+), 13 deletions(-)
+
+--- a/drivers/md/dm-crypt.c
++++ b/drivers/md/dm-crypt.c
+@@ -399,7 +399,8 @@ static struct bio *crypt_alloc_buffer(st
+       struct bio *clone;
+       unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+       gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM;
+-      unsigned int i;
++      unsigned i, len;
++      struct page *page;
+       clone = bio_alloc_bioset(GFP_NOIO, nr_iovecs, cc->bs);
+       if (!clone)
+@@ -408,10 +409,8 @@ static struct bio *crypt_alloc_buffer(st
+       clone_init(io, clone);
+       for (i = 0; i < nr_iovecs; i++) {
+-              struct bio_vec *bv = bio_iovec_idx(clone, i);
+-
+-              bv->bv_page = mempool_alloc(cc->page_pool, gfp_mask);
+-              if (!bv->bv_page)
++              page = mempool_alloc(cc->page_pool, gfp_mask);
++              if (!page)
+                       break;
+               /*
+@@ -422,15 +421,14 @@ static struct bio *crypt_alloc_buffer(st
+               if (i == (MIN_BIO_PAGES - 1))
+                       gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT;
+-              bv->bv_offset = 0;
+-              if (size > PAGE_SIZE)
+-                      bv->bv_len = PAGE_SIZE;
+-              else
+-                      bv->bv_len = size;
++              len = (size > PAGE_SIZE) ? PAGE_SIZE : size;
++
++              if (!bio_add_page(clone, page, len, 0)) {
++                      mempool_free(page, cc->page_pool);
++                      break;
++              }
+-              clone->bi_size += bv->bv_len;
+-              clone->bi_vcnt++;
+-              size -= bv->bv_len;
++              size -= len;
+       }
+       if (!clone->bi_size) {
diff --git a/queue-2.6.23/dm-table-detect-io-beyond-device.patch b/queue-2.6.23/dm-table-detect-io-beyond-device.patch
new file mode 100644 (file)
index 0000000..d16b8a4
--- /dev/null
@@ -0,0 +1,195 @@
+From stable-bounces@linux.kernel.org Thu Dec 13 06:42:48 2007
+From: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
+Date: Thu, 13 Dec 2007 14:42:08 +0000
+Subject: dm: table detect io beyond device
+To: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: "Jun'ichi Nomura" <j-nomura@ce.jp.nec.com>, dm-devel@redhat.com, linux-kernel@vger.kernel.org, stable@kernel.org
+Message-ID: <20071213144208.GT24157@agk.fab.redhat.com>
+Content-Disposition: inline
+
+
+From: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
+
+Patch 512875bd9661368da6f993205a61213b79ba1df0 in mainline.
+
+This patch fixes a panic on shrinking a DM device if there is
+outstanding I/O to the part of the device that is being removed.
+(Normally this doesn't happen - a filesystem would be resized first,
+for example.)
+
+The bug is that __clone_and_map() assumes dm_table_find_target()
+always returns a valid pointer.  It may fail if a bio arrives from the
+block layer but its target sector is no longer included in the DM
+btree.
+
+This patch appends an empty entry to table->targets[] which will
+be returned by a lookup beyond the end of the device.
+
+After calling dm_table_find_target(), __clone_and_map() and target_message()
+check for this condition using 
+dm_target_is_valid().
+
+Sample test script to trigger oops:
+
+#!/bin/bash
+
+FILE=$(mktemp)
+LODEV=$(losetup -f)
+MAP=$(basename ${FILE})
+SIZE=4M
+
+dd if=/dev/zero of=${FILE} bs=${SIZE} count=1
+losetup ${LODEV} ${FILE}
+
+echo "0 $(blockdev --getsz ${LODEV}) linear ${LODEV} 0" |dmsetup create ${MAP}
+dmsetup suspend ${MAP}
+echo "0 1 linear ${LODEV} 0" |dmsetup load ${MAP}
+dd if=/dev/zero of=/dev/mapper/${MAP} bs=${SIZE} count=1 &
+echo "Wait til dd push some I/O"
+sleep 5
+dmsetup resume ${MAP}
+
+Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
+Signed-off-by: Alasdair G Kergon <agk@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/md/dm-ioctl.c |   10 +++-------
+ drivers/md/dm-table.c |    7 ++++++-
+ drivers/md/dm.c       |   24 ++++++++++++++++++------
+ drivers/md/dm.h       |    5 +++++
+ 4 files changed, 32 insertions(+), 14 deletions(-)
+
+--- a/drivers/md/dm-ioctl.c
++++ b/drivers/md/dm-ioctl.c
+@@ -1250,21 +1250,17 @@ static int target_message(struct dm_ioct
+       if (!table)
+               goto out_argv;
+-      if (tmsg->sector >= dm_table_get_size(table)) {
++      ti = dm_table_find_target(table, tmsg->sector);
++      if (!dm_target_is_valid(ti)) {
+               DMWARN("Target message sector outside device.");
+               r = -EINVAL;
+-              goto out_table;
+-      }
+-
+-      ti = dm_table_find_target(table, tmsg->sector);
+-      if (ti->type->message)
++      } else if (ti->type->message)
+               r = ti->type->message(ti, argc, argv);
+       else {
+               DMWARN("Target type does not support messages");
+               r = -EINVAL;
+       }
+- out_table:
+       dm_table_put(table);
+  out_argv:
+       kfree(argv);
+--- a/drivers/md/dm-table.c
++++ b/drivers/md/dm-table.c
+@@ -187,8 +187,10 @@ static int alloc_targets(struct dm_table
+       /*
+        * Allocate both the target array and offset array at once.
++       * Append an empty entry to catch sectors beyond the end of
++       * the device.
+        */
+-      n_highs = (sector_t *) dm_vcalloc(num, sizeof(struct dm_target) +
++      n_highs = (sector_t *) dm_vcalloc(num + 1, sizeof(struct dm_target) +
+                                         sizeof(sector_t));
+       if (!n_highs)
+               return -ENOMEM;
+@@ -862,6 +864,9 @@ struct dm_target *dm_table_get_target(st
+ /*
+  * Search the btree for the correct target.
++ *
++ * Caller should check returned pointer with dm_target_is_valid()
++ * to trap I/O beyond end of device.
+  */
+ struct dm_target *dm_table_find_target(struct dm_table *t, sector_t sector)
+ {
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -663,13 +663,19 @@ static struct bio *clone_bio(struct bio 
+       return clone;
+ }
+-static void __clone_and_map(struct clone_info *ci)
++static int __clone_and_map(struct clone_info *ci)
+ {
+       struct bio *clone, *bio = ci->bio;
+-      struct dm_target *ti = dm_table_find_target(ci->map, ci->sector);
+-      sector_t len = 0, max = max_io_len(ci->md, ci->sector, ti);
++      struct dm_target *ti;
++      sector_t len = 0, max;
+       struct dm_target_io *tio;
++      ti = dm_table_find_target(ci->map, ci->sector);
++      if (!dm_target_is_valid(ti))
++              return -EIO;
++
++      max = max_io_len(ci->md, ci->sector, ti);
++
+       /*
+        * Allocate a target io object.
+        */
+@@ -727,6 +733,9 @@ static void __clone_and_map(struct clone
+               do {
+                       if (offset) {
+                               ti = dm_table_find_target(ci->map, ci->sector);
++                              if (!dm_target_is_valid(ti))
++                                      return -EIO;
++
+                               max = max_io_len(ci->md, ci->sector, ti);
+                               tio = alloc_tio(ci->md);
+@@ -750,6 +759,8 @@ static void __clone_and_map(struct clone
+               ci->idx++;
+       }
++
++      return 0;
+ }
+ /*
+@@ -758,6 +769,7 @@ static void __clone_and_map(struct clone
+ static void __split_bio(struct mapped_device *md, struct bio *bio)
+ {
+       struct clone_info ci;
++      int error = 0;
+       ci.map = dm_get_table(md);
+       if (!ci.map) {
+@@ -777,11 +789,11 @@ static void __split_bio(struct mapped_de
+       ci.idx = bio->bi_idx;
+       start_io_acct(ci.io);
+-      while (ci.sector_count)
+-              __clone_and_map(&ci);
++      while (ci.sector_count && !error)
++              error = __clone_and_map(&ci);
+       /* drop the extra reference count */
+-      dec_pending(ci.io, 0);
++      dec_pending(ci.io, error);
+       dm_table_put(ci.map);
+ }
+ /*-----------------------------------------------------------------
+--- a/drivers/md/dm.h
++++ b/drivers/md/dm.h
+@@ -113,6 +113,11 @@ int dm_table_any_congested(struct dm_tab
+ void dm_table_unplug_all(struct dm_table *t);
+ int dm_table_flush_all(struct dm_table *t);
++/*
++ * To check the return value from dm_table_find_target().
++ */
++#define dm_target_is_valid(t) ((t)->table)
++
+ /*-----------------------------------------------------------------
+  * A registry of target types.
+  *---------------------------------------------------------------*/
diff --git a/queue-2.6.23/series b/queue-2.6.23/series
new file mode 100644 (file)
index 0000000..7c09e32
--- /dev/null
@@ -0,0 +1,5 @@
+dm-table-detect-io-beyond-device.patch
+dm-crypt-fix-write-endio.patch
+dm-crypt-use-bio_add_page.patch
+acpi-video_device_list-corruption.patch
+acpi-thinkpad-acpi-fix-lenovo-keymap-for-brightness.patch