public inbox for linux-ia64@vger.kernel.org
 help / color / mirror / Atom feed
From: Ian Wienand <ianw@gelato.unsw.edu.au>
To: linux-ia64@vger.kernel.org
Subject: [Linux-ia64] glibc fsyscall patch
Date: Wed, 09 Apr 2003 02:38:45 +0000	[thread overview]
Message-ID: <marc-linux-ia64-105590723705444@msgid-missing> (raw)

[-- Attachment #1: Type: text/plain, Size: 1045 bytes --]

Hello,

An updated version of David M's patch posted at
https://lists.linuxia64.org/archives//linux-ia64/2003-February/004656.html
is attached.  The libc part should apply ontop libc cvs and the NPTL
part with NPTL 0.34.  To build I used

../libc/configure --with-tls --with-__thread
--with-headers=/usr/src/linux-2.5.64/include
--enable-add-ons=nptl --prefix=/usr CC=gcc-snap

where gcc-snap is the latest 3.3 snapshot [*].  You will obviously
need a kernel that is sufficient to run NPTL and have fsyscall support
enabled.

I can make some debian archives of this if it would help people to
test it.  It passes make check (except for known failures) and we here
at Gelato@UNSW will be using it internally, but at the moment all I
would say is "works for me".

Regards,

-i
ianw@gelato.unsw.edu.au
http://www.gelato.unsw.edu.au

[*] I have seen problems with 3.3 snapshots locking up the system and
causing a machine check.  I would be interested if anyone using redhat
and their gcc 3.2 with the backported __thread changes sees this
problem.

[-- Attachment #2: libc-cvs-fsyscall.diff --]
[-- Type: text/plain, Size: 5655 bytes --]

? fsyscall-libc.diff
? nptl
? nptl_db
Index: sysdeps/unix/sysv/linux/dl-osinfo.h
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/dl-osinfo.h,v
retrieving revision 1.13
diff -u -w -r1.13 dl-osinfo.h
--- sysdeps/unix/sysv/linux/dl-osinfo.h	1 Dec 2002 22:14:40 -0000	1.13
+++ sysdeps/unix/sysv/linux/dl-osinfo.h	9 Apr 2003 02:10:20 -0000
@@ -53,9 +53,12 @@
 	int parts;							      \
 	char *cp;							      \
 	struct utsname uts;						      \
+	int uname_err;								\
 									      \
-	/* Try the uname syscall */					      \
-	if (__uname (&uts))					      	      \
+ 	/* use an inline call incase TLS isn't setup and something 		\
+	   like fast syscalls are in use */					\
+	INTERNAL_SYSCALL(uname,uname_err,1,&uts);				\
+	if ( uname_err )							\
 	  {							      	      \
 	    /* This was not successful.  Now try reading the /proc	      \
 	       filesystem.  */						      \
Index: sysdeps/unix/sysv/linux/ia64/clone2.S
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/ia64/clone2.S,v
retrieving revision 1.7
diff -u -w -r1.7 clone2.S
--- sysdeps/unix/sysv/linux/ia64/clone2.S	13 Mar 2003 04:36:59 -0000	1.7
+++ sysdeps/unix/sysv/linux/ia64/clone2.S	9 Apr 2003 02:10:20 -0000
@@ -25,18 +25,16 @@
 /* 	         size_t child_stack_size, int flags, void *arg,		*/
 /*	         pid_t *parent_tid, void *tls, pid_t *child_tid)	*/
 
+#define CHILD	p8
+#define PARENT	p9
+	
 ENTRY(__clone2)
-	alloc r2=ar.pfs,8,2,6,0
+	.prologue
+	alloc r2=ar.pfs,8,3,6,0
 	cmp.eq p6,p0=0,in0
 	mov r8=EINVAL
 (p6)	br.cond.spnt.few __syscall_error
 	;;
-	flushrs			/* This is necessary, since the child	*/
-				/* will be running with the same 	*/
-				/* register backing store for a few 	*/
-				/* instructions.  We need to ensure	*/
-				/* that it will not read or write the	*/
-				/* backing store.			*/
 	mov loc0=in0		/* save fn	*/
 	mov loc1=in4		/* save arg	*/
 	mov out0=in3		/* Flags are first syscall argument.	*/
@@ -45,14 +43,30 @@
 	mov out3=in5		/* Parent TID Pointer			*/
 	mov out4=in7		/* Child TID Pointer			*/
  	mov out5=in6		/* TLS pointer				*/
-        DO_CALL (SYS_ify (clone2))
-        cmp.eq p6,p0=-1,r10
+	/*
+	 * clone2() is special: the child cannot execute br.ret right after
+	 * the system call returns, because it starts out executing on an
+	 * empty stack.  Because of this, we can't use the new (lightweight)
+	 * syscall convention here.  Instead, we just fall back on always
+	 * using "break".
+	 */
+	mov r15=SYS_ify (clone2)
+	/*
+	 * The child will start with an empty stack.  To avoid unwinding
+	 * past invalid memory, we'll pretend now that __clone2() is
+	 * the end of the call-chain.  This is wrong for the parent, but
+	 * only until it returns from clone2() but it's better than the
+	 * alternative.
+	 */
+	mov b7=r0
+	.prologue
+	.altrp b7
+	.body
+	break __BREAK_SYSCALL
 	;;
-(p6)	br.cond.spnt.few __syscall_error
-
-#	define CHILD p6
-#	define PARENT p7
 	cmp.eq CHILD,PARENT=0,r8 /* Are we the child?	*/
+	cmp.eq p6,p0=-1,r10
+(p6)	br.cond.spnt.few __syscall_error
 	;;
 (CHILD)	ld8 out1=[loc0],8	/* Retrieve code pointer.	*/
 (CHILD)	mov out0=loc1		/* Pass proper argument	to fn */
@@ -60,7 +74,6 @@
 	;;
 	ld8 gp=[loc0]		/* Load function gp.		*/
 	mov b6=out1
-	;;
 	br.call.dptk.few rp=b6	/* Call fn(arg) in the child 	*/
 	;;
 	mov out0=r8		/* Argument to _exit		*/
Index: sysdeps/unix/sysv/linux/ia64/sysdep.h
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/ia64/sysdep.h,v
retrieving revision 1.14
diff -u -w -r1.14 sysdep.h
--- sysdeps/unix/sysv/linux/ia64/sysdep.h	24 Mar 2003 07:54:28 -0000	1.14
+++ sysdeps/unix/sysv/linux/ia64/sysdep.h	9 Apr 2003 02:10:20 -0000
@@ -24,6 +24,8 @@
 #include <sysdeps/unix/sysdep.h>
 #include <sysdeps/ia64/sysdep.h>
 
+#include <tls.h>
+
 /* For Linux we can use the system call table in the header file
 	/usr/include/asm/unistd.h
    of the kernel.  But these symbols do not follow the SYS_* syntax
@@ -89,9 +91,30 @@
 	cmp.eq p6,p0=-1,r10;			\
 (p6)	br.cond.spnt.few __syscall_error;
 
+#if defined HAVE_TLS_SUPPORT && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+
+/* Use the lightweight stub only if (a) we have a suitably modern
+   thread-control block (HAVE_TLS_SUPPORT) and (b) we're not compiling
+   the runtime loader (which might do syscalls before being fully
+   relocated). */
+
+#define DO_CALL(num)				\
+	.prologue;				\
+        adds r2 = SYSINFO_OFFSET, r13;;		\
+        ld8 r2 = [r2];				\
+	.save ar.pfs, r11;			\
+        mov r11 = ar.pfs;;			\
+	.body;					\
+	mov r15 = num;				\
+        mov b7 = r2;				\
+        br.call.sptk.many b6 = b7;;		\
+	.restore sp;				\
+        mov ar.pfs = r11
+#else
 #define DO_CALL(num)				\
 	mov r15=num;				\
 	break __BREAK_SYSCALL;
+#endif
 
 #undef PSEUDO_END
 #define PSEUDO_END(name)	.endp C_SYMBOL_NAME(name);
Index: sysdeps/unix/sysv/linux/ia64/vfork.S
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/ia64/vfork.S,v
retrieving revision 1.4
diff -u -w -r1.4 vfork.S
--- sysdeps/unix/sysv/linux/ia64/vfork.S	31 Dec 2002 20:37:30 -0000	1.4
+++ sysdeps/unix/sysv/linux/ia64/vfork.S	9 Apr 2003 02:10:20 -0000
@@ -34,9 +34,13 @@
 	mov out0=CLONE_VM+CLONE_VFORK+SIGCHLD
 	mov out1=0		/* Standard sp value.			*/
 	;;
+#if 0
 	DO_CALL (SYS_ify (clone))
+#else
+	mov r15=SYS_ify(clone)
+	break __BREAK_SYSCALL
+#endif
 	cmp.eq p6,p0=-1,r10
-	;;
 (p6)	br.cond.spnt.few __syscall_error
 	ret
 PSEUDO_END(__vfork)

[-- Attachment #3: nptl-0-34-fsyscall.diff --]
[-- Type: text/plain, Size: 6819 bytes --]

Index: allocatestack.c
===================================================================
RCS file: /home/ianw/cvs/nptl/allocatestack.c,v
retrieving revision 1.1.1.3
retrieving revision 1.5
diff -u -r1.1.1.3 -r1.5
Index: descr.h
===================================================================
RCS file: /home/ianw/cvs/nptl/descr.h,v
retrieving revision 1.1.1.3
retrieving revision 1.7
diff -u -r1.1.1.3 -r1.7
--- descr.h	3 Apr 2003 01:02:57 -0000	1.1.1.3
+++ descr.h	7 Apr 2003 02:54:09 -0000	1.7
@@ -62,10 +62,16 @@
 #if !TLS_DTV_AT_TP
     /* This overlaps the TCB as used for TLS without threads (see tls.h).  */
     tcbhead_t header;
-#elif TLS_MULTIPLE_THREADS_IN_TCB
+    /* For arch's who don't have room in the TCB */
+#elif (TLS_MULTIPLE_THREADS_IN_TCB || TLS_SYSINFO_IN_TCB)
     struct
     {
+      #if TLS_MULTIPLE_THREADS_IN_TCB
       int multiple_threads;
+      #endif
+      #if TLS_SYSINFO_IN_TCB
+      uintptr_t sysinfo;
+      #endif
     } header;
 #endif
 
Index: sysdeps/ia64/tcb-offsets.sym
===================================================================
RCS file: /home/ianw/cvs/nptl/sysdeps/ia64/tcb-offsets.sym,v
retrieving revision 1.1.1.2
retrieving revision 1.5
diff -u -r1.1.1.2 -r1.5
--- sysdeps/ia64/tcb-offsets.sym	31 Mar 2003 00:07:19 -0000	1.1.1.2
+++ sysdeps/ia64/tcb-offsets.sym	7 Apr 2003 02:54:09 -0000	1.5
@@ -2,3 +2,7 @@
 #include <tls.h>
 
 MULTIPLE_THREADS_OFFSET offsetof (struct pthread, header.multiple_threads) - sizeof (struct pthread)
+
+#ifdef TLS_SYSINFO_IN_TCB
+SYSINFO_OFFSET		offsetof (struct pthread, header.sysinfo) - sizeof (struct pthread)
+#endif
Index: sysdeps/ia64/tls.h
===================================================================
RCS file: /home/ianw/cvs/nptl/sysdeps/ia64/tls.h,v
retrieving revision 1.1.1.1
retrieving revision 1.6
diff -u -r1.1.1.1 -r1.6
--- sysdeps/ia64/tls.h	31 Mar 2003 00:06:49 -0000	1.1.1.1
+++ sysdeps/ia64/tls.h	7 Apr 2003 02:54:09 -0000	1.6
@@ -27,6 +27,22 @@
 # include <stdlib.h>
 # include <list.h>
 
+/* TLS LAYOUT
+
+ The IA64 ABI specifies that after the thread pointer there is a
+ pointer to the DTV and a private pointer.  Consequently in NPTL the
+ thread descriptor is placed directly before the thread pointer (this
+ is significantly cleaner than using indirection with the private
+ pointer).
+
+ [struct pthread][dtv][private][static tls block]
+     tp (r13)----^
+ [ in descr.h   ][ tcbhead_t  ]
+
+ Note that space is made for the descriptor during TLS setup with the
+ use of TCB_PRE_TCB_SIZE.
+
+*/
 
 /* Type for the dtv.  */
 typedef union dtv
@@ -35,14 +51,16 @@
   void *pointer;
 } dtv_t;
 
-
 typedef struct
 {
   dtv_t *dtv;
   void *private;
 } tcbhead_t;
 
+/* As TCB_DTV_AT_TP doesn't allow us more room in the tcbhead defined
+   above, we have extra pointers in our thread descriptor.  */
 # define TLS_MULTIPLE_THREADS_IN_TCB 1
+# define TLS_SYSINFO_IN_TCB 1
 
 #else /* __ASSEMBLER__ */
 # include <tcb-offsets.h>
@@ -100,11 +118,21 @@
 #  define GET_DTV(descr) \
   (((tcbhead_t *) (descr))->dtv)
 
+/* The room for the thread descriptor is allocated thanks to setting
+   TLS_PRE_TCB_SIZE so we are safe set this here */
+#if NEED_DL_SYSINFO
+# define INIT_SYSINFO \
+  THREAD_SELF->header.sysinfo = GL(dl_sysinfo)
+#else
+# define INIT_SYSINFO
+#endif
+
 /* Code to initially initialize the thread pointer.  This might need
    special attention since 'errno' is not yet available and if the
-   operation can cause a failure 'errno' must not be touched.  */
-# define TLS_INIT_TP(thrdescr, secondcall) \
-  (__thread_self = (thrdescr), NULL)
+   operation can cause a failure 'errno' must not be touched.  This
+   should return a string error, but we really can't fail */
+#define TLS_INIT_TP(thrdescr, secondcall) \
+ ( __thread_self = (thrdescr) , INIT_SYSINFO , NULL )
 
 /* Return the address of the dtv for the current thread.  */
 #  define THREAD_DTV() \
Index: sysdeps/pthread/createthread.c
===================================================================
RCS file: /home/ianw/cvs/nptl/sysdeps/pthread/createthread.c,v
retrieving revision 1.1.1.3
retrieving revision 1.4
diff -u -r1.1.1.3 -r1.4
--- sysdeps/pthread/createthread.c	31 Mar 2003 00:13:16 -0000	1.1.1.3
+++ sysdeps/pthread/createthread.c	7 Apr 2003 02:54:09 -0000	1.4
@@ -113,7 +113,7 @@
 	}
     }
 
-#ifdef NEED_DL_SYSINFO
+#ifdef NEED_DL_SYSINFO 
   assert (THREAD_GETMEM (THREAD_SELF, header.sysinfo) == pd->header.sysinfo);
 #endif
 
Index: sysdeps/unix/sysv/linux/ia64/dl-sysdep.h
===================================================================
RCS file: sysdeps/unix/sysv/linux/ia64/dl-sysdep.h
diff -N sysdeps/unix/sysv/linux/ia64/dl-sysdep.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sysdeps/unix/sysv/linux/ia64/dl-sysdep.h	31 Mar 2003 00:12:36 -0000	1.1
@@ -0,0 +1,44 @@
+/* System-specific settings for dynamic linker code.  IA-64 version.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by David Mosberger <davidm@napali.hpl.hp.com>
+
+   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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _DL_SYSDEP_H
+#define _DL_SYSDEP_H	1
+
+#define NEED_DL_SYSINFO 1
+
+#ifndef __ASSEMBLER__
+/* Don't declare this as a function---we want it's entry-point, not
+   it's function descriptor... */
+extern int _dl_sysinfo_break attribute_hidden;
+# define DL_SYSINFO_DEFAULT ((uintptr_t) &_dl_sysinfo_break)
+# define DL_SYSINFO_IMPLEMENTATION			\
+  asm (".text\n\t"					\
+       ".hidden _dl_sysinfo_break\n\t"			\
+       ".proc _dl_sysinfo_break\n\t"			\
+       "_dl_sysinfo_break:\n\t"				\
+       ".prologue\n\t"					\
+       ".altrp b6\n\t"					\
+       ".body\n\t"					\
+       "break 0x100000;\n\t"				\
+       "br.ret.sptk.many b6;\n\t"			\
+       ".endp _dl_sysinfo_break");
+#endif
+
+#endif	/* dl-sysdep.h */
Index: sysdeps/unix/sysv/linux/ia64/lowlevellock.h
===================================================================
RCS file: /home/ianw/cvs/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h,v
retrieving revision 1.1.1.4
retrieving revision 1.2
diff -u -r1.1.1.4 -r1.2

                 reply	other threads:[~2003-04-09  2:38 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=marc-linux-ia64-105590723705444@msgid-missing \
    --to=ianw@gelato.unsw.edu.au \
    --cc=linux-ia64@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox