|
11 | 11 | #ifndef HWLOC_PRIVATE_CPUID_X86_H
|
12 | 12 | #define HWLOC_PRIVATE_CPUID_X86_H
|
13 | 13 |
|
| 14 | +/* A macro for annotating memory as uninitialized when building with MSAN |
| 15 | + * (and otherwise having no effect). See below for why this is used with |
| 16 | + * our custom assembly. |
| 17 | + */ |
| 18 | +#ifdef __has_feature |
| 19 | +#define HWLOC_HAS_FEATURE(name) __has_feature(name) |
| 20 | +#else |
| 21 | +#define HWLOC_HAS_FEATURE(name) 0 |
| 22 | +#endif |
| 23 | +#if HWLOC_HAS_FEATURE(memory_sanitizer) || defined(MEMORY_SANITIZER) |
| 24 | +#include <sanitizer/msan_interface.h> |
| 25 | +#define HWLOC_ANNOTATE_MEMORY_IS_INITIALIZED(ptr, len) __msan_unpoison(ptr, len) |
| 26 | +#else |
| 27 | +#define HWLOC_ANNOTATE_MEMORY_IS_INITIALIZED(ptr, len) |
| 28 | +#endif |
| 29 | + |
14 | 30 | #if (defined HWLOC_X86_32_ARCH) && (!defined HWLOC_HAVE_MSVC_CPUIDEX)
|
15 | 31 | static __hwloc_inline int hwloc_have_x86_cpuid(void)
|
16 | 32 | {
|
@@ -71,12 +87,18 @@ static __hwloc_inline void hwloc_x86_cpuid(unsigned *eax, unsigned *ebx, unsigne
|
71 | 87 | "movl %k2,%1\n\t"
|
72 | 88 | : "+a" (*eax), "=m" (*ebx), "=&r"(sav_rbx),
|
73 | 89 | "+c" (*ecx), "=&d" (*edx));
|
| 90 | + /* MSAN does not recognize the effect of the above assembly on the memory operand |
| 91 | + * (`"=m"(*ebx)`). This may get improved in MSAN at some point in the future, e.g. |
| 92 | + * see https://github.com/llvm/llvm-project/pull/77393. */ |
| 93 | + HWLOC_ANNOTATE_MEMORY_IS_INITIALIZED(ebx, sizeof *ebx); |
74 | 94 | #elif defined(HWLOC_X86_32_ARCH)
|
75 | 95 | __asm__(
|
76 | 96 | "mov %%ebx,%1\n\t"
|
77 | 97 | "cpuid\n\t"
|
78 | 98 | "xchg %%ebx,%1\n\t"
|
79 | 99 | : "+a" (*eax), "=&SD" (*ebx), "+c" (*ecx), "=&d" (*edx));
|
| 100 | + /* See above. */ |
| 101 | + HWLOC_ANNOTATE_MEMORY_IS_INITIALIZED(ebx, sizeof *ebx); |
80 | 102 | #else
|
81 | 103 | #error unknown architecture
|
82 | 104 | #endif
|
|
0 commit comments