DragonFly bugs List (threaded) for 2007-01
DragonFly BSD
DragonFly bugs List (threaded) for 2007-01
[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]

Re: [issue524] Making world with gcc41?


From: "Simon 'corecode' Schubert" <corecode@xxxxxxxxxxxx>
Date: Sun, 21 Jan 2007 12:38:36 +0100

Sascha Wildner wrote:
Here's the panic string Peter Avalos got when he tried to boot a kernel compiled with 4.1:

http://leaf.dragonflybsd.org/~pavalos/gcc41-kernel.crash

Okay, I fixed it, lets go for some explanation first:


The gpfault comes from vm86_bioscall(...) in init386(). The cause is that the assembler code passes the struct vm86frame by value, i.e. simply creating it on the stack. This worked up to gcc34, but gcc41 now optimizes stores to unused memory locations away, whis is allowed per the standards. This led to an uninitialized stack frame which in turn panicked the box.

After some time of bug searching (qemu with gdbserver being *very* helpful) it turns out that freebsd did have the same problem one month ago. So, the fix is the same: pass structs by reference if you expect the callee to modify them.

The attached patch does this. It is quite a bit, but well, it needs to be done. Gcc41 kernel boots fine now. Best we get that in before release.

cheers
 simon

--
Serve - BSD     +++  RENT this banner advert  +++    ASCII Ribbon   /"\
Work - Mac      +++  space for low €€€ NOW!1  +++      Campaign     \ /
Party Enjoy Relax   |   http://dragonflybsd.org      Against  HTML   \
Dude 2c 2 the max   !   http://golden-apple.biz       Mail + News   / \
Index: cpu/i386/include/cpu.h
===================================================================
RCS file: /home/dcvs/src/sys/cpu/i386/include/cpu.h,v
retrieving revision 1.22
diff -u -p -r1.22 cpu.h
--- cpu/i386/include/cpu.h	14 Jan 2007 20:07:11 -0000	1.22
+++ cpu/i386/include/cpu.h	21 Jan 2007 08:55:49 -0000
@@ -125,7 +125,7 @@ 
 extern char	etext[];
 
 void	fork_trampoline (void);
-void	fork_return (struct lwp *, struct trapframe);
+void	fork_return (struct lwp *, struct trapframe *);
 
 #endif
 
Index: kern/kern_intr.c
===================================================================
RCS file: /home/dcvs/src/sys/kern/kern_intr.c,v
retrieving revision 1.45
diff -u -p -r1.45 kern_intr.c
--- kern/kern_intr.c	23 Dec 2006 00:35:04 -0000	1.45
+++ kern/kern_intr.c	21 Jan 2007 08:22:48 -0000
@@ -536,10 +536,10 @@  *
  * Must return non-zero if we do not want the vector code to re-enable
  * the interrupt (which we don't if we have to schedule the interrupt)
  */
-int ithread_fast_handler(struct intrframe frame);
+int ithread_fast_handler(struct intrframe *frame);
 
 int
-ithread_fast_handler(struct intrframe frame)
+ithread_fast_handler(struct intrframe *frame)
 {
     int intr;
     struct intr_info *info;
@@ -551,7 +551,7 @@ #endif
     intrec_t rec, next_rec;
     globaldata_t gd;
 
-    intr = frame.if_vec;
+    intr = frame->if_vec;
     gd = mycpu;
 
     info = &intr_info_ary[intr];
@@ -622,9 +622,9 @@ #endif
 	    if (rec->serializer) {
 		must_schedule += lwkt_serialize_handler_try(
 					rec->serializer, rec->handler,
-					rec->argument, &frame);
+					rec->argument, frame);
 	    } else {
-		rec->handler(rec->argument, &frame);
+		rec->handler(rec->argument, frame);
 	    }
 	}
     }
Index: kern/lwkt_ipiq.c
===================================================================
RCS file: /home/dcvs/src/sys/kern/lwkt_ipiq.c,v
retrieving revision 1.20
diff -u -p -r1.20 lwkt_ipiq.c
--- kern/lwkt_ipiq.c	27 Dec 2006 06:51:47 -0000	1.20
+++ kern/lwkt_ipiq.c	21 Jan 2007 08:37:19 -0000
@@ -465,7 +465,7 @@ }
 
 #ifdef _KERNEL
 void
-lwkt_process_ipiq_frame(struct intrframe frame)
+lwkt_process_ipiq_frame(struct intrframe *frame)
 {
     globaldata_t gd = mycpu;
     globaldata_t sgd;
@@ -478,13 +478,13 @@ 	if (n != gd->gd_cpuid) {
 	    sgd = globaldata_find(n);
 	    ip = sgd->gd_ipiq;
 	    if (ip != NULL) {
-		while (lwkt_process_ipiq_core(sgd, &ip[gd->gd_cpuid], &frame))
+		while (lwkt_process_ipiq_core(sgd, &ip[gd->gd_cpuid], frame))
 		    ;
 	    }
 	}
     }
     if (gd->gd_cpusyncq.ip_rindex != gd->gd_cpusyncq.ip_windex) {
-	if (lwkt_process_ipiq_core(gd, &gd->gd_cpusyncq, &frame)) {
+	if (lwkt_process_ipiq_core(gd, &gd->gd_cpusyncq, frame)) {
 	    if (gd->gd_curthread->td_cscount == 0)
 		goto again;
 	    need_ipiq();
Index: platform/pc32/apic/apic_vector.s
===================================================================
RCS file: /home/dcvs/src/sys/platform/pc32/apic/apic_vector.s,v
retrieving revision 1.35
diff -u -p -r1.35 apic_vector.s
--- platform/pc32/apic/apic_vector.s	8 Jan 2007 03:33:42 -0000	1.35
+++ platform/pc32/apic/apic_vector.s	21 Jan 2007 10:10:27 -0000
@@ -166,8 +166,9 @@ 2: ;									\
 	/* clear pending bit, run handler */				\
 	andl	$~IRQ_LBIT(irq_num),PCPU(fpending) ;			\
 	pushl	$irq_num ;						\
+	pushl	%esp ;			 /* pass frame by reference */	\
 	call	ithread_fast_handler ;	 /* returns 0 to unmask */	\
-	addl	$4, %esp ;						\
+	addl	$8, %esp ;						\
 	UNMASK_IRQ(irq_num) ;						\
 5: ;									\
 	MEXITCOUNT ;							\
@@ -378,12 +379,13 @@ 	movl	PCPU(curthread),%ebx
 	cmpl	$TDPRI_CRIT,TD_PRI(%ebx)
 	jge	1f
 	subl	$8,%esp			/* make same as interrupt frame */
+	pushl	%esp			/* pass frame by reference */
 	incl	PCPU(intr_nesting_level)
 	addl	$TDPRI_CRIT,TD_PRI(%ebx)
 	call	lwkt_process_ipiq_frame
 	subl	$TDPRI_CRIT,TD_PRI(%ebx)
 	decl	PCPU(intr_nesting_level)
-	addl	$8,%esp
+	addl	$12,%esp
 	pushl	$0			/* CPL for frame (REMOVED) */
 	MEXITCOUNT
 	jmp	doreti
Index: platform/pc32/apic/apicvar.h
===================================================================
RCS file: /home/dcvs/src/sys/platform/pc32/apic/apicvar.h,v
retrieving revision 1.2
diff -u -p -r1.2 apicvar.h
--- platform/pc32/apic/apicvar.h	27 Jun 2004 08:52:46 -0000	1.2
+++ platform/pc32/apic/apicvar.h	21 Jan 2007 08:42:56 -0000
@@ -148,7 +148,7 @@ 
 void	lapic_ipi_raw(register_t icrlo, u_int dest);
 void	lapic_ipi_vectored(u_int vector, int dest);
 int	lapic_ipi_wait(int delay);
-void	lapic_handle_intr(struct intrframe frame);
+void	lapic_handle_intr(struct intrframe *frame);
 void	lapic_set_logical_id(u_int apic_id, u_int cluster, u_int cluster_id);
 int	lapic_set_lvt_mask(u_int apic_id, u_int lvt, u_char masked);
 int	lapic_set_lvt_mode(u_int apic_id, u_int lvt, u_int32_t mode);
Index: platform/pc32/i386/exception.s
===================================================================
RCS file: /home/dcvs/src/sys/platform/pc32/i386/exception.s,v
retrieving revision 1.30
diff -u -p -r1.30 exception.s
--- platform/pc32/i386/exception.s	8 Jan 2007 03:33:42 -0000	1.30
+++ platform/pc32/i386/exception.s	21 Jan 2007 10:06:02 -0000
@@ -779,7 +779,9 @@ 	FAKE_MCOUNT(15*4(%esp))
 	FAKE_MCOUNT(btrap)		/* init "from" _btrap -> calltrap */
 	incl	PCPU(cnt)+V_TRAP
 	/* warning, trap frame dummy arg, no extra reg pushes */
+	pushl	%esp			/* pass frame by reference */
 	call	trap
+	addl	$4,%esp
 
 	/*
 	 * Return via doreti to handle ASTs.  Have to change trap frame
@@ -826,7 +828,9 @@ 	movl	$7,TF_ERR(%esp) 	/* sizeof "lcall 
 	FAKE_MCOUNT(15*4(%esp))
 	incl	PCPU(cnt)+V_SYSCALL	/* YYY per-cpu */
 	/* warning, trap frame dummy arg, no extra reg pushes */
+	push	%esp			/* pass frame by reference */
 	call	syscall2
+	addl	$4,%esp
 	MEXITCOUNT
 	cli				/* atomic reqflags interlock w/iret */
 	cmpl    $0,PCPU(reqflags)
@@ -864,7 +868,9 @@ 	movl	$2,TF_ERR(%esp)		/* sizeof "int 0x
 	FAKE_MCOUNT(15*4(%esp))
 	incl	PCPU(cnt)+V_SYSCALL
 	/* warning, trap frame dummy arg, no extra reg pushes */
+	push	%esp			/* pass frame by reference */
 	call	syscall2
+	addl	$4,%esp
 	MEXITCOUNT
 	cli				/* atomic reqflags interlock w/irq */
 	cmpl    $0,PCPU(reqflags)
@@ -893,10 +899,16 @@ 	 * have this call a non-return function
 	 *
 	 * initproc has its own fork handler, start_init(), which DOES
 	 * return.
+	 *
+	 * The function (set in pcb_esi) gets passed two arguments,
+	 * the primary parameter set in pcb_ebx and a pointer to the
+	 * trapframe.
+	 *   void (func)(int arg, struct trapframe *frame);
 	 */
+	pushl	%esp			/* pass frame by reference */
 	pushl	%ebx			/* arg1 */
 	call	*%esi			/* function */
-	addl	$4,%esp
+	addl	$8,%esp
 	/* cut from syscall */
 
 	sti
Index: platform/pc32/i386/trap.c
===================================================================
RCS file: /home/dcvs/src/sys/platform/pc32/i386/trap.c,v
retrieving revision 1.95
diff -u -p -r1.95 trap.c
--- platform/pc32/i386/trap.c	14 Jan 2007 20:07:12 -0000	1.95
+++ platform/pc32/i386/trap.c	21 Jan 2007 08:50:43 -0000
@@ -119,9 +119,9 @@ #endif
 
 int (*pmath_emulate) (struct trapframe *);
 
-extern void trap (struct trapframe frame);
+extern void trap (struct trapframe *frame);
 extern int trapwrite (unsigned addr);
-extern void syscall2 (struct trapframe frame);
+extern void syscall2 (struct trapframe *frame);
 
 static int trap_pfault (struct trapframe *, int, vm_offset_t);
 static void trap_fatal (struct trapframe *, vm_offset_t);
@@ -373,7 +373,7 @@  * get_mplock() has to block.
  */
 
 void
-trap(struct trapframe frame)
+trap(struct trapframe *frame)
 {
 	struct globaldata *gd = mycpu;
 	struct thread *td = gd->gd_curthread;
@@ -392,10 +392,10 @@ 
 	p = td->td_proc;
 #ifdef DDB
 	if (db_active) {
-		eva = (frame.tf_trapno == T_PAGEFLT ? rcr2() : 0);
+		eva = (frame->tf_trapno == T_PAGEFLT ? rcr2() : 0);
 		++gd->gd_trap_nesting_level;
 		MAKEMPSAFE(have_mplock);
-		trap_fatal(&frame, eva);
+		trap_fatal(frame, eva);
 		--gd->gd_trap_nesting_level;
 		goto out2;
 	}
@@ -403,7 +403,7 @@ #endif
 
 	eva = 0;
 	++gd->gd_trap_nesting_level;
-	if (frame.tf_trapno == T_PAGEFLT) {
+	if (frame->tf_trapno == T_PAGEFLT) {
 		/*
 		 * For some Cyrix CPUs, %cr2 is clobbered by interrupts.
 		 * This problem is worked around by using an interrupt
@@ -425,15 +425,15 @@ #endif
 
 	--gd->gd_trap_nesting_level;
 
-	if (!(frame.tf_eflags & PSL_I)) {
+	if (!(frame->tf_eflags & PSL_I)) {
 		/*
 		 * Buggy application or kernel code has disabled interrupts
 		 * and then trapped.  Enabling interrupts now is wrong, but
 		 * it is better than running with interrupts disabled until
 		 * they are accidentally enabled later.
 		 */
-		type = frame.tf_trapno;
-		if (ISPL(frame.tf_cs)==SEL_UPL || (frame.tf_eflags & PSL_VM)) {
+		type = frame->tf_trapno;
+		if (ISPL(frame->tf_cs)==SEL_UPL || (frame->tf_eflags & PSL_VM)) {
 			MAKEMPSAFE(have_mplock);
 			kprintf(
 			    "pid %ld (%s): trap %d with interrupts disabled\n",
@@ -453,17 +453,17 @@ 
 #if defined(I586_CPU) && !defined(NO_F00F_HACK)
 restart:
 #endif
-	type = frame.tf_trapno;
-	code = frame.tf_err;
+	type = frame->tf_trapno;
+	code = frame->tf_err;
 
 	if (in_vm86call) {
 		ASSERT_MP_LOCK_HELD(curthread);
-		if (frame.tf_eflags & PSL_VM &&
+		if (frame->tf_eflags & PSL_VM &&
 		    (type == T_PROTFLT || type == T_STKFLT)) {
 #ifdef SMP
 			KKASSERT(td->td_mpcount > 0);
 #endif
-			i = vm86_emulate((struct vm86frame *)&frame);
+			i = vm86_emulate((struct vm86frame *)frame);
 #ifdef SMP
 			KKASSERT(td->td_mpcount > 0);
 #endif
@@ -472,10 +472,10 @@ 				/*
 				 * returns to original process
 				 */
 #ifdef SMP
-				vm86_trap((struct vm86frame *)&frame,
+				vm86_trap((struct vm86frame *)frame,
 					  have_mplock);
 #else
-				vm86_trap((struct vm86frame *)&frame, 0);
+				vm86_trap((struct vm86frame *)frame, 0);
 #endif
 				KKASSERT(0); /* NOT REACHED */
 			}
@@ -488,7 +488,7 @@ 			 * assume a normal userspace trap.
 			 */
 		case T_PROTFLT:
 		case T_SEGNPFLT:
-			trap_fatal(&frame, eva);
+			trap_fatal(frame, eva);
 			goto out2;
 		case T_TRCTRAP:
 			type = T_BPTFLT;	/* kernel breakpoint */
@@ -497,13 +497,13 @@ 		}
 		goto kernel_trap;	/* normal kernel trap handling */
 	}
 
-        if ((ISPL(frame.tf_cs) == SEL_UPL) || (frame.tf_eflags & PSL_VM)) {
+        if ((ISPL(frame->tf_cs) == SEL_UPL) || (frame->tf_eflags & PSL_VM)) {
 		/* user trap */
 
 		userenter(td);
 
 		sticks = (int)td->td_sticks;
-		lp->lwp_md.md_regs = &frame;
+		lp->lwp_md.md_regs = frame;
 
 		switch (type) {
 		case T_PRIVINFLT:	/* privileged instruction fault */
@@ -513,7 +513,7 @@ 			break;
 
 		case T_BPTFLT:		/* bpt instruction fault */
 		case T_TRCTRAP:		/* trace trap */
-			frame.tf_eflags &= ~PSL_T;
+			frame->tf_eflags &= ~PSL_T;
 			i = SIGTRAP;
 			break;
 
@@ -539,8 +539,8 @@ 			 * them specially.
 			 */
 		case T_PROTFLT:		/* general protection fault */
 		case T_STKFLT:		/* stack fault */
-			if (frame.tf_eflags & PSL_VM) {
-				i = vm86_emulate((struct vm86frame *)&frame);
+			if (frame->tf_eflags & PSL_VM) {
+				i = vm86_emulate((struct vm86frame *)frame);
 				if (i == 0)
 					goto out;
 				break;
@@ -557,7 +557,7 @@ 			break;
 
 		case T_PAGEFLT:		/* page fault */
 			MAKEMPSAFE(have_mplock);
-			i = trap_pfault(&frame, TRUE, eva);
+			i = trap_pfault(frame, TRUE, eva);
 			if (i == -1)
 				goto out;
 #if defined(I586_CPU) && !defined(NO_F00F_HACK)
@@ -590,7 +590,7 @@ 				 * for debugging.
 				 */
 				if (ddb_on_nmi) {
 					kprintf ("NMI ... going to debugger\n");
-					kdb_trap (type, 0, &frame);
+					kdb_trap (type, 0, frame);
 				}
 #endif /* DDB */
 				goto out2;
@@ -644,11 +644,11 @@ 				i = SIGFPE;
 				ucode = FPE_FPU_NP_TRAP;
 				break;
 			}
-			i = (*pmath_emulate)(&frame);
+			i = (*pmath_emulate)(frame);
 			if (i == 0) {
-				if (!(frame.tf_eflags & PSL_T))
+				if (!(frame->tf_eflags & PSL_T))
 					goto out2;
-				frame.tf_eflags &= ~PSL_T;
+				frame->tf_eflags &= ~PSL_T;
 				i = SIGTRAP;
 			}
 			/* else ucode = emulator_only_knows() XXX */
@@ -671,7 +671,7 @@ 
 		switch (type) {
 		case T_PAGEFLT:			/* page fault */
 			MAKEMPSAFE(have_mplock);
-			trap_pfault(&frame, FALSE, eva);
+			trap_pfault(frame, FALSE, eva);
 			goto out2;
 
 		case T_DNA:
@@ -699,8 +699,8 @@ 			 * them.
 			 */
 #define	MAYBE_DORETI_FAULT(where, whereto)				\
 	do {								\
-		if (frame.tf_eip == (int)where) {			\
-			frame.tf_eip = (int)whereto;			\
+		if (frame->tf_eip == (int)where) {			\
+			frame->tf_eip = (int)whereto;			\
 			goto out2;					\
 		}							\
 	} while (0)
@@ -725,7 +725,7 @@ 						   doreti_popl_fs_fault);
 				MAYBE_DORETI_FAULT(doreti_popl_gs,
 						   doreti_popl_gs_fault);
 				if (td->td_pcb->pcb_onfault) {
-					frame.tf_eip = 
+					frame->tf_eip = 
 					    (register_t)td->td_pcb->pcb_onfault;
 					goto out2;
 				}
@@ -742,14 +742,14 @@ 			 * want to get this fault so that we 
 			 * problem here and not every time the kernel is
 			 * entered.
 			 */
-			if (frame.tf_eflags & PSL_NT) {
-				frame.tf_eflags &= ~PSL_NT;
+			if (frame->tf_eflags & PSL_NT) {
+				frame->tf_eflags &= ~PSL_NT;
 				goto out2;
 			}
 			break;
 
 		case T_TRCTRAP:	 /* trace trap */
-			if (frame.tf_eip == (int)IDTVEC(syscall)) {
+			if (frame->tf_eip == (int)IDTVEC(syscall)) {
 				/*
 				 * We've just entered system mode via the
 				 * syscall lcall.  Continue single stepping
@@ -758,12 +758,12 @@ 				 * saved the flags.
 				 */
 				goto out2;
 			}
-			if (frame.tf_eip == (int)IDTVEC(syscall) + 1) {
+			if (frame->tf_eip == (int)IDTVEC(syscall) + 1) {
 				/*
 				 * The syscall handler has now saved the
 				 * flags.  Stop single stepping it.
 				 */
-				frame.tf_eflags &= ~PSL_T;
+				frame->tf_eflags &= ~PSL_T;
 				goto out2;
 			}
                         /*
@@ -794,7 +794,7 @@ 			 * Otherwise, debugger traps "can't h
 			 */
 #ifdef DDB
 			MAKEMPSAFE(have_mplock);
-			if (kdb_trap (type, 0, &frame))
+			if (kdb_trap (type, 0, frame))
 				goto out2;
 #endif
 			break;
@@ -829,7 +829,7 @@ 				 * for debugging.
 				 */
 				if (ddb_on_nmi) {
 					kprintf ("NMI ... going to debugger\n");
-					kdb_trap (type, 0, &frame);
+					kdb_trap (type, 0, frame);
 				}
 #endif /* DDB */
 				goto out2;
@@ -841,7 +841,7 @@ #endif /* NISA > 0 */
 		}
 
 		MAKEMPSAFE(have_mplock);
-		trap_fatal(&frame, eva);
+		trap_fatal(frame, eva);
 		goto out2;
 	}
 
@@ -851,7 +851,7 @@ 	 * VM context managed by a virtual kern
 	 * handle it.
 	 */
 	if (p->p_vkernel && p->p_vkernel->vk_current) {
-		vkernel_trap(p, &frame);
+		vkernel_trap(p, frame);
 		goto out;
 	}
 
@@ -876,10 +876,10 @@ #endif
 
 out:
 #ifdef SMP
-        if (ISPL(frame.tf_cs) == SEL_UPL)
-		KASSERT(td->td_mpcount == have_mplock, ("badmpcount trap/end from %p", (void *)frame.tf_eip));
+        if (ISPL(frame->tf_cs) == SEL_UPL)
+		KASSERT(td->td_mpcount == have_mplock, ("badmpcount trap/end from %p", (void *)frame->tf_eip));
 #endif
-	userret(lp, &frame, sticks);
+	userret(lp, frame, sticks);
 	userexit(lp);
 out2:	;
 #ifdef SMP
@@ -1182,7 +1182,7 @@  *		 the MP lock.
  */
 
 void
-syscall2(struct trapframe frame)
+syscall2(struct trapframe *frame)
 {
 	struct thread *td = curthread;
 	struct proc *p = td->td_proc;
@@ -1203,7 +1203,7 @@ 	u_int code;
 	union sysunion args;
 
 #ifdef DIAGNOSTIC
-	if (ISPL(frame.tf_cs) != SEL_UPL) {
+	if (ISPL(frame->tf_cs) != SEL_UPL) {
 		get_mplock();
 		panic("syscall");
 		/* NOT REACHED */
@@ -1211,7 +1211,7 @@ 	}
 #endif
 
 #ifdef SMP
-	KASSERT(td->td_mpcount == 0, ("badmpcount syscall2 from %p", (void *)frame.tf_eip));
+	KASSERT(td->td_mpcount == 0, ("badmpcount syscall2 from %p", (void *)frame->tf_eip));
 	if (syscall_mpsafe == 0)
 		MAKEMPSAFE(have_mplock);
 #endif
@@ -1221,7 +1221,7 @@ 	/*
 	 * Misc
 	 */
 	sticks = (int)td->td_sticks;
-	orig_tf_eflags = frame.tf_eflags;
+	orig_tf_eflags = frame->tf_eflags;
 
 	/*
 	 * Virtual kernel intercept - if a VM context managed by a virtual
@@ -1230,10 +1230,10 @@ 	 * Restore the virtual kernel context a
 	 * call.  The current frame is copied out to the virtual kernel.
 	 */
 	if (p->p_vkernel && p->p_vkernel->vk_current) {
-		error = vkernel_trap(p, &frame);
-		frame.tf_eax = error;
+		error = vkernel_trap(p, frame);
+		frame->tf_eax = error;
 		if (error)
-			frame.tf_eflags |= PSL_C;
+			frame->tf_eflags |= PSL_C;
 		error = EJUSTRETURN;
 		goto out;
 	}
@@ -1241,13 +1241,13 @@ 
 	/*
 	 * Get the system call parameters and account for time
 	 */
-	lp->lwp_md.md_regs = &frame;
-	params = (caddr_t)frame.tf_esp + sizeof(int);
-	code = frame.tf_eax;
+	lp->lwp_md.md_regs = frame;
+	params = (caddr_t)frame->tf_esp + sizeof(int);
+	code = frame->tf_eax;
 
 	if (p->p_sysent->sv_prepsyscall) {
 		(*p->p_sysent->sv_prepsyscall)(
-			&frame, (int *)(&args.nosys.sysmsg + 1),
+			frame, (int *)(&args.nosys.sysmsg + 1),
 			&code, &params);
 	} else {
 		/*
@@ -1310,13 +1310,13 @@ 	 * results are returned.  Since edx is 
 	 * system call returns we pre-set it here.
 	 */
 	args.sysmsg_fds[0] = 0;
-	args.sysmsg_fds[1] = frame.tf_edx;
+	args.sysmsg_fds[1] = frame->tf_edx;
 
 	/*
 	 * The syscall might manipulate the trap frame. If it does it
 	 * will probably return EJUSTRETURN.
 	 */
-	args.sysmsg_frame = &frame;
+	args.sysmsg_frame = frame;
 
 	STOPEVENT(p, S_SCE, narg);	/* MP aware */
 
@@ -1344,16 +1344,16 @@ 		 * if this is a child returning from f
 		 */
 		p = curproc;
 		lp = curthread->td_lwp;
-		frame.tf_eax = args.sysmsg_fds[0];
-		frame.tf_edx = args.sysmsg_fds[1];
-		frame.tf_eflags &= ~PSL_C;
+		frame->tf_eax = args.sysmsg_fds[0];
+		frame->tf_edx = args.sysmsg_fds[1];
+		frame->tf_eflags &= ~PSL_C;
 		break;
 	case ERESTART:
 		/*
 		 * Reconstruct pc, assuming lcall $X,y is 7 bytes,
 		 * int 0x80 is 2 bytes. We saved this in tf_err.
 		 */
-		frame.tf_eip -= frame.tf_err;
+		frame->tf_eip -= frame->tf_err;
 		break;
 	case EJUSTRETURN:
 		break;
@@ -1367,8 +1367,8 @@ 				error = -1;	/* XXX */
 			else
 				error = p->p_sysent->sv_errtbl[error];
 		}
-		frame.tf_eax = error;
-		frame.tf_eflags |= PSL_C;
+		frame->tf_eax = error;
+		frame->tf_eflags |= PSL_C;
 		break;
 	}
 
@@ -1377,14 +1377,14 @@ 	 * Traced syscall.  trapsignal() is not
 	 */
 	if ((orig_tf_eflags & PSL_T) && !(orig_tf_eflags & PSL_VM)) {
 		MAKEMPSAFE(have_mplock);
-		frame.tf_eflags &= ~PSL_T;
+		frame->tf_eflags &= ~PSL_T;
 		trapsignal(p, SIGTRAP, 0);
 	}
 
 	/*
 	 * Handle reschedule and other end-of-syscall issues
 	 */
-	userret(lp, &frame, sticks);
+	userret(lp, frame, sticks);
 
 #ifdef KTRACE
 	if (KTRPOINT(td, KTR_SYSRET)) {
@@ -1406,7 +1406,7 @@ 	/*
 	 * Release the MP lock if we had to get it
 	 */
 	KASSERT(td->td_mpcount == have_mplock, 
-		("badmpcount syscall2/end from %p", (void *)frame.tf_eip));
+		("badmpcount syscall2/end from %p", (void *)frame->tf_eip));
 	if (have_mplock)
 		rel_mplock();
 #endif
@@ -1424,13 +1424,13 @@  * released on return.  This code will r
  * trampoline code which then runs doreti.
  */
 void
-fork_return(struct lwp *lp, struct trapframe frame)
+fork_return(struct lwp *lp, struct trapframe *frame)
 {
 	struct proc *p = lp->lwp_proc;
 
-	frame.tf_eax = 0;		/* Child returns zero */
-	frame.tf_eflags &= ~PSL_C;	/* success */
-	frame.tf_edx = 1;
+	frame->tf_eax = 0;		/* Child returns zero */
+	frame->tf_eflags &= ~PSL_C;	/* success */
+	frame->tf_edx = 1;
 
 	/*
 	 * Newly forked processes are given a kernel priority.  We have to
@@ -1443,7 +1443,7 @@ 	 * released when the thread goes to sle
 	 */
 	lwkt_setpri_self(TDPRI_USER_NORM);
 	userenter(lp->lwp_thread);
-	userret(lp, &frame, 0);
+	userret(lp, frame, 0);
 #ifdef KTRACE
 	if (KTRPOINT(lp->lwp_thread, KTR_SYSRET))
 		ktrsysret(p, SYS_fork, 0, 0);
Index: platform/pc32/i386/vm86.c
===================================================================
RCS file: /home/dcvs/src/sys/platform/pc32/i386/vm86.c,v
retrieving revision 1.24
diff -u -p -r1.24 vm86.c
--- platform/pc32/i386/vm86.c	8 Jan 2007 03:33:42 -0000	1.24
+++ platform/pc32/i386/vm86.c	21 Jan 2007 09:42:18 -0000
@@ -77,7 +77,7 @@ 	char	vml_iomap[IOMAP_SIZE];
 	char	vml_iomap_trailer;
 };
 
-void vm86_prepcall(struct vm86frame);
+void vm86_prepcall(struct vm86frame *);
 
 struct system_map {
 	int		type;
@@ -569,25 +569,25 @@ /*
  * called from vm86_bioscall, while in vm86 address space, to finalize setup.
  */
 void
-vm86_prepcall(struct vm86frame vmf)
+vm86_prepcall(struct vm86frame *vmf)
 {
 	uintptr_t addr[] = { 0xA00, 0x1000 };	/* code, stack */
 	u_char intcall[] = {
 		CLI, INTn, 0x00, STI, HLT
 	};
 
-	if ((vmf.vmf_trapno & PAGE_MASK) <= 0xff) {
+	if ((vmf->vmf_trapno & PAGE_MASK) <= 0xff) {
 		/* interrupt call requested */
-        	intcall[2] = (u_char)(vmf.vmf_trapno & 0xff);
+        	intcall[2] = (u_char)(vmf->vmf_trapno & 0xff);
 		memcpy((void *)addr[0], (void *)intcall, sizeof(intcall));
-		vmf.vmf_ip = addr[0];
-		vmf.vmf_cs = 0;
+		vmf->vmf_ip = addr[0];
+		vmf->vmf_cs = 0;
 	}
-	vmf.vmf_sp = addr[1] - 2;              /* keep aligned */
-	vmf.kernel_fs = vmf.kernel_es = vmf.kernel_ds = vmf.kernel_gs = 0;
-	vmf.vmf_ss = 0;
-	vmf.vmf_eflags = PSL_VIF | PSL_VM | PSL_USER;
-	vm86_initflags(&vmf);
+	vmf->vmf_sp = addr[1] - 2;              /* keep aligned */
+	vmf->kernel_fs = vmf->kernel_es = vmf->kernel_ds = vmf->kernel_gs = 0;
+	vmf->vmf_ss = 0;
+	vmf->vmf_eflags = PSL_VIF | PSL_VM | PSL_USER;
+	vm86_initflags(vmf);
 }
 
 /*
Index: platform/pc32/i386/vm86bios.s
===================================================================
RCS file: /home/dcvs/src/sys/platform/pc32/i386/vm86bios.s,v
retrieving revision 1.13
diff -u -p -r1.13 vm86bios.s
--- platform/pc32/i386/vm86bios.s	16 Jun 2005 21:12:44 -0000	1.13
+++ platform/pc32/i386/vm86bios.s	21 Jan 2007 09:43:47 -0000
@@ -130,7 +130,9 @@ 
 	movl	%ecx,%cr3		/* new page tables */
 	movl	SCR_VMFRAME(%edx),%esp	/* switch to new stack */
 	
+	pushl	%esp			/* pass frame by reference */
 	call	vm86_prepcall		/* finish setup */
+	addl	$4,%esp
 
 	movl	$1,in_vm86call		/* set flag for trap() */
 
Index: platform/pc32/icu/icu_vector.s
===================================================================
RCS file: /home/dcvs/src/sys/platform/pc32/icu/icu_vector.s,v
retrieving revision 1.29
diff -u -p -r1.29 icu_vector.s
--- platform/pc32/icu/icu_vector.s	8 Jan 2007 03:33:42 -0000	1.29
+++ platform/pc32/icu/icu_vector.s	21 Jan 2007 10:10:12 -0000
@@ -155,8 +155,9 @@ 2: ;									\
 	/* clear pending bit, run handler */				\
 	andl	$~IRQ_LBIT(irq_num),PCPU(fpending) ;			\
 	pushl	$irq_num ;						\
+	pushl	%esp ;			/* pass frame by reference */	\
 	call	ithread_fast_handler ;	/* returns 0 to unmask int */	\
-	addl	$4,%esp ;						\
+	addl	$8,%esp ;						\
 	UNMASK_IRQ(icu, irq_num) ;					\
 5: ;									\
 	MEXITCOUNT ;							\
Index: platform/pc32/isa/ipl.s
===================================================================
RCS file: /home/dcvs/src/sys/platform/pc32/isa/ipl.s,v
retrieving revision 1.27
diff -u -p -r1.27 ipl.s
--- platform/pc32/isa/ipl.s	8 Jan 2007 03:33:43 -0000	1.27
+++ platform/pc32/isa/ipl.s	21 Jan 2007 11:02:33 -0000
@@ -310,9 +310,11 @@ 	andl	$~(RQF_AST_SIGNAL|RQF_AST_UPCALL),
 	sti
 	movl	%eax,%esi		/* save cpl (can't use stack) */
 	movl	$T_ASTFLT,TF_TRAPNO(%esp)
+	pushl	%esp			/* pass frame by reference */
 	subl	$TDPRI_CRIT,TD_PRI(%ebx)
 	call	trap
 	addl	$TDPRI_CRIT,TD_PRI(%ebx)
+	addl	$4,%esp
 	movl	%esi,%eax		/* restore cpl for loop */
 	jmp	doreti_next
 
@@ -325,8 +327,9 @@ 	movl	%eax,%esi		/* save cpl (can't use 
 	incl	PCPU(intr_nesting_level)
 	andl	$~RQF_IPIQ,PCPU(reqflags)
 	subl	$8,%esp			/* add dummy vec and ppl */
+	pushl	%esp			/* pass frame by reference */
 	call	lwkt_process_ipiq_frame
-	addl	$8,%esp
+	addl	$12,%esp
 	decl	PCPU(intr_nesting_level)
 	movl	%esi,%eax		/* restore cpl for loop */
 	jmp	doreti_next
@@ -504,7 +507,9 @@ 	movl	%esp,%ebp
 	PUSH_DUMMY
 	pushl	%ecx			/* last part of intrframe = intr */
 	incl	fastunpend_count
+	pushl	%esp			/* pass frame by reference */
 	call	ithread_fast_handler	/* returns 0 to unmask */
+	addl	$4,%esp			/* remove pointer, now intr on top */
 	cmpl	$0,%eax
 	jnz	1f
 	movl	MachIntrABI + MACHINTR_INTREN, %eax
Index: platform/vkernel/i386/fork_tramp.s
===================================================================
RCS file: /home/dcvs/src/sys/platform/vkernel/i386/fork_tramp.s,v
retrieving revision 1.2
diff -u -p -r1.2 fork_tramp.s
--- platform/vkernel/i386/fork_tramp.s	14 Jan 2007 07:59:05 -0000	1.2
+++ platform/vkernel/i386/fork_tramp.s	21 Jan 2007 09:38:17 -0000
@@ -67,10 +67,16 @@ 	 * have this call a non-return function
 	 *
 	 * initproc has its own fork handler, start_init(), which DOES
 	 * return.
+	 *
+	 * The function (set in pcb_esi) gets passed two arguments,
+	 * the primary parameter set in pcb_ebx and a pointer to the
+	 * trapframe.
+	 *   void (func)(int arg, struct trapframe *frame);
 	 */
+	pushl	%esp			/* pass frame by reference */
 	pushl	%ebx			/* arg1 */
 	call	*%esi			/* function */
-	addl	$4,%esp
+	addl	$8,%esp
 	/* cut from syscall */
 
 	call	splz
@@ -93,6 +99,7 @@ 	 */
 	MEXITCOUNT
 	pushl	$0		/* if_ppl */
 	pushl	$0		/* if_vec */
+	pushl	%esp		/* pass by reference */
 	call	go_user
 	/* NOT REACHED */
 
Index: platform/vkernel/i386/trap.c
===================================================================
RCS file: /home/dcvs/src/sys/platform/vkernel/i386/trap.c,v
retrieving revision 1.13
diff -u -p -r1.13 trap.c
--- platform/vkernel/i386/trap.c	14 Jan 2007 20:07:14 -0000	1.13
+++ platform/vkernel/i386/trap.c	21 Jan 2007 08:53:03 -0000
@@ -1333,13 +1333,13 @@  * released on return.  This code will r
  * trampoline code which then runs doreti.
  */
 void
-fork_return(struct lwp *lp, struct trapframe frame)
+fork_return(struct lwp *lp, struct trapframe *frame)
 {
 	struct proc *p = lp->lwp_proc;
 
-	frame.tf_eax = 0;		/* Child returns zero */
-	frame.tf_eflags &= ~PSL_C;	/* success */
-	frame.tf_edx = 1;
+	frame->tf_eax = 0;		/* Child returns zero */
+	frame->tf_eflags &= ~PSL_C;	/* success */
+	frame->tf_edx = 1;
 
 	/*
 	 * Newly forked processes are given a kernel priority.  We have to
@@ -1352,7 +1352,7 @@ 	 * released when the thread goes to sle
 	 */
 	lwkt_setpri_self(TDPRI_USER_NORM);
 	userenter(lp->lwp_thread);
-	userret(lp, &frame, 0);
+	userret(lp, frame, 0);
 #ifdef KTRACE
 	if (KTRPOINT(lp->lwp_thread, KTR_SYSRET))
 		ktrsysret(p, SYS_fork, 0, 0);
@@ -1381,9 +1381,9 @@  * vmspace_ctl() returns an error only i
  * context we supplied or problems copying data to/from our VM space.
  */
 void
-go_user(struct intrframe frame)
+go_user(struct intrframe *frame)
 {
-	struct trapframe *tf = (void *)&frame.if_gs;
+	struct trapframe *tf = (void *)&frame->if_gs;
 	int r;
 
 	/*
@@ -1427,19 +1427,19 @@ 		 * bit is normally set only by T_PAGEF
 		 */
 		r = vmspace_ctl(&curproc->p_vmspace->vm_pmap, VMSPACE_CTL_RUN,
 				tf, &curthread->td_savevext);
-		frame.if_xflags |= PGEX_U;
+		frame->if_xflags |= PGEX_U;
 #if 0
 		kprintf("GO USER %d trap %d EVA %08x EIP %08x ESP %08x XFLAGS %02x/%02x\n", 
 			r, tf->tf_trapno, tf->tf_err, tf->tf_eip, tf->tf_esp,
-			tf->tf_xflags, frame.if_xflags);
+			tf->tf_xflags, frame->if_xflags);
 #endif
 		if (r < 0) {
 			if (errno == EINTR)
-				signalmailbox(&frame);
+				signalmailbox(frame);
 			else
 				panic("vmspace_ctl failed");
 		} else {
-			signalmailbox(&frame);
+			signalmailbox(frame);
 			if (tf->tf_trapno) {
 				user_trap(tf);
 			} else if (mycpu->gd_reqflags & RQF_AST_MASK) {
Index: platform/vkernel/include/md_var.h
===================================================================
RCS file: /home/dcvs/src/sys/platform/vkernel/include/md_var.h,v
retrieving revision 1.16
diff -u -p -r1.16 md_var.h
--- platform/vkernel/include/md_var.h	15 Jan 2007 05:27:30 -0000	1.16
+++ platform/vkernel/include/md_var.h	21 Jan 2007 08:53:10 -0000
@@ -82,7 +82,7 @@ 
 void cpu_exit_switch (struct thread *next);
 void cpu_setregs (void);
 void cpu_idle (void);
-void go_user (struct intrframe frame);
+void go_user (struct intrframe *frame);
 
 void init_exceptions(void);
 void init_kqueue(void);
Index: sys/thread.h
===================================================================
RCS file: /home/dcvs/src/sys/sys/thread.h,v
retrieving revision 1.86
diff -u -p -r1.86 thread.h
--- sys/thread.h	4 Jun 2006 21:09:50 -0000	1.86
+++ sys/thread.h	21 Jan 2007 08:37:26 -0000
@@ -389,7 +389,7 @@ 				void *arg1, int arg2);
 extern int  lwkt_seq_ipiq(struct globaldata *targ);
 extern void lwkt_process_ipiq(void);
 #ifdef _KERNEL
-extern void lwkt_process_ipiq_frame(struct intrframe frame);
+extern void lwkt_process_ipiq_frame(struct intrframe *frame);
 #endif
 extern void lwkt_smp_stopped(void);
 

Attachment: signature.asc
Description: OpenPGP digital signature



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