ACPI: handle invalid ACPI SLIT table
This is a SLIT sanity checking patch. It moves slit_valid() function to generic ACPI code and does sanity checking for both x86 and ia64. It sets up node_distance with LOCAL_DISTANCE and REMOTE_DISTANCE when hitting invalid SLIT table on ia64. It also cleans up unused variable localities in acpi_parse_slit() on x86. Signed-off-by: Fenghua Yu <fenghua.yu@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
@@ -140,19 +140,42 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* A lot of BIOS fill in 10 (= no distance) everywhere. This messes
|
||||
* up the NUMA heuristics which wants the local node to have a smaller
|
||||
* distance than the others.
|
||||
* Do some quick checks here and only use the SLIT if it passes.
|
||||
*/
|
||||
static __init int slit_valid(struct acpi_table_slit *slit)
|
||||
{
|
||||
int i, j;
|
||||
int d = slit->locality_count;
|
||||
for (i = 0; i < d; i++) {
|
||||
for (j = 0; j < d; j++) {
|
||||
u8 val = slit->entry[d*i + j];
|
||||
if (i == j) {
|
||||
if (val != LOCAL_DISTANCE)
|
||||
return 0;
|
||||
} else if (val <= LOCAL_DISTANCE)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __init acpi_parse_slit(struct acpi_table_header *table)
|
||||
{
|
||||
struct acpi_table_slit *slit;
|
||||
u32 localities;
|
||||
|
||||
if (!table)
|
||||
return -EINVAL;
|
||||
|
||||
slit = (struct acpi_table_slit *)table;
|
||||
|
||||
/* downcast just for %llu vs %lu for i386/ia64 */
|
||||
localities = (u32) slit->locality_count;
|
||||
|
||||
if (!slit_valid(slit)) {
|
||||
printk(KERN_INFO "ACPI: SLIT table looks invalid. Not used.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
acpi_numa_slit_init(slit);
|
||||
|
||||
return 0;
|
||||
|
Reference in New Issue
Block a user