]> wimlib.net Git - wimlib/commitdiff
cpu_features.c: fix unconditional execution of xgetbv
authorEric Biggers <ebiggers3@gmail.com>
Thu, 27 Apr 2023 00:35:37 +0000 (17:35 -0700)
committerEric Biggers <ebiggers3@gmail.com>
Thu, 27 Apr 2023 00:36:16 +0000 (17:36 -0700)
Ensure that the execution of the xgetbv instruction doesn't get moved
out from under the check for OSXSAVE support by a compiler optimization.
This fixes a crash on older CPUs, introduced in v1.14.0.

Reported at https://wimlib.net/forums/viewtopic.php?p=1527

src/cpu_features.c

index 7611b3db52e8ef0e43f3e960f0584c1794642924..08520c9c681896410cf28d22e740f32955e67875 100644 (file)
 static inline void
 cpuid(u32 leaf, u32 subleaf, u32 *a, u32 *b, u32 *c, u32 *d)
 {
-       asm(".ifnc %%ebx, %1; mov  %%ebx, %1; .endif\n"
-           "cpuid                                  \n"
-           ".ifnc %%ebx, %1; xchg %%ebx, %1; .endif\n"
-           : "=a" (*a), EBX_CONSTRAINT (*b), "=c" (*c), "=d" (*d)
-           : "a" (leaf), "c" (subleaf));
+       asm volatile(".ifnc %%ebx, %1; mov  %%ebx, %1; .endif\n"
+                    "cpuid                                  \n"
+                    ".ifnc %%ebx, %1; xchg %%ebx, %1; .endif\n"
+                    : "=a" (*a), EBX_CONSTRAINT (*b), "=c" (*c), "=d" (*d)
+                    : "a" (leaf), "c" (subleaf));
 }
 
 /* Read an extended control register. */
@@ -70,8 +70,12 @@ read_xcr(u32 index)
        /*
         * Execute the "xgetbv" instruction.  Old versions of binutils do not
         * recognize this instruction, so list the raw bytes instead.
+        *
+        * This must be 'volatile' to prevent this code from being moved out
+        * from under the check for OSXSAVE.
         */
-       asm(".byte 0x0f, 0x01, 0xd0" : "=d" (d), "=a" (a) : "c" (index));
+       asm volatile(".byte 0x0f, 0x01, 0xd0" :
+                    "=d" (d), "=a" (a) : "c" (index));
 
        return ((u64)d << 32) | a;
 }