Skip to contentSkip to conversation

Fix HPUX fork

PATCH In review Matthew Wilcox 2 participants 2 messages Feb 23, 2001 exec and binfmt

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Fix HPUX fork

jsm pointed out I'd broken HPUX fork recently. This fix is untested (except that it builds), but if it's wrong it does at least point the way. I don't know if we want to enable STICKY_TIMEOUTS or some other bugs for PER_HPUX, but they weren't enabled for SOM processes before, so I haven't enabled them now.

Index: arch/parisc/hpux/entry_hpux.S
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/hpux/entry_hpux.S,v retrieving revision 1.14

entry_hpux.S +2 -6
diff -u -p -r1.14 entry_hpux.S
@@ -1,17 +1,13 @@
-/* -----------------------------------------------------------------------------
+/*
  *
- * Native PARISC/Linux Project (http://www.puffingroup.com/parisc)
+ * PARISC/Linux Project (http://www.parisc-linux.org/)
  *
  * modified by Matthew Wilcox <[email protected]> 1999-07-26
  */
 
-
-#define ASSEMBLY
-
 #include <linux/sys.h>
 #include <linux/linkage.h>
 #include <asm/unistd.h>
-
 
 	.text
 

Index: arch/parisc/hpux/wrappers.S
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/hpux/wrappers.S,v retrieving revision 1.12

wrappers.S +5 -7
diff -u -p -r1.12 wrappers.S
@@ -1,5 +1,5 @@
-/*------------------------------------------------------------------------------
- * Native PARISC/Linux Project (http://www.puffingroup.com/parisc)
+/*
+ * PARISC/Linux Project (http://www.parisc-linux.org/)
  *
  * HP-UX System Call Wrapper routines and System Call Return Path
  *
@@ -80,6 +80,7 @@
 
 
 	.export hpux_fork_wrapper
+	.export hpux_child_return
 	.import sys_fork
 
 hpux_fork_wrapper:
@@ -90,10 +91,7 @@ hpux_fork_wrapper:
 	stw	%r2,-20(%r30)
 	ldo	64(%r30),%r30
 	stw	%r2,PT_GR19(%r1)	;! save for child
-	stw	%r30,PT_GR20(%r1)	;! save for child
-	ldil	L%child_return,%r3
-	ldo	R%child_return(%r3),%r3
-	stw	%r3,PT_GR21(%r1)	;! save for child
+	stw	%r30,PT_GR21(%r1)	;! save for child
 
 	ldw	TASK_PT_GR30(%r1),%r25
 	copy	%r1,%r24
@@ -129,7 +127,7 @@ fork_exit:
 
 	/* Set the return value for the child */
 
-child_return:
+hpux_child_return:
 	ldw TASK_PT_GR19-TASK_SZ_ALGN-128(%r30),%r2
 	b fork_return
 	copy %r0,%r28

Index: arch/parisc/kernel/process.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/process.c,v retrieving revision 1.32

process.c +6 -1
diff -u -p -r1.32 process.c
@@ -223,6 +223,7 @@ copy_thread(int nr, unsigned long clone_
 	 * function pointers aren't a pointer to the function on 64-bit */
 	extern void *ret_from_kernel_thread;
 	extern void *child_return;
+	extern void *hpux_child_return;
 
 	*cregs = *pregs;
 
@@ -262,8 +263,12 @@ copy_thread(int nr, unsigned long clone_
 		/* Use same stack depth as parent */
 		cregs->ksp = ((unsigned long)(p))
 			+ (pregs->gr[21] & (INIT_TASK_SIZE - 1));
-		cregs->kpc = &child_return;
 		cregs->gr[30] = usp;
+		if (p->personality == PER_HPUX) {
+			cregs->kpc = &hpux_child_return;
+		} else {
+			cregs->kpc = &child_return;
+		}
 	}
 
 	return 0;

Index: fs/binfmt_som.c
===================================================================
RCS file: /home/cvs/parisc/linux/fs/binfmt_som.c,v retrieving revision 1.14

binfmt_som.c +1 -1
diff -u -p -r1.14 binfmt_som.c
@@ -228,7 +228,7 @@ do_load_som_binary(struct linux_binprm *
 
 	/* OK, This is the point of no return */
 	current->flags &= ~PF_FORKNOEXEC;
-	current->personality = PER_LINUX; /* I suspect we want a PER_HPUX */
+	current->personality = PER_HPUX;
 
 	retval = map_som_binary(bprm->file, hpuxhdr);
 	if (retval < 0)

Index: include/linux/personality.h
===================================================================
RCS file: /home/cvs/parisc/linux/include/linux/personality.h,v retrieving revision 1.3

personality.h +4 -3
diff -u -p -r1.3 personality.h
@@ -25,11 +25,12 @@
 #define PER_SUNOS		(PER_BSD | STICKY_TIMEOUTS)
 #define PER_XENIX		(0x0007 | STICKY_TIMEOUTS)
 #define PER_LINUX32		(0x0008)
-#define PER_IRIX32              (0x0009 | STICKY_TIMEOUTS) /* IRIX5 32-bit     */
-#define PER_IRIXN32             (0x000a | STICKY_TIMEOUTS) /* IRIX6 new 32-bit */
-#define PER_IRIX64              (0x000b | STICKY_TIMEOUTS) /* IRIX6 64-bit     */
+#define PER_IRIX32		(0x0009 | STICKY_TIMEOUTS) /* IRIX5 32-bit     */
+#define PER_IRIXN32		(0x000a | STICKY_TIMEOUTS) /* IRIX6 new 32-bit */
+#define PER_IRIX64		(0x000b | STICKY_TIMEOUTS) /* IRIX6 64-bit     */
 #define PER_RISCOS		(0x000c)
 #define PER_SOLARIS		(0x000d | STICKY_TIMEOUTS)
+#define PER_HPUX		(0x000e)
 
 /* Prototype for an lcall7 syscall handler. */
 typedef void (*lcall7_func)(int, struct pt_regs *);
#1 lore raw

process.c copy_thread(int nr, unsigned long clone_ · line 271

Quoted 7 lines · Matthew Wilcox
process.c +5 -1
-		cregs->kpc = &child_return;
 		cregs->gr[30] = usp;
+		if (p->personality == PER_HPUX) {
+			cregs->kpc = &hpux_child_return;
+		} else {
+			cregs->kpc = &child_return;
+		}

Matthew,
In general, branches hurt performance on RISC archs. Could the code be structured something like:

	cregs->kpc = child_return_ftn[p->personality];
or 
	cregs->kpc = personality_data[p->personality].child_ret_ftn;

For PARISC-linux, do we need more personalities for wide-mode or SOM support? If so, then indexing is probably a better solution.

thanks,
grant

Grant Grundler
parisc-linux {PCI|IOMMU|SMP} hacker
+1.408.447.7253