Commit 379b97e2 authored by Mike Travis's avatar Mike Travis Committed by Ingo Molnar

x86/apic/uv: Update the UV APIC driver check

Fix a bug in the OEM check function that determines if the
system is a UV system and the BIOS is compatible with the
kernel's UV apic driver.  This prevents some possibly obscure
panics and guards the system against being started on SGI
hardware that does not have the required kernel support.
Signed-off-by: default avatarMike Travis <travis@sgi.com>
Acked-by: default avatarHedi Berriche <hedi@sgi.com>
Acked-by: default avatarDimitri Sivanich <sivanich@sgi.com>
Link: http://lkml.kernel.org/r/20150409182629.112998930@asylum.americas.sgi.comSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 7a4e0170
......@@ -144,36 +144,60 @@ static void __init uv_set_apicid_hibit(void)
static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
{
int pnodeid, is_uv1, is_uv2, is_uv3;
int pnodeid;
int uv_apic;
if (strncmp(oem_id, "SGI", 3) != 0)
return 0;
is_uv1 = !strcmp(oem_id, "SGI");
is_uv2 = !strcmp(oem_id, "SGI2");
is_uv3 = !strncmp(oem_id, "SGI3", 4); /* there are varieties of UV3 */
if (is_uv1 || is_uv2 || is_uv3) {
uv_hub_info->hub_revision =
(is_uv1 ? UV1_HUB_REVISION_BASE :
(is_uv2 ? UV2_HUB_REVISION_BASE :
UV3_HUB_REVISION_BASE));
pnodeid = early_get_pnodeid();
early_get_apic_pnode_shift();
x86_platform.is_untracked_pat_range = uv_is_untracked_pat_range;
x86_platform.nmi_init = uv_nmi_init;
if (!strcmp(oem_table_id, "UVL"))
uv_system_type = UV_LEGACY_APIC;
else if (!strcmp(oem_table_id, "UVX"))
uv_system_type = UV_X2APIC;
else if (!strcmp(oem_table_id, "UVH")) {
__this_cpu_write(x2apic_extra_bits,
pnodeid << uvh_apicid.s.pnode_shift);
uv_system_type = UV_NON_UNIQUE_APIC;
uv_set_apicid_hibit();
return 1;
}
/*
* Determine UV arch type.
* SGI: UV100/1000
* SGI2: UV2000/3000
* SGI3: UV300 (truncated to 4 chars because of different varieties)
*/
uv_hub_info->hub_revision =
!strncmp(oem_id, "SGI3", 4) ? UV3_HUB_REVISION_BASE :
!strcmp(oem_id, "SGI2") ? UV2_HUB_REVISION_BASE :
!strcmp(oem_id, "SGI") ? UV1_HUB_REVISION_BASE : 0;
if (uv_hub_info->hub_revision == 0)
goto badbios;
pnodeid = early_get_pnodeid();
early_get_apic_pnode_shift();
x86_platform.is_untracked_pat_range = uv_is_untracked_pat_range;
x86_platform.nmi_init = uv_nmi_init;
if (!strcmp(oem_table_id, "UVX")) { /* most common */
uv_system_type = UV_X2APIC;
uv_apic = 0;
} else if (!strcmp(oem_table_id, "UVH")) { /* only UV1 systems */
uv_system_type = UV_NON_UNIQUE_APIC;
__this_cpu_write(x2apic_extra_bits,
pnodeid << uvh_apicid.s.pnode_shift);
uv_set_apicid_hibit();
uv_apic = 1;
} else if (!strcmp(oem_table_id, "UVL")) { /* only used for */
uv_system_type = UV_LEGACY_APIC; /* very small systems */
uv_apic = 0;
} else {
goto badbios;
}
return 0;
pr_info("UV: OEM IDs %s/%s, System/HUB Types %d/%d, uv_apic %d\n",
oem_id, oem_table_id, uv_system_type,
uv_min_hub_revision_id, uv_apic);
return uv_apic;
badbios:
pr_err("UV: OEM_ID:%s OEM_TABLE_ID:%s\n", oem_id, oem_table_id);
pr_err("Current BIOS not supported, update kernel and/or BIOS\n");
BUG();
}
enum uv_system_type get_uv_system_type(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment