summaryrefslogtreecommitdiffstats
path: root/sys/x86
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2012-01-03 20:53:58 +0000
committerjhb <jhb@FreeBSD.org>2012-01-03 20:53:58 +0000
commit6d5201fff5de9848473516a5a44af10d3453890c (patch)
treea20bb1afc42a8b4194be47565b5a0b77a26ac301 /sys/x86
parentb168d78675f739ce802bf0e2264c8ae4c538e984 (diff)
downloadFreeBSD-src-6d5201fff5de9848473516a5a44af10d3453890c.zip
FreeBSD-src-6d5201fff5de9848473516a5a44af10d3453890c.tar.gz
Fix a few bugs in the SRAT parsing code:
- Actually increment ndomain when building our list of known domains so that we can properly renumber them to be 0-based and dense. - If the number of domains exceeds the configured maximum (VM_NDOMAIN), bail out of processing the SRAT and disable NUMA rather than hitting an obscure panic later. - Don't bother parsing the SRAT at all if VM_NDOMAIN is set to 1 to disable NUMA (the default). Reported by: phk (2) MFC after: 1 week
Diffstat (limited to 'sys/x86')
-rw-r--r--sys/x86/acpica/srat.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/sys/x86/acpica/srat.c b/sys/x86/acpica/srat.c
index cd04f87..6c6eb8f 100644
--- a/sys/x86/acpica/srat.c
+++ b/sys/x86/acpica/srat.c
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <dev/acpica/acpivar.h>
+#if VM_NDOMAIN > 1
struct cpu_info {
int enabled:1;
int has_memory:1;
@@ -237,9 +238,9 @@ check_phys_avail(void)
/*
* Renumber the memory domains to be compact and zero-based if not
- * already.
+ * already. Returns an error if there are too many domains.
*/
-static void
+static int
renumber_domains(void)
{
int domains[VM_PHYSSEG_MAX];
@@ -261,6 +262,11 @@ renumber_domains(void)
for (j = ndomain; j > slot; j--)
domains[j] = domains[j - 1];
domains[slot] = mem_info[i].domain;
+ ndomain++;
+ if (ndomain > VM_NDOMAIN) {
+ printf("SRAT: Too many memory domains\n");
+ return (EFBIG);
+ }
}
/* Renumber each domain to its index in the sorted 'domains' list. */
@@ -280,6 +286,7 @@ renumber_domains(void)
if (cpus[j].enabled && cpus[j].domain == domains[i])
cpus[j].domain = i;
}
+ return (0);
}
/*
@@ -306,13 +313,12 @@ parse_srat(void *dummy)
srat_walk_table(srat_parse_entry, &error);
acpi_unmap_table(srat);
srat = NULL;
- if (error || check_domains() != 0 || check_phys_avail() != 0) {
+ if (error || check_domains() != 0 || check_phys_avail() != 0 ||
+ renumber_domains() != 0) {
srat_physaddr = 0;
return;
}
- renumber_domains();
-
/* Point vm_phys at our memory affinity table. */
mem_affinity = mem_info;
}
@@ -354,3 +360,4 @@ srat_set_cpus(void *dummy)
}
}
SYSINIT(srat_set_cpus, SI_SUB_CPU, SI_ORDER_ANY, srat_set_cpus, NULL);
+#endif /* VM_NDOMAIN > 1 */
OpenPOWER on IntegriCloud