x86: Make unsuccessful CPUID instructions zero the result.
authorGabe Black <gabeblack@google.com>
Wed, 14 Aug 2019 22:32:37 +0000 (15:32 -0700)
committerGabe Black <gabeblack@google.com>
Thu, 15 Aug 2019 02:53:04 +0000 (02:53 +0000)
The previous implementation left the registers unmodified which is
technically correct since there is no defined behavior in that case or
a fault to raise. That would make what happened when the following code
consumed the result unpredictable because it would depend on what junk
values were left in the registers. This was originally not a problem
since the space of supported functions were tightly packed, but someone
added a new function with a gap without adjusting this behavior.

This change makes CPUID zero out RAX, RBX, RCX, and RDX when it fails.
That should be more predictable and cause less flakey failures.

Change-Id: If6ffb17c2969d34aff1600c0ffc32333d0b9be44
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20168
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Reviewed-by: Pouya Fotouhi <pfotouhi@ucdavis.edu>
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/arch/x86/isa/decoder/two_byte_opcodes.isa

index 339e5a0ab487992e039c0e7455cc581dca276422..7a4f9e198788bcf44068602a9d2f6374a87a77b5 100644 (file)
                     Rcx = result.rcx;
                     Rdx = result.rdx;
                 } else {
-                    Rax = Rax;
-                    Rbx = Rbx;
-                    Rcx = Rcx;
-                    Rdx = Rdx;
+                    // It isn't defined what to do in this case. We used to
+                    // leave R[abcd]x unmodified, but setting them all to 0
+                    // seems a little safer and more predictable.
+                    Rax = 0;
+                    Rbx = 0;
+                    Rcx = 0;
+                    Rdx = 0;
                 }
                 }});
             0x3: Inst::BT(Ev,Gv);