i386,amd64: Explicitly set ECX=0 in do_cpuid() to be future-proof#2027
i386,amd64: Explicitly set ECX=0 in do_cpuid() to be future-proof#2027liweitianux wants to merge 1 commit intofreebsd:mainfrom
Conversation
|
Thank you for taking the time to contribute to FreeBSD! All issues resolved. |
bd45859 to
689d52e
Compare
|
BTW, can you point out the locations in code where we use do_cpuid() for CPUID leaves with sub-leafs, instead of using cpuid_count()? I think that such places must be fixed. I do not object against the change, but I think that it does not fix real bugs, unless you can provide examples from above. |
Yes I understand. It also surprised me when tuxillo showed me the
The relevant code in NVMM is: if (exit->u.rdmsr.msr == MSR_IA32_ARCH_CAPABILITIES) {
cpuid_desc_t descs;
x86_get_cpuid(0x00000000, &descs);
if (descs.eax < 7) {
goto error;
}
x86_get_cpuid(0x00000007, &descs);
if (!(descs.edx & CPUID_0_07_EDX_ARCH_CAP)) {
goto error; // XXX: incorrectly hit this
}
...The second So we've been quite lucky with the old |
Oh, I see your point. However, I think it's an extra burden to verify whether a CPUID leaf has sub-leaves. I think it also prevents misusing by explicitly setting ECX (sub-leaf) to 0. |
I mean, I might simply assume |
|
IOW, this was some porting bug. Another note, why re-ordering the functions? Make the patch where only do_cpuid() is changed to call cpuid_count(), leaving the functions in the place (AKA diff reduction). |
Yep. I agree with you. I'll update NVMM to be completely correct :)
They're |
|
I suggest to adjust the commit message to note that this is not a fix for existing bug in FreeBSD, but a porting aid. |
689d52e to
4c742cd
Compare
In principle, do_cpuid() should only be used for CPUID leaves without sub-leaves. Even accessing sub-leaf zero (ECX=0), one must use cpuid_count(ax, 0) rather than cpuid(ax). However, one might assume do_cpuid(ax) is equivalent to cpuid_count(ax, 0), but the old do_cpuid() did not initialize ECX before executing the CPUID instruction. If ECX contained a non-zero value, the instruction could return unexpected results, potentially leading to subtle and hard-to-debug issues, especially in ported code. To be future-proof and to help port code, adjust do_cpuid(ax) to be cpuid_count(ax, 0) to explicitly set ECX=0. It's believed that this change does not fix any real bugs in FreeBSD. See also the DragonFly commit: DragonFlyBSD/DragonFlyBSD@0087a1d Signed-off-by: Aaron LI <aly@aaronly.me>
4c742cd to
8267ef7
Compare
Hi. I've amended the commit message as you suggested. Please have another look. Thank you. |
In principle, do_cpuid() should only be used for CPUID leaves without sub-leaves. Even accessing sub-leaf zero (ECX=0), one must use cpuid_count(ax, 0) rather than cpuid(ax). However, one might assume do_cpuid(ax) is equivalent to cpuid_count(ax, 0), but the old do_cpuid() did not initialize ECX before executing the CPUID instruction. If ECX contained a non-zero value, the instruction could return unexpected results, potentially leading to subtle and hard-to-debug issues, especially in ported code. To be future-proof and to help port code, adjust do_cpuid(ax) to be cpuid_count(ax, 0) to explicitly set ECX=0. It's believed that this change does not fix any real bugs in FreeBSD. See also the DragonFly commit: DragonFlyBSD/DragonFlyBSD@0087a1d Signed-off-by: Aaron LI <aly@aaronly.me> Reviewed by: kib Pull Request: #2027
In principle, do_cpuid() should only be used for CPUID leaves without
sub-leaves. Even accessing sub-leaf zero (ECX=0), one must use
cpuid_count(ax, 0) rather than cpuid(ax).
However, one might assume do_cpuid(ax) is equivalent to
cpuid_count(ax, 0), but the old do_cpuid() did not initialize ECX before
executing the CPUID instruction. If ECX contained a non-zero value, the
instruction could return unexpected results, potentially leading to
subtle and hard-to-debug issues, especially in ported code.
To be future-proof and to help port code, adjust do_cpuid(ax) to be
cpuid_count(ax, 0) to explicitly set ECX=0.
It's believed that this change does not fix any real bugs in FreeBSD.
See also the DragonFly commit:
DragonFlyBSD/DragonFlyBSD@0087a1d