> Date: Fri, 26 Nov 2010 16:35:28 +1000 > From: David Gwynne <l...@animata.net> > > information about each cpu is stored in a statically sized array. > if we have more physical cpus than entries in that array, we currently > start storing cpu_info structures in unowned memory after that > array. this leads to Bad Things(tm). > > MAXCPUs should be bumped up on amd64, but we should also avoid > panicking on ridiculously overspecced boxes. i am sure i will regret > claiming that a 48core machine is overspecced in the very near > future though. > > Index: amd64/cpu.c > =================================================================== > RCS file: /cvs/src/sys/arch/amd64/amd64/cpu.c,v > retrieving revision 1.38 > diff -u -p -r1.38 cpu.c > --- amd64/cpu.c 13 Nov 2010 04:16:42 -0000 1.38 > +++ amd64/cpu.c 26 Nov 2010 06:31:53 -0000 > @@ -167,10 +165,24 @@ cpu_match(struct device *parent, void *m > { > struct cfdata *cf = match; > struct cpu_attach_args *caa = aux; > + int cpunum; > > - if (strcmp(caa->caa_name, cf->cf_driver->cd_name) == 0) > + /* > + * we cannot attach more cpus than we are set up to store in the > + * cpu_info array, so fail to match if we have more cpus than slots > + * in the array. > + */ > + > + for (cpunum = 0; cpunum < nitems(cpu_info); cpunum++) { > + if (cpu_info[cpunum] == NULL) > + break; > + } > + > + if (cpunum < nitems(cpu_info) && > + strcmp(caa->caa_name, cf->cf_driver->cd_name) == 0) > return 1; > - return 0; > + > + return (0); > } > > static void >
Sorry, but I think it is better to do this the same way it's done on hppa. The changes to i386 are a bit arger than strictly necessary to make the code identical to amd64. Only tested on i386, artificially limiting MAXCPUS to 1. Index: amd64/amd64/cpu.c =================================================================== RCS file: /cvs/src/sys/arch/amd64/amd64/cpu.c,v retrieving revision 1.38 diff -u -p -r1.38 cpu.c --- amd64/amd64/cpu.c 13 Nov 2010 04:16:42 -0000 1.38 +++ amd64/amd64/cpu.c 26 Nov 2010 15:00:49 -0000 @@ -168,9 +168,13 @@ cpu_match(struct device *parent, void *m struct cfdata *cf = match; struct cpu_attach_args *caa = aux; - if (strcmp(caa->caa_name, cf->cf_driver->cd_name) == 0) - return 1; - return 0; + if (strcmp(caa->caa_name, cf->cf_driver->cd_name) != 0) + return 0; + + if (cf->cf_unit >= MAXCPUS) + return 0; + + return 1; } static void Index: i386/i386/cpu.c =================================================================== RCS file: /cvs/src/sys/arch/i386/i386/cpu.c,v retrieving revision 1.41 diff -u -p -r1.41 cpu.c --- i386/i386/cpu.c 25 Jul 2010 21:43:35 -0000 1.41 +++ i386/i386/cpu.c 26 Nov 2010 15:00:53 -0000 @@ -157,14 +157,18 @@ struct cfdriver cpu_cd = { }; int -cpu_match(struct device *parent, void *matchv, void *aux) +cpu_match(struct device *parent, void *match, void *aux) { - struct cfdata *match = (struct cfdata *)matchv; - struct cpu_attach_args *caa = (struct cpu_attach_args *)aux; + struct cfdata *cf = match; + struct cpu_attach_args *caa = aux; - if (strcmp(caa->caa_name, match->cf_driver->cd_name) == 0) - return (1); - return (0); + if (strcmp(caa->caa_name, cf->cf_driver->cd_name) != 0) + return 0; + + if (cf->cf_unit >= MAXCPUS) + return 0; + + return 1; } void