PR21166: Validate rdrand/rdseed support separately in gdb.reverse/insn-reverse-x86.c

Message ID 1487878141-21578-1-git-send-email-lgustavo@codesourcery.com
State New, archived
Headers

Commit Message

Luis Machado Feb. 23, 2017, 7:29 p.m. UTC
  As reported in PR21166, there are Intel processors out there that support
rdrand but not rdseed. The fix is to verify both features separately and only
run rdrand/rdseed tests if supported.

Pedro, could you please confirm this fixes what you see in your Fedora box?

2017-02-23  Luis Machado  <lgustavo@codesourcery.com>

	* gdb.reverse/insn-reverse.x86.c (check_rdrand_support): Renamed to ...
	(check_supported_features): ... this. Changed return type to void.
	(supports_rdseed): New static global.
	(rdseed): Check supports_rdseed.
	(initialize): Call check_supported_features.
---
 gdb/testsuite/gdb.reverse/insn-reverse-x86.c | 36 +++++++++++++++++++++-------
 1 file changed, 27 insertions(+), 9 deletions(-)
  

Comments

Pedro Alves Feb. 23, 2017, 7:51 p.m. UTC | #1
On 02/23/2017 07:29 PM, Luis Machado wrote:
> As reported in PR21166, there are Intel processors out there that support
> rdrand but not rdseed. The fix is to verify both features separately and only
> run rdrand/rdseed tests if supported.
> 
> Pedro, could you please confirm this fixes what you see in your Fedora box?

Will do.

Thanks,
Pedro Alves
  
Pedro Alves Feb. 23, 2017, 8 p.m. UTC | #2
On 02/23/2017 07:51 PM, Pedro Alves wrote:
> On 02/23/2017 07:29 PM, Luis Machado wrote:
>> As reported in PR21166, there are Intel processors out there that support
>> rdrand but not rdseed. The fix is to verify both features separately and only
>> run rdrand/rdseed tests if supported.
>>
>> Pedro, could you please confirm this fixes what you see in your Fedora box?
> 
> Will do.

Below's what I see when running insn-reverse.exp.  Ship it!

Thanks for fixing this.  It'd also be nice to fix the Tcl
ERROR.

Test run by pedro on Thu Feb 23 19:55:45 2017
Native configuration is x86_64-pc-linux-gnu

		=== gdb tests ===

Schedule of variations:
    unix

Running target unix
Running src/gdb/testsuite/gdb.reverse/insn-reverse.exp ...
PASS: gdb.reverse/insn-reverse.exp: get integer valueof "n_testcases" (2)
PASS: gdb.reverse/insn-reverse.exp: rdrand: continue
PASS: gdb.reverse/insn-reverse.exp: rdrand: turn on process record
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 0:mov    0x2009e7(%rip),%eax        # 0x601058 <supports_rdrand>
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 1:test   %eax,%eax
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 2:je     0x400783 <rdrand+284>
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 3:rdrand %ax
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 4:rdrand %bx
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 5:rdrand %cx
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 6:rdrand %dx
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 7:mov    %di,%ax
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 8:rdrand %di
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 9:mov    %ax,%di
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 10:mov    %si,%ax
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 11:rdrand %si
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 12:mov    %ax,%si
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 13:mov    %bp,%ax
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 14:rdrand %bp
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 15:mov    %ax,%bp
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 16:mov    %sp,%ax
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 17:rdrand %sp
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 18:mov    %ax,%sp
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 19:rdrand %r8w
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 20:rdrand %r9w
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 21:rdrand %r10w
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 22:rdrand %r11w
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 23:rdrand %r12w
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 24:rdrand %r13w
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 25:rdrand %r14w
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 26:rdrand %r15w
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 27:rdrand %eax
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 28:rdrand %ebx
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 29:rdrand %ecx
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 30:rdrand %edx
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 31:mov    %rdi,%rax
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 32:rdrand %edi
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 33:mov    %rax,%rdi
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 34:mov    %rsi,%rax
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 35:rdrand %esi
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 36:mov    %rax,%rsi
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 37:mov    %rbp,%rax
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 38:rdrand %ebp
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 39:mov    %rax,%rbp
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 40:mov    %rsp,%rax
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 41:rdrand %esp
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 42:mov    %rax,%rsp
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 43:rdrand %r8d
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 44:rdrand %r9d
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 45:rdrand %r10d
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 46:rdrand %r11d
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 47:rdrand %r12d
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 48:rdrand %r13d
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 49:rdrand %r14d
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 50:rdrand %r15d
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 51:rdrand %rax
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 52:rdrand %rbx
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 53:rdrand %rcx
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 54:rdrand %rdx
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 55:mov    %rdi,%rax
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 56:rdrand %rdi
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 57:mov    %rax,%rdi
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 58:mov    %rsi,%rax
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 59:rdrand %rsi
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 60:mov    %rax,%rsi
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 61:mov    %rbp,%rax
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 62:rdrand %rbp
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 63:mov    %rax,%rbp
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 64:mov    %rsp,%rax
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 65:rdrand %rsp
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 66:mov    %rax,%rsp
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 67:rdrand %r8
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 68:rdrand %r9
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 69:rdrand %r10
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 70:rdrand %r11
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 71:rdrand %r12
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 72:rdrand %r13
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 73:rdrand %r14
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 74:rdrand %r15
PASS: gdb.reverse/insn-reverse.exp: rdrand: compare registers on insn 75:jmp    0x400784 <rdrand+285>
PASS: gdb.reverse/insn-reverse.exp: rdrand: record stop
PASS: gdb.reverse/insn-reverse.exp: rdseed: continue
PASS: gdb.reverse/insn-reverse.exp: rdseed: turn on process record
PASS: gdb.reverse/insn-reverse.exp: rdseed: compare registers on insn 0:mov    0x2008cc(%rip),%eax        # 0x60105c <supports_rdseed>
PASS: gdb.reverse/insn-reverse.exp: rdseed: compare registers on insn 1:test   %eax,%eax
PASS: gdb.reverse/insn-reverse.exp: rdseed: compare registers on insn 2:je     0x4008a2 <rdseed+284>
PASS: gdb.reverse/insn-reverse.exp: rdseed: compare registers on insn 3:nop
PASS: gdb.reverse/insn-reverse.exp: rdseed: record stop

		=== gdb Summary ===

# of expected passes		87
  
Luis Machado Feb. 23, 2017, 8:43 p.m. UTC | #3
On 02/23/2017 02:00 PM, Pedro Alves wrote:
> On 02/23/2017 07:51 PM, Pedro Alves wrote:
>> On 02/23/2017 07:29 PM, Luis Machado wrote:
>>> Pedro, could you please confirm this fixes what you see in your Fedora box?
>>
>> Will do.
>
> Below's what I see when running insn-reverse.exp.  Ship it!
>

Good! Thanks for checking.

Pushed as c26db3b33b7274946e42c6656ee1c0911cefb865.

> Thanks for fixing this.  It'd also be nice to fix the Tcl
> ERROR.

I'll take a look at it. We should probably detect a bad situation and 
abort further tests. Otherwise we end up with a bunch of repeated failures.
  

Patch

diff --git a/gdb/testsuite/gdb.reverse/insn-reverse-x86.c b/gdb/testsuite/gdb.reverse/insn-reverse-x86.c
index 7f87392..85b169d 100644
--- a/gdb/testsuite/gdb.reverse/insn-reverse-x86.c
+++ b/gdb/testsuite/gdb.reverse/insn-reverse-x86.c
@@ -18,20 +18,38 @@ 
 #include <cpuid.h>
 #include <stdint.h>
 
-/* 0 if the CPU supports rdrand/rdseed and non-zero otherwise.  */
+/* 0 if the CPU supports rdrand and non-zero otherwise.  */
 static unsigned int supports_rdrand;
 
-/* Returns non-zero if rdrand/rdseed instructions are supported and
-   zero otherwise.  */
+/* 0 if the CPU supports rdseed and non-zero otherwise.  */
+static unsigned int supports_rdseed;
 
-static unsigned int
-check_rdrand_support (void)
+/* Check supported features and set globals accordingly.  The globals
+   can be used to prevent unsupported tests from running.  */
+
+static void
+check_supported_features (void)
 {
   unsigned int rdrand_mask = (1 << 30);
+  unsigned int rdseed_mask = (1 << 18);
   unsigned int eax, ebx, ecx, edx;
+  unsigned int vendor;
+  unsigned int max_level;
+
+  max_level = __get_cpuid_max (0, &vendor);
+
+  if (max_level < 1)
+    return;
+
+  __cpuid (1, eax, ebx, ecx, edx);
 
-  __get_cpuid (1, &eax, &ebx, &ecx, &edx);
-  return ((ecx & rdrand_mask) == rdrand_mask);
+  supports_rdrand = ((ecx & rdrand_mask) == rdrand_mask);
+
+  if (max_level >= 7)
+    {
+      __cpuid_count (7, 0, eax, ebx, ecx, edx);
+      supports_rdseed = ((ebx & rdseed_mask) == rdseed_mask);
+    }
 }
 
 /* Test rdrand support for various output registers.  */
@@ -147,7 +165,7 @@  rdseed (void)
   /* Get a random seed from the rdseed assembly instruction.  */
   register long seed;
 
-  if (!supports_rdrand)
+  if (!supports_rdseed)
     return;
 
   /* 16-bit random seeds.  */
@@ -250,7 +268,7 @@  static void
 initialize (void)
 {
   /* Initialize supported features.  */
-  supports_rdrand = check_rdrand_support ();
+  check_supported_features ();
 }
 
 /* Functions testing instruction decodings.  GDB will test all of these.  */