summaryrefslogtreecommitdiff
path: root/arch/x86/kernel/apic/x2apic_uv_x.c
diff options
context:
space:
mode:
authorMike Travis <travis@sgi.com>2017-01-13 09:21:11 -0600
committerIngo Molnar <mingo@kernel.org>2017-01-14 09:26:35 +0100
commiteee5715efd8c268724b14c956de6af5d4931f470 (patch)
treea6891e0fefac5c62371720b8f5db8ab3edede68a /arch/x86/kernel/apic/x2apic_uv_x.c
parentde1c2540aa4f7796f31acf5432597bb0eb086250 (diff)
x86/platform/UV: Fix panic with missing UVsystab support
Fix the panic where KEXEC'd kernel does not have access to EFI runtime mappings. This may cause the extended UVsystab to not be available. The solution is to revert to non-UV mode and continue with limited capabilities. Signed-off-by: Mike Travis <travis@sgi.com> Reviewed-by: Russ Anderson <rja@hpe.com> Reviewed-by: Alex Thorlton <athorlton@sgi.com> Acked-by: Dimitri Sivanich <sivanich@hpe.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/20170113152111.118886202@asylum.americas.sgi.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86/kernel/apic/x2apic_uv_x.c')
-rw-r--r--arch/x86/kernel/apic/x2apic_uv_x.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c
index 35690a168cf7..43930787cab9 100644
--- a/arch/x86/kernel/apic/x2apic_uv_x.c
+++ b/arch/x86/kernel/apic/x2apic_uv_x.c
@@ -1172,19 +1172,25 @@ static void __init decode_gam_rng_tbl(unsigned long ptr)
index, _min_socket, _max_socket, _min_pnode, _max_pnode);
}
-static void __init decode_uv_systab(void)
+static int __init decode_uv_systab(void)
{
struct uv_systab *st;
int i;
+ if (uv_hub_info->hub_revision < UV4_HUB_REVISION_BASE)
+ return 0; /* No extended UVsystab required */
+
st = uv_systab;
- if ((!st || st->revision < UV_SYSTAB_VERSION_UV4) && !is_uv4_hub())
- return;
- if (st->revision != UV_SYSTAB_VERSION_UV4_LATEST) {
- pr_crit(
+ if ((!st) || (st->revision < UV_SYSTAB_VERSION_UV4_LATEST)) {
+ int rev = st ? st->revision : 0;
+
+ pr_err(
"UV: BIOS UVsystab version(%x) mismatch, expecting(%x)\n",
- st->revision, UV_SYSTAB_VERSION_UV4_LATEST);
- BUG();
+ rev, UV_SYSTAB_VERSION_UV4_LATEST);
+ pr_err(
+ "UV: Cannot support UV operations, switching to generic PC\n");
+ uv_system_type = UV_NONE;
+ return -EINVAL;
}
for (i = 0; st->entry[i].type != UV_SYSTAB_TYPE_UNUSED; i++) {
@@ -1205,6 +1211,7 @@ static void __init decode_uv_systab(void)
break;
}
}
+ return 0;
}
/*
@@ -1373,7 +1380,8 @@ void __init uv_system_init(void)
map_low_mmrs();
uv_bios_init(); /* get uv_systab for decoding */
- decode_uv_systab();
+ if (decode_uv_systab() < 0)
+ return; /* UVsystab problem, abort UV init */
build_socket_tables();
build_uv_gr_table();
uv_init_hub_info(&hub_info);