From 576197a5ec84bde5889d4ac0df69aa427aa61f48 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 23 Oct 2008 13:51:33 -0700 Subject: [PATCH] start up the 2.6.27 queue --- ...ed-illegal_device_table_entry-errors.patch | 45 ++++ ...ly-lock-even-newly-allocated-entries.patch | 104 ++++++++ ...ng-of-resume-key-before-cifsfindnext.patch | 46 ++++ ...xception-store-fix-misordered-writes.patch | 51 ++++ ...m-exception-store-refactor-zero_area.patch | 220 ++++++++++++++++ .../dm-kcopyd-avoid-queue-shuffle.patch | 102 ++++++++ .../dm-snapshot-fix-primary_pe-race.patch | 109 ++++++++ .../edac-cell-fix-incorrect-edac_mode.patch | 36 +++ ...-in-the-face-of-directory-corruption.patch | 247 ++++++++++++++++++ ...-fix-oops-in-gpio_get_value_cansleep.patch | 58 ++++ ...e-fix-free_irq-in-spinlocked-section.patch | 62 +++++ ...lost-ifdef-guarding-defrag-exception.patch | 48 ++++ ...-nat-leaks-memory-in-case-of-failure.patch | 31 +++ ...xt_iprange-fix-range-inversion-match.patch | 63 +++++ ...module.h-triggers-a-compiler-warning.patch | 57 ++++ .../sched-fix-the-wrong-mask_len.patch | 35 +++ queue-2.6.27/series | 21 ++ ...sb-cdc-wdm-make-module-autoload-work.patch | 32 +++ ...drivers-after-failed-resume-or-reset.patch | 53 ++++ .../usb-fix-memory-leak-in-cdc-acm.patch | 36 +++ ...dd-pre_reset-and-post_reset-routines.patch | 53 ++++ ...on-64-bit-up-systems-with-smp-kernel.patch | 58 ++++ 22 files changed, 1567 insertions(+) create mode 100644 queue-2.6.27/amd_iommu-fix-nasty-bug-that-caused-illegal_device_table_entry-errors.patch create mode 100644 queue-2.6.27/anon_vma_prepare-properly-lock-even-newly-allocated-entries.patch create mode 100644 queue-2.6.27/cifs-fix-saving-of-resume-key-before-cifsfindnext.patch create mode 100644 queue-2.6.27/dm-exception-store-fix-misordered-writes.patch create mode 100644 queue-2.6.27/dm-exception-store-refactor-zero_area.patch create mode 100644 queue-2.6.27/dm-kcopyd-avoid-queue-shuffle.patch create mode 100644 queue-2.6.27/dm-snapshot-fix-primary_pe-race.patch create mode 100644 queue-2.6.27/edac-cell-fix-incorrect-edac_mode.patch create mode 100644 queue-2.6.27/ext-avoid-printk-floods-in-the-face-of-directory-corruption.patch create mode 100644 queue-2.6.27/gpiolib-fix-oops-in-gpio_get_value_cansleep.patch create mode 100644 queue-2.6.27/hvc_console-fix-free_irq-in-spinlocked-section.patch create mode 100644 queue-2.6.27/netfilter-restore-lost-ifdef-guarding-defrag-exception.patch create mode 100644 queue-2.6.27/netfilter-snmp-nat-leaks-memory-in-case-of-failure.patch create mode 100644 queue-2.6.27/netfilter-xt_iprange-fix-range-inversion-match.patch create mode 100644 queue-2.6.27/regression-inclusion-of-linux-module.h-triggers-a-compiler-warning.patch create mode 100644 queue-2.6.27/sched-fix-the-wrong-mask_len.patch create mode 100644 queue-2.6.27/series create mode 100644 queue-2.6.27/usb-cdc-wdm-make-module-autoload-work.patch create mode 100644 queue-2.6.27/usb-don-t-rebind-drivers-after-failed-resume-or-reset.patch create mode 100644 queue-2.6.27/usb-fix-memory-leak-in-cdc-acm.patch create mode 100644 queue-2.6.27/usb-speedtouch-add-pre_reset-and-post_reset-routines.patch create mode 100644 queue-2.6.27/x86-acpi-fix-breakage-of-resume-on-64-bit-up-systems-with-smp-kernel.patch diff --git a/queue-2.6.27/amd_iommu-fix-nasty-bug-that-caused-illegal_device_table_entry-errors.patch b/queue-2.6.27/amd_iommu-fix-nasty-bug-that-caused-illegal_device_table_entry-errors.patch new file mode 100644 index 00000000000..8ad1fe60248 --- /dev/null +++ b/queue-2.6.27/amd_iommu-fix-nasty-bug-that-caused-illegal_device_table_entry-errors.patch @@ -0,0 +1,45 @@ +From jejb@kernel.org Thu Oct 23 13:11:21 2008 +From: Andreas Herrmann +Date: Thu, 23 Oct 2008 17:35:28 GMT +Subject: amd_iommu: fix nasty bug that caused ILLEGAL_DEVICE_TABLE_ENTRY errors +To: jejb@kernel.org, stable@kernel.org +Message-ID: <200810231735.m9NHZSI0008803@hera.kernel.org> + +From: Andreas Herrmann + +commit f609891f428e1c20e270e7c350daf8c93cc459d7 upstream + +We are on 64-bit so better use u64 instead of u32 to deal with +addresses: + +static void __init iommu_set_device_table(struct amd_iommu *iommu) +{ + u64 entry; + ... + entry = virt_to_phys(amd_iommu_dev_table); + ... + +(I am wondering why gcc 4.2.x did not warn about the assignment +between u32 and unsigned long.) + +Cc: iommu@lists.linux-foundation.org +Signed-off-by: Andreas Herrmann +Signed-off-by: Joerg Roedel +Signed-off-by: David Woodhouse +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/amd_iommu_init.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/kernel/amd_iommu_init.c ++++ b/arch/x86/kernel/amd_iommu_init.c +@@ -210,7 +210,7 @@ static void __init iommu_set_exclusion_r + /* Programs the physical address of the device table into the IOMMU hardware */ + static void __init iommu_set_device_table(struct amd_iommu *iommu) + { +- u32 entry; ++ u64 entry; + + BUG_ON(iommu->mmio_base == NULL); + diff --git a/queue-2.6.27/anon_vma_prepare-properly-lock-even-newly-allocated-entries.patch b/queue-2.6.27/anon_vma_prepare-properly-lock-even-newly-allocated-entries.patch new file mode 100644 index 00000000000..6803884c805 --- /dev/null +++ b/queue-2.6.27/anon_vma_prepare-properly-lock-even-newly-allocated-entries.patch @@ -0,0 +1,104 @@ +From d9d332e0874f46b91d8ac4604b68ee42b8a7a2c6 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Sun, 19 Oct 2008 10:32:20 -0700 +Subject: anon_vma_prepare: properly lock even newly allocated entries + +From: Linus Torvalds + +commit d9d332e0874f46b91d8ac4604b68ee42b8a7a2c6 upstream + +The anon_vma code is very subtle, and we end up doing optimistic lookups +of anon_vmas under RCU in page_lock_anon_vma() with no locking. Other +CPU's can also see the newly allocated entry immediately after we've +exposed it by setting "vma->anon_vma" to the new value. + +We protect against the anon_vma being destroyed by having the SLAB +marked as SLAB_DESTROY_BY_RCU, so the RCU lookup can depend on the +allocation not being destroyed - but it might still be free'd and +re-allocated here to a new vma. + +As a result, we should not do the anon_vma list ops on a newly allocated +vma without proper locking. + +Acked-by: Nick Piggin +Acked-by: Hugh Dickins +Acked-by: Peter Zijlstra +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/rmap.c | 42 ++++++++++++++++++++++++++++++++---------- + 1 file changed, 32 insertions(+), 10 deletions(-) + +--- a/mm/rmap.c ++++ b/mm/rmap.c +@@ -55,7 +55,33 @@ + + struct kmem_cache *anon_vma_cachep; + +-/* This must be called under the mmap_sem. */ ++/** ++ * anon_vma_prepare - attach an anon_vma to a memory region ++ * @vma: the memory region in question ++ * ++ * This makes sure the memory mapping described by 'vma' has ++ * an 'anon_vma' attached to it, so that we can associate the ++ * anonymous pages mapped into it with that anon_vma. ++ * ++ * The common case will be that we already have one, but if ++ * if not we either need to find an adjacent mapping that we ++ * can re-use the anon_vma from (very common when the only ++ * reason for splitting a vma has been mprotect()), or we ++ * allocate a new one. ++ * ++ * Anon-vma allocations are very subtle, because we may have ++ * optimistically looked up an anon_vma in page_lock_anon_vma() ++ * and that may actually touch the spinlock even in the newly ++ * allocated vma (it depends on RCU to make sure that the ++ * anon_vma isn't actually destroyed). ++ * ++ * As a result, we need to do proper anon_vma locking even ++ * for the new allocation. At the same time, we do not want ++ * to do any locking for the common case of already having ++ * an anon_vma. ++ * ++ * This must be called with the mmap_sem held for reading. ++ */ + int anon_vma_prepare(struct vm_area_struct *vma) + { + struct anon_vma *anon_vma = vma->anon_vma; +@@ -63,20 +89,17 @@ int anon_vma_prepare(struct vm_area_stru + might_sleep(); + if (unlikely(!anon_vma)) { + struct mm_struct *mm = vma->vm_mm; +- struct anon_vma *allocated, *locked; ++ struct anon_vma *allocated; + + anon_vma = find_mergeable_anon_vma(vma); +- if (anon_vma) { +- allocated = NULL; +- locked = anon_vma; +- spin_lock(&locked->lock); +- } else { ++ allocated = NULL; ++ if (!anon_vma) { + anon_vma = anon_vma_alloc(); + if (unlikely(!anon_vma)) + return -ENOMEM; + allocated = anon_vma; +- locked = NULL; + } ++ spin_lock(&anon_vma->lock); + + /* page_table_lock to protect against threads */ + spin_lock(&mm->page_table_lock); +@@ -87,8 +110,7 @@ int anon_vma_prepare(struct vm_area_stru + } + spin_unlock(&mm->page_table_lock); + +- if (locked) +- spin_unlock(&locked->lock); ++ spin_unlock(&anon_vma->lock); + if (unlikely(allocated)) + anon_vma_free(allocated); + } diff --git a/queue-2.6.27/cifs-fix-saving-of-resume-key-before-cifsfindnext.patch b/queue-2.6.27/cifs-fix-saving-of-resume-key-before-cifsfindnext.patch new file mode 100644 index 00000000000..08270610d88 --- /dev/null +++ b/queue-2.6.27/cifs-fix-saving-of-resume-key-before-cifsfindnext.patch @@ -0,0 +1,46 @@ +From jejb@kernel.org Thu Oct 23 13:12:20 2008 +From: Jeff Layton +Date: Thu, 23 Oct 2008 18:05:02 GMT +Subject: CIFS: fix saving of resume key before CIFSFindNext +To: jejb@kernel.org, stable@kernel.org +Message-ID: <200810231805.m9NI526B029178@hera.kernel.org> + +From: Jeff Layton + +commit a364bc0b37f14ffd66c1f982af42990a9d77fa43 upstream + +We recently fixed the cifs readdir code so that it saves the resume key +before calling CIFSFindNext. Unfortunately, this assumes that we have +just done a CIFSFindFirst (or FindNext) and have resume info to save. +This isn't necessarily the case. Fix the code to save resume info if we +had to reinitiate the search, and after a FindNext. + +This fixes connectathon basic test6 against NetApp filers. + +Signed-off-by: Jeff Layton +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/readdir.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/cifs/readdir.c ++++ b/fs/cifs/readdir.c +@@ -762,14 +762,15 @@ static int find_cifs_entry(const int xid + rc)); + return rc; + } ++ cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile); + } + + while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) && + (rc == 0) && !cifsFile->srch_inf.endOfSearch) { + cFYI(1, ("calling findnext2")); +- cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile); + rc = CIFSFindNext(xid, pTcon, cifsFile->netfid, + &cifsFile->srch_inf); ++ cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile); + if (rc) + return -ENOENT; + } diff --git a/queue-2.6.27/dm-exception-store-fix-misordered-writes.patch b/queue-2.6.27/dm-exception-store-fix-misordered-writes.patch new file mode 100644 index 00000000000..16654828b76 --- /dev/null +++ b/queue-2.6.27/dm-exception-store-fix-misordered-writes.patch @@ -0,0 +1,51 @@ +From jejb@kernel.org Thu Oct 23 13:10:46 2008 +From: Mikulas Patocka +Date: Thu, 23 Oct 2008 17:35:17 GMT +Subject: dm exception store: fix misordered writes +To: jejb@kernel.org, stable@kernel.org +Message-ID: <200810231735.m9NHZHnu008554@hera.kernel.org> + +From: Mikulas Patocka + +commit 7acedc5b98a2fcff64f00c21110aae7d3ac2f7df upstream + +We must zero the next chunk on disk *before* writing out the current chunk, not +after. Otherwise if the machine crashes at the wrong time, the "end of metadata" +marker may be missing. + +Signed-off-by: Mikulas Patocka +Signed-off-by: Alasdair G Kergon +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-exception-store.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/drivers/md/dm-exception-store.c ++++ b/drivers/md/dm-exception-store.c +@@ -603,17 +603,22 @@ static void persistent_commit(struct exc + return; + + /* ++ * If we completely filled the current area, then wipe the next one. ++ */ ++ if ((ps->current_committed == ps->exceptions_per_area) && ++ zero_disk_area(ps, ps->current_area + 1)) ++ ps->valid = 0; ++ ++ /* + * Commit exceptions to disk. + */ +- if (area_io(ps, WRITE)) ++ if (ps->valid && area_io(ps, WRITE)) + ps->valid = 0; + + /* + * Advance to the next area if this one is full. + */ + if (ps->current_committed == ps->exceptions_per_area) { +- if (zero_disk_area(ps, ps->current_area + 1)) +- ps->valid = 0; + ps->current_committed = 0; + ps->current_area++; + zero_memory_area(ps); diff --git a/queue-2.6.27/dm-exception-store-refactor-zero_area.patch b/queue-2.6.27/dm-exception-store-refactor-zero_area.patch new file mode 100644 index 00000000000..3763c8fae95 --- /dev/null +++ b/queue-2.6.27/dm-exception-store-refactor-zero_area.patch @@ -0,0 +1,220 @@ +From jejb@kernel.org Thu Oct 23 13:05:28 2008 +From: Alasdair G Kergon +Date: Thu, 23 Oct 2008 17:35:19 GMT +Subject: dm exception store: refactor zero_area +To: jejb@kernel.org, stable@kernel.org +Message-ID: <200810231735.m9NHZJcS008600@hera.kernel.org> + +From: Alasdair G Kergon + +commit 7c9e6c17325fab380fbe9c9787680ff7d4a51abd upstream + +Use a separate buffer for writing zeroes to the on-disk snapshot +exception store, make the updating of ps->current_area explicit and +refactor the code in preparation for the fix in the next patch. + +No functional change. + +Signed-off-by: Alasdair G Kergon +Signed-off-by: Mikulas Patocka +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-exception-store.c | 103 ++++++++++++++++++++++++++-------------- + 1 file changed, 69 insertions(+), 34 deletions(-) + +--- a/drivers/md/dm-exception-store.c ++++ b/drivers/md/dm-exception-store.c +@@ -105,6 +105,11 @@ struct pstore { + void *area; + + /* ++ * An area of zeros used to clear the next area. ++ */ ++ void *zero_area; ++ ++ /* + * Used to keep track of which metadata area the data in + * 'chunk' refers to. + */ +@@ -149,6 +154,13 @@ static int alloc_area(struct pstore *ps) + if (!ps->area) + return r; + ++ ps->zero_area = vmalloc(len); ++ if (!ps->zero_area) { ++ vfree(ps->area); ++ return r; ++ } ++ memset(ps->zero_area, 0, len); ++ + return 0; + } + +@@ -156,6 +168,8 @@ static void free_area(struct pstore *ps) + { + vfree(ps->area); + ps->area = NULL; ++ vfree(ps->zero_area); ++ ps->zero_area = NULL; + } + + struct mdata_req { +@@ -212,13 +226,13 @@ static int chunk_io(struct pstore *ps, u + * Read or write a metadata area. Remembering to skip the first + * chunk which holds the header. + */ +-static int area_io(struct pstore *ps, uint32_t area, int rw) ++static int area_io(struct pstore *ps, int rw) + { + int r; + uint32_t chunk; + + /* convert a metadata area index to a chunk index */ +- chunk = 1 + ((ps->exceptions_per_area + 1) * area); ++ chunk = area_location(ps, ps->current_area); + + r = chunk_io(ps, chunk, rw, 0); + if (r) +@@ -228,10 +242,27 @@ static int area_io(struct pstore *ps, ui + return 0; + } + +-static int zero_area(struct pstore *ps, uint32_t area) ++static void zero_memory_area(struct pstore *ps) + { + memset(ps->area, 0, ps->snap->chunk_size << SECTOR_SHIFT); +- return area_io(ps, area, WRITE); ++} ++ ++static int zero_disk_area(struct pstore *ps, chunk_t area) ++{ ++ struct dm_io_region where = { ++ .bdev = ps->snap->cow->bdev, ++ .sector = ps->snap->chunk_size * area_location(ps, area), ++ .count = ps->snap->chunk_size, ++ }; ++ struct dm_io_request io_req = { ++ .bi_rw = WRITE, ++ .mem.type = DM_IO_VMA, ++ .mem.ptr.vma = ps->zero_area, ++ .client = ps->io_client, ++ .notify.fn = NULL, ++ }; ++ ++ return dm_io(&io_req, 1, &where, NULL); + } + + static int read_header(struct pstore *ps, int *new_snapshot) +@@ -404,15 +435,14 @@ static int insert_exceptions(struct psto + + static int read_exceptions(struct pstore *ps) + { +- uint32_t area; + int r, full = 1; + + /* + * Keeping reading chunks and inserting exceptions until + * we find a partially full area. + */ +- for (area = 0; full; area++) { +- r = area_io(ps, area, READ); ++ for (ps->current_area = 0; full; ps->current_area++) { ++ r = area_io(ps, READ); + if (r) + return r; + +@@ -421,6 +451,8 @@ static int read_exceptions(struct pstore + return r; + } + ++ ps->current_area--; ++ + return 0; + } + +@@ -479,12 +511,13 @@ static int persistent_read_metadata(stru + return r; + } + +- r = zero_area(ps, 0); ++ ps->current_area = 0; ++ zero_memory_area(ps); ++ r = zero_disk_area(ps, 0); + if (r) { +- DMWARN("zero_area(0) failed"); ++ DMWARN("zero_disk_area(0) failed"); + return r; + } +- + } else { + /* + * Sanity checks. +@@ -542,7 +575,6 @@ static void persistent_commit(struct exc + void (*callback) (void *, int success), + void *callback_context) + { +- int r; + unsigned int i; + struct pstore *ps = get_info(store); + struct disk_exception de; +@@ -563,33 +595,36 @@ static void persistent_commit(struct exc + cb->context = callback_context; + + /* +- * If there are no more exceptions in flight, or we have +- * filled this metadata area we commit the exceptions to +- * disk. +- */ +- if (atomic_dec_and_test(&ps->pending_count) || +- (ps->current_committed == ps->exceptions_per_area)) { +- r = area_io(ps, ps->current_area, WRITE); +- if (r) +- ps->valid = 0; ++ * If there are exceptions in flight and we have not yet ++ * filled this metadata area there's nothing more to do. ++ */ ++ if (!atomic_dec_and_test(&ps->pending_count) && ++ (ps->current_committed != ps->exceptions_per_area)) ++ return; + +- /* +- * Have we completely filled the current area ? +- */ +- if (ps->current_committed == ps->exceptions_per_area) { +- ps->current_committed = 0; +- r = zero_area(ps, ps->current_area + 1); +- if (r) +- ps->valid = 0; +- } ++ /* ++ * Commit exceptions to disk. ++ */ ++ if (area_io(ps, WRITE)) ++ ps->valid = 0; + +- for (i = 0; i < ps->callback_count; i++) { +- cb = ps->callbacks + i; +- cb->callback(cb->context, r == 0 ? 1 : 0); +- } ++ /* ++ * Advance to the next area if this one is full. ++ */ ++ if (ps->current_committed == ps->exceptions_per_area) { ++ if (zero_disk_area(ps, ps->current_area + 1)) ++ ps->valid = 0; ++ ps->current_committed = 0; ++ ps->current_area++; ++ zero_memory_area(ps); ++ } + +- ps->callback_count = 0; ++ for (i = 0; i < ps->callback_count; i++) { ++ cb = ps->callbacks + i; ++ cb->callback(cb->context, ps->valid); + } ++ ++ ps->callback_count = 0; + } + + static void persistent_drop(struct exception_store *store) diff --git a/queue-2.6.27/dm-kcopyd-avoid-queue-shuffle.patch b/queue-2.6.27/dm-kcopyd-avoid-queue-shuffle.patch new file mode 100644 index 00000000000..6c3b97db8c4 --- /dev/null +++ b/queue-2.6.27/dm-kcopyd-avoid-queue-shuffle.patch @@ -0,0 +1,102 @@ +From jejb@kernel.org Thu Oct 23 13:06:15 2008 +From: Kazuo Ito +Date: Thu, 23 Oct 2008 17:35:24 GMT +Subject: dm kcopyd: avoid queue shuffle +To: jejb@kernel.org, stable@kernel.org +Message-ID: <200810231735.m9NHZOgW008656@hera.kernel.org> + +From: Kazuo Ito + +commit b673c3a8192e28f13e2050a4b82c1986be92cc15 upstream + +Write throughput to LVM snapshot origin volume is an order +of magnitude slower than those to LV without snapshots or +snapshot target volumes, especially in the case of sequential +writes with O_SYNC on. + +The following patch originally written by Kevin Jamieson and +Jan Blunck and slightly modified for the current RCs by myself +tries to improve the performance by modifying the behaviour +of kcopyd, so that it pushes back an I/O job to the head of +the job queue instead of the tail as process_jobs() currently +does when it has to wait for free pages. This way, write +requests aren't shuffled to cause extra seeks. + +I tested the patch against 2.6.27-rc5 and got the following results. +The test is a dd command writing to snapshot origin followed by fsync +to the file just created/updated. A couple of filesystem benchmarks +gave me similar results in case of sequential writes, while random +writes didn't suffer much. + +dd if=/dev/zero of= bs=4096 count=... + [conv=notrunc when updating] + +1) linux 2.6.27-rc5 without the patch, write to snapshot origin, +average throughput (MB/s) + 10M 100M 1000M +create,dd 511.46 610.72 11.81 +create,dd+fsync 7.10 6.77 8.13 +update,dd 431.63 917.41 12.75 +update,dd+fsync 7.79 7.43 8.12 + +compared with write throughput to LV without any snapshots, +all dd+fsync and 1000 MiB writes perform very poorly. + + 10M 100M 1000M +create,dd 555.03 608.98 123.29 +create,dd+fsync 114.27 72.78 76.65 +update,dd 152.34 1267.27 124.04 +update,dd+fsync 130.56 77.81 77.84 + +2) linux 2.6.27-rc5 with the patch, write to snapshot origin, +average throughput (MB/s) + + 10M 100M 1000M +create,dd 537.06 589.44 46.21 +create,dd+fsync 31.63 29.19 29.23 +update,dd 487.59 897.65 37.76 +update,dd+fsync 34.12 30.07 26.85 + +Although still not on par with plain LV performance - +cannot be avoided because it's copy on write anyway - +this simple patch successfully improves throughtput +of dd+fsync while not affecting the rest. + +Signed-off-by: Jan Blunck +Signed-off-by: Kazuo Ito +Signed-off-by: Alasdair G Kergon +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-kcopyd.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +--- a/drivers/md/dm-kcopyd.c ++++ b/drivers/md/dm-kcopyd.c +@@ -268,6 +268,17 @@ static void push(struct list_head *jobs, + spin_unlock_irqrestore(&kc->job_lock, flags); + } + ++ ++static void push_head(struct list_head *jobs, struct kcopyd_job *job) ++{ ++ unsigned long flags; ++ struct dm_kcopyd_client *kc = job->kc; ++ ++ spin_lock_irqsave(&kc->job_lock, flags); ++ list_add(&job->list, jobs); ++ spin_unlock_irqrestore(&kc->job_lock, flags); ++} ++ + /* + * These three functions process 1 item from the corresponding + * job list. +@@ -398,7 +409,7 @@ static int process_jobs(struct list_head + * We couldn't service this job ATM, so + * push this job back onto the list. + */ +- push(jobs, job); ++ push_head(jobs, job); + break; + } + diff --git a/queue-2.6.27/dm-snapshot-fix-primary_pe-race.patch b/queue-2.6.27/dm-snapshot-fix-primary_pe-race.patch new file mode 100644 index 00000000000..37f160e9089 --- /dev/null +++ b/queue-2.6.27/dm-snapshot-fix-primary_pe-race.patch @@ -0,0 +1,109 @@ +From jejb@kernel.org Thu Oct 23 13:07:01 2008 +From: Mikulas Patocka +Date: Thu, 23 Oct 2008 17:35:22 GMT +Subject: dm snapshot: fix primary_pe race +To: jejb@kernel.org, stable@kernel.org +Message-ID: <200810231735.m9NHZMDk008629@hera.kernel.org> + +From: Mikulas Patocka + +commit 7c5f78b9d7f21937e46c26db82976df4b459c95c upstream + +Fix a race condition with primary_pe ref_count handling. + +put_pending_exception runs under dm_snapshot->lock, it does atomic_dec_and_test +on primary_pe->ref_count, and later does atomic_read primary_pe->ref_count. + +__origin_write does atomic_dec_and_test on primary_pe->ref_count without holding +dm_snapshot->lock. + +This opens the following race condition: +Assume two CPUs, CPU1 is executing put_pending_exception (and holding +dm_snapshot->lock). CPU2 is executing __origin_write in parallel. +primary_pe->ref_count == 2. + +CPU1: +if (primary_pe && atomic_dec_and_test(&primary_pe->ref_count)) + origin_bios = bio_list_get(&primary_pe->origin_bios); +.. decrements primary_pe->ref_count to 1. Doesn't load origin_bios + +CPU2: +if (first && atomic_dec_and_test(&primary_pe->ref_count)) { + flush_bios(bio_list_get(&primary_pe->origin_bios)); + free_pending_exception(primary_pe); + /* If we got here, pe_queue is necessarily empty. */ + return r; +} +.. decrements primary_pe->ref_count to 0, submits pending bios, frees +primary_pe. + +CPU1: +if (!primary_pe || primary_pe != pe) + free_pending_exception(pe); +.. this has no effect. +if (primary_pe && !atomic_read(&primary_pe->ref_count)) + free_pending_exception(primary_pe); +.. sees ref_count == 0 (written by CPU 2), does double free !! + +This bug can happen only if someone is simultaneously writing to both the +origin and the snapshot. + +If someone is writing only to the origin, __origin_write will submit kcopyd +request after it decrements primary_pe->ref_count (so it can't happen that the +finished copy races with primary_pe->ref_count decrementation). + +If someone is writing only to the snapshot, __origin_write isn't invoked at all +and the race can't happen. + +The race happens when someone writes to the snapshot --- this creates +pending_exception with primary_pe == NULL and starts copying. Then, someone +writes to the same chunk in the snapshot, and __origin_write races with +termination of already submitted request in pending_complete (that calls +put_pending_exception). + +This race may be reason for bugs: + http://bugzilla.kernel.org/show_bug.cgi?id=11636 + https://bugzilla.redhat.com/show_bug.cgi?id=465825 + +The patch fixes the code to make sure that: +1. If atomic_dec_and_test(&primary_pe->ref_count) returns false, the process +must no longer dereference primary_pe (because someone else may free it under +us). +2. If atomic_dec_and_test(&primary_pe->ref_count) returns true, the process +is responsible for freeing primary_pe. + +Signed-off-by: Mikulas Patocka +Signed-off-by: Alasdair G Kergon +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-snap.c | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +--- a/drivers/md/dm-snap.c ++++ b/drivers/md/dm-snap.c +@@ -824,8 +824,10 @@ static struct bio *put_pending_exception + * the bios for the original write to the origin. + */ + if (primary_pe && +- atomic_dec_and_test(&primary_pe->ref_count)) ++ atomic_dec_and_test(&primary_pe->ref_count)) { + origin_bios = bio_list_get(&primary_pe->origin_bios); ++ free_pending_exception(primary_pe); ++ } + + /* + * Free the pe if it's not linked to an origin write or if +@@ -834,12 +836,6 @@ static struct bio *put_pending_exception + if (!primary_pe || primary_pe != pe) + free_pending_exception(pe); + +- /* +- * Free the primary pe if nothing references it. +- */ +- if (primary_pe && !atomic_read(&primary_pe->ref_count)) +- free_pending_exception(primary_pe); +- + return origin_bios; + } + diff --git a/queue-2.6.27/edac-cell-fix-incorrect-edac_mode.patch b/queue-2.6.27/edac-cell-fix-incorrect-edac_mode.patch new file mode 100644 index 00000000000..24370305d83 --- /dev/null +++ b/queue-2.6.27/edac-cell-fix-incorrect-edac_mode.patch @@ -0,0 +1,36 @@ +From jejb@kernel.org Thu Oct 23 12:58:23 2008 +From: Benjamin Herrenschmidt +Date: Mon, 20 Oct 2008 16:50:07 GMT +Subject: edac cell: fix incorrect edac_mode +To: jejb@kernel.org, stable@kernel.org +Message-ID: <200810201650.m9KGo7ld012751@hera.kernel.org> + +From: Benjamin Herrenschmidt + +commit 3b274f44d2ca05f719fe39947b6a5293a2dbd8fd upstream + +The cell_edac driver is setting the edac_mode field of the csrow's to an +incorrect value, causing the sysfs show routine for that field to go out +of an array bound and Oopsing the kernel when used. + +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Doug Thompson +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/edac/cell_edac.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/edac/cell_edac.c ++++ b/drivers/edac/cell_edac.c +@@ -142,7 +142,7 @@ static void __devinit cell_edac_init_csr + csrow->nr_pages = (r.end - r.start + 1) >> PAGE_SHIFT; + csrow->last_page = csrow->first_page + csrow->nr_pages - 1; + csrow->mtype = MEM_XDR; +- csrow->edac_mode = EDAC_FLAG_EC | EDAC_FLAG_SECDED; ++ csrow->edac_mode = EDAC_SECDED; + dev_dbg(mci->dev, + "Initialized on node %d, chanmask=0x%x," + " first_page=0x%lx, nr_pages=0x%x\n", diff --git a/queue-2.6.27/ext-avoid-printk-floods-in-the-face-of-directory-corruption.patch b/queue-2.6.27/ext-avoid-printk-floods-in-the-face-of-directory-corruption.patch new file mode 100644 index 00000000000..f9cf4b5a955 --- /dev/null +++ b/queue-2.6.27/ext-avoid-printk-floods-in-the-face-of-directory-corruption.patch @@ -0,0 +1,247 @@ +From sandeen@redhat.com Thu Oct 23 13:13:44 2008 +From: Eric Sandeen +Date: Wed, 22 Oct 2008 10:11:52 -0500 +Subject: ext[234]: Avoid printk floods in the face of directory corruption (CVE-2008-3528) +To: stable@kernel.org +Cc: ext4 development +Message-ID: <48FF42B8.3030606@redhat.com> + +From: Eric Sandeen + +This is a trivial backport of the following upstream commits: + +- bd39597cbd42a784105a04010100e27267481c67 (ext2) +- cdbf6dba28e8e6268c8420857696309470009fd9 (ext3) +- 9d9f177572d9e4eba0f2e18523b44f90dd51fe74 (ext4) + +This addresses CVE-2008-3528 + +ext[234]: Avoid printk floods in the face of directory corruption + +Note: some people thinks this represents a security bug, since it +might make the system go away while it is printing a large number of +console messages, especially if a serial console is involved. Hence, +it has been assigned CVE-2008-3528, but it requires that the attacker +either has physical access to your machine to insert a USB disk with a +corrupted filesystem image (at which point why not just hit the power +button), or is otherwise able to convince the system administrator to +mount an arbitrary filesystem image (at which point why not just +include a setuid shell or world-writable hard disk device file or some +such). Me, I think they're just being silly. --tytso + +Signed-off-by: Eric Sandeen +Signed-off-by: "Theodore Ts'o" +Cc: linux-ext4@vger.kernel.org +Cc: Eugene Teo +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext2/dir.c | 60 +++++++++++++++++++++++++++++++++------------------------- + fs/ext3/dir.c | 10 ++++++--- + fs/ext4/dir.c | 11 +++++++--- + 3 files changed, 50 insertions(+), 31 deletions(-) + +--- a/fs/ext2/dir.c ++++ b/fs/ext2/dir.c +@@ -103,7 +103,7 @@ static int ext2_commit_chunk(struct page + return err; + } + +-static void ext2_check_page(struct page *page) ++static void ext2_check_page(struct page *page, int quiet) + { + struct inode *dir = page->mapping->host; + struct super_block *sb = dir->i_sb; +@@ -146,10 +146,10 @@ out: + /* Too bad, we had an error */ + + Ebadsize: +- ext2_error(sb, "ext2_check_page", +- "size of directory #%lu is not a multiple of chunk size", +- dir->i_ino +- ); ++ if (!quiet) ++ ext2_error(sb, __func__, ++ "size of directory #%lu is not a multiple " ++ "of chunk size", dir->i_ino); + goto fail; + Eshort: + error = "rec_len is smaller than minimal"; +@@ -166,32 +166,36 @@ Espan: + Einumber: + error = "inode out of bounds"; + bad_entry: +- ext2_error (sb, "ext2_check_page", "bad entry in directory #%lu: %s - " +- "offset=%lu, inode=%lu, rec_len=%d, name_len=%d", +- dir->i_ino, error, (page->index<inode), +- rec_len, p->name_len); ++ if (!quiet) ++ ext2_error(sb, __func__, "bad entry in directory #%lu: : %s - " ++ "offset=%lu, inode=%lu, rec_len=%d, name_len=%d", ++ dir->i_ino, error, (page->index<inode), ++ rec_len, p->name_len); + goto fail; + Eend: +- p = (ext2_dirent *)(kaddr + offs); +- ext2_error (sb, "ext2_check_page", +- "entry in directory #%lu spans the page boundary" +- "offset=%lu, inode=%lu", +- dir->i_ino, (page->index<inode)); ++ if (!quiet) { ++ p = (ext2_dirent *)(kaddr + offs); ++ ext2_error(sb, "ext2_check_page", ++ "entry in directory #%lu spans the page boundary" ++ "offset=%lu, inode=%lu", ++ dir->i_ino, (page->index<inode)); ++ } + fail: + SetPageChecked(page); + SetPageError(page); + } + +-static struct page * ext2_get_page(struct inode *dir, unsigned long n) ++static struct page * ext2_get_page(struct inode *dir, unsigned long n, ++ int quiet) + { + struct address_space *mapping = dir->i_mapping; + struct page *page = read_mapping_page(mapping, n, NULL); + if (!IS_ERR(page)) { + kmap(page); + if (!PageChecked(page)) +- ext2_check_page(page); ++ ext2_check_page(page, quiet); + if (PageError(page)) + goto fail; + } +@@ -292,7 +296,7 @@ ext2_readdir (struct file * filp, void * + for ( ; n < npages; n++, offset = 0) { + char *kaddr, *limit; + ext2_dirent *de; +- struct page *page = ext2_get_page(inode, n); ++ struct page *page = ext2_get_page(inode, n, 0); + + if (IS_ERR(page)) { + ext2_error(sb, __func__, +@@ -361,6 +365,7 @@ struct ext2_dir_entry_2 * ext2_find_entr + struct page *page = NULL; + struct ext2_inode_info *ei = EXT2_I(dir); + ext2_dirent * de; ++ int dir_has_error = 0; + + if (npages == 0) + goto out; +@@ -374,7 +379,7 @@ struct ext2_dir_entry_2 * ext2_find_entr + n = start; + do { + char *kaddr; +- page = ext2_get_page(dir, n); ++ page = ext2_get_page(dir, n, dir_has_error); + if (!IS_ERR(page)) { + kaddr = page_address(page); + de = (ext2_dirent *) kaddr; +@@ -391,7 +396,9 @@ struct ext2_dir_entry_2 * ext2_find_entr + de = ext2_next_entry(de); + } + ext2_put_page(page); +- } ++ } else ++ dir_has_error = 1; ++ + if (++n >= npages) + n = 0; + /* next page is past the blocks we've got */ +@@ -414,7 +421,7 @@ found: + + struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p) + { +- struct page *page = ext2_get_page(dir, 0); ++ struct page *page = ext2_get_page(dir, 0, 0); + ext2_dirent *de = NULL; + + if (!IS_ERR(page)) { +@@ -487,7 +494,7 @@ int ext2_add_link (struct dentry *dentry + for (n = 0; n <= npages; n++) { + char *dir_end; + +- page = ext2_get_page(dir, n); ++ page = ext2_get_page(dir, n, 0); + err = PTR_ERR(page); + if (IS_ERR(page)) + goto out; +@@ -655,14 +662,17 @@ int ext2_empty_dir (struct inode * inode + { + struct page *page = NULL; + unsigned long i, npages = dir_pages(inode); ++ int dir_has_error = 0; + + for (i = 0; i < npages; i++) { + char *kaddr; + ext2_dirent * de; +- page = ext2_get_page(inode, i); ++ page = ext2_get_page(inode, i, dir_has_error); + +- if (IS_ERR(page)) ++ if (IS_ERR(page)) { ++ dir_has_error = 1; + continue; ++ } + + kaddr = page_address(page); + de = (ext2_dirent *)kaddr; +--- a/fs/ext3/dir.c ++++ b/fs/ext3/dir.c +@@ -102,6 +102,7 @@ static int ext3_readdir(struct file * fi + int err; + struct inode *inode = filp->f_path.dentry->d_inode; + int ret = 0; ++ int dir_has_error = 0; + + sb = inode->i_sb; + +@@ -148,9 +149,12 @@ static int ext3_readdir(struct file * fi + * of recovering data when there's a bad sector + */ + if (!bh) { +- ext3_error (sb, "ext3_readdir", +- "directory #%lu contains a hole at offset %lu", +- inode->i_ino, (unsigned long)filp->f_pos); ++ if (!dir_has_error) { ++ ext3_error(sb, __func__, "directory #%lu " ++ "contains a hole at offset %lld", ++ inode->i_ino, filp->f_pos); ++ dir_has_error = 1; ++ } + /* corrupt size? Maybe no more blocks to read */ + if (filp->f_pos > inode->i_blocks << 9) + break; +--- a/fs/ext4/dir.c ++++ b/fs/ext4/dir.c +@@ -102,6 +102,7 @@ static int ext4_readdir(struct file * fi + int err; + struct inode *inode = filp->f_path.dentry->d_inode; + int ret = 0; ++ int dir_has_error = 0; + + sb = inode->i_sb; + +@@ -148,9 +149,13 @@ static int ext4_readdir(struct file * fi + * of recovering data when there's a bad sector + */ + if (!bh) { +- ext4_error (sb, "ext4_readdir", +- "directory #%lu contains a hole at offset %lu", +- inode->i_ino, (unsigned long)filp->f_pos); ++ if (!dir_has_error) { ++ ext4_error(sb, __func__, "directory #%lu " ++ "contains a hole at offset %Lu", ++ inode->i_ino, ++ (unsigned long long) filp->f_pos); ++ dir_has_error = 1; ++ } + /* corrupt size? Maybe no more blocks to read */ + if (filp->f_pos > inode->i_blocks << 9) + break; diff --git a/queue-2.6.27/gpiolib-fix-oops-in-gpio_get_value_cansleep.patch b/queue-2.6.27/gpiolib-fix-oops-in-gpio_get_value_cansleep.patch new file mode 100644 index 00000000000..05d34df5879 --- /dev/null +++ b/queue-2.6.27/gpiolib-fix-oops-in-gpio_get_value_cansleep.patch @@ -0,0 +1,58 @@ +From jejb@kernel.org Thu Oct 23 12:54:37 2008 +From: David Brownell +Date: Mon, 20 Oct 2008 16:50:10 GMT +Subject: gpiolib: fix oops in gpio_get_value_cansleep() +To: jejb@kernel.org, stable@kernel.org +Message-ID: <200810201650.m9KGoAvI012814@hera.kernel.org> + +From: David Brownell + +commit 978ccaa8ea5d8c7bf6b676209f2fc126eae6355b upstream + +We can get the following oops from gpio_get_value_cansleep() when a GPIO +controller doesn't provide a get() callback: + + Unable to handle kernel paging request for instruction fetch + Faulting instruction address: 0x00000000 + Oops: Kernel access of bad area, sig: 11 [#1] + [...] + NIP [00000000] 0x0 + LR [c0182fb0] gpio_get_value_cansleep+0x40/0x50 + Call Trace: + [c7b79e80] [c0183f28] gpio_value_show+0x5c/0x94 + [c7b79ea0] [c01a584c] dev_attr_show+0x30/0x7c + [c7b79eb0] [c00d6b48] fill_read_buffer+0x68/0xe0 + [c7b79ed0] [c00d6c54] sysfs_read_file+0x94/0xbc + [c7b79ef0] [c008f24c] vfs_read+0xb4/0x16c + [c7b79f10] [c008f580] sys_read+0x4c/0x90 + [c7b79f40] [c0013a14] ret_from_syscall+0x0/0x38 + +It's OK to request the value of *any* GPIO; most GPIOs are bidirectional, +so configuring them as outputs just enables an output driver and doesn't +disable the input logic. + +So the problem is that gpio_get_value_cansleep() isn't making the same +sanity check that gpio_get_value() does: making sure this GPIO isn't one +of the atypical "no input logic" cases. + +Reported-by: Anton Vorontsov +Signed-off-by: David Brownell +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpio/gpiolib.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpio/gpiolib.c ++++ b/drivers/gpio/gpiolib.c +@@ -1020,7 +1020,7 @@ int gpio_get_value_cansleep(unsigned gpi + + might_sleep_if(extra_checks); + chip = gpio_to_chip(gpio); +- return chip->get(chip, gpio - chip->base); ++ return chip->get ? chip->get(chip, gpio - chip->base) : 0; + } + EXPORT_SYMBOL_GPL(gpio_get_value_cansleep); + diff --git a/queue-2.6.27/hvc_console-fix-free_irq-in-spinlocked-section.patch b/queue-2.6.27/hvc_console-fix-free_irq-in-spinlocked-section.patch new file mode 100644 index 00000000000..916d60b3ddb --- /dev/null +++ b/queue-2.6.27/hvc_console-fix-free_irq-in-spinlocked-section.patch @@ -0,0 +1,62 @@ +From benh@kernel.crashing.org Thu Oct 23 13:18:50 2008 +From: Christian Borntraeger +Date: Thu, 23 Oct 2008 12:18:31 +1100 +Subject: hvc_console: Fix free_irq in spinlocked section +To: stable +Message-ID: <1224724711.7654.357.camel@pasglop> + +From: Christian Borntraeger + +commit eef2622a9fcfa964073333ea72c7c9cd20ad45e6 upstream + +hvc_console: Fix free_irq in spinlocked section + + commit 611e097d7707741a336a0677d9d69bec40f29f3d + Author: Christian Borntraeger + hvc_console: rework setup to replace irq functions with callbacks + introduced a spinlock recursion problem. The notifier_del is + called with a lock held, and in turns calls free_irq which then + complains when manipulating procfs. This fixes it by moving the + call to the notifier to outside of the locked section. + +Signed-off-by: Christian Borntraeger +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/hvc_console.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/char/hvc_console.c ++++ b/drivers/char/hvc_console.c +@@ -367,13 +367,13 @@ static void hvc_close(struct tty_struct + spin_lock_irqsave(&hp->lock, flags); + + if (--hp->count == 0) { +- if (hp->ops->notifier_del) +- hp->ops->notifier_del(hp, hp->data); +- + /* We are done with the tty pointer now. */ + hp->tty = NULL; + spin_unlock_irqrestore(&hp->lock, flags); + ++ if (hp->ops->notifier_del) ++ hp->ops->notifier_del(hp, hp->data); ++ + /* + * Chain calls chars_in_buffer() and returns immediately if + * there is no buffered data otherwise sleeps on a wait queue +@@ -416,11 +416,11 @@ static void hvc_hangup(struct tty_struct + hp->n_outbuf = 0; + hp->tty = NULL; + ++ spin_unlock_irqrestore(&hp->lock, flags); ++ + if (hp->ops->notifier_del) + hp->ops->notifier_del(hp, hp->data); + +- spin_unlock_irqrestore(&hp->lock, flags); +- + while(temp_open_count) { + --temp_open_count; + kref_put(&hp->kref, destroy_hvc_struct); diff --git a/queue-2.6.27/netfilter-restore-lost-ifdef-guarding-defrag-exception.patch b/queue-2.6.27/netfilter-restore-lost-ifdef-guarding-defrag-exception.patch new file mode 100644 index 00000000000..91839dda6d7 --- /dev/null +++ b/queue-2.6.27/netfilter-restore-lost-ifdef-guarding-defrag-exception.patch @@ -0,0 +1,48 @@ +From kaber@trash.net Thu Oct 23 13:16:48 2008 +From: Patrick McHardy +Date: Wed, 22 Oct 2008 19:41:31 +0200 (MEST) +Subject: netfilter: restore lost ifdef guarding defrag exception +To: stable@kernel.org +Cc: netfilter-devel@vger.kernel.org, Patrick McHardy , davem@davemloft.net +Message-ID: <20081022174130.21341.48347.sendpatchset@x2.localnet> + +From: Patrick McHardy + +netfilter: restore lost #ifdef guarding defrag exception + +Upstream commit 38f7ac3eb: + +Nir Tzachar reported a warning when sending +fragments over loopback with NAT: + +[ 6658.338121] WARNING: at net/ipv4/netfilter/nf_nat_standalone.c:89 nf_nat_fn+0x33/0x155() + +The reason is that defragmentation is skipped for already tracked connections. +This is wrong in combination with NAT and ip_conntrack actually had some ifdefs +to avoid this behaviour when NAT is compiled in. + +The entire "optimization" may seem a bit silly, for now simply restoring the +lost #ifdef is the easiest solution until we can come up with something better. + +Signed-off-by: Patrick McHardy +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c ++++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +@@ -150,10 +150,12 @@ static unsigned int ipv4_conntrack_defra + const struct net_device *out, + int (*okfn)(struct sk_buff *)) + { ++#if !defined(CONFIG_NF_NAT) && !defined(CONFIG_NF_NAT_MODULE) + /* Previously seen (loopback)? Ignore. Do this before + fragment check. */ + if (skb->nfct) + return NF_ACCEPT; ++#endif + + /* Gather fragments. */ + if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { diff --git a/queue-2.6.27/netfilter-snmp-nat-leaks-memory-in-case-of-failure.patch b/queue-2.6.27/netfilter-snmp-nat-leaks-memory-in-case-of-failure.patch new file mode 100644 index 00000000000..24e7fe0da49 --- /dev/null +++ b/queue-2.6.27/netfilter-snmp-nat-leaks-memory-in-case-of-failure.patch @@ -0,0 +1,31 @@ +From kaber@trash.net Thu Oct 23 13:16:08 2008 +From: Ilpo Järvinen +Date: Wed, 22 Oct 2008 19:41:29 +0200 (MEST) +Subject: netfilter: snmp nat leaks memory in case of failure +To: stable@kernel.org +Cc: netfilter-devel@vger.kernel.org, Patrick McHardy , davem@davemloft.net +Message-ID: <20081022174129.21341.93881.sendpatchset@x2.localnet> + +From: Ilpo Järvinen + +netfilter: snmp nat leaks memory in case of failure + +Upstream commit 311670f3e: + +Signed-off-by: Ilpo Järvinen +Signed-off-by: Patrick McHardy + +--- + net/ipv4/netfilter/nf_nat_snmp_basic.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/ipv4/netfilter/nf_nat_snmp_basic.c ++++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c +@@ -742,6 +742,7 @@ static unsigned char snmp_object_decode( + *obj = kmalloc(sizeof(struct snmp_object) + len, + GFP_ATOMIC); + if (*obj == NULL) { ++ kfree(p); + kfree(id); + if (net_ratelimit()) + printk("OOM in bsalg (%d)\n", __LINE__); diff --git a/queue-2.6.27/netfilter-xt_iprange-fix-range-inversion-match.patch b/queue-2.6.27/netfilter-xt_iprange-fix-range-inversion-match.patch new file mode 100644 index 00000000000..e8999a578da --- /dev/null +++ b/queue-2.6.27/netfilter-xt_iprange-fix-range-inversion-match.patch @@ -0,0 +1,63 @@ +From kaber@trash.net Thu Oct 23 13:14:58 2008 +From: Alexey Dobriyan +Date: Wed, 22 Oct 2008 19:41:28 +0200 (MEST) +Subject: netfilter: xt_iprange: fix range inversion match +To: stable@kernel.org +Cc: netfilter-devel@vger.kernel.org, Patrick McHardy , davem@davemloft.net +Message-ID: <20081022174128.21341.79877.sendpatchset@x2.localnet> + + +From: Alexey Dobriyan + +netfilter: xt_iprange: fix range inversion match + +Upstream commit 6def1eb48: + +Inverted IPv4 v1 and IPv6 v0 matches don't match anything since 2.6.25-rc1! + +Signed-off-by: Alexey Dobriyan +Acked-by: Jan Engelhardt +Signed-off-by: Patrick McHardy +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/xt_iprange.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/net/netfilter/xt_iprange.c ++++ b/net/netfilter/xt_iprange.c +@@ -67,7 +67,7 @@ iprange_mt4(const struct sk_buff *skb, c + if (info->flags & IPRANGE_SRC) { + m = ntohl(iph->saddr) < ntohl(info->src_min.ip); + m |= ntohl(iph->saddr) > ntohl(info->src_max.ip); +- m ^= info->flags & IPRANGE_SRC_INV; ++ m ^= !!(info->flags & IPRANGE_SRC_INV); + if (m) { + pr_debug("src IP " NIPQUAD_FMT " NOT in range %s" + NIPQUAD_FMT "-" NIPQUAD_FMT "\n", +@@ -81,7 +81,7 @@ iprange_mt4(const struct sk_buff *skb, c + if (info->flags & IPRANGE_DST) { + m = ntohl(iph->daddr) < ntohl(info->dst_min.ip); + m |= ntohl(iph->daddr) > ntohl(info->dst_max.ip); +- m ^= info->flags & IPRANGE_DST_INV; ++ m ^= !!(info->flags & IPRANGE_DST_INV); + if (m) { + pr_debug("dst IP " NIPQUAD_FMT " NOT in range %s" + NIPQUAD_FMT "-" NIPQUAD_FMT "\n", +@@ -123,14 +123,14 @@ iprange_mt6(const struct sk_buff *skb, c + if (info->flags & IPRANGE_SRC) { + m = iprange_ipv6_sub(&iph->saddr, &info->src_min.in6) < 0; + m |= iprange_ipv6_sub(&iph->saddr, &info->src_max.in6) > 0; +- m ^= info->flags & IPRANGE_SRC_INV; ++ m ^= !!(info->flags & IPRANGE_SRC_INV); + if (m) + return false; + } + if (info->flags & IPRANGE_DST) { + m = iprange_ipv6_sub(&iph->daddr, &info->dst_min.in6) < 0; + m |= iprange_ipv6_sub(&iph->daddr, &info->dst_max.in6) > 0; +- m ^= info->flags & IPRANGE_DST_INV; ++ m ^= !!(info->flags & IPRANGE_DST_INV); + if (m) + return false; + } diff --git a/queue-2.6.27/regression-inclusion-of-linux-module.h-triggers-a-compiler-warning.patch b/queue-2.6.27/regression-inclusion-of-linux-module.h-triggers-a-compiler-warning.patch new file mode 100644 index 00000000000..8dd3cf56d74 --- /dev/null +++ b/queue-2.6.27/regression-inclusion-of-linux-module.h-triggers-a-compiler-warning.patch @@ -0,0 +1,57 @@ +From bart.vanassche@gmail.com Thu Oct 23 13:40:27 2008 +From: Bart Van Assche +Date: Tue, 21 Oct 2008 19:05:50 +0200 +Subject: Regression: inclusion of triggers a compiler warning +To: stable@kernel.org +Cc: Vladislav Bolkhovitin , Andrew Morton , Linus Torvalds , Dave Young +Message-ID: <200810211905.50915.bart.vanassche@gmail.com> +Content-Disposition: inline + +From: Bart Van Assche + +Not upstream, only a 2.6.27-stable issue. + +When compiling kernel modules against the 2.6.27, 2.6.27.1 or 2.6.27.2 kernel +headers, a compiler warning similar to the following is reported: + +CC [M] trunk/scst/src/scst_targ.o +In file included from include/linux/kernel.h:19, + from include/asm/system.h:11, + from include/asm/processor.h:18, + from include/linux/prefetch.h:15, + from include/linux/list.h:7, + from include/linux/module.h:10, + from trunk/scst/src/scst_main.c:20: +include/linux/ratelimit.h: In function 'ratelimit': +include/linux/ratelimit.h:23: warning: missing initializer +include/linux/ratelimit.h:23: warning: (near initialization for 'rs.printed') + +This issue was introduced through commit +717115e1a5856b57af0f71e1df7149108294fc10 +(http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.27.y.git;a=commit;h=717115e1a5856b57af0f71e1df7149108294fc10). +I have added the people who signed this patch in CC. + +The patch below fixes this warning, without changing the semantics of the code. + +Signed-off-by: Bart Van Assche +Acked-by: Dave Young +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/ratelimit.h | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/include/linux/ratelimit.h ++++ b/include/linux/ratelimit.h +@@ -13,8 +13,9 @@ struct ratelimit_state { + unsigned long begin; + }; + +-#define DEFINE_RATELIMIT_STATE(name, interval, burst) \ +- struct ratelimit_state name = {interval, burst,} ++#define DEFINE_RATELIMIT_STATE(name, interval_value, burst_value) \ ++ struct ratelimit_state name \ ++ = { .interval = (interval_value), .burst = (burst_value) } + + extern int __ratelimit(struct ratelimit_state *rs); + diff --git a/queue-2.6.27/sched-fix-the-wrong-mask_len.patch b/queue-2.6.27/sched-fix-the-wrong-mask_len.patch new file mode 100644 index 00000000000..0d6c357cb47 --- /dev/null +++ b/queue-2.6.27/sched-fix-the-wrong-mask_len.patch @@ -0,0 +1,35 @@ +From jejb@kernel.org Thu Oct 23 13:00:30 2008 +From: Miao Xie +Date: Thu, 23 Oct 2008 16:50:03 GMT +Subject: sched: fix the wrong mask_len +To: jejb@kernel.org, stable@kernel.org +Message-ID: <200810231650.m9NGo3aY001438@hera.kernel.org> + +From: Miao Xie + +commit c851c8676bd7ae456e9b3af8e6bb2c434eddcc75 upstream + +If NR_CPUS isn't a multiple of 32, we get a truncated string of sched +domains by catting /proc/schedstat. This is caused by the wrong mask_len. + +This patch fixes it. + +Signed-off-by: Miao Xie +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/sched_stats.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/sched_stats.h ++++ b/kernel/sched_stats.h +@@ -9,7 +9,7 @@ + static int show_schedstat(struct seq_file *seq, void *v) + { + int cpu; +- int mask_len = NR_CPUS/32 * 9; ++ int mask_len = (NR_CPUS/32 + 1) * 9; + char *mask_str = kmalloc(mask_len, GFP_KERNEL); + + if (mask_str == NULL) diff --git a/queue-2.6.27/series b/queue-2.6.27/series new file mode 100644 index 00000000000..e414f069d97 --- /dev/null +++ b/queue-2.6.27/series @@ -0,0 +1,21 @@ +gpiolib-fix-oops-in-gpio_get_value_cansleep.patch +edac-cell-fix-incorrect-edac_mode.patch +x86-acpi-fix-breakage-of-resume-on-64-bit-up-systems-with-smp-kernel.patch +sched-fix-the-wrong-mask_len.patch +usb-cdc-wdm-make-module-autoload-work.patch +usb-don-t-rebind-drivers-after-failed-resume-or-reset.patch +usb-fix-memory-leak-in-cdc-acm.patch +usb-speedtouch-add-pre_reset-and-post_reset-routines.patch +dm-kcopyd-avoid-queue-shuffle.patch +dm-snapshot-fix-primary_pe-race.patch +dm-exception-store-refactor-zero_area.patch +dm-exception-store-fix-misordered-writes.patch +amd_iommu-fix-nasty-bug-that-caused-illegal_device_table_entry-errors.patch +cifs-fix-saving-of-resume-key-before-cifsfindnext.patch +ext-avoid-printk-floods-in-the-face-of-directory-corruption.patch +netfilter-xt_iprange-fix-range-inversion-match.patch +netfilter-snmp-nat-leaks-memory-in-case-of-failure.patch +netfilter-restore-lost-ifdef-guarding-defrag-exception.patch +anon_vma_prepare-properly-lock-even-newly-allocated-entries.patch +hvc_console-fix-free_irq-in-spinlocked-section.patch +regression-inclusion-of-linux-module.h-triggers-a-compiler-warning.patch diff --git a/queue-2.6.27/usb-cdc-wdm-make-module-autoload-work.patch b/queue-2.6.27/usb-cdc-wdm-make-module-autoload-work.patch new file mode 100644 index 00000000000..6b92ed9631d --- /dev/null +++ b/queue-2.6.27/usb-cdc-wdm-make-module-autoload-work.patch @@ -0,0 +1,32 @@ +From jejb@kernel.org Thu Oct 23 13:02:01 2008 +From: Oliver Neukum +Date: Thu, 23 Oct 2008 17:35:11 GMT +Subject: USB: cdc-wdm: make module autoload work +To: jejb@kernel.org, stable@kernel.org +Message-ID: <200810231735.m9NHZBH3008400@hera.kernel.org> + +From: Oliver Neukum + +commit aa5380b904e7f896db0931320160bdea93e41f6a upstream + +this fixes an omission that led to no alias being computed for the +cdc-wdm module. + +Signed-off-by: Oliver Neukum +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/class/cdc-wdm.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/class/cdc-wdm.c ++++ b/drivers/usb/class/cdc-wdm.c +@@ -42,6 +42,8 @@ static struct usb_device_id wdm_ids[] = + { } + }; + ++MODULE_DEVICE_TABLE (usb, wdm_ids); ++ + #define WDM_MINOR_BASE 176 + + diff --git a/queue-2.6.27/usb-don-t-rebind-drivers-after-failed-resume-or-reset.patch b/queue-2.6.27/usb-don-t-rebind-drivers-after-failed-resume-or-reset.patch new file mode 100644 index 00000000000..c8aae3341a4 --- /dev/null +++ b/queue-2.6.27/usb-don-t-rebind-drivers-after-failed-resume-or-reset.patch @@ -0,0 +1,53 @@ +From jejb@kernel.org Thu Oct 23 13:02:28 2008 +From: Alan Stern +Date: Thu, 23 Oct 2008 17:35:07 GMT +Subject: USB: don't rebind drivers after failed resume or reset +To: jejb@kernel.org, stable@kernel.org +Message-ID: <200810231735.m9NHZ7jJ008353@hera.kernel.org> + +From: Alan Stern + +commit 6c6409459a18a825ce12ecb003d5686af61f7a2f upstream + +This patch (as1152) may help prevent some problems associated with the +new policy of unbinding drivers that don't support suspend/resume or +pre_reset/post_reset. If for any reason the resume or reset fails, and +the device is logically disconnected, there's no point in trying to +rebind the driver. So the patch checks for success before carrying +out the unbind/rebind. + +There was a report from one user that this fixed a problem he was +experiencing, but the details never became fully clear. In any case, +adding these tests can't hurt. + +Signed-off-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/driver.c | 3 ++- + drivers/usb/core/hub.c | 2 +- + 2 files changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/usb/core/driver.c ++++ b/drivers/usb/core/driver.c +@@ -1609,7 +1609,8 @@ int usb_external_resume_device(struct us + status = usb_resume_both(udev); + udev->last_busy = jiffies; + usb_pm_unlock(udev); +- do_unbind_rebind(udev, DO_REBIND); ++ if (status == 0) ++ do_unbind_rebind(udev, DO_REBIND); + + /* Now that the device is awake, we can start trying to autosuspend + * it again. */ +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -3424,7 +3424,7 @@ int usb_reset_device(struct usb_device * + USB_INTERFACE_BOUND) + rebind = 1; + } +- if (rebind) ++ if (ret == 0 && rebind) + usb_rebind_intf(cintf); + } + } diff --git a/queue-2.6.27/usb-fix-memory-leak-in-cdc-acm.patch b/queue-2.6.27/usb-fix-memory-leak-in-cdc-acm.patch new file mode 100644 index 00000000000..176a2c0d8f2 --- /dev/null +++ b/queue-2.6.27/usb-fix-memory-leak-in-cdc-acm.patch @@ -0,0 +1,36 @@ +From jejb@kernel.org Thu Oct 23 13:04:06 2008 +From: Oliver Neukum +Date: Thu, 23 Oct 2008 17:35:09 GMT +Subject: USB: fix memory leak in cdc-acm +To: jejb@kernel.org, stable@kernel.org +Message-ID: <200810231735.m9NHZ9bR008373@hera.kernel.org> + +From: Oliver Neukum + +commit a496c64f1363ec4d67ebdc1e1f619ad6372a574c upstream + +This fixes a memory leak on disconnect in cdc-acm + +Thanks to 施金前 for finding it. + +Signed-off-by: Oliver Neukum +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/class/cdc-acm.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -849,9 +849,10 @@ static void acm_write_buffers_free(struc + { + int i; + struct acm_wb *wb; ++ struct usb_device *usb_dev = interface_to_usbdev(acm->control); + + for (wb = &acm->wb[0], i = 0; i < ACM_NW; i++, wb++) { +- usb_buffer_free(acm->dev, acm->writesize, wb->buf, wb->dmah); ++ usb_buffer_free(usb_dev, acm->writesize, wb->buf, wb->dmah); + } + } + diff --git a/queue-2.6.27/usb-speedtouch-add-pre_reset-and-post_reset-routines.patch b/queue-2.6.27/usb-speedtouch-add-pre_reset-and-post_reset-routines.patch new file mode 100644 index 00000000000..8aae1c2847c --- /dev/null +++ b/queue-2.6.27/usb-speedtouch-add-pre_reset-and-post_reset-routines.patch @@ -0,0 +1,53 @@ +From jejb@kernel.org Thu Oct 23 13:04:42 2008 +From: Alan Stern +Date: Thu, 23 Oct 2008 17:35:13 GMT +Subject: USB: Speedtouch: add pre_reset and post_reset routines +To: jejb@kernel.org, stable@kernel.org +Message-ID: <200810231735.m9NHZDhu008428@hera.kernel.org> + +From: Alan Stern + +commit 8fc7aeab3851ed8c3ecf28901ca2c6f0400955c7 upstream + +This patch (as1150) fixes a problem in the speedtch driver. When it +resets the modem during probe it will be unbound from the other +interfaces it has claimed, because it doesn't define a pre_reset and a +post_reset method. + +The patch defines "do-nothing" methods. This fixes Bugzilla #11767. + +Signed-off-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/atm/speedtch.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/drivers/usb/atm/speedtch.c ++++ b/drivers/usb/atm/speedtch.c +@@ -722,6 +722,16 @@ static void speedtch_atm_stop(struct usb + flush_scheduled_work(); + } + ++static int speedtch_pre_reset(struct usb_interface *intf) ++{ ++ return 0; ++} ++ ++static int speedtch_post_reset(struct usb_interface *intf) ++{ ++ return 0; ++} ++ + + /********** + ** USB ** +@@ -740,6 +750,8 @@ static struct usb_driver speedtch_usb_dr + .name = speedtch_driver_name, + .probe = speedtch_usb_probe, + .disconnect = usbatm_usb_disconnect, ++ .pre_reset = speedtch_pre_reset, ++ .post_reset = speedtch_post_reset, + .id_table = speedtch_usb_ids + }; + diff --git a/queue-2.6.27/x86-acpi-fix-breakage-of-resume-on-64-bit-up-systems-with-smp-kernel.patch b/queue-2.6.27/x86-acpi-fix-breakage-of-resume-on-64-bit-up-systems-with-smp-kernel.patch new file mode 100644 index 00000000000..4817a641056 --- /dev/null +++ b/queue-2.6.27/x86-acpi-fix-breakage-of-resume-on-64-bit-up-systems-with-smp-kernel.patch @@ -0,0 +1,58 @@ +From jejb@kernel.org Thu Oct 23 12:59:15 2008 +From: Rafael J. Wysocki +Date: Mon, 20 Oct 2008 21:30:19 GMT +Subject: x86 ACPI: fix breakage of resume on 64-bit UP systems with SMP kernel +To: jejb@kernel.org, stable@kernel.org +Message-ID: <200810202130.m9KLUJU5017800@hera.kernel.org> + +From: Rafael J. Wysocki + +commit 3038edabf48f01421c621cb77a712b446d3a5d67 upstream + +x86 ACPI: Fix breakage of resume on 64-bit UP systems with SMP kernel + +We are now using per CPU GDT tables in head_64.S and the original +early_gdt_descr.address is invalidated after boot by +setup_per_cpu_areas(). This breaks resume from suspend to RAM on +x86_64 UP systems using SMP kernels, because this part of head_64.S +is also executed during the resume and the invalid GDT address +causes the system to crash. It doesn't break on 'true' SMP systems, +because early_gdt_descr.address is modified every time +native_cpu_up() runs. However, during resume it should point to the +GDT of the boot CPU rather than to another CPU's GDT. + +For this reason, during suspend to RAM always make +early_gdt_descr.address point to the boot CPU's GDT. + +This fixes http://bugzilla.kernel.org/show_bug.cgi?id=11568, which +is a regression from 2.6.26. + +Signed-off-by: Rafael J. Wysocki +Acked-by: Pavel Machek +Signed-off-by: Ingo Molnar +Reported-and-tested-by: Andy Wettstein +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/acpi/sleep.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/arch/x86/kernel/acpi/sleep.c ++++ b/arch/x86/kernel/acpi/sleep.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + + #include "realmode/wakeup.h" + #include "sleep.h" +@@ -98,6 +99,8 @@ int acpi_save_state_mem(void) + header->trampoline_segment = setup_trampoline() >> 4; + #ifdef CONFIG_SMP + stack_start.sp = temp_stack + 4096; ++ early_gdt_descr.address = ++ (unsigned long)get_cpu_gdt_table(smp_processor_id()); + #endif + initial_code = (unsigned long)wakeup_long64; + saved_magic = 0x123456789abcdef0; -- 2.47.3