From: Andi Kleen <ak@suse.de>

The code to detect IO links on Opteron would not check if the node had
actually memory.  This could lead to pci_bus_to_node returning an invalid
node, which might cause crashes later when dma_alloc_coherent passes it to
page_alloc_node().  

The bug has been there forever but for some reason it is causing now
crashes.

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 arch/x86_64/pci/k8-bus.c |   13 +++++++++++--
 1 files changed, 11 insertions(+), 2 deletions(-)

diff -puN arch/x86_64/pci/k8-bus.c~x86_64-dont-oops-at-boot-when-empty-opteron-node-has-io arch/x86_64/pci/k8-bus.c
--- devel/arch/x86_64/pci/k8-bus.c~x86_64-dont-oops-at-boot-when-empty-opteron-node-has-io	2005-08-22 18:15:30.000000000 -0700
+++ devel-akpm/arch/x86_64/pci/k8-bus.c	2005-08-22 18:15:30.000000000 -0700
@@ -47,13 +47,22 @@ fill_mp_bus_to_cpumask(void)
 			 * if there are no busses hanging off of the current
 			 * ldt link then both the secondary and subordinate
 			 * bus number fields are set to 0.
+			 *
+			 * RED-PEN
+			 * This is slightly broken because it assumes
+ 			 * HT node IDs == Linux node ids, which is not always
+			 * true. However it is probably mostly true.
 			 */
 			if (!(SECONDARY_LDT_BUS_NUMBER(ldtbus) == 0
 				&& SUBORDINATE_LDT_BUS_NUMBER(ldtbus) == 0)) {
 				for (j = SECONDARY_LDT_BUS_NUMBER(ldtbus);
 				     j <= SUBORDINATE_LDT_BUS_NUMBER(ldtbus);
-				     j++)
-					pci_bus_to_node[j] = NODE_ID(nid);
+				     j++) {
+					int node = NODE_ID(nid);
+					if (!node_online(node))
+						node = 0;
+					pci_bus_to_node[j] = node;
+				}
 			}
 		}
 	}
_