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:
parent
9c50a94180
commit
a5c5d4402c
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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, ¶ms);
|
(*p->p_sysent->sv_prepsyscall)(frame, args, &code, ¶ms);
|
||||||
} 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);
|
||||||
|
@ -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 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user