Evidently FreeBSD has long relied on the compiler to treat structures

passed by value (trap frames) as if they were in fact being passed by
reference. For better or worse, this incorrect behaviour is no longer
present in gcc 4.1. In this patch I convert all trapframe arguments to
be explicitly pass by reference. I also remove vm86_initflags, pushing
the very little work that it actually does up into vm86_prepcall.

Reviewed by: kan
Tested by: kan
This commit is contained in:
Kip Macy 2006-12-17 05:07:01 +00:00
parent 9c50a94180
commit a5c5d4402c
10 changed files with 105 additions and 103 deletions

View File

@ -63,9 +63,10 @@ IDTVEC(vec_name) ; \
jz 2f ; \ jz 2f ; \
addl $(32 * index),%eax ; \ addl $(32 * index),%eax ; \
1: ; \ 1: ; \
pushl %esp ; \
pushl %eax ; /* pass the IRQ */ \ pushl %eax ; /* pass the IRQ */ \
call lapic_handle_intr ; \ call lapic_handle_intr ; \
addl $4, %esp ; /* discard parameter */ \ addl $8, %esp ; /* discard parameter */ \
MEXITCOUNT ; \ MEXITCOUNT ; \
jmp doreti ; \ jmp doreti ; \
2: movl $-1, %eax ; /* send a vector of -1 */ \ 2: movl $-1, %eax ; /* send a vector of -1 */ \
@ -103,8 +104,9 @@ IDTVEC(timerint)
PUSH_FRAME PUSH_FRAME
SET_KERNEL_SREGS SET_KERNEL_SREGS
FAKE_MCOUNT(TF_EIP(%esp)) FAKE_MCOUNT(TF_EIP(%esp))
pushl %esp
call lapic_handle_timer call lapic_handle_timer
add $4, %esp
MEXITCOUNT MEXITCOUNT
jmp doreti jmp doreti

View File

@ -135,7 +135,9 @@ alltraps_with_regs_pushed:
SET_KERNEL_SREGS SET_KERNEL_SREGS
FAKE_MCOUNT(TF_EIP(%esp)) FAKE_MCOUNT(TF_EIP(%esp))
calltrap: calltrap:
pushl %esp
call trap call trap
add $4, %esp
/* /*
* Return via doreti to handle ASTs. * Return via doreti to handle ASTs.
@ -167,7 +169,9 @@ IDTVEC(lcall_syscall)
pushl %fs pushl %fs
SET_KERNEL_SREGS SET_KERNEL_SREGS
FAKE_MCOUNT(TF_EIP(%esp)) FAKE_MCOUNT(TF_EIP(%esp))
pushl %esp
call syscall call syscall
add $4, %esp
MEXITCOUNT MEXITCOUNT
jmp doreti jmp doreti
@ -188,7 +192,9 @@ IDTVEC(int0x80_syscall)
pushl %fs pushl %fs
SET_KERNEL_SREGS SET_KERNEL_SREGS
FAKE_MCOUNT(TF_EIP(%esp)) FAKE_MCOUNT(TF_EIP(%esp))
pushl %esp
call syscall call syscall
add $4, %esp
MEXITCOUNT MEXITCOUNT
jmp doreti jmp doreti

View File

@ -612,18 +612,18 @@ lapic_eoi(void)
} }
void void
lapic_handle_intr(int vector, struct trapframe frame) lapic_handle_intr(int vector, struct trapframe *frame)
{ {
struct intsrc *isrc; struct intsrc *isrc;
if (vector == -1) if (vector == -1)
panic("Couldn't get vector from ISR!"); panic("Couldn't get vector from ISR!");
isrc = intr_lookup_source(apic_idt_to_irq(vector)); isrc = intr_lookup_source(apic_idt_to_irq(vector));
intr_execute_handlers(isrc, &frame); intr_execute_handlers(isrc, frame);
} }
void void
lapic_handle_timer(struct trapframe frame) lapic_handle_timer(struct trapframe *frame)
{ {
struct lapic *la; struct lapic *la;
@ -656,16 +656,16 @@ lapic_handle_timer(struct trapframe frame)
if (la->la_hard_ticks >= lapic_timer_hz) { if (la->la_hard_ticks >= lapic_timer_hz) {
la->la_hard_ticks -= lapic_timer_hz; la->la_hard_ticks -= lapic_timer_hz;
if (PCPU_GET(cpuid) == 0) if (PCPU_GET(cpuid) == 0)
hardclock(TRAPF_USERMODE(&frame), TRAPF_PC(&frame)); hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
else else
hardclock_cpu(TRAPF_USERMODE(&frame)); hardclock_cpu(TRAPF_USERMODE(frame));
} }
/* Fire statclock at stathz. */ /* Fire statclock at stathz. */
la->la_stat_ticks += stathz; la->la_stat_ticks += stathz;
if (la->la_stat_ticks >= lapic_timer_hz) { if (la->la_stat_ticks >= lapic_timer_hz) {
la->la_stat_ticks -= lapic_timer_hz; la->la_stat_ticks -= lapic_timer_hz;
statclock(TRAPF_USERMODE(&frame)); statclock(TRAPF_USERMODE(frame));
} }
/* Fire profclock at profhz, but only when needed. */ /* Fire profclock at profhz, but only when needed. */
@ -673,7 +673,7 @@ lapic_handle_timer(struct trapframe frame)
if (la->la_prof_ticks >= lapic_timer_hz) { if (la->la_prof_ticks >= lapic_timer_hz) {
la->la_prof_ticks -= lapic_timer_hz; la->la_prof_ticks -= lapic_timer_hz;
if (profprocs != 0) if (profprocs != 0)
profclock(TRAPF_USERMODE(&frame), TRAPF_PC(&frame)); profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
} }
critical_exit(); critical_exit();
} }

View File

@ -102,8 +102,8 @@ __FBSDID("$FreeBSD$");
#include <machine/clock.h> #include <machine/clock.h>
#endif #endif
extern void trap(struct trapframe frame); extern void trap(struct trapframe *frame);
extern void syscall(struct trapframe frame); extern void syscall(struct trapframe *frame);
static int trap_pfault(struct trapframe *, int, vm_offset_t); static int trap_pfault(struct trapframe *, int, vm_offset_t);
static void trap_fatal(struct trapframe *, vm_offset_t); static void trap_fatal(struct trapframe *, vm_offset_t);
@ -169,8 +169,7 @@ extern char *syscallnames[];
*/ */
void void
trap(frame) trap(struct trapframe *frame)
struct trapframe frame;
{ {
struct thread *td = curthread; struct thread *td = curthread;
struct proc *p = td->td_proc; struct proc *p = td->td_proc;
@ -183,7 +182,7 @@ trap(frame)
#endif #endif
PCPU_LAZY_INC(cnt.v_trap); PCPU_LAZY_INC(cnt.v_trap);
type = frame.tf_trapno; type = frame->tf_trapno;
#ifdef SMP #ifdef SMP
#ifdef STOP_NMI #ifdef STOP_NMI
@ -211,12 +210,12 @@ trap(frame)
* return immediately. * return immediately.
*/ */
if (type == T_NMI && pmc_intr && if (type == T_NMI && pmc_intr &&
(*pmc_intr)(PCPU_GET(cpuid), (uintptr_t) frame.tf_eip, (*pmc_intr)(PCPU_GET(cpuid), (uintptr_t) frame->tf_eip,
TRAPF_USERMODE(&frame))) TRAPF_USERMODE(frame)))
goto out; goto out;
#endif #endif
if ((frame.tf_eflags & PSL_I) == 0) { if ((frame->tf_eflags & PSL_I) == 0) {
/* /*
* Buggy application or kernel code has disabled * Buggy application or kernel code has disabled
* interrupts and then trapped. Enabling interrupts * interrupts and then trapped. Enabling interrupts
@ -224,12 +223,12 @@ trap(frame)
* interrupts disabled until they are accidentally * interrupts disabled until they are accidentally
* enabled later. * enabled later.
*/ */
if (ISPL(frame.tf_cs) == SEL_UPL || (frame.tf_eflags & PSL_VM)) if (ISPL(frame->tf_cs) == SEL_UPL || (frame->tf_eflags & PSL_VM))
printf( printf(
"pid %ld (%s): trap %d with interrupts disabled\n", "pid %ld (%s): trap %d with interrupts disabled\n",
(long)curproc->p_pid, curproc->p_comm, type); (long)curproc->p_pid, curproc->p_comm, type);
else if (type != T_BPTFLT && type != T_TRCTRAP && else if (type != T_BPTFLT && type != T_TRCTRAP &&
frame.tf_eip != (int)cpu_switch_load_gs) { frame->tf_eip != (int)cpu_switch_load_gs) {
/* /*
* XXX not quite right, since this may be for a * XXX not quite right, since this may be for a
* multiple fault in user mode. * multiple fault in user mode.
@ -248,7 +247,7 @@ trap(frame)
} }
eva = 0; eva = 0;
code = frame.tf_err; code = frame->tf_err;
if (type == T_PAGEFLT) { if (type == T_PAGEFLT) {
/* /*
* For some Cyrix CPUs, %cr2 is clobbered by * For some Cyrix CPUs, %cr2 is clobbered by
@ -274,19 +273,19 @@ trap(frame)
if (td->td_critnest != 0 || if (td->td_critnest != 0 ||
WITNESS_CHECK(WARN_SLEEPOK | WARN_GIANTOK, NULL, WITNESS_CHECK(WARN_SLEEPOK | WARN_GIANTOK, NULL,
"Kernel page fault") != 0) "Kernel page fault") != 0)
trap_fatal(&frame, eva); trap_fatal(frame, eva);
else else
enable_intr(); enable_intr();
} }
if ((ISPL(frame.tf_cs) == SEL_UPL) || if ((ISPL(frame->tf_cs) == SEL_UPL) ||
((frame.tf_eflags & PSL_VM) && ((frame->tf_eflags & PSL_VM) &&
!(PCPU_GET(curpcb)->pcb_flags & PCB_VM86CALL))) { !(PCPU_GET(curpcb)->pcb_flags & PCB_VM86CALL))) {
/* user trap */ /* user trap */
td->td_pticks = 0; td->td_pticks = 0;
td->td_frame = &frame; td->td_frame = frame;
addr = frame.tf_eip; addr = frame->tf_eip;
if (td->td_ucred != p->p_ucred) if (td->td_ucred != p->p_ucred)
cred_update_thread(td); cred_update_thread(td);
@ -299,7 +298,7 @@ trap(frame)
case T_BPTFLT: /* bpt instruction fault */ case T_BPTFLT: /* bpt instruction fault */
case T_TRCTRAP: /* trace trap */ case T_TRCTRAP: /* trace trap */
enable_intr(); enable_intr();
frame.tf_eflags &= ~PSL_T; frame->tf_eflags &= ~PSL_T;
i = SIGTRAP; i = SIGTRAP;
ucode = (type == T_TRCTRAP ? TRAP_TRACE : TRAP_BRKPT); ucode = (type == T_TRCTRAP ? TRAP_TRACE : TRAP_BRKPT);
break; break;
@ -322,8 +321,8 @@ trap(frame)
*/ */
case T_PROTFLT: /* general protection fault */ case T_PROTFLT: /* general protection fault */
case T_STKFLT: /* stack fault */ case T_STKFLT: /* stack fault */
if (frame.tf_eflags & PSL_VM) { if (frame->tf_eflags & PSL_VM) {
i = vm86_emulate((struct vm86frame *)&frame); i = vm86_emulate((struct vm86frame *)frame);
if (i == 0) if (i == 0)
goto user; goto user;
break; break;
@ -351,7 +350,7 @@ trap(frame)
thread_user_enter(td); thread_user_enter(td);
#endif #endif
i = trap_pfault(&frame, TRUE, eva); i = trap_pfault(frame, TRUE, eva);
#if defined(I586_CPU) && !defined(NO_F00F_HACK) #if defined(I586_CPU) && !defined(NO_F00F_HACK)
if (i == -2) { if (i == -2) {
/* /*
@ -359,7 +358,7 @@ trap(frame)
* treat the fault as an illegal instruction * treat the fault as an illegal instruction
* (T_PRIVINFLT) instead of a page fault. * (T_PRIVINFLT) instead of a page fault.
*/ */
type = frame.tf_trapno = T_PRIVINFLT; type = frame->tf_trapno = T_PRIVINFLT;
/* Proceed as in that case. */ /* Proceed as in that case. */
ucode = ILL_PRVOPC; ucode = ILL_PRVOPC;
@ -411,7 +410,7 @@ trap(frame)
*/ */
if (kdb_on_nmi) { if (kdb_on_nmi) {
printf ("NMI ... going to debugger\n"); printf ("NMI ... going to debugger\n");
kdb_trap(type, 0, &frame); kdb_trap(type, 0, frame);
} }
#endif /* KDB */ #endif /* KDB */
goto userout; goto userout;
@ -460,7 +459,7 @@ trap(frame)
("kernel trap doesn't have ucred")); ("kernel trap doesn't have ucred"));
switch (type) { switch (type) {
case T_PAGEFLT: /* page fault */ case T_PAGEFLT: /* page fault */
(void) trap_pfault(&frame, FALSE, eva); (void) trap_pfault(frame, FALSE, eva);
goto out; goto out;
case T_DNA: case T_DNA:
@ -482,13 +481,13 @@ trap(frame)
*/ */
case T_PROTFLT: /* general protection fault */ case T_PROTFLT: /* general protection fault */
case T_STKFLT: /* stack fault */ case T_STKFLT: /* stack fault */
if (frame.tf_eflags & PSL_VM) { if (frame->tf_eflags & PSL_VM) {
i = vm86_emulate((struct vm86frame *)&frame); i = vm86_emulate((struct vm86frame *)frame);
if (i != 0) if (i != 0)
/* /*
* returns to original process * returns to original process
*/ */
vm86_trap((struct vm86frame *)&frame); vm86_trap((struct vm86frame *)frame);
goto out; goto out;
} }
if (type == T_STKFLT) if (type == T_STKFLT)
@ -509,7 +508,7 @@ trap(frame)
* (XXX) so that we can continue, and generate * (XXX) so that we can continue, and generate
* a signal. * a signal.
*/ */
if (frame.tf_eip == (int)cpu_switch_load_gs) { if (frame->tf_eip == (int)cpu_switch_load_gs) {
PCPU_GET(curpcb)->pcb_gs = 0; PCPU_GET(curpcb)->pcb_gs = 0;
#if 0 #if 0
PROC_LOCK(p); PROC_LOCK(p);
@ -532,24 +531,24 @@ trap(frame)
* selectors and pointers when the user changes * selectors and pointers when the user changes
* them. * them.
*/ */
if (frame.tf_eip == (int)doreti_iret) { if (frame->tf_eip == (int)doreti_iret) {
frame.tf_eip = (int)doreti_iret_fault; frame->tf_eip = (int)doreti_iret_fault;
goto out; goto out;
} }
if (frame.tf_eip == (int)doreti_popl_ds) { if (frame->tf_eip == (int)doreti_popl_ds) {
frame.tf_eip = (int)doreti_popl_ds_fault; frame->tf_eip = (int)doreti_popl_ds_fault;
goto out; goto out;
} }
if (frame.tf_eip == (int)doreti_popl_es) { if (frame->tf_eip == (int)doreti_popl_es) {
frame.tf_eip = (int)doreti_popl_es_fault; frame->tf_eip = (int)doreti_popl_es_fault;
goto out; goto out;
} }
if (frame.tf_eip == (int)doreti_popl_fs) { if (frame->tf_eip == (int)doreti_popl_fs) {
frame.tf_eip = (int)doreti_popl_fs_fault; frame->tf_eip = (int)doreti_popl_fs_fault;
goto out; goto out;
} }
if (PCPU_GET(curpcb)->pcb_onfault != NULL) { if (PCPU_GET(curpcb)->pcb_onfault != NULL) {
frame.tf_eip = frame->tf_eip =
(int)PCPU_GET(curpcb)->pcb_onfault; (int)PCPU_GET(curpcb)->pcb_onfault;
goto out; goto out;
} }
@ -565,14 +564,14 @@ trap(frame)
* problem here and not every time the kernel is * problem here and not every time the kernel is
* entered. * entered.
*/ */
if (frame.tf_eflags & PSL_NT) { if (frame->tf_eflags & PSL_NT) {
frame.tf_eflags &= ~PSL_NT; frame->tf_eflags &= ~PSL_NT;
goto out; goto out;
} }
break; break;
case T_TRCTRAP: /* trace trap */ case T_TRCTRAP: /* trace trap */
if (frame.tf_eip == (int)IDTVEC(lcall_syscall)) { if (frame->tf_eip == (int)IDTVEC(lcall_syscall)) {
/* /*
* We've just entered system mode via the * We've just entered system mode via the
* syscall lcall. Continue single stepping * syscall lcall. Continue single stepping
@ -581,12 +580,12 @@ trap(frame)
*/ */
goto out; goto out;
} }
if (frame.tf_eip == (int)IDTVEC(lcall_syscall) + 1) { if (frame->tf_eip == (int)IDTVEC(lcall_syscall) + 1) {
/* /*
* The syscall handler has now saved the * The syscall handler has now saved the
* flags. Stop single stepping it. * flags. Stop single stepping it.
*/ */
frame.tf_eflags &= ~PSL_T; frame->tf_eflags &= ~PSL_T;
goto out; goto out;
} }
/* /*
@ -619,7 +618,7 @@ trap(frame)
*/ */
#ifdef KDB #ifdef KDB
/* XXX Giant */ /* XXX Giant */
if (kdb_trap(type, 0, &frame)) if (kdb_trap(type, 0, frame))
goto out; goto out;
#endif #endif
break; break;
@ -646,7 +645,7 @@ trap(frame)
*/ */
if (kdb_on_nmi) { if (kdb_on_nmi) {
printf ("NMI ... going to debugger\n"); printf ("NMI ... going to debugger\n");
kdb_trap(type, 0, &frame); kdb_trap(type, 0, frame);
} }
#endif /* KDB */ #endif /* KDB */
goto out; goto out;
@ -657,7 +656,7 @@ trap(frame)
#endif /* DEV_ISA */ #endif /* DEV_ISA */
} }
trap_fatal(&frame, eva); trap_fatal(frame, eva);
goto out; goto out;
} }
@ -683,7 +682,7 @@ trap(frame)
#endif #endif
user: user:
userret(td, &frame); userret(td, frame);
mtx_assert(&Giant, MA_NOTOWNED); mtx_assert(&Giant, MA_NOTOWNED);
userout: userout:
out: out:
@ -904,8 +903,7 @@ dblfault_handler()
* A system call is essentially treated as a trap. * A system call is essentially treated as a trap.
*/ */
void void
syscall(frame) syscall(struct trapframe *frame)
struct trapframe frame;
{ {
caddr_t params; caddr_t params;
struct sysent *callp; struct sysent *callp;
@ -925,7 +923,7 @@ syscall(frame)
PCPU_LAZY_INC(cnt.v_syscall); PCPU_LAZY_INC(cnt.v_syscall);
#ifdef DIAGNOSTIC #ifdef DIAGNOSTIC
if (ISPL(frame.tf_cs) != SEL_UPL) { if (ISPL(frame->tf_cs) != SEL_UPL) {
mtx_lock(&Giant); /* try to stabilize the system XXX */ mtx_lock(&Giant); /* try to stabilize the system XXX */
panic("syscall"); panic("syscall");
/* NOT REACHED */ /* NOT REACHED */
@ -934,22 +932,22 @@ syscall(frame)
#endif #endif
td->td_pticks = 0; td->td_pticks = 0;
td->td_frame = &frame; td->td_frame = frame;
if (td->td_ucred != p->p_ucred) if (td->td_ucred != p->p_ucred)
cred_update_thread(td); cred_update_thread(td);
#ifdef KSE #ifdef KSE
if (p->p_flag & P_SA) if (p->p_flag & P_SA)
thread_user_enter(td); thread_user_enter(td);
#endif #endif
params = (caddr_t)frame.tf_esp + sizeof(int); params = (caddr_t)frame->tf_esp + sizeof(int);
code = frame.tf_eax; code = frame->tf_eax;
orig_tf_eflags = frame.tf_eflags; orig_tf_eflags = frame->tf_eflags;
if (p->p_sysent->sv_prepsyscall) { if (p->p_sysent->sv_prepsyscall) {
/* /*
* The prep code is MP aware. * The prep code is MP aware.
*/ */
(*p->p_sysent->sv_prepsyscall)(&frame, args, &code, &params); (*p->p_sysent->sv_prepsyscall)(frame, args, &code, &params);
} else { } else {
/* /*
* Need to check if this is a 32 bit or 64 bit syscall. * Need to check if this is a 32 bit or 64 bit syscall.
@ -1000,7 +998,7 @@ syscall(frame)
if (error == 0) { if (error == 0) {
td->td_retval[0] = 0; td->td_retval[0] = 0;
td->td_retval[1] = frame.tf_edx; td->td_retval[1] = frame->tf_edx;
STOPEVENT(p, S_SCE, narg); STOPEVENT(p, S_SCE, narg);
@ -1013,9 +1011,9 @@ syscall(frame)
switch (error) { switch (error) {
case 0: case 0:
frame.tf_eax = td->td_retval[0]; frame->tf_eax = td->td_retval[0];
frame.tf_edx = td->td_retval[1]; frame->tf_edx = td->td_retval[1];
frame.tf_eflags &= ~PSL_C; frame->tf_eflags &= ~PSL_C;
break; break;
case ERESTART: case ERESTART:
@ -1023,7 +1021,7 @@ syscall(frame)
* Reconstruct pc, assuming lcall $X,y is 7 bytes, * Reconstruct pc, assuming lcall $X,y is 7 bytes,
* int 0x80 is 2 bytes. We saved this in tf_err. * int 0x80 is 2 bytes. We saved this in tf_err.
*/ */
frame.tf_eip -= frame.tf_err; frame->tf_eip -= frame->tf_err;
break; break;
case EJUSTRETURN: case EJUSTRETURN:
@ -1036,8 +1034,8 @@ syscall(frame)
else else
error = p->p_sysent->sv_errtbl[error]; error = p->p_sysent->sv_errtbl[error];
} }
frame.tf_eax = error; frame->tf_eax = error;
frame.tf_eflags |= PSL_C; frame->tf_eflags |= PSL_C;
break; break;
} }
@ -1045,11 +1043,11 @@ syscall(frame)
* Traced syscall. * Traced syscall.
*/ */
if ((orig_tf_eflags & PSL_T) && !(orig_tf_eflags & PSL_VM)) { if ((orig_tf_eflags & PSL_T) && !(orig_tf_eflags & PSL_VM)) {
frame.tf_eflags &= ~PSL_T; frame->tf_eflags &= ~PSL_T;
ksiginfo_init_trap(&ksi); ksiginfo_init_trap(&ksi);
ksi.ksi_signo = SIGTRAP; ksi.ksi_signo = SIGTRAP;
ksi.ksi_code = TRAP_TRACE; ksi.ksi_code = TRAP_TRACE;
ksi.ksi_addr = (void *)frame.tf_eip; ksi.ksi_addr = (void *)frame->tf_eip;
trapsignal(td, &ksi); trapsignal(td, &ksi);
} }
@ -1069,7 +1067,7 @@ syscall(frame)
/* /*
* Handle reschedule and other end-of-syscall issues * Handle reschedule and other end-of-syscall issues
*/ */
userret(td, &frame); userret(td, frame);
CTR4(KTR_SYSC, "syscall exit thread %p pid %d proc %s code %d", td, CTR4(KTR_SYSC, "syscall exit thread %p pid %d proc %s code %d", td,
td->td_proc->p_pid, td->td_proc->p_comm, code); td->td_proc->p_pid, td->td_proc->p_comm, code);

View File

@ -55,7 +55,7 @@ static struct mtx vm86_lock;
extern int vm86_bioscall(struct vm86frame *); extern int vm86_bioscall(struct vm86frame *);
extern void vm86_biosret(struct vm86frame *); extern void vm86_biosret(struct vm86frame *);
void vm86_prepcall(struct vm86frame); void vm86_prepcall(struct vm86frame *);
struct system_map { struct system_map {
int type; int type;
@ -506,40 +506,33 @@ vm86_addpage(struct vm86context *vmc, int pagenum, vm_offset_t kva)
panic("vm86_addpage: not enough room"); panic("vm86_addpage: not enough room");
} }
static void
vm86_initflags(struct vm86frame *vmf)
{
struct vm86_kernel *vm86 = &PCPU_GET(curpcb)->pcb_ext->ext_vm86;
if (!vm86->vm86_has_vme)
vm86->vm86_eflags = vmf->vmf_eflags; /* save VIF, VIP */
vmf->vmf_eflags |= PSL_VM;
}
/* /*
* called from vm86_bioscall, while in vm86 address space, to finalize setup. * called from vm86_bioscall, while in vm86 address space, to finalize setup.
*/ */
void void
vm86_prepcall(struct vm86frame vmf) vm86_prepcall(struct vm86frame *vmf)
{ {
uintptr_t addr[] = { 0xA00, 0x1000 }; /* code, stack */ uintptr_t addr[] = { 0xA00, 0x1000 }; /* code, stack */
u_char intcall[] = { u_char intcall[] = {
CLI, INTn, 0x00, STI, HLT CLI, INTn, 0x00, STI, HLT
}; };
struct vm86_kernel *vm86;
if ((vmf.vmf_trapno & PAGE_MASK) <= 0xff) { if ((vmf->vmf_trapno & PAGE_MASK) <= 0xff) {
/* interrupt call requested */ /* 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)); memcpy((void *)addr[0], (void *)intcall, sizeof(intcall));
vmf.vmf_ip = addr[0]; vmf->vmf_ip = addr[0];
vmf.vmf_cs = 0; vmf->vmf_cs = 0;
} }
vmf.vmf_sp = addr[1] - 2; /* keep aligned */ vmf->vmf_sp = addr[1] - 2; /* keep aligned */
vmf.kernel_fs = vmf.kernel_es = vmf.kernel_ds = 0; vmf->kernel_fs = vmf->kernel_es = vmf->kernel_ds = 0;
vmf.vmf_ss = 0; vmf->vmf_ss = 0;
vmf.vmf_eflags = PSL_VIF | PSL_VM | PSL_USER; vmf->vmf_eflags = PSL_VIF | PSL_VM | PSL_USER;
vm86_initflags(&vmf);
vm86 = &PCPU_GET(curpcb)->pcb_ext->ext_vm86;
if (!vm86->vm86_has_vme)
vm86->vm86_eflags = vmf->vmf_eflags; /* save VIF, VIP */
} }
/* /*

View File

@ -129,7 +129,9 @@ ENTRY(vm86_bioscall)
movl %ecx,%cr3 /* new page tables */ movl %ecx,%cr3 /* new page tables */
movl SCR_VMFRAME(%edx),%esp /* switch to new stack */ movl SCR_VMFRAME(%edx),%esp /* switch to new stack */
pushl %esp
call vm86_prepcall /* finish setup */ call vm86_prepcall /* finish setup */
add $4, %esp
/* /*
* Return via doreti * Return via doreti

View File

@ -201,8 +201,8 @@ int lapic_intr_pending(u_int vector);
void lapic_ipi_raw(register_t icrlo, u_int dest); void lapic_ipi_raw(register_t icrlo, u_int dest);
void lapic_ipi_vectored(u_int vector, int dest); void lapic_ipi_vectored(u_int vector, int dest);
int lapic_ipi_wait(int delay); int lapic_ipi_wait(int delay);
void lapic_handle_intr(int vector, struct trapframe frame); void lapic_handle_intr(int vector, struct trapframe *frame);
void lapic_handle_timer(struct trapframe frame); void lapic_handle_timer(struct trapframe *frame);
void lapic_set_logical_id(u_int apic_id, u_int cluster, u_int cluster_id); 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_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); int lapic_set_lvt_mode(u_int apic_id, u_int lvt, u_int32_t mode);

View File

@ -558,7 +558,7 @@ atpic_init(void *dummy __unused)
SYSINIT(atpic_init, SI_SUB_INTR, SI_ORDER_SECOND + 1, atpic_init, NULL) SYSINIT(atpic_init, SI_SUB_INTR, SI_ORDER_SECOND + 1, atpic_init, NULL)
void void
atpic_handle_intr(u_int vector, struct trapframe frame) atpic_handle_intr(u_int vector, struct trapframe *frame)
{ {
struct intsrc *isrc; struct intsrc *isrc;
@ -585,7 +585,7 @@ atpic_handle_intr(u_int vector, struct trapframe frame)
if ((isr & IRQ_MASK(7)) == 0) if ((isr & IRQ_MASK(7)) == 0)
return; return;
} }
intr_execute_handlers(isrc, &frame); intr_execute_handlers(isrc, frame);
} }
#ifdef DEV_ISA #ifdef DEV_ISA

View File

@ -51,9 +51,10 @@ IDTVEC(vec_name) ; \
SET_KERNEL_SREGS ; \ SET_KERNEL_SREGS ; \
; \ ; \
FAKE_MCOUNT(TF_EIP(%esp)) ; \ FAKE_MCOUNT(TF_EIP(%esp)) ; \
pushl %esp ; \
pushl $irq_num; /* pass the IRQ */ \ pushl $irq_num; /* pass the IRQ */ \
call atpic_handle_intr ; \ call atpic_handle_intr ; \
addl $4, %esp ; /* discard the parameter */ \ addl $8, %esp ; /* discard the parameters */ \
; \ ; \
MEXITCOUNT ; \ MEXITCOUNT ; \
jmp doreti jmp doreti

View File

@ -47,7 +47,7 @@
#define ICU_IMR_OFFSET 1 #define ICU_IMR_OFFSET 1
#endif #endif
void atpic_handle_intr(u_int vector, struct trapframe frame); void atpic_handle_intr(u_int vector, struct trapframe *frame);
void atpic_startup(void); void atpic_startup(void);
#endif /* !_I386_ISA_ICU_H_ */ #endif /* !_I386_ISA_ICU_H_ */