public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2] S390: Fix TDB regset recognition
@ 2013-11-05 17:46 Andreas Arnez
  2013-11-06 20:49 ` Ulrich Weigand
  0 siblings, 1 reply; 2+ messages in thread
From: Andreas Arnez @ 2013-11-05 17:46 UTC (permalink / raw)
  To: gdb-patches; +Cc: Ulrich Weigand, Andreas Krebbel

When checking for the presence of the TDB regset, the current code
interprets ENODATA from PTRACE_GETREGSET as an indication that the TDB
regset *could* occur on this system, but the inferior stopped outside
a transaction.  However, the Linux kernel actually reports ENODATA
even on systems without the transactional execution facility.  Thus
the logic is now changed to check the TE field in the HWCAP as well.

This version also checks the existence of the TDB regset -- just to be
on the safe side when running on TE-enabled hardware with a kernel
that does not offer the TDB regset for some reason.

gdb/
	* s390-linux-nat.c (s390_read_description): Consider the TE field
	in the HWCAP for determining 'have_regset_tdb'.

gdbserver/
	* linux-s390-low.c (HWCAP_S390_TE): New define.
	(s390_arch_setup): Consider the TE field in the HWCAP for
	determining 'have_regset_tdb'.
---
 gdb/gdbserver/linux-s390-low.c | 48 ++++++++++++++++++++++++++----------------
 gdb/s390-linux-nat.c           |  5 +++--
 2 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/gdb/gdbserver/linux-s390-low.c b/gdb/gdbserver/linux-s390-low.c
index a2df037..ae8204b 100644
--- a/gdb/gdbserver/linux-s390-low.c
+++ b/gdb/gdbserver/linux-s390-low.c
@@ -32,6 +32,10 @@
 #define HWCAP_S390_HIGH_GPRS 512
 #endif
 
+#ifndef HWCAP_S390_TE
+#define HWCAP_S390_TE 1024
+#endif
+
 #ifndef PTRACE_GETREGSET
 #define PTRACE_GETREGSET 0x4204
 #endif
@@ -425,23 +429,6 @@ s390_arch_setup (void)
     = s390_check_regset (pid, NT_S390_SYSTEM_CALL, 4);
   int have_regset_tdb = s390_check_regset (pid, NT_S390_TDB, 256);
 
-  /* Update target_regsets according to available register sets.  */
-  for (regset = s390_regsets; regset->fill_function != NULL; regset++)
-    if (regset->get_request == PTRACE_GETREGSET)
-      switch (regset->nt_type)
-	{
-	case NT_S390_LAST_BREAK:
-	  regset->size = have_regset_last_break? 8 : 0;
-	  break;
-	case NT_S390_SYSTEM_CALL:
-	  regset->size = have_regset_system_call? 4 : 0;
-	  break;
-	case NT_S390_TDB:
-	  regset->size = have_regset_tdb ? 256 : 0;
-	default:
-	  break;
-	}
-
   /* Assume 31-bit inferior process.  */
   if (have_regset_system_call)
     tdesc = tdesc_s390_linux32v2;
@@ -456,6 +443,7 @@ s390_arch_setup (void)
   {
     unsigned int pswm;
     struct regcache *regcache = new_register_cache (tdesc);
+
     fetch_inferior_registers (regcache, find_regno (tdesc, "pswm"));
     collect_register_by_name (regcache, "pswm", &pswm);
     free_register_cache (regcache);
@@ -463,8 +451,12 @@ s390_arch_setup (void)
     if (pswm & 1)
       {
 	if (have_regset_tdb)
+	  have_regset_tdb =
+	    (s390_get_hwcap (tdesc_s390x_linux64v2) & HWCAP_S390_TE) != 0;
+
+	if (have_regset_tdb)
 	  tdesc = tdesc_s390x_te_linux64;
-	if (have_regset_system_call)
+	else if (have_regset_system_call)
 	  tdesc = tdesc_s390x_linux64v2;
 	else if (have_regset_last_break)
 	  tdesc = tdesc_s390x_linux64v1;
@@ -477,6 +469,8 @@ s390_arch_setup (void)
     else if (s390_get_hwcap (tdesc) & HWCAP_S390_HIGH_GPRS)
       {
 	have_hwcap_s390_high_gprs = 1;
+	if (have_regset_tdb)
+	  have_regset_tdb = (s390_get_hwcap (tdesc) & HWCAP_S390_TE) != 0;
 
 	if (have_regset_tdb)
 	  tdesc = tdesc_s390_te_linux64;
@@ -489,6 +483,24 @@ s390_arch_setup (void)
       }
   }
 #endif
+
+  /* Update target_regsets according to available register sets.  */
+  for (regset = s390_regsets; regset->fill_function != NULL; regset++)
+    if (regset->get_request == PTRACE_GETREGSET)
+      switch (regset->nt_type)
+	{
+	case NT_S390_LAST_BREAK:
+	  regset->size = have_regset_last_break? 8 : 0;
+	  break;
+	case NT_S390_SYSTEM_CALL:
+	  regset->size = have_regset_system_call? 4 : 0;
+	  break;
+	case NT_S390_TDB:
+	  regset->size = have_regset_tdb ? 256 : 0;
+	default:
+	  break;
+	}
+
   current_process ()->tdesc = tdesc;
 }
 
diff --git a/gdb/s390-linux-nat.c b/gdb/s390-linux-nat.c
index 67f97f9..cf3f7d7 100644
--- a/gdb/s390-linux-nat.c
+++ b/gdb/s390-linux-nat.c
@@ -632,8 +632,6 @@ s390_read_description (struct target_ops *ops)
     = check_regset (tid, NT_S390_LAST_BREAK, 8);
   have_regset_system_call
     = check_regset (tid, NT_S390_SYSTEM_CALL, 4);
-  have_regset_tdb
-    = check_regset (tid, NT_S390_TDB, s390_sizeof_tdbregset);
 
 #ifdef __s390x__
   /* If GDB itself is compiled as 64-bit, we are running on a machine in
@@ -642,6 +640,9 @@ s390_read_description (struct target_ops *ops)
      addressing mode, but the kernel supports using 64-bit registers in
      that mode, report s390 architecture with 64-bit GPRs.  */
 
+  have_regset_tdb = (s390_get_hwcap () & HWCAP_S390_TE) ?
+    check_regset (tid, NT_S390_TDB, s390_sizeof_tdbregset) : 0;
+
   if (s390_target_wordsize () == 8)
     return (have_regset_tdb ? tdesc_s390x_te_linux64 :
 	    have_regset_system_call? tdesc_s390x_linux64v2 :
-- 
1.7.11.4

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH v2] S390: Fix TDB regset recognition
  2013-11-05 17:46 [PATCH v2] S390: Fix TDB regset recognition Andreas Arnez
@ 2013-11-06 20:49 ` Ulrich Weigand
  0 siblings, 0 replies; 2+ messages in thread
From: Ulrich Weigand @ 2013-11-06 20:49 UTC (permalink / raw)
  To: Andreas Arnez; +Cc: gdb-patches, Andreas Krebbel

Andreas Arnez wrote:

> When checking for the presence of the TDB regset, the current code
> interprets ENODATA from PTRACE_GETREGSET as an indication that the TDB
> regset *could* occur on this system, but the inferior stopped outside
> a transaction.  However, the Linux kernel actually reports ENODATA
> even on systems without the transactional execution facility.  Thus
> the logic is now changed to check the TE field in the HWCAP as well.
> 
> This version also checks the existence of the TDB regset -- just to be
> on the safe side when running on TE-enabled hardware with a kernel
> that does not offer the TDB regset for some reason.
> 
> gdb/
> 	* s390-linux-nat.c (s390_read_description): Consider the TE field
> 	in the HWCAP for determining 'have_regset_tdb'.
> 
> gdbserver/
> 	* linux-s390-low.c (HWCAP_S390_TE): New define.
> 	(s390_arch_setup): Consider the TE field in the HWCAP for
> 	determining 'have_regset_tdb'.

This is OK.  I've checked it in now.

Thanks,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2013-11-06 20:47 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-05 17:46 [PATCH v2] S390: Fix TDB regset recognition Andreas Arnez
2013-11-06 20:49 ` Ulrich Weigand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).