Skip to content

Commit

Permalink
x86: fix a crash when adding both legacy AMD and CPUID 0x04 caches
Browse files Browse the repository at this point in the history
The old code increased numcaches in the second case
but it added additional caches at the beginning of the array.
Uninitialized caches in the array caused a divide by zero
(cache->nbthreads_sharing) when used later.

Only occurs if the CPUID vendor isn't recognized
(neither Intel, nor AMD, nor Zhaoxin) or in case
of clang 4.0 bug on FreeBSD11.1 (#282).

That's also why the code was crashing on Zhaoxin
instead of just reporting wrong topology (#279).

Signed-off-by: Brice Goglin <Brice.Goglin@inria.fr>
(cherry picked from commit a6f013c)
  • Loading branch information
bgoglin committed Jan 14, 2018
1 parent 1ff9b8b commit 94ec48a
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 2 deletions.
1 change: 1 addition & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Version 1.11.9
* Add support for Zhaoxin ZX-C and ZX-D processors in the x86 backend,
thanks to Jeff Zhao for the patch.
* Fix AMD Epyc 24-core L3 cache locality in the x86 backend.
* Don't crash in the x86 backend when the CPUID vendor string is unknown.
* Fix the missing pu discovery support bit on some OS.
* Fix the management of the lstopoStyle info attribute for custom colors.
* Add verbose warnings when failing to load hwloc v2.0+ XMLs.
Expand Down
11 changes: 9 additions & 2 deletions src/topology-x86.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright © 2010-2017 Inria. All rights reserved.
* Copyright © 2010-2018 Inria. All rights reserved.
* Copyright © 2010-2013 Université Bordeaux
* Copyright © 2010-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
Expand Down Expand Up @@ -250,6 +250,9 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
if (cpuid_type != intel && cpuid_type != zhaoxin && has_topoext(features)) {
unsigned apic_id, node_id, nodes_per_proc;

/* the code below doesn't want any other cache yet */
assert(!infos->numcaches);

eax = 0x8000001e;
hwloc_x86_cpuid(&eax, &ebx, &ecx, &edx);
infos->apicid = apic_id = eax;
Expand Down Expand Up @@ -357,6 +360,9 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
*/
if (cpuid_type != amd && highest_cpuid >= 0x04) {
unsigned level;

unsigned oldnumcaches = infos->numcaches; /* in case we got caches above */

for (cachenum = 0; ; cachenum++) {
unsigned type;
eax = 0x04;
Expand Down Expand Up @@ -386,7 +392,8 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
}
}

cache = infos->cache = malloc(infos->numcaches * sizeof(*infos->cache));
infos->cache = realloc(infos->cache, infos->numcaches * sizeof(*infos->cache));
cache = &infos->cache[oldnumcaches];

for (cachenum = 0; ; cachenum++) {
unsigned long linesize, linepart, ways, sets;
Expand Down

0 comments on commit 94ec48a

Please sign in to comment.