--- /dev/null
+From 47ea91b4052d9e94b9dca5d7a3d947fbebd07ba9 Mon Sep 17 00:00:00 2001
+From: Ram Pai <linuxram@us.ibm.com>
+Date: Thu, 22 Sep 2011 15:48:58 +0800
+Subject: Resource: fix wrong resource window calculation
+
+From: Ram Pai <linuxram@us.ibm.com>
+
+commit 47ea91b4052d9e94b9dca5d7a3d947fbebd07ba9 upstream.
+
+__find_resource() incorrectly returns a resource window which overlaps
+an existing allocated window. This happens when the parent's
+resource-window spans 0x00000000 to 0xffffffff and is entirely allocated
+to all its children resource-windows.
+
+__find_resource() looks for gaps in resource allocation among the
+children resource windows. When it encounters the last child window it
+blindly tries the range next to one allocated to the last child. Since
+the last child's window ends at 0xffffffff the calculation overflows,
+leading the algorithm to believe that any window in the range 0x0000000
+to 0xfffffff is available for allocation. This leads to a conflicting
+window allocation.
+
+Michal Ludvig reported this issue seen on his platform. The following
+patch fixes the problem and has been verified by Michal. I believe this
+bug has been there for ages. It got exposed by git commit 2bbc6942273b
+("PCI : ability to relocate assigned pci-resources")
+
+Signed-off-by: Ram Pai <linuxram@us.ibm.com>
+Tested-by: Michal Ludvig <mludvig@logix.net.nz>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Herton Ronaldo Krzesinski <herton.krzesinski@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/resource.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/kernel/resource.c
++++ b/kernel/resource.c
+@@ -419,6 +419,9 @@ static int __find_resource(struct resour
+ else
+ tmp.end = root->end;
+
++ if (tmp.end < tmp.start)
++ goto next;
++
+ resource_clip(&tmp, constraint->min, constraint->max);
+ arch_remove_reservations(&tmp);
+
+@@ -436,8 +439,10 @@ static int __find_resource(struct resour
+ return 0;
+ }
+ }
+- if (!this)
++
++next: if (!this || this->end == root->end)
+ break;
++
+ if (this != old)
+ tmp.start = this->end + 1;
+ this = this->sibling;