about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--intl/dcigettext.c2
-rw-r--r--locale/programs/ld-collate.c2
-rw-r--r--locale/programs/ld-ctype.c2
-rw-r--r--locale/programs/ld-measurement.c2
-rw-r--r--locale/programs/ld-numeric.c2
-rw-r--r--locale/programs/ld-paper.c2
-rw-r--r--locale/programs/ld-telephone.c2
-rw-r--r--locale/programs/ld-time.c2
-rw-r--r--localedata/locales/scn_IT14
-rw-r--r--support/process_state.h7
-rw-r--r--support/support_process_state.c6
-rw-r--r--support/tst-support-process_state.c19
-rw-r--r--sysdeps/unix/sysv/linux/Makefile1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/syscall_cancel.S4
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h3
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/syscall_cancel.S4
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h3
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sysdep.h74
-rw-r--r--sysdeps/unix/sysv/linux/tst-syscall-restart.c112
19 files changed, 202 insertions, 61 deletions
diff --git a/intl/dcigettext.c b/intl/dcigettext.c
index a028518c2a..70ba4a547f 100644
--- a/intl/dcigettext.c
+++ b/intl/dcigettext.c
@@ -687,7 +687,7 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2,
 	  /* When this is a SUID binary we must not allow accessing files
 	     outside the dedicated directories.  */
 	  if (ENABLE_SECURE && IS_PATH_WITH_DIR (single_locale))
-	    /* Ingore this entry.  */
+	    /* Ignore this entry.  */
 	    continue;
 	}
 
diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c
index 5048adbd9f..2cf9a4bc53 100644
--- a/locale/programs/ld-collate.c
+++ b/locale/programs/ld-collate.c
@@ -2678,7 +2678,7 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
       if (nowtok == tok_eof)
 	break;
 
-      /* Ingore empty lines.  */
+      /* Ignore empty lines.  */
       if (nowtok == tok_eol)
 	{
 	  now = lr_token (ldfile, charmap, result, NULL, verbose);
diff --git a/locale/programs/ld-ctype.c b/locale/programs/ld-ctype.c
index eb6e7e145c..2270960bd2 100644
--- a/locale/programs/ld-ctype.c
+++ b/locale/programs/ld-ctype.c
@@ -2164,7 +2164,7 @@ ctype_read (struct linereader *ldfile, struct localedef_t *result,
       if (nowtok == tok_eof)
 	break;
 
-      /* Ingore empty lines.  */
+      /* Ignore empty lines.  */
       if (nowtok == tok_eol)
 	{
 	  now = lr_token (ldfile, charmap, NULL, NULL, verbose);
diff --git a/locale/programs/ld-measurement.c b/locale/programs/ld-measurement.c
index c4061264ea..ba7f0c0bff 100644
--- a/locale/programs/ld-measurement.c
+++ b/locale/programs/ld-measurement.c
@@ -168,7 +168,7 @@ measurement_read (struct linereader *ldfile, struct localedef_t *result,
       if (nowtok == tok_eof)
 	break;
 
-      /* Ingore empty lines.  */
+      /* Ignore empty lines.  */
       if (nowtok == tok_eol)
 	{
 	  now = lr_token (ldfile, charmap, result, NULL, verbose);
diff --git a/locale/programs/ld-numeric.c b/locale/programs/ld-numeric.c
index 11fdac06fa..e20e322923 100644
--- a/locale/programs/ld-numeric.c
+++ b/locale/programs/ld-numeric.c
@@ -188,7 +188,7 @@ numeric_read (struct linereader *ldfile, struct localedef_t *result,
       if (nowtok == tok_eof)
 	break;
 
-      /* Ingore empty lines.  */
+      /* Ignore empty lines.  */
       if (nowtok == tok_eol)
 	{
 	  now = lr_token (ldfile, charmap, result, NULL, verbose);
diff --git a/locale/programs/ld-paper.c b/locale/programs/ld-paper.c
index 95b3d1074a..a755140707 100644
--- a/locale/programs/ld-paper.c
+++ b/locale/programs/ld-paper.c
@@ -167,7 +167,7 @@ paper_read (struct linereader *ldfile, struct localedef_t *result,
       if (nowtok == tok_eof)
 	break;
 
-      /* Ingore empty lines.  */
+      /* Ignore empty lines.  */
       if (nowtok == tok_eol)
 	{
 	  now = lr_token (ldfile, charmap, result, NULL, verbose);
diff --git a/locale/programs/ld-telephone.c b/locale/programs/ld-telephone.c
index b45573974a..79aba6ef15 100644
--- a/locale/programs/ld-telephone.c
+++ b/locale/programs/ld-telephone.c
@@ -223,7 +223,7 @@ telephone_read (struct linereader *ldfile, struct localedef_t *result,
       if (nowtok == tok_eof)
 	break;
 
-      /* Ingore empty lines.  */
+      /* Ignore empty lines.  */
       if (nowtok == tok_eol)
 	{
 	  now = lr_token (ldfile, charmap, result, NULL, verbose);
diff --git a/locale/programs/ld-time.c b/locale/programs/ld-time.c
index 1abff3cf53..349b31fff5 100644
--- a/locale/programs/ld-time.c
+++ b/locale/programs/ld-time.c
@@ -710,7 +710,7 @@ time_read (struct linereader *ldfile, struct localedef_t *result,
       if (nowtok == tok_eof)
 	break;
 
-      /* Ingore empty lines.  */
+      /* Ignore empty lines.  */
       if (nowtok == tok_eol)
 	{
 	  now = lr_token (ldfile, charmap, result, repertoire, verbose);
diff --git a/localedata/locales/scn_IT b/localedata/locales/scn_IT
index 227745c23f..bda21522ce 100644
--- a/localedata/locales/scn_IT
+++ b/localedata/locales/scn_IT
@@ -56,15 +56,11 @@ END LC_COLLATE
 LC_CTYPE
 copy "it_IT"
 
-% These translit rules don’t work at the moment,
-% see: https://sourceware.org/bugzilla/show_bug.cgi?id=31859
-% and: https://sourceware.org/pipermail/libc-alpha/2024-May/156769.html
-%
-%translit_start
-%"ḌḌ" "DDH"
-%"ḍḍ" "ddh"
-%"Ḍḍ" "Ddh"
-%translit_end
+translit_start
+"ḌḌ" "DDH"
+"ḍḍ" "ddh"
+"Ḍḍ" "Ddh"
+translit_end
 
 END LC_CTYPE
 
diff --git a/support/process_state.h b/support/process_state.h
index 1cf902e91b..9541d8c343 100644
--- a/support/process_state.h
+++ b/support/process_state.h
@@ -31,13 +31,16 @@ enum support_process_state
   support_process_state_dead         = 0x20,  /* X (dead).  */
   support_process_state_zombie       = 0x40,  /* Z (zombie).  */
   support_process_state_parked       = 0x80,  /* P (parked).  */
+  support_process_state_invalid      = 0x100  /* Invalid state.  */
 };
 
 /* Wait for process PID to reach state STATE.  It can be a combination of
    multiple possible states ('process_state_running | process_state_sleeping')
    where the function return when any of these state are observed.
    For an invalid state not represented by SUPPORT_PROCESS_STATE, it fallbacks
-   to a 2 second sleep.  */
-void support_process_state_wait (pid_t pid, enum support_process_state state);
+   to a 2 second sleep.
+   Return the found process state.  */
+enum support_process_state
+support_process_state_wait (pid_t pid, enum support_process_state state);
 
 #endif
diff --git a/support/support_process_state.c b/support/support_process_state.c
index 062335234f..ae8e0a531c 100644
--- a/support/support_process_state.c
+++ b/support/support_process_state.c
@@ -27,7 +27,7 @@
 #include <support/xstdio.h>
 #include <support/check.h>
 
-void
+enum support_process_state
 support_process_state_wait (pid_t pid, enum support_process_state state)
 {
 #ifdef __linux__
@@ -75,7 +75,7 @@ support_process_state_wait (pid_t pid, enum support_process_state state)
 	  {
 	    free (line);
 	    xfclose (fstatus);
-	    return;
+	    return process_states[i].s;
 	  }
 
       rewind (fstatus);
@@ -90,4 +90,6 @@ support_process_state_wait (pid_t pid, enum support_process_state state)
   /* Fallback to nanosleep if an invalid state is found.  */
 #endif
   nanosleep (&(struct timespec) { 1, 0 }, NULL);
+
+  return support_process_state_invalid;
 }
diff --git a/support/tst-support-process_state.c b/support/tst-support-process_state.c
index d73269320f..4a88eae3a7 100644
--- a/support/tst-support-process_state.c
+++ b/support/tst-support-process_state.c
@@ -68,28 +68,39 @@ do_test (void)
   if (test_verbose)
     printf ("info: waiting pid %d, state_stopped/state_tracing_stop\n",
 	    (int) pid);
-  support_process_state_wait (pid, stop_state);
+  {
+    enum support_process_state state =
+      support_process_state_wait (pid, stop_state);
+    TEST_VERIFY (state == support_process_state_stopped
+		 || state == support_process_state_tracing_stop);
+  }
 
   if (kill (pid, SIGCONT) != 0)
     FAIL_RET ("kill (%d, SIGCONT): %m\n", pid);
 
   if (test_verbose)
     printf ("info: waiting pid %d, state_sleeping\n", (int) pid);
-  support_process_state_wait (pid, support_process_state_sleeping);
+  TEST_COMPARE (support_process_state_wait (pid,
+					    support_process_state_sleeping),
+		support_process_state_sleeping);
 
   if (kill (pid, SIGUSR1) != 0)
     FAIL_RET ("kill (%d, SIGUSR1): %m\n", pid);
 
   if (test_verbose)
     printf ("info: waiting pid %d, state_running\n", (int) pid);
-  support_process_state_wait (pid, support_process_state_running);
+  TEST_COMPARE (support_process_state_wait (pid,
+					    support_process_state_running),
+		support_process_state_running);
 
   if (kill (pid, SIGKILL) != 0)
     FAIL_RET ("kill (%d, SIGKILL): %m\n", pid);
 
   if (test_verbose)
     printf ("info: waiting pid %d, state_zombie\n", (int) pid);
-  support_process_state_wait (pid, support_process_state_zombie);
+  TEST_COMPARE (support_process_state_wait (pid,
+					    support_process_state_zombie),
+		support_process_state_zombie);;
 
   siginfo_t info;
   int r = waitid (P_PID, pid, &info, WEXITED);
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 7df51a325c..527c7a5ae8 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -230,6 +230,7 @@ tests += \
   tst-scm_rights \
   tst-sigtimedwait \
   tst-sync_file_range \
+  tst-syscall-restart \
   tst-sysconf-iov_max \
   tst-sysvmsg-linux \
   tst-sysvsem-linux \
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/syscall_cancel.S b/sysdeps/unix/sysv/linux/sparc/sparc32/syscall_cancel.S
index 0db93c77bf..45c6ae7a86 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/syscall_cancel.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/syscall_cancel.S
@@ -48,13 +48,13 @@ __syscall_cancel_arch_start:
 	bne	2f
 #endif
 	/* Issue a 6 argument syscall.  */
-	 mov	%i1, %g1
-	mov	%i2, %o0
+	 mov	%i2, %o0
 	mov	%i3, %o1
 	mov	%i4, %o2
 	mov	%i5, %o3
 	ld	[%fp+92], %o4
 	ld	[%fp+96], %o5
+	 mov	%i1, %g1
 	ta	0x10
 
 	.globl __syscall_cancel_arch_end
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h b/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h
index d2d68f5312..c2ffbb5c8f 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h
@@ -107,6 +107,7 @@ ENTRY(name);					\
 #else  /* __ASSEMBLER__ */
 
 #define __SYSCALL_STRING						\
+	"mov	%[scn], %%g1;"						\
 	"ta	0x10;"							\
 	"bcc	1f;"							\
 	" nop;"								\
@@ -114,7 +115,7 @@ ENTRY(name);					\
 	"1:"
 
 #define __SYSCALL_CLOBBERS						\
-	"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",			\
+	"g1", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",		\
 	"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",		\
 	"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",		\
 	"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",		\
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/syscall_cancel.S b/sysdeps/unix/sysv/linux/sparc/sparc64/syscall_cancel.S
index 21b0728d5a..6c8d1330cb 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/syscall_cancel.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/syscall_cancel.S
@@ -46,13 +46,13 @@ __syscall_cancel_arch_start:
 	andcc	%g2, TCB_CANCELED_BITMASK, %g0
 	bne,pn	%xcc, 2f
 	/* Issue a 6 argument syscall.  */
-	 mov	%i1, %g1
-	mov	%i2, %o0
+	 mov	%i2, %o0
 	mov	%i3, %o1
 	mov	%i4, %o2
 	mov	%i5, %o3
 	ldx	[%fp + STACK_BIAS + 176], %o4
 	ldx	[%fp + STACK_BIAS + 184], %o5
+	mov	%i1, %g1
 	ta	0x6d
 
 	.global __syscall_cancel_arch_end
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h b/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h
index 96047424e9..5598fab08a 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h
@@ -106,6 +106,7 @@ ENTRY(name);					\
 #else  /* __ASSEMBLER__ */
 
 #define __SYSCALL_STRING						\
+	"mov	%[scn], %%g1;"						\
 	"ta	0x6d;"							\
 	"bcc,pt	%%xcc, 1f;"						\
 	" nop;"								\
@@ -113,7 +114,7 @@ ENTRY(name);					\
 	"1:"
 
 #define __SYSCALL_CLOBBERS						\
-	"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",			\
+	"g1", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",		\
 	"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",		\
 	"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",		\
 	"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",		\
diff --git a/sysdeps/unix/sysv/linux/sparc/sysdep.h b/sysdeps/unix/sysv/linux/sparc/sysdep.h
index dcabb57fe2..c287740a8c 100644
--- a/sysdeps/unix/sysv/linux/sparc/sysdep.h
+++ b/sysdeps/unix/sysv/linux/sparc/sysdep.h
@@ -50,97 +50,109 @@
 
 #undef INTERNAL_SYSCALL_NCS
 #define INTERNAL_SYSCALL_NCS(name, nr, args...) \
-  internal_syscall##nr(__SYSCALL_STRING, name, args)
+  _internal_syscall##nr(__SYSCALL_STRING, "p", name, args)
 
-#define internal_syscall0(string,name,dummy...)			\
+#define _internal_syscall0(string,nc,name,dummy...)	\
 ({									\
-	register long int __g1 __asm__ ("g1") = (name);			\
 	register long __o0 __asm__ ("o0");				\
+	long int _name = (long int) (name);				\
 	__asm __volatile (string : "=r" (__o0) :			\
-			  "r" (__g1) :					\
+			  [scn] nc (_name) :				\
 			  __SYSCALL_CLOBBERS);				\
 	__o0;								\
 })
+#define internal_syscall0(string,name,args...)				\
+  _internal_syscall0(string, "i", name, args)
 
-#define internal_syscall1(string,name,arg1)				\
+#define _internal_syscall1(string,nc,name,arg1)				\
 ({									\
 	long int _arg1 = (long int) (arg1);				\
-	register long int __g1 __asm__("g1") = (name);			\
+	long int _name = (long int) (name);				\
 	register long int  __o0 __asm__ ("o0") = _arg1;			\
-	__asm __volatile (string : "=r" (__o0) :			\
-			  "r" (__g1), "0" (__o0) :			\
+	__asm __volatile (string : "+r" (__o0) :			\
+			  [scn] nc (_name) :				\
 			  __SYSCALL_CLOBBERS);				\
 	__o0;								\
 })
+#define internal_syscall1(string,name,args...)				\
+  _internal_syscall1(string, "i", name, args)
 
-#define internal_syscall2(string,name,arg1,arg2)			\
+#define _internal_syscall2(string,nc,name,arg1,arg2)			\
 ({									\
 	long int _arg1 = (long int) (arg1);				\
 	long int _arg2 = (long int) (arg2);				\
-	register long int __g1 __asm__("g1") = (name);			\
+	long int _name = (long int) (name);				\
 	register long int __o0 __asm__ ("o0") = _arg1;			\
 	register long int __o1 __asm__ ("o1") = _arg2;			\
-	__asm __volatile (string : "=r" (__o0) :			\
-			  "r" (__g1), "0" (__o0), "r" (__o1) :		\
+	__asm __volatile (string : "+r" (__o0) :			\
+			  [scn] nc (_name), "r" (__o1) :		\
 			  __SYSCALL_CLOBBERS);				\
 	__o0;								\
 })
+#define internal_syscall2(string,name,args...)				\
+  _internal_syscall2(string, "i", name, args)
 
-#define internal_syscall3(string,name,arg1,arg2,arg3)			\
+#define _internal_syscall3(string,nc,name,arg1,arg2,arg3)		\
 ({									\
 	long int _arg1 = (long int) (arg1);				\
 	long int _arg2 = (long int) (arg2);				\
 	long int _arg3 = (long int) (arg3);				\
-	register long int __g1 __asm__("g1") = (name);			\
+	long int _name = (long int) (name);				\
 	register long int __o0 __asm__ ("o0") = _arg1;			\
 	register long int __o1 __asm__ ("o1") = _arg2;			\
 	register long int __o2 __asm__ ("o2") = _arg3;			\
-	__asm __volatile (string : "=r" (__o0) :			\
-			  "r" (__g1), "0" (__o0), "r" (__o1),		\
+	__asm __volatile (string : "+r" (__o0) :			\
+			  [scn] nc (_name), "r" (__o1),			\
 			  "r" (__o2) :					\
 			  __SYSCALL_CLOBBERS);				\
 	__o0;								\
 })
+#define internal_syscall3(string,name,args...)				\
+  _internal_syscall3(string, "i", name, args)
 
-#define internal_syscall4(string,name,arg1,arg2,arg3,arg4)		\
+#define _internal_syscall4(string,nc,name,arg1,arg2,arg3,arg4)		\
 ({									\
 	long int _arg1 = (long int) (arg1);				\
 	long int _arg2 = (long int) (arg2);				\
 	long int _arg3 = (long int) (arg3);				\
 	long int _arg4 = (long int) (arg4);				\
-	register long int __g1 __asm__("g1") = (name);			\
+	long int _name = (long int) (name);				\
 	register long int __o0 __asm__ ("o0") = _arg1;			\
 	register long int __o1 __asm__ ("o1") = _arg2;			\
 	register long int __o2 __asm__ ("o2") = _arg3;			\
 	register long int __o3 __asm__ ("o3") = _arg4;			\
-	__asm __volatile (string : "=r" (__o0) :			\
-			  "r" (__g1), "0" (__o0), "r" (__o1),		\
+	__asm __volatile (string : "+r" (__o0) :			\
+			  [scn] nc (_name), "r" (__o1),			\
 			  "r" (__o2), "r" (__o3) :			\
 			  __SYSCALL_CLOBBERS);				\
 	__o0;								\
 })
+#define internal_syscall4(string,name,args...)				\
+  _internal_syscall4(string, "i", name, args)
 
-#define internal_syscall5(string,name,arg1,arg2,arg3,arg4,arg5)		\
+#define _internal_syscall5(string,nc,name,arg1,arg2,arg3,arg4,arg5)	\
 ({									\
 	long int _arg1 = (long int) (arg1);				\
 	long int _arg2 = (long int) (arg2);				\
 	long int _arg3 = (long int) (arg3);				\
 	long int _arg4 = (long int) (arg4);				\
 	long int _arg5 = (long int) (arg5);				\
-	register long int __g1 __asm__("g1") = (name);			\
+	long int _name = (long int) (name);				\
 	register long int __o0 __asm__ ("o0") = _arg1;			\
 	register long int __o1 __asm__ ("o1") = _arg2;			\
 	register long int __o2 __asm__ ("o2") = _arg3;			\
 	register long int __o3 __asm__ ("o3") = _arg4;			\
 	register long int __o4 __asm__ ("o4") = _arg5;			\
-	__asm __volatile (string : "=r" (__o0) :			\
-			  "r" (__g1), "0" (__o0), "r" (__o1),		\
+	__asm __volatile (string : "+r" (__o0) :			\
+			  [scn] nc (_name), "r" (__o1),			\
 			  "r" (__o2), "r" (__o3), "r" (__o4) :		\
 			  __SYSCALL_CLOBBERS);				\
 	__o0;								\
 })
+#define internal_syscall5(string,name,args...)				\
+  _internal_syscall5(string, "i", name, args)
 
-#define internal_syscall6(string,name,arg1,arg2,arg3,arg4,arg5,arg6)	\
+#define _internal_syscall6(string,nc,name,arg1,arg2,arg3,arg4,arg5,arg6)\
 ({									\
 	long int _arg1 = (long int) (arg1);				\
 	long int _arg2 = (long int) (arg2);				\
@@ -148,20 +160,22 @@
 	long int _arg4 = (long int) (arg4);				\
 	long int _arg5 = (long int) (arg5);				\
 	long int _arg6 = (long int) (arg6);				\
-	register long int __g1 __asm__("g1") = (name);			\
+	long int _name = (long int) (name);				\
 	register long int __o0 __asm__ ("o0") = _arg1;			\
 	register long int __o1 __asm__ ("o1") = _arg2;			\
 	register long int __o2 __asm__ ("o2") = _arg3;			\
 	register long int __o3 __asm__ ("o3") = _arg4;			\
 	register long int __o4 __asm__ ("o4") = _arg5;			\
 	register long int __o5 __asm__ ("o5") = _arg6;			\
-	__asm __volatile (string : "=r" (__o0) :			\
-			  "r" (__g1), "0" (__o0), "r" (__o1),		\
+	__asm __volatile (string : "+r" (__o0) :			\
+			  [scn] nc (_name), "r" (__o1),			\
 			  "r" (__o2), "r" (__o3), "r" (__o4),		\
 			  "r" (__o5) :					\
 			  __SYSCALL_CLOBBERS);				\
 	__o0;								\
 })
+#define internal_syscall6(string,name,args...)				\
+  _internal_syscall6(string, "i", name, args)
 
 #define INLINE_CLONE_SYSCALL(arg1,arg2,arg3,arg4,arg5)			\
 ({									\
@@ -170,15 +184,15 @@
 	long int _arg3 = (long int) (arg3);				\
 	long int _arg4 = (long int) (arg4);				\
 	long int _arg5 = (long int) (arg5);				\
+	long int _name = __NR_clone;					\
 	register long int __o0 __asm__ ("o0") = _arg1;			\
 	register long int __o1 __asm__ ("o1") = _arg2;			\
 	register long int __o2 __asm__ ("o2") = _arg3;			\
 	register long int __o3 __asm__ ("o3") = _arg4;			\
 	register long int __o4 __asm__ ("o4") = _arg5;			\
-	register long int __g1 __asm__ ("g1") = __NR_clone;		\
 	__asm __volatile (__SYSCALL_STRING :				\
 			  "=r" (__o0), "=r" (__o1) :			\
-			  "r" (__g1), "0" (__o0), "1" (__o1),		\
+			  [scn] "i" (_name), "0" (__o0), "1" (__o1),	\
 			  "r" (__o2), "r" (__o3), "r" (__o4) :		\
 			  __SYSCALL_CLOBBERS);				\
 	if (__glibc_unlikely ((unsigned long int) (__o0) > -4096UL))	\
diff --git a/sysdeps/unix/sysv/linux/tst-syscall-restart.c b/sysdeps/unix/sysv/linux/tst-syscall-restart.c
new file mode 100644
index 0000000000..84a8a41b5c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-syscall-restart.c
@@ -0,0 +1,112 @@
+/* Test if a syscall is correctly restarted.
+   Copyright (C) 2024 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <support/xsignal.h>
+#include <support/check.h>
+#include <support/process_state.h>
+#include <support/xunistd.h>
+#include <support/xthread.h>
+#include <sys/wait.h>
+
+static int
+check_pid (pid_t pid)
+{
+  /* Wait until the child has called pause and it blocking on kernel.  */
+  support_process_state_wait (pid, support_process_state_sleeping);
+
+  TEST_COMPARE (kill (pid, SIGSTOP), 0);
+
+  /* Adding process_state_tracing_stop ('t') allows the test to work under
+     trace programs such as ptrace.  */
+  support_process_state_wait (pid, support_process_state_stopped
+				   | support_process_state_tracing_stop);
+
+  TEST_COMPARE (kill (pid, SIGCONT), 0);
+
+  enum support_process_state state
+    = support_process_state_wait (pid, support_process_state_sleeping
+				       | support_process_state_zombie);
+
+  TEST_COMPARE (state, support_process_state_sleeping);
+
+  TEST_COMPARE (kill (pid, SIGTERM), 0);
+
+  siginfo_t info;
+  TEST_COMPARE (waitid (P_PID, pid, &info, WEXITED), 0);
+  TEST_COMPARE (info.si_signo, SIGCHLD);
+  TEST_COMPARE (info.si_code, CLD_KILLED);
+  TEST_COMPARE (info.si_status, SIGTERM);
+  TEST_COMPARE (info.si_pid, pid);
+
+  return 0;
+}
+
+static void *
+tf (void *)
+{
+  pause ();
+  return NULL;
+}
+
+static void
+child_mt (void)
+{
+  /* Let only the created thread to handle signals.  */
+  sigset_t set;
+  sigfillset (&set);
+  xpthread_sigmask (SIG_BLOCK, &set, NULL);
+
+  sigdelset (&set, SIGSTOP);
+  sigdelset (&set, SIGCONT);
+  sigdelset (&set, SIGTERM);
+
+  pthread_attr_t attr;
+  xpthread_attr_init (&attr);
+  TEST_COMPARE (pthread_attr_setsigmask_np (&attr, &set), 0);
+
+  xpthread_join (xpthread_create (&attr, tf, NULL));
+}
+
+static void
+do_test_syscall (bool multithread)
+{
+  pid_t pid = xfork ();
+  if (pid == 0)
+    {
+      if (multithread)
+	child_mt ();
+      else
+	pause ();
+      _exit (127);
+    }
+
+  check_pid (pid);
+}
+
+static int
+do_test (void)
+{
+  /* Check for both single and multi thread, since they use different syscall
+     mechanisms.  */
+  do_test_syscall (false);
+  do_test_syscall (true);
+
+  return 0;
+}
+
+#include <support/test-driver.c>