]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
.38 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Mon, 11 Apr 2011 19:05:16 +0000 (12:05 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 11 Apr 2011 19:05:16 +0000 (12:05 -0700)
queue-2.6.38/amd64_edac-fix-potential-memleak.patch [new file with mode: 0644]
queue-2.6.38/irda-prevent-heap-corruption-on-invalid-nickname.patch [new file with mode: 0644]
queue-2.6.38/irda-validate-peer-name-and-attribute-lengths.patch [new file with mode: 0644]
queue-2.6.38/nilfs2-fix-data-loss-in-mmap-page-write-for-hole-blocks.patch [new file with mode: 0644]
queue-2.6.38/powerpc-fix-accounting-of-softirq-time-when-idle.patch [new file with mode: 0644]
queue-2.6.38/relax-si_code-check-in-rt_sigqueueinfo-and-rt_tgsigqueueinfo.patch [new file with mode: 0644]
queue-2.6.38/series
queue-2.6.38/watchdog-convert-release_resource-to-release_region-release_mem_region.patch [new file with mode: 0644]
queue-2.6.38/watchdog-s3c2410_wdt.c-convert-release_resource-to-release_region-release_mem_region.patch [new file with mode: 0644]
queue-2.6.38/watchdog-sp5100_tco.c-check-if-firmware-has-set-correct-value-in-tcobase.patch [new file with mode: 0644]
queue-2.6.38/xfs-register-the-inode-cache-shrinker-before-quotachecks.patch [new file with mode: 0644]

diff --git a/queue-2.6.38/amd64_edac-fix-potential-memleak.patch b/queue-2.6.38/amd64_edac-fix-potential-memleak.patch
new file mode 100644 (file)
index 0000000..58d47f3
--- /dev/null
@@ -0,0 +1,32 @@
+From a9f0fbe2bbf328f869fc5ee5a12c6a4118c32689 Mon Sep 17 00:00:00 2001
+From: Borislav Petkov <borislav.petkov@amd.com>
+Date: Tue, 29 Mar 2011 18:10:53 +0200
+Subject: amd64_edac: Fix potential memleak
+
+From: Borislav Petkov <borislav.petkov@amd.com>
+
+commit a9f0fbe2bbf328f869fc5ee5a12c6a4118c32689 upstream.
+
+We check the pointers together but at least one of them could be invalid
+due to failed allocation. Since we cannot continue if either of the two
+allocations has failed, exit early by freeing them both.
+
+Reported-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/edac/amd64_edac.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/edac/amd64_edac.c
++++ b/drivers/edac/amd64_edac.c
+@@ -2765,7 +2765,7 @@ static int __init amd64_edac_init(void)
+       mcis      = kzalloc(amd_nb_num() * sizeof(mcis[0]), GFP_KERNEL);
+       ecc_stngs = kzalloc(amd_nb_num() * sizeof(ecc_stngs[0]), GFP_KERNEL);
+       if (!(mcis && ecc_stngs))
+-              goto err_ret;
++              goto err_free;
+       msrs = msrs_alloc();
+       if (!msrs)
diff --git a/queue-2.6.38/irda-prevent-heap-corruption-on-invalid-nickname.patch b/queue-2.6.38/irda-prevent-heap-corruption-on-invalid-nickname.patch
new file mode 100644 (file)
index 0000000..fd5824f
--- /dev/null
@@ -0,0 +1,36 @@
+From d50e7e3604778bfc2dc40f440e0742dbae399d54 Mon Sep 17 00:00:00 2001
+From: Dan Rosenberg <drosenberg@vsecurity.com>
+Date: Sat, 19 Mar 2011 20:14:30 +0000
+Subject: irda: prevent heap corruption on invalid nickname
+
+From: Dan Rosenberg <drosenberg@vsecurity.com>
+
+commit d50e7e3604778bfc2dc40f440e0742dbae399d54 upstream.
+
+Invalid nicknames containing only spaces will result in an underflow in
+a memcpy size calculation, subsequently destroying the heap and
+panicking.
+
+v2 also catches the case where the provided nickname is longer than the
+buffer size, which can result in controllable heap corruption.
+
+Signed-off-by: Dan Rosenberg <drosenberg@vsecurity.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/irda/irnet/irnet_ppp.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/net/irda/irnet/irnet_ppp.c
++++ b/net/irda/irnet/irnet_ppp.c
+@@ -105,6 +105,9 @@ irnet_ctrl_write(irnet_socket *    ap,
+             while(isspace(start[length - 1]))
+               length--;
++            DABORT(length < 5 || length > NICKNAME_MAX_LEN + 5,
++                   -EINVAL, CTRL_ERROR, "Invalid nickname.\n");
++
+             /* Copy the name for later reuse */
+             memcpy(ap->rname, start + 5, length - 5);
+             ap->rname[length - 5] = '\0';
diff --git a/queue-2.6.38/irda-validate-peer-name-and-attribute-lengths.patch b/queue-2.6.38/irda-validate-peer-name-and-attribute-lengths.patch
new file mode 100644 (file)
index 0000000..6d37a0a
--- /dev/null
@@ -0,0 +1,40 @@
+From d370af0ef7951188daeb15bae75db7ba57c67846 Mon Sep 17 00:00:00 2001
+From: Dan Rosenberg <drosenberg@vsecurity.com>
+Date: Sun, 20 Mar 2011 15:32:06 +0000
+Subject: irda: validate peer name and attribute lengths
+
+From: Dan Rosenberg <drosenberg@vsecurity.com>
+
+commit d370af0ef7951188daeb15bae75db7ba57c67846 upstream.
+
+Length fields provided by a peer for names and attributes may be longer
+than the destination array sizes.  Validate lengths to prevent stack
+buffer overflows.
+
+Signed-off-by: Dan Rosenberg <drosenberg@vsecurity.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/irda/iriap.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/net/irda/iriap.c
++++ b/net/irda/iriap.c
+@@ -656,10 +656,16 @@ static void iriap_getvaluebyclass_indica
+       n = 1;
+       name_len = fp[n++];
++
++      IRDA_ASSERT(name_len < IAS_MAX_CLASSNAME + 1, return;);
++
+       memcpy(name, fp+n, name_len); n+=name_len;
+       name[name_len] = '\0';
+       attr_len = fp[n++];
++
++      IRDA_ASSERT(attr_len < IAS_MAX_ATTRIBNAME + 1, return;);
++
+       memcpy(attr, fp+n, attr_len); n+=attr_len;
+       attr[attr_len] = '\0';
diff --git a/queue-2.6.38/nilfs2-fix-data-loss-in-mmap-page-write-for-hole-blocks.patch b/queue-2.6.38/nilfs2-fix-data-loss-in-mmap-page-write-for-hole-blocks.patch
new file mode 100644 (file)
index 0000000..5a94fed
--- /dev/null
@@ -0,0 +1,80 @@
+From 34094537943113467faee98fe67c8a3d3f9a0a8b Mon Sep 17 00:00:00 2001
+From: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
+Date: Sun, 27 Mar 2011 22:50:49 +0900
+Subject: nilfs2: fix data loss in mmap page write for hole blocks
+
+From: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
+
+commit 34094537943113467faee98fe67c8a3d3f9a0a8b upstream.
+
+From the result of a function test of mmap, mmap write to shared pages
+turned out to be broken for hole blocks.  It doesn't write out filled
+blocks and the data will be lost after umount.  This is due to a bug
+that the target file is not queued for log writer when filling hole
+blocks.
+
+Also, nilfs_page_mkwrite function exits normal code path even after
+successfully filled hole blocks due to a change of block_page_mkwrite
+function; just after nilfs was merged into the mainline,
+block_page_mkwrite() started to return VM_FAULT_LOCKED instead of zero
+by the patch "mm: close page_mkwrite races" (commit:
+b827e496c893de0c).  The current nilfs_page_mkwrite() is not handling
+this value properly.
+
+This corrects nilfs_page_mkwrite() and will resolve the data loss
+problem in mmap write.
+
+[This should be applied to every kernel since 2.6.30 but a fix is
+ needed for 2.6.37 and prior kernels]
+
+Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
+Tested-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/nilfs2/file.c |   11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+--- a/fs/nilfs2/file.c
++++ b/fs/nilfs2/file.c
+@@ -72,10 +72,9 @@ static int nilfs_page_mkwrite(struct vm_
+       /*
+        * check to see if the page is mapped already (no holes)
+        */
+-      if (PageMappedToDisk(page)) {
+-              unlock_page(page);
++      if (PageMappedToDisk(page))
+               goto mapped;
+-      }
++
+       if (page_has_buffers(page)) {
+               struct buffer_head *bh, *head;
+               int fully_mapped = 1;
+@@ -90,7 +89,6 @@ static int nilfs_page_mkwrite(struct vm_
+               if (fully_mapped) {
+                       SetPageMappedToDisk(page);
+-                      unlock_page(page);
+                       goto mapped;
+               }
+       }
+@@ -105,16 +103,17 @@ static int nilfs_page_mkwrite(struct vm_
+               return VM_FAULT_SIGBUS;
+       ret = block_page_mkwrite(vma, vmf, nilfs_get_block);
+-      if (unlikely(ret)) {
++      if (ret != VM_FAULT_LOCKED) {
+               nilfs_transaction_abort(inode->i_sb);
+               return ret;
+       }
++      nilfs_set_file_dirty(inode, 1 << (PAGE_SHIFT - inode->i_blkbits));
+       nilfs_transaction_commit(inode->i_sb);
+  mapped:
+       SetPageChecked(page);
+       wait_on_page_writeback(page);
+-      return 0;
++      return VM_FAULT_LOCKED;
+ }
+ static const struct vm_operations_struct nilfs_file_vm_ops = {
diff --git a/queue-2.6.38/powerpc-fix-accounting-of-softirq-time-when-idle.patch b/queue-2.6.38/powerpc-fix-accounting-of-softirq-time-when-idle.patch
new file mode 100644 (file)
index 0000000..65b2e35
--- /dev/null
@@ -0,0 +1,54 @@
+From ad5d1c888e556bc00c4e86f452cad4a3a87d22c1 Mon Sep 17 00:00:00 2001
+From: Anton Blanchard <anton@samba.org>
+Date: Sun, 20 Mar 2011 15:28:03 +0000
+Subject: powerpc: Fix accounting of softirq time when idle
+
+From: Anton Blanchard <anton@samba.org>
+
+commit ad5d1c888e556bc00c4e86f452cad4a3a87d22c1 upstream.
+
+commit cf9efce0ce31 (powerpc: Account time using timebase rather
+than PURR) used in_irq() to detect if the time was spent in
+interrupt processing. This only catches hardirq context so if we
+are in softirq context and in the idle loop we end up accounting it
+as idle time. If we instead use in_interrupt() we catch both softirq
+and hardirq time.
+
+The issue was found when running a network intensive workload. top
+showed the following:
+
+0.0%us,  1.1%sy,  0.0%ni, 85.7%id,  0.0%wa,  9.9%hi,  3.3%si,  0.0%st
+
+85.7% idle. But this was wildly different to the perf events data.
+To confirm the suspicion I ran something to keep the core busy:
+
+# yes > /dev/null &
+
+8.2%us,  0.0%sy,  0.0%ni,  0.0%id,  0.0%wa, 10.3%hi, 81.4%si,  0.0%st
+
+We only got 8.2% of the CPU for the userspace task and softirq has
+shot up to 81.4%.
+
+With the patch below top shows the correct stats:
+
+0.0%us,  0.0%sy,  0.0%ni,  5.3%id,  0.0%wa, 13.3%hi, 81.3%si,  0.0%st
+
+Signed-off-by: Anton Blanchard <anton@samba.org>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/powerpc/kernel/time.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/powerpc/kernel/time.c
++++ b/arch/powerpc/kernel/time.c
+@@ -356,7 +356,7 @@ void account_system_vtime(struct task_st
+       }
+       get_paca()->user_time_scaled += user_scaled;
+-      if (in_irq() || idle_task(smp_processor_id()) != tsk) {
++      if (in_interrupt() || idle_task(smp_processor_id()) != tsk) {
+               account_system_time(tsk, 0, delta, sys_scaled);
+               if (stolen)
+                       account_steal_time(stolen);
diff --git a/queue-2.6.38/relax-si_code-check-in-rt_sigqueueinfo-and-rt_tgsigqueueinfo.patch b/queue-2.6.38/relax-si_code-check-in-rt_sigqueueinfo-and-rt_tgsigqueueinfo.patch
new file mode 100644 (file)
index 0000000..5657a2a
--- /dev/null
@@ -0,0 +1,56 @@
+From 243b422af9ea9af4ead07a8ad54c90d4f9b6081a Mon Sep 17 00:00:00 2001
+From: Roland Dreier <roland@purestorage.com>
+Date: Mon, 28 Mar 2011 14:13:35 -0700
+Subject: Relax si_code check in rt_sigqueueinfo and rt_tgsigqueueinfo
+
+From: Roland Dreier <roland@purestorage.com>
+
+commit 243b422af9ea9af4ead07a8ad54c90d4f9b6081a upstream.
+
+Commit da48524eb206 ("Prevent rt_sigqueueinfo and rt_tgsigqueueinfo
+from spoofing the signal code") made the check on si_code too strict.
+There are several legitimate places where glibc wants to queue a
+negative si_code different from SI_QUEUE:
+
+ - This was first noticed with glibc's aio implementation, which wants
+   to queue a signal with si_code SI_ASYNCIO; the current kernel
+   causes glibc's tst-aio4 test to fail because rt_sigqueueinfo()
+   fails with EPERM.
+
+ - Further examination of the glibc source shows that getaddrinfo_a()
+   wants to use SI_ASYNCNL (which the kernel does not even define).
+   The timer_create() fallback code wants to queue signals with SI_TIMER.
+
+As suggested by Oleg Nesterov <oleg@redhat.com>, loosen the check to
+forbid only the problematic SI_TKILL case.
+
+Reported-by: Klaus Dittrich <kladit@arcor.de>
+Acked-by: Julien Tinnes <jln@google.com>
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ kernel/signal.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/kernel/signal.c
++++ b/kernel/signal.c
+@@ -2423,7 +2423,7 @@ SYSCALL_DEFINE3(rt_sigqueueinfo, pid_t,
+       /* Not even root can pretend to send signals from the kernel.
+        * Nor can they impersonate a kill()/tgkill(), which adds source info.
+        */
+-      if (info.si_code != SI_QUEUE) {
++      if (info.si_code >= 0 || info.si_code == SI_TKILL) {
+               /* We used to allow any < 0 si_code */
+               WARN_ON_ONCE(info.si_code < 0);
+               return -EPERM;
+@@ -2443,7 +2443,7 @@ long do_rt_tgsigqueueinfo(pid_t tgid, pi
+       /* Not even root can pretend to send signals from the kernel.
+        * Nor can they impersonate a kill()/tgkill(), which adds source info.
+        */
+-      if (info->si_code != SI_QUEUE) {
++      if (info->si_code >= 0 || info->si_code == SI_TKILL) {
+               /* We used to allow any < 0 si_code */
+               WARN_ON_ONCE(info->si_code < 0);
+               return -EPERM;
index 58a1f878803e8f0bffa960ee0fb45f585cba3019..561709dae38fd57398186b401be4c83793bf511d 100644 (file)
@@ -20,3 +20,13 @@ staging-usbip-bugfix-add-number-of-packets-for-isochronous-frames.patch
 staging-usbip-bugfix-for-isochronous-packets-and-optimization.patch
 staging-hv-use-sync_bitops-when-interacting-with-the-hypervisor.patch
 staging-hv-fix-garp-not-sent-after-quick-migration.patch
+relax-si_code-check-in-rt_sigqueueinfo-and-rt_tgsigqueueinfo.patch
+xfs-register-the-inode-cache-shrinker-before-quotachecks.patch
+amd64_edac-fix-potential-memleak.patch
+watchdog-s3c2410_wdt.c-convert-release_resource-to-release_region-release_mem_region.patch
+watchdog-convert-release_resource-to-release_region-release_mem_region.patch
+watchdog-sp5100_tco.c-check-if-firmware-has-set-correct-value-in-tcobase.patch
+irda-validate-peer-name-and-attribute-lengths.patch
+irda-prevent-heap-corruption-on-invalid-nickname.patch
+powerpc-fix-accounting-of-softirq-time-when-idle.patch
+nilfs2-fix-data-loss-in-mmap-page-write-for-hole-blocks.patch
diff --git a/queue-2.6.38/watchdog-convert-release_resource-to-release_region-release_mem_region.patch b/queue-2.6.38/watchdog-convert-release_resource-to-release_region-release_mem_region.patch
new file mode 100644 (file)
index 0000000..acd37db
--- /dev/null
@@ -0,0 +1,231 @@
+From f712eacf02ecfbf4f1686addb8c569841549b0b7 Mon Sep 17 00:00:00 2001
+From: Julia Lawall <julia@diku.dk>
+Date: Sat, 26 Feb 2011 17:34:39 +0100
+Subject: watchdog: Convert release_resource to release_region/release_mem_region
+
+From: Julia Lawall <julia@diku.dk>
+
+commit f712eacf02ecfbf4f1686addb8c569841549b0b7 upstream.
+
+Request_mem_region should be used with release_mem_region, not
+release_resource.
+
+In pnx4008_wdt.c, a missing clk_put is added as well.
+
+The semantic match that finds the first problem is as follows:
+(http://coccinelle.lip6.fr/)
+
+// <smpl>
+@@
+expression x,E;
+@@
+*x = request_mem_region(...)
+... when != release_mem_region(x)
+    when != x = E
+* release_resource(x);
+// </smpl>
+
+Signed-off-by: Julia Lawall <julia@diku.dk>
+Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/watchdog/davinci_wdt.c |   22 ++++++++++------------
+ drivers/watchdog/max63xx_wdt.c |   20 ++++++++------------
+ drivers/watchdog/pnx4008_wdt.c |   28 +++++++++++++---------------
+ 3 files changed, 31 insertions(+), 39 deletions(-)
+
+--- a/drivers/watchdog/davinci_wdt.c
++++ b/drivers/watchdog/davinci_wdt.c
+@@ -202,7 +202,6 @@ static struct miscdevice davinci_wdt_mis
+ static int __devinit davinci_wdt_probe(struct platform_device *pdev)
+ {
+       int ret = 0, size;
+-      struct resource *res;
+       struct device *dev = &pdev->dev;
+       wdt_clk = clk_get(dev, NULL);
+@@ -216,31 +215,31 @@ static int __devinit davinci_wdt_probe(s
+       dev_info(dev, "heartbeat %d sec\n", heartbeat);
+-      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-      if (res == NULL) {
++      wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      if (wdt_mem == NULL) {
+               dev_err(dev, "failed to get memory region resource\n");
+               return -ENOENT;
+       }
+-      size = resource_size(res);
+-      wdt_mem = request_mem_region(res->start, size, pdev->name);
+-
+-      if (wdt_mem == NULL) {
++      size = resource_size(wdt_mem);
++      if (!request_mem_region(wdt_mem->start, size, pdev->name)) {
+               dev_err(dev, "failed to get memory region\n");
+               return -ENOENT;
+       }
+-      wdt_base = ioremap(res->start, size);
++      wdt_base = ioremap(wdt_mem->start, size);
+       if (!wdt_base) {
+               dev_err(dev, "failed to map memory region\n");
++              release_mem_region(wdt_mem->start, size);
++              wdt_mem = NULL;
+               return -ENOMEM;
+       }
+       ret = misc_register(&davinci_wdt_miscdev);
+       if (ret < 0) {
+               dev_err(dev, "cannot register misc device\n");
+-              release_resource(wdt_mem);
+-              kfree(wdt_mem);
++              release_mem_region(wdt_mem->start, size);
++              wdt_mem = NULL;
+       } else {
+               set_bit(WDT_DEVICE_INITED, &wdt_status);
+       }
+@@ -253,8 +252,7 @@ static int __devexit davinci_wdt_remove(
+ {
+       misc_deregister(&davinci_wdt_miscdev);
+       if (wdt_mem) {
+-              release_resource(wdt_mem);
+-              kfree(wdt_mem);
++              release_mem_region(wdt_mem->start, resource_size(wdt_mem));
+               wdt_mem = NULL;
+       }
+--- a/drivers/watchdog/max63xx_wdt.c
++++ b/drivers/watchdog/max63xx_wdt.c
+@@ -270,7 +270,6 @@ static int __devinit max63xx_wdt_probe(s
+ {
+       int ret = 0;
+       int size;
+-      struct resource *res;
+       struct device *dev = &pdev->dev;
+       struct max63xx_timeout *table;
+@@ -294,21 +293,19 @@ static int __devinit max63xx_wdt_probe(s
+       max63xx_pdev = pdev;
+-      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-      if (res == NULL) {
++      wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      if (wdt_mem == NULL) {
+               dev_err(dev, "failed to get memory region resource\n");
+               return -ENOENT;
+       }
+-      size = resource_size(res);
+-      wdt_mem = request_mem_region(res->start, size, pdev->name);
+-
+-      if (wdt_mem == NULL) {
++      size = resource_size(wdt_mem);
++      if (!request_mem_region(wdt_mem->start, size, pdev->name)) {
+               dev_err(dev, "failed to get memory region\n");
+               return -ENOENT;
+       }
+-      wdt_base = ioremap(res->start, size);
++      wdt_base = ioremap(wdt_mem->start, size);
+       if (!wdt_base) {
+               dev_err(dev, "failed to map memory region\n");
+               ret = -ENOMEM;
+@@ -326,8 +323,8 @@ static int __devinit max63xx_wdt_probe(s
+ out_unmap:
+       iounmap(wdt_base);
+ out_request:
+-      release_resource(wdt_mem);
+-      kfree(wdt_mem);
++      release_mem_region(wdt_mem->start, size);
++      wdt_mem = NULL;
+       return ret;
+ }
+@@ -336,8 +333,7 @@ static int __devexit max63xx_wdt_remove(
+ {
+       misc_deregister(&max63xx_wdt_miscdev);
+       if (wdt_mem) {
+-              release_resource(wdt_mem);
+-              kfree(wdt_mem);
++              release_mem_region(wdt_mem->start, resource_size(wdt_mem));
+               wdt_mem = NULL;
+       }
+--- a/drivers/watchdog/pnx4008_wdt.c
++++ b/drivers/watchdog/pnx4008_wdt.c
+@@ -254,7 +254,6 @@ static struct miscdevice pnx4008_wdt_mis
+ static int __devinit pnx4008_wdt_probe(struct platform_device *pdev)
+ {
+       int ret = 0, size;
+-      struct resource *res;
+       if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT)
+               heartbeat = DEFAULT_HEARTBEAT;
+@@ -262,42 +261,42 @@ static int __devinit pnx4008_wdt_probe(s
+       printk(KERN_INFO MODULE_NAME
+               "PNX4008 Watchdog Timer: heartbeat %d sec\n", heartbeat);
+-      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-      if (res == NULL) {
++      wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      if (wdt_mem == NULL) {
+               printk(KERN_INFO MODULE_NAME
+                       "failed to get memory region resouce\n");
+               return -ENOENT;
+       }
+-      size = resource_size(res);
+-      wdt_mem = request_mem_region(res->start, size, pdev->name);
++      size = resource_size(wdt_mem);
+-      if (wdt_mem == NULL) {
++      if (!request_mem_region(wdt_mem->start, size, pdev->name)) {
+               printk(KERN_INFO MODULE_NAME "failed to get memory region\n");
+               return -ENOENT;
+       }
+-      wdt_base = (void __iomem *)IO_ADDRESS(res->start);
++      wdt_base = (void __iomem *)IO_ADDRESS(wdt_mem->start);
+       wdt_clk = clk_get(&pdev->dev, NULL);
+       if (IS_ERR(wdt_clk)) {
+               ret = PTR_ERR(wdt_clk);
+-              release_resource(wdt_mem);
+-              kfree(wdt_mem);
++              release_mem_region(wdt_mem->start, size);
++              wdt_mem = NULL;
+               goto out;
+       }
+       ret = clk_enable(wdt_clk);
+       if (ret) {
+-              release_resource(wdt_mem);
+-              kfree(wdt_mem);
++              release_mem_region(wdt_mem->start, size);
++              wdt_mem = NULL;
++              clk_put(wdt_clk);
+               goto out;
+       }
+       ret = misc_register(&pnx4008_wdt_miscdev);
+       if (ret < 0) {
+               printk(KERN_ERR MODULE_NAME "cannot register misc device\n");
+-              release_resource(wdt_mem);
+-              kfree(wdt_mem);
++              release_mem_region(wdt_mem->start, size);
++              wdt_mem = NULL;
+               clk_disable(wdt_clk);
+               clk_put(wdt_clk);
+       } else {
+@@ -320,8 +319,7 @@ static int __devexit pnx4008_wdt_remove(
+       clk_put(wdt_clk);
+       if (wdt_mem) {
+-              release_resource(wdt_mem);
+-              kfree(wdt_mem);
++              release_mem_region(wdt_mem->start, resource_size(wdt_mem));
+               wdt_mem = NULL;
+       }
+       return 0;
diff --git a/queue-2.6.38/watchdog-s3c2410_wdt.c-convert-release_resource-to-release_region-release_mem_region.patch b/queue-2.6.38/watchdog-s3c2410_wdt.c-convert-release_resource-to-release_region-release_mem_region.patch
new file mode 100644 (file)
index 0000000..0b429c7
--- /dev/null
@@ -0,0 +1,90 @@
+From f72401e94d159bc4b2beab51d74e956da2c32e0a Mon Sep 17 00:00:00 2001
+From: Julia Lawall <julia@diku.dk>
+Date: Sat, 26 Feb 2011 17:34:38 +0100
+Subject: watchdog: s3c2410_wdt.c: Convert release_resource to release_region/release_mem_region
+
+From: Julia Lawall <julia@diku.dk>
+
+commit f72401e94d159bc4b2beab51d74e956da2c32e0a upstream.
+
+Request_mem_region should be used with release_mem_region, not
+release_resource.
+
+The semantic match that finds this problem is as follows:
+(http://coccinelle.lip6.fr/)
+
+// <smpl>
+@@
+expression x,E;
+@@
+*x = request_mem_region(...)
+... when != release_mem_region(x)
+    when != x = E
+* release_resource(x);
+// </smpl>
+
+Signed-off-by: Julia Lawall <julia@diku.dk>
+Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/watchdog/s3c2410_wdt.c |   19 ++++++++-----------
+ 1 file changed, 8 insertions(+), 11 deletions(-)
+
+--- a/drivers/watchdog/s3c2410_wdt.c
++++ b/drivers/watchdog/s3c2410_wdt.c
+@@ -402,7 +402,6 @@ static inline void s3c2410wdt_cpufreq_de
+ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
+ {
+-      struct resource *res;
+       struct device *dev;
+       unsigned int wtcon;
+       int started = 0;
+@@ -416,20 +415,19 @@ static int __devinit s3c2410wdt_probe(st
+       /* get the memory region for the watchdog timer */
+-      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-      if (res == NULL) {
++      wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      if (wdt_mem == NULL) {
+               dev_err(dev, "no memory resource specified\n");
+               return -ENOENT;
+       }
+-      size = resource_size(res);
+-      wdt_mem = request_mem_region(res->start, size, pdev->name);
+-      if (wdt_mem == NULL) {
++      size = resource_size(wdt_mem);
++      if (!request_mem_region(wdt_mem->start, size, pdev->name)) {
+               dev_err(dev, "failed to get memory region\n");
+               return -EBUSY;
+       }
+-      wdt_base = ioremap(res->start, size);
++      wdt_base = ioremap(wdt_mem->start, size);
+       if (wdt_base == NULL) {
+               dev_err(dev, "failed to ioremap() region\n");
+               ret = -EINVAL;
+@@ -524,8 +522,8 @@ static int __devinit s3c2410wdt_probe(st
+       iounmap(wdt_base);
+  err_req:
+-      release_resource(wdt_mem);
+-      kfree(wdt_mem);
++      release_mem_region(wdt_mem->start, size);
++      wdt_mem = NULL;
+       return ret;
+ }
+@@ -545,8 +543,7 @@ static int __devexit s3c2410wdt_remove(s
+       iounmap(wdt_base);
+-      release_resource(wdt_mem);
+-      kfree(wdt_mem);
++      release_mem_region(wdt_mem->start, resource_size(wdt_mem));
+       wdt_mem = NULL;
+       return 0;
+ }
diff --git a/queue-2.6.38/watchdog-sp5100_tco.c-check-if-firmware-has-set-correct-value-in-tcobase.patch b/queue-2.6.38/watchdog-sp5100_tco.c-check-if-firmware-has-set-correct-value-in-tcobase.patch
new file mode 100644 (file)
index 0000000..7d64e99
--- /dev/null
@@ -0,0 +1,85 @@
+From 90d241edd13bdeef70f264b569f7e150bf23621e Mon Sep 17 00:00:00 2001
+From: Yinghai Lu <yinghai@kernel.org>
+Date: Wed, 16 Mar 2011 20:01:07 -0700
+Subject: watchdog: sp5100_tco.c: Check if firmware has set correct value in tcobase.
+
+From: Yinghai Lu <yinghai@kernel.org>
+
+commit 90d241edd13bdeef70f264b569f7e150bf23621e upstream.
+
+Stefano found SP5100 TCO watchdog driver using wrong address.
+
+[    9.148536] SP5100 TCO timer: SP5100 TCO WatchDog Timer Driver v0.01
+[    9.148628] DEBUG __ioremap_caller WARNING address=b8fe00 size=8 valid=1 reserved=1
+
+and e820 said that range is RAM.
+
+We should check if we can use that reading out. BIOS could just program wrong address there.
+
+Reported-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
+Signed-off-by:Yinghai Lu <yinghai@kernel.org>
+Acked-by: Mike Waychison <mikew@google.com>
+Tested-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/watchdog/sp5100_tco.c |   16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+--- a/drivers/watchdog/sp5100_tco.c
++++ b/drivers/watchdog/sp5100_tco.c
+@@ -42,6 +42,7 @@
+ #define PFX TCO_MODULE_NAME ": "
+ /* internal variables */
++static u32 tcobase_phys;
+ static void __iomem *tcobase;
+ static unsigned int pm_iobase;
+ static DEFINE_SPINLOCK(tco_lock);     /* Guards the hardware */
+@@ -305,10 +306,18 @@ static unsigned char __devinit sp5100_tc
+       /* Low three bits of BASE0 are reserved. */
+       val = val << 8 | (inb(SP5100_IO_PM_DATA_REG) & 0xf8);
++      if (!request_mem_region_exclusive(val, SP5100_WDT_MEM_MAP_SIZE,
++                                                              "SP5100 TCO")) {
++              printk(KERN_ERR PFX "mmio address 0x%04x already in use\n",
++                      val);
++              goto unreg_region;
++      }
++      tcobase_phys = val;
++
+       tcobase = ioremap(val, SP5100_WDT_MEM_MAP_SIZE);
+       if (tcobase == 0) {
+               printk(KERN_ERR PFX "failed to get tcobase address\n");
+-              goto unreg_region;
++              goto unreg_mem_region;
+       }
+       /* Enable watchdog decode bit */
+@@ -346,7 +355,8 @@ static unsigned char __devinit sp5100_tc
+       /* Done */
+       return 1;
+-      iounmap(tcobase);
++unreg_mem_region:
++      release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
+ unreg_region:
+       release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
+ exit:
+@@ -401,6 +411,7 @@ static int __devinit sp5100_tco_init(str
+ exit:
+       iounmap(tcobase);
++      release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
+       release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
+       return ret;
+ }
+@@ -414,6 +425,7 @@ static void __devexit sp5100_tco_cleanup
+       /* Deregister */
+       misc_deregister(&sp5100_tco_miscdev);
+       iounmap(tcobase);
++      release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
+       release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
+ }
diff --git a/queue-2.6.38/xfs-register-the-inode-cache-shrinker-before-quotachecks.patch b/queue-2.6.38/xfs-register-the-inode-cache-shrinker-before-quotachecks.patch
new file mode 100644 (file)
index 0000000..46cdd3b
--- /dev/null
@@ -0,0 +1,101 @@
+From 704b2907c2d47ceb187c0e25a6bbc2174b198f2f Mon Sep 17 00:00:00 2001
+From: Dave Chinner <dchinner@redhat.com>
+Date: Sat, 26 Mar 2011 09:14:57 +1100
+Subject: xfs: register the inode cache shrinker before quotachecks
+
+From: Dave Chinner <dchinner@redhat.com>
+
+commit 704b2907c2d47ceb187c0e25a6bbc2174b198f2f upstream.
+
+During mount, we can do a quotacheck that involves a bulkstat pass
+on all inodes. If there are more inodes in the filesystem than can
+be held in memory, we require the inode cache shrinker to run to
+ensure that we don't run out of memory.
+
+Unfortunately, the inode cache shrinker is not registered until we
+get to the end of the superblock setup process, which is after a
+quotacheck is run if it is needed. Hence we need to register the
+inode cache shrinker earlier in the mount process so that we don't
+OOM during mount. This requires that we also initialise the syncd
+work before we register the shrinker, so we nee dto juggle that
+around as well.
+
+While there, make sure that we have set up the block sizes in the
+VFS superblock correctly before the quotacheck is run so that any
+inodes that are cached as a result of the quotacheck have their
+block size fields set up correctly.
+
+Signed-off-by: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Alex Elder <aelder@sgi.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/xfs/linux-2.6/xfs_super.c |   34 ++++++++++++++++++++++++----------
+ 1 file changed, 24 insertions(+), 10 deletions(-)
+
+--- a/fs/xfs/linux-2.6/xfs_super.c
++++ b/fs/xfs/linux-2.6/xfs_super.c
+@@ -1551,10 +1551,14 @@ xfs_fs_fill_super(
+       if (error)
+               goto out_free_sb;
+-      error = xfs_mountfs(mp);
+-      if (error)
+-              goto out_filestream_unmount;
+-
++      /*
++       * we must configure the block size in the superblock before we run the
++       * full mount process as the mount process can lookup and cache inodes.
++       * For the same reason we must also initialise the syncd and register
++       * the inode cache shrinker so that inodes can be reclaimed during
++       * operations like a quotacheck that iterate all inodes in the
++       * filesystem.
++       */
+       sb->s_magic = XFS_SB_MAGIC;
+       sb->s_blocksize = mp->m_sb.sb_blocksize;
+       sb->s_blocksize_bits = ffs(sb->s_blocksize) - 1;
+@@ -1562,6 +1566,16 @@ xfs_fs_fill_super(
+       sb->s_time_gran = 1;
+       set_posix_acl_flag(sb);
++      error = xfs_syncd_init(mp);
++      if (error)
++              goto out_filestream_unmount;
++
++      xfs_inode_shrinker_register(mp);
++
++      error = xfs_mountfs(mp);
++      if (error)
++              goto out_syncd_stop;
++
+       root = igrab(VFS_I(mp->m_rootip));
+       if (!root) {
+               error = ENOENT;
+@@ -1577,14 +1591,11 @@ xfs_fs_fill_super(
+               goto fail_vnrele;
+       }
+-      error = xfs_syncd_init(mp);
+-      if (error)
+-              goto fail_vnrele;
+-
+-      xfs_inode_shrinker_register(mp);
+-
+       return 0;
++ out_syncd_stop:
++      xfs_inode_shrinker_unregister(mp);
++      xfs_syncd_stop(mp);
+  out_filestream_unmount:
+       xfs_filestream_unmount(mp);
+  out_free_sb:
+@@ -1608,6 +1619,9 @@ xfs_fs_fill_super(
+       }
+  fail_unmount:
++      xfs_inode_shrinker_unregister(mp);
++      xfs_syncd_stop(mp);
++
+       /*
+        * Blow away any referenced inode in the filestreams cache.
+        * This can and will cause log traffic as inodes go inactive