[systemd-devel] rdrand generated with march=winchip-c6 in systemd-241
tedheadster
tedheadster at gmail.com
Sun May 19 01:28:57 UTC 2019
On Sat, May 18, 2019 at 6:57 PM Segher Boessenkool
<segher at kernel.crashing.org> wrote:
> Something like
>
> *__ebx = *__ecx = *__edx = 0;
> asm volatile("" : "+r"(*__eax), "+r"(*__ebx), "+r"(*__ecx), "+r"(*__edx));
> __cpuid (__leaf, *__eax, *__ebx, *__ecx, *__edx);
>
> should do the trick.
Segher,
that got closer, but not quite there. I made a change to your
suggesting and got what I think I want:
0xb7e21491 <+81>: test $0x200000,%eax
0xb7e21496 <+86>: je 0xb7e214c0 <rdrand+128>
0xb7e21498 <+88>: xor %edi,%edi <--- zeroes %edi for use below
0xb7e2149a <+90>: mov %edi,%eax
0xb7e2149c <+92>: cpuid
0xb7e2149e <+94>: test %eax,%eax
0xb7e214a0 <+96>: je 0xb7e214c0 <rdrand+128>
0xb7e214a2 <+98>: mov %edi,%ebx <--- zeroes %ebx
0xb7e214a4 <+100>: mov %edi,%ecx <--- zeroes %ecx
0xb7e214a6 <+102>: mov %edi,%edx <--- zeroes %edx
0xb7e214a8 <+104>: mov $0x1,%eax
0xb7e214ad <+109>: cpuid
0xb7e214af <+111>: shr $0x1e,%ecx
0xb7e214b2 <+114>: and $0x1,%ecx
0xb7e214b5 <+117>: mov %ecx,0x35a0(%esi)
0xb7e214bb <+123>: jmp 0xb7e21458 <rdrand+24>
Here is the patch:
--- cpuid.h.orig 2019-05-14 05:52:11.000000000 -0400
+++ cpuid.h 2019-05-18 21:25:27.000000000 -0400
@@ -251,6 +251,14 @@
if (__maxlevel == 0 || __maxlevel < __leaf)
return 0;
+ /* At least one confirmed cpu (Winchip 2) does not set %ecx correctly for
+ cpuid() and leaves garbage in it upon return ('auls' from 'CentaurHauls'
+ in %ebx:%edx:%ecx vendor identification string). Forcibly zero the
+ registers before calling cpuid() as a precaution. */
+
+ *__ebx = *__ecx = *__edx = 0;
+ asm volatile("" : "+b" (*__ebx), "+c" (*__ecx), "+d" (*__edx));
+
__cpuid (__leaf, *__eax, *__ebx, *__ecx, *__edx);
return 1;
}
I tested this with systemd on real hardware and it worked nicely.
- Matthew
More information about the systemd-devel
mailing list