--- /dev/null
+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)
--- /dev/null
+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';
--- /dev/null
+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';
+
--- /dev/null
+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 = {
--- /dev/null
+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);
--- /dev/null
+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;
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
--- /dev/null
+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;
--- /dev/null
+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;
+ }
--- /dev/null
+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);
+ }
+
--- /dev/null
+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