From 27229ca63269c1be0a710f074fa9de4024f283f1 Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Fri, 17 Apr 2009 09:24:47 -0500 Subject: x86/uv: fix init of cpu-less nodes Fix an endcase in the UV initialization code for the "UV large system mode" of apicids. If node zero contains no cpus, cpus on another node will be the boot cpu. The percpu data that contains the extra apicid bits was not being initialized early enough. [ Impact: fix potential boot crash on cpu-less UV nodes ] Signed-off-by: Jack Steiner LKML-Reference: <20090417142447.GA23759@sgi.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic/x2apic_uv_x.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'arch/x86/kernel/apic/x2apic_uv_x.c') diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 1248318436e..49d2f5c739b 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -34,6 +35,17 @@ DEFINE_PER_CPU(int, x2apic_extra_bits); static enum uv_system_type uv_system_type; +static int early_get_nodeid(void) +{ + union uvh_node_id_u node_id; + unsigned long *mmr; + + mmr = early_ioremap(UV_LOCAL_MMR_BASE | UVH_NODE_ID, sizeof(*mmr)); + node_id.v = *mmr; + early_iounmap(mmr, sizeof(*mmr)); + return node_id.s.node_id; +} + static int uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id) { if (!strcmp(oem_id, "SGI")) { @@ -42,6 +54,8 @@ static int uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id) else if (!strcmp(oem_table_id, "UVX")) uv_system_type = UV_X2APIC; else if (!strcmp(oem_table_id, "UVH")) { + __get_cpu_var(x2apic_extra_bits) = + early_get_nodeid() << (UV_APIC_PNODE_SHIFT - 1); uv_system_type = UV_NON_UNIQUE_APIC; return 1; } -- cgit v1.2.3 From fc61e6636d13eb3a23eb29b4327eeee9de0ef3bc Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Mon, 20 Apr 2009 08:25:31 -0500 Subject: x86/uv: fix for no memory at paddr 0 Fix endcase where the memory at physical address 0 does not really exist AND one of the sockets on blade 0 has no active cpus. The memory that _appears_ to be at physical address 0 is actually memory that located at a different address but has been remapped by the chipset so that it appears to be at physical address 0. When determining the UV pnode, the algorithm for determining the pnode incorrectly used the relocated physical address instead of the actual (global) address. [ Impact: boot failure on partitioned systems ] Signed-off-by: Jack Steiner LKML-Reference: <20090420132530.GA23156@sgi.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic/x2apic_uv_x.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/x86/kernel/apic/x2apic_uv_x.c') diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index d6712334ce4..2bda6935297 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -652,6 +652,7 @@ void __init uv_system_init(void) if (uv_node_to_blade[nid] >= 0) continue; paddr = node_start_pfn(nid) << PAGE_SHIFT; + paddr = uv_soc_phys_ram_to_gpa(paddr); pnode = (paddr >> m_val) & pnode_mask; blade = boot_pnode_to_blade(pnode); uv_node_to_blade[nid] = blade; -- cgit v1.2.3