[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#799478: glibc: revised atomic and new syscall patches for hppa



Source: glibc
Version: 13
Severity: normal
Tags: patch

Dear Maintainer,

Attached are two patches for hppa.  Both use the register asm feature
of gcc to load arguments to specific registers prior to a syscall.

The updated atomic patch avoids the infamous "can't find a register in
class R1_REGS" and avoids the noinline function in the previous version.

The old hppa/local-atomic.diff patch needs to be deleted before applying
the hppa/submitted-atomic.diff change.

The syscall patch fixes the miscompilation of sched_setaffinity().  It
is similar to the fix applied to other archs.

Both patches have been submitted and applied to the upstream glibc source:
https://sourceware.org/bugzilla/show_bug.cgi?id=18787
https://sourceware.org/ml/libc-alpha/2015-08/msg00266.html

I would appreciate your adding these two changes to the set of hppa
changes.

I now need to look at 2.21...

Thanks,
Dave

-- System Information:
Debian Release: stretch/sid
  APT prefers unreleased
  APT policy: (500, 'unreleased'), (500, 'unstable')
Architecture: hppa (parisc64)

Kernel: Linux 3.18.21+ (SMP w/4 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) (ignored: LC_ALL set to en_CA.utf8)
Shell: /bin/sh linked to /bin/dash
Init: sysvinit (via /sbin/init)
Index: glibc-2.19/ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h
===================================================================
--- glibc-2.19.orig/ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h
+++ glibc-2.19/ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h
@@ -53,7 +53,7 @@ typedef uintmax_t uatomic_max_t;
 #define _LWS "0xb0"
 #define _LWS_CAS "0"
 /* Note r31 is the link register.  */
-#define _LWS_CLOBBER "r1", "r26", "r25", "r24", "r23", "r22", "r21", "r20", "r28", "r31", "memory"
+#define _LWS_CLOBBER "r1", "r23", "r22", "r20", "r31", "memory"
 /* String constant for -EAGAIN.  */
 #define _ASM_EAGAIN "-11"
 /* String constant for -EDEADLOCK.  */
@@ -63,25 +63,23 @@ typedef uintmax_t uatomic_max_t;
 /* The only basic operation needed is compare and exchange.  */
 # define atomic_compare_and_exchange_val_acq(mem, newval, oldval) 	\
   ({									\
-     volatile int lws_errno;						\
-     volatile int lws_ret;						\
+     register int lws_errno asm("r21");					\
+     register int lws_ret asm("r28");					\
+     register unsigned long lws_mem asm("r26") = (unsigned long)(mem);	\
+     register unsigned long lws_old asm("r25") = (unsigned long)(oldval);\
+     register unsigned long lws_new asm("r24") = (unsigned long)(newval);\
      asm volatile(							\
 	"0:					\n\t"			\
-	"copy	%2, %%r26			\n\t"			\
-	"copy	%3, %%r25			\n\t"			\
-	"copy	%4, %%r24			\n\t"			\
 	"ble	" _LWS "(%%sr2, %%r0)		\n\t"			\
 	"ldi	" _LWS_CAS ", %%r20		\n\t"			\
-	"ldi	" _ASM_EAGAIN ", %%r24		\n\t"			\
-	"cmpb,=,n %%r24, %%r21, 0b		\n\t"			\
+	"ldi	" _ASM_EAGAIN ", %%r20		\n\t"			\
+	"cmpb,=,n %%r20, %%r21, 0b		\n\t"			\
 	"nop					\n\t"			\
-	"ldi	" _ASM_EDEADLOCK ", %%r25	\n\t"			\
-	"cmpb,=,n %%r25, %%r21, 0b		\n\t"			\
+	"ldi	" _ASM_EDEADLOCK ", %%r20	\n\t"			\
+	"cmpb,=,n %%r20, %%r21, 0b		\n\t"			\
 	"nop					\n\t"			\
-	"stw	%%r28, %0			\n\t"			\
-	"stw	%%r21, %1			\n\t"			\
-	: "=m" (lws_ret), "=m" (lws_errno) 				\
-        : "r" (mem), "r" (oldval), "r" (newval)				\
+	: "=r" (lws_ret), "=r" (lws_errno)		 		\
+        : "r" (lws_mem), "r" (lws_old), "r" (lws_new)			\
 	: _LWS_CLOBBER							\
      );									\
     									\
Index: glibc-2.19/ports/sysdeps/unix/sysv/linux/hppa/sysdep.h
===================================================================
--- glibc-2.19.orig/ports/sysdeps/unix/sysv/linux/hppa/sysdep.h
+++ glibc-2.19/ports/sysdeps/unix/sysv/linux/hppa/sysdep.h
@@ -361,9 +361,10 @@ L(pre_end):					ASM_LINE_SEP	\
 ({									\
 	long __sys_res;							\
 	{								\
+		LOAD_ARGS_##nr(args)					\
 		register unsigned long __res asm("r28");		\
 		PIC_REG_DEF						\
-		LOAD_ARGS_##nr(args)					\
+		LOAD_REGS_##nr						\
 		/* FIXME: HACK save/load r19 around syscall */		\
 		asm volatile(						\
 			SAVE_ASM_PIC					\
@@ -407,9 +408,10 @@ L(pre_end):					ASM_LINE_SEP	\
 ({									\
 	long __sys_res;							\
 	{								\
+		LOAD_ARGS_##nr(args)					\
 		register unsigned long __res asm("r28");		\
 		PIC_REG_DEF						\
-		LOAD_ARGS_##nr(args)					\
+		LOAD_REGS_##nr						\
 		/* FIXME: HACK save/load r19 around syscall */		\
 		asm volatile(						\
 			SAVE_ASM_PIC					\
@@ -432,9 +434,10 @@ L(pre_end):					ASM_LINE_SEP	\
 ({									\
 	long __sys_res;							\
 	{								\
+		LOAD_ARGS_##nr(args)					\
 		register unsigned long __res asm("r28");		\
 		PIC_REG_DEF						\
-		LOAD_ARGS_##nr(args)					\
+		LOAD_REGS_##nr						\
 		/* FIXME: HACK save/load r19 around syscall */		\
 		asm volatile(						\
 			SAVE_ASM_PIC					\
@@ -453,24 +456,43 @@ L(pre_end):					ASM_LINE_SEP	\
 
 
 #define LOAD_ARGS_0()
-#define LOAD_ARGS_1(r26)						\
-  register unsigned long __r26 __asm__("r26") = (unsigned long)(r26);	\
+#define LOAD_REGS_0
+#define LOAD_ARGS_1(a1)							\
+  register unsigned long __x26 = (unsigned long)(a1);			\
   LOAD_ARGS_0()
-#define LOAD_ARGS_2(r26,r25)						\
-  register unsigned long __r25 __asm__("r25") = (unsigned long)(r25);	\
-  LOAD_ARGS_1(r26)
-#define LOAD_ARGS_3(r26,r25,r24)					\
-  register unsigned long __r24 __asm__("r24") = (unsigned long)(r24);	\
-  LOAD_ARGS_2(r26,r25)
-#define LOAD_ARGS_4(r26,r25,r24,r23)					\
-  register unsigned long __r23 __asm__("r23") = (unsigned long)(r23);	\
-  LOAD_ARGS_3(r26,r25,r24)
-#define LOAD_ARGS_5(r26,r25,r24,r23,r22)				\
-  register unsigned long __r22 __asm__("r22") = (unsigned long)(r22);	\
-  LOAD_ARGS_4(r26,r25,r24,r23)
-#define LOAD_ARGS_6(r26,r25,r24,r23,r22,r21)				\
-  register unsigned long __r21 __asm__("r21") = (unsigned long)(r21);	\
-  LOAD_ARGS_5(r26,r25,r24,r23,r22)
+#define LOAD_REGS_1							\
+  register unsigned long __r26 __asm__("r26") = __x26;			\
+  LOAD_REGS_0
+#define LOAD_ARGS_2(a1,a2)						\
+  register unsigned long __x25 = (unsigned long)(a2);			\
+  LOAD_ARGS_1(a1)
+#define LOAD_REGS_2							\
+  register unsigned long __r25 __asm__("r25") = __x25;			\
+  LOAD_REGS_1
+#define LOAD_ARGS_3(a1,a2,a3)						\
+  register unsigned long __x24 = (unsigned long)(a3);			\
+  LOAD_ARGS_2(a1,a2)
+#define LOAD_REGS_3							\
+  register unsigned long __r24 __asm__("r24") = __x24;			\
+  LOAD_REGS_2
+#define LOAD_ARGS_4(a1,a2,a3,a4)					\
+  register unsigned long __x23 = (unsigned long)(a4);			\
+  LOAD_ARGS_3(a1,a2,a3)
+#define LOAD_REGS_4							\
+  register unsigned long __r23 __asm__("r23") = __x23;			\
+  LOAD_REGS_3
+#define LOAD_ARGS_5(a1,a2,a3,a4,a5)					\
+  register unsigned long __x22 = (unsigned long)(a5);			\
+  LOAD_ARGS_4(a1,a2,a3,a4)
+#define LOAD_REGS_5							\
+  register unsigned long __r22 __asm__("r22") = __x22;			\
+  LOAD_REGS_4
+#define LOAD_ARGS_6(a1,a2,a3,a4,a5,a6)					\
+  register unsigned long __x21 = (unsigned long)(a6);			\
+  LOAD_ARGS_5(a1,a2,a3,a4,a5)
+#define LOAD_REGS_6							\
+  register unsigned long __r21 __asm__("r21") = __x21;			\
+  LOAD_REGS_5
 
 /* Even with zero args we use r20 for the syscall number */
 #define ASM_ARGS_0
Index: glibc-2.19/ports/sysdeps/unix/sysv/linux/hppa/sysdep.c
===================================================================
--- glibc-2.19.orig/ports/sysdeps/unix/sysv/linux/hppa/sysdep.c
+++ glibc-2.19/ports/sysdeps/unix/sysv/linux/hppa/sysdep.c
@@ -56,9 +56,10 @@ syscall (long int __sysno, ...)
   va_end (args);
 
   {
+    LOAD_ARGS_6 (arg0, arg1, arg2, arg3, arg4, arg5)
     register unsigned long int __res asm("r28");
     PIC_REG_DEF
-    LOAD_ARGS_6 (arg0, arg1, arg2, arg3, arg4, arg5)
+    LOAD_REGS_6
     asm volatile (SAVE_ASM_PIC
 		  "	ble  0x100(%%sr2, %%r0)	\n"
 		  "	copy %1, %%r20		\n"

Reply to: