On Sun, May 19, 2019 at 12:10 PM tedheadster <tedheads...@gmail.com> wrote: > > I have confirmed that the IDT Winchip 2 does not expressly set %ecx > after a call to cpuid() with %eax = 1, and this causes incorrect > reporting of cpu capabilities. The %ecx register should return 0x0 > (and likely %ebx should too) on this hardware. This patch proposes a > fix. > > The symptoms of this arose on a Winchip 2 system when systemd called > cpuid() with %eax = 1 and it incorrectly reported rdrand() support > (bit 30 set in %ecx). A call to the supposedly supported rdrand() > function triggered an illegal instruction exception, causing the > system to panic early in booting. > > The IDT Winchip documentation is silent on what happens to %ecx and > %ebx after such a call (see below). It appears to leave whatever is in > %ecx untouched instead of zeroing it. This patch defensively zeroes > out %ebx:%ecx:%edx before such a call in cpuid.h. > > I should be able to test the earlier Winchip C6 model in the future. I > wlll also check older AMD, Cyrix, and VIA processors. > > Thanks to Mike Gilbert for suggesting the solution. Thank you also to > Segher Boessenkool for helping get the inline assembly syntax correct.
Sorry for the lack of feedback; your mails were getting filed into my systemd-devel label and I only review that every few days. I think it would be simpler/better to clear the registers within the __cpuid macro itself. Something like this I think: diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h index 8ddd425c8b7..ae05bfc6114 100644 --- a/gcc/config/i386/cpuid.h +++ b/gcc/config/i386/cpuid.h @@ -188,7 +188,10 @@ #define signature_VORTEX_edx 0x36387865 #define __cpuid(level, a, b, c, d) \ - __asm__ ("cpuid\n\t" \ + __asm__ ("xorl\t%1, %1\n\t" \ + "xorl\t%2, %2\n\t" \ + "xorl\t%3, %3\n\t" \ + "cpuid\n\t" \ : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ : "0" (level))