[issue524] Making world with gcc41?
Simon 'corecode' Schubert
corecode at fs.ei.tum.de
Sun Jan 21 03:41:07 PST 2007
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, ¶ms);
} 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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pgp00016.pgp
Type: application/octet-stream
Size: 252 bytes
Desc: "Description: OpenPGP digital signature"
URL: <http://lists.dragonflybsd.org/pipermail/bugs/attachments/20070121/54567b00/attachment-0022.obj>
More information about the Bugs
mailing list