summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authorkmacy <kmacy@FreeBSD.org>2006-12-17 06:48:40 +0000
committerkmacy <kmacy@FreeBSD.org>2006-12-17 06:48:40 +0000
commit20611107850a6c1de42880a35271d3a18a4b8811 (patch)
tree4a10bc4aba837d9f1be450b197838da90973dd1b /sys/amd64
parentee539b99dcacb73703a09f64d8ada227bb88a165 (diff)
downloadFreeBSD-src-20611107850a6c1de42880a35271d3a18a4b8811.zip
FreeBSD-src-20611107850a6c1de42880a35271d3a18a4b8811.tar.gz
Newer versions of gcc don't support treating structures passed by value
as if they were really passed by reference. Specifically, the dead stores elimination pass in the GCC 4.1 optimiser breaks the non-compliant behavior on which FreeBSD relied. This change brings FreeBSD up to date by switching trap frames to being explicitly passed by reference. Reviewed by: kan Tested by: kan
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/amd64/apic_vector.S3
-rw-r--r--sys/amd64/amd64/exception.S2
-rw-r--r--sys/amd64/amd64/local_apic.c14
-rw-r--r--sys/amd64/amd64/trap.c98
-rw-r--r--sys/amd64/ia32/ia32_exception.S1
-rw-r--r--sys/amd64/ia32/ia32_syscall.c34
-rw-r--r--sys/amd64/include/apicvar.h4
-rw-r--r--sys/amd64/isa/atpic.c4
-rw-r--r--sys/amd64/isa/atpic_vector.S1
9 files changed, 82 insertions, 79 deletions
diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S
index ab781ca..14a6f87 100644
--- a/sys/amd64/amd64/apic_vector.S
+++ b/sys/amd64/amd64/apic_vector.S
@@ -60,6 +60,7 @@ IDTVEC(vec_name) ; \
jz 2f ; \
addl $(32 * index),%eax ; \
1: ; \
+ movq %rsp, %rsi ; \
movl %eax, %edi ; /* pass the IRQ */ \
call lapic_handle_intr ; \
MEXITCOUNT ; \
@@ -98,7 +99,7 @@ IDTVEC(spuriousint)
IDTVEC(timerint)
PUSH_FRAME
FAKE_MCOUNT(TF_RIP(%rsp))
-
+ movq %rsp, %rdi
call lapic_handle_timer
MEXITCOUNT
jmp doreti
diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S
index 9b87cee..773239f 100644
--- a/sys/amd64/amd64/exception.S
+++ b/sys/amd64/amd64/exception.S
@@ -165,6 +165,7 @@ alltraps_pushregs_no_rdi:
.globl calltrap
.type calltrap,@function
calltrap:
+ movq %rsp, %rdi
call trap
MEXITCOUNT
jmp doreti /* Handle any pending ASTs */
@@ -267,6 +268,7 @@ IDTVEC(fast_syscall)
movq %r14,TF_R14(%rsp) /* C preserved */
movq %r15,TF_R15(%rsp) /* C preserved */
FAKE_MCOUNT(TF_RIP(%rsp))
+ movq %rsp, %rdi
call syscall
movq PCPU(CURPCB),%rax
testq $PCB_FULLCTX,PCB_FLAGS(%rax)
diff --git a/sys/amd64/amd64/local_apic.c b/sys/amd64/amd64/local_apic.c
index 14ce4ce..66c0d0e 100644
--- a/sys/amd64/amd64/local_apic.c
+++ b/sys/amd64/amd64/local_apic.c
@@ -610,18 +610,18 @@ lapic_eoi(void)
}
void
-lapic_handle_intr(int vector, struct trapframe frame)
+lapic_handle_intr(int vector, struct trapframe *frame)
{
struct intsrc *isrc;
if (vector == -1)
panic("Couldn't get vector from ISR!");
isrc = intr_lookup_source(apic_idt_to_irq(vector));
- intr_execute_handlers(isrc, &frame);
+ intr_execute_handlers(isrc, frame);
}
void
-lapic_handle_timer(struct trapframe frame)
+lapic_handle_timer(struct trapframe *frame)
{
struct lapic *la;
@@ -654,16 +654,16 @@ lapic_handle_timer(struct trapframe frame)
if (la->la_hard_ticks >= lapic_timer_hz) {
la->la_hard_ticks -= lapic_timer_hz;
if (PCPU_GET(cpuid) == 0)
- hardclock(TRAPF_USERMODE(&frame), TRAPF_PC(&frame));
+ hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
else
- hardclock_cpu(TRAPF_USERMODE(&frame));
+ hardclock_cpu(TRAPF_USERMODE(frame));
}
/* Fire statclock at stathz. */
la->la_stat_ticks += stathz;
if (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. */
@@ -671,7 +671,7 @@ lapic_handle_timer(struct trapframe frame)
if (la->la_prof_ticks >= lapic_timer_hz) {
la->la_prof_ticks -= lapic_timer_hz;
if (profprocs != 0)
- profclock(TRAPF_USERMODE(&frame), TRAPF_PC(&frame));
+ profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
}
critical_exit();
}
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index a1772fa..7957c34 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -94,8 +94,8 @@ __FBSDID("$FreeBSD$");
#endif
#include <machine/tss.h>
-extern void trap(struct trapframe frame);
-extern void syscall(struct trapframe frame);
+extern void trap(struct trapframe *frame);
+extern void syscall(struct trapframe *frame);
static int trap_pfault(struct trapframe *, int);
static void trap_fatal(struct trapframe *, vm_offset_t);
@@ -155,8 +155,7 @@ extern char *syscallnames[];
*/
void
-trap(frame)
- struct trapframe frame;
+trap(struct trapframe *frame)
{
struct thread *td = curthread;
struct proc *p = td->td_proc;
@@ -165,7 +164,7 @@ trap(frame)
ksiginfo_t ksi;
PCPU_LAZY_INC(cnt.v_trap);
- type = frame.tf_trapno;
+ type = frame->tf_trapno;
#ifdef SMP
#ifdef STOP_NMI
@@ -192,12 +191,12 @@ trap(frame)
* the NMI was handled by it and we can return immediately.
*/
if (type == T_NMI && pmc_intr &&
- (*pmc_intr)(PCPU_GET(cpuid), (uintptr_t) frame.tf_rip,
- TRAPF_USERMODE(&frame)))
+ (*pmc_intr)(PCPU_GET(cpuid), (uintptr_t) frame->tf_rip,
+ TRAPF_USERMODE(frame)))
goto out;
#endif
- if ((frame.tf_rflags & PSL_I) == 0) {
+ if ((frame->tf_rflags & PSL_I) == 0) {
/*
* Buggy application or kernel code has disabled
* interrupts and then trapped. Enabling interrupts
@@ -205,7 +204,7 @@ trap(frame)
* interrupts disabled until they are accidentally
* enabled later.
*/
- if (ISPL(frame.tf_cs) == SEL_UPL)
+ if (ISPL(frame->tf_cs) == SEL_UPL)
printf(
"pid %ld (%s): trap %d with interrupts disabled\n",
(long)curproc->p_pid, curproc->p_comm, type);
@@ -226,7 +225,7 @@ trap(frame)
}
}
- code = frame.tf_err;
+ code = frame->tf_err;
if (type == T_PAGEFLT) {
/*
* If we get a page fault while in a critical section, then
@@ -245,15 +244,15 @@ trap(frame)
if (td->td_critnest != 0 ||
WITNESS_CHECK(WARN_SLEEPOK | WARN_GIANTOK, NULL,
"Kernel page fault") != 0)
- trap_fatal(&frame, frame.tf_addr);
+ trap_fatal(frame, frame->tf_addr);
}
- if (ISPL(frame.tf_cs) == SEL_UPL) {
+ if (ISPL(frame->tf_cs) == SEL_UPL) {
/* user trap */
td->td_pticks = 0;
- td->td_frame = &frame;
- addr = frame.tf_rip;
+ td->td_frame = frame;
+ addr = frame->tf_rip;
if (td->td_ucred != p->p_ucred)
cred_update_thread(td);
@@ -266,7 +265,7 @@ trap(frame)
case T_BPTFLT: /* bpt instruction fault */
case T_TRCTRAP: /* trace trap */
enable_intr();
- frame.tf_rflags &= ~PSL_T;
+ frame->tf_rflags &= ~PSL_T;
i = SIGTRAP;
ucode = (type == T_TRCTRAP ? TRAP_TRACE : TRAP_BRKPT);
break;
@@ -298,12 +297,12 @@ trap(frame)
break;
case T_PAGEFLT: /* page fault */
- addr = frame.tf_addr;
+ addr = frame->tf_addr;
#ifdef KSE
if (td->td_pflags & TDP_SA)
thread_user_enter(td);
#endif
- i = trap_pfault(&frame, TRUE);
+ i = trap_pfault(frame, TRUE);
if (i == -1)
goto userout;
if (i == 0)
@@ -334,7 +333,7 @@ trap(frame)
*/
if (kdb_on_nmi) {
printf ("NMI ... going to debugger\n");
- kdb_trap(type, 0, &frame);
+ kdb_trap(type, 0, frame);
}
#endif /* KDB */
goto userout;
@@ -380,7 +379,7 @@ trap(frame)
("kernel trap doesn't have ucred"));
switch (type) {
case T_PAGEFLT: /* page fault */
- (void) trap_pfault(&frame, FALSE);
+ (void) trap_pfault(frame, FALSE);
goto out;
case T_DNA:
@@ -413,12 +412,12 @@ trap(frame)
* selectors and pointers when the user changes
* them.
*/
- if (frame.tf_rip == (long)doreti_iret) {
- frame.tf_rip = (long)doreti_iret_fault;
+ if (frame->tf_rip == (long)doreti_iret) {
+ frame->tf_rip = (long)doreti_iret_fault;
goto out;
}
if (PCPU_GET(curpcb)->pcb_onfault != NULL) {
- frame.tf_rip =
+ frame->tf_rip =
(long)PCPU_GET(curpcb)->pcb_onfault;
goto out;
}
@@ -434,8 +433,8 @@ trap(frame)
* problem here and not every time the kernel is
* entered.
*/
- if (frame.tf_rflags & PSL_NT) {
- frame.tf_rflags &= ~PSL_NT;
+ if (frame->tf_rflags & PSL_NT) {
+ frame->tf_rflags &= ~PSL_NT;
goto out;
}
break;
@@ -470,7 +469,7 @@ trap(frame)
*/
#ifdef KDB
/* XXX Giant */
- if (kdb_trap(type, 0, &frame))
+ if (kdb_trap(type, 0, frame))
goto out;
#endif
break;
@@ -487,7 +486,7 @@ trap(frame)
*/
if (kdb_on_nmi) {
printf ("NMI ... going to debugger\n");
- kdb_trap(type, 0, &frame);
+ kdb_trap(type, 0, frame);
}
#endif /* KDB */
goto out;
@@ -497,7 +496,7 @@ trap(frame)
#endif /* DEV_ISA */
}
- trap_fatal(&frame, 0);
+ trap_fatal(frame, 0);
goto out;
}
@@ -517,13 +516,13 @@ trap(frame)
uprintf("fatal process exception: %s",
trap_msg[type]);
if ((type == T_PAGEFLT) || (type == T_PROTFLT))
- uprintf(", fault VA = 0x%lx", frame.tf_addr);
+ uprintf(", fault VA = 0x%lx", frame->tf_addr);
uprintf("\n");
}
#endif
user:
- userret(td, &frame);
+ userret(td, frame);
mtx_assert(&Giant, MA_NOTOWNED);
userout:
out:
@@ -723,8 +722,7 @@ dblfault_handler()
* A system call is essentially treated as a trap.
*/
void
-syscall(frame)
- struct trapframe frame;
+syscall(struct trapframe *frame)
{
caddr_t params;
struct sysent *callp;
@@ -746,7 +744,7 @@ syscall(frame)
PCPU_LAZY_INC(cnt.v_syscall);
#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 */
panic("syscall");
/* NOT REACHED */
@@ -757,25 +755,25 @@ syscall(frame)
reg = 0;
regcnt = 6;
td->td_pticks = 0;
- td->td_frame = &frame;
+ td->td_frame = frame;
if (td->td_ucred != p->p_ucred)
cred_update_thread(td);
#ifdef KSE
if (p->p_flag & P_SA)
thread_user_enter(td);
#endif
- params = (caddr_t)frame.tf_rsp + sizeof(register_t);
- code = frame.tf_rax;
- orig_tf_rflags = frame.tf_rflags;
+ params = (caddr_t)frame->tf_rsp + sizeof(register_t);
+ code = frame->tf_rax;
+ orig_tf_rflags = frame->tf_rflags;
if (p->p_sysent->sv_prepsyscall) {
/*
* The prep code is MP aware.
*/
- (*p->p_sysent->sv_prepsyscall)(&frame, (int *)args, &code, &params);
+ (*p->p_sysent->sv_prepsyscall)(frame, (int *)args, &code, &params);
} else {
if (code == SYS_syscall || code == SYS___syscall) {
- code = frame.tf_rdi;
+ code = frame->tf_rdi;
reg++;
regcnt--;
}
@@ -797,7 +795,7 @@ syscall(frame)
KASSERT(narg <= sizeof(args) / sizeof(args[0]),
("Too many syscall arguments!"));
error = 0;
- argp = &frame.tf_rdi;
+ argp = &frame->tf_rdi;
argp += reg;
bcopy(argp, args, sizeof(args[0]) * regcnt);
if (narg > regcnt) {
@@ -817,7 +815,7 @@ syscall(frame)
if (error == 0) {
td->td_retval[0] = 0;
- td->td_retval[1] = frame.tf_rdx;
+ td->td_retval[1] = frame->tf_rdx;
STOPEVENT(p, S_SCE, narg);
@@ -830,9 +828,9 @@ syscall(frame)
switch (error) {
case 0:
- frame.tf_rax = td->td_retval[0];
- frame.tf_rdx = td->td_retval[1];
- frame.tf_rflags &= ~PSL_C;
+ frame->tf_rax = td->td_retval[0];
+ frame->tf_rdx = td->td_retval[1];
+ frame->tf_rflags &= ~PSL_C;
break;
case ERESTART:
@@ -842,8 +840,8 @@ syscall(frame)
* (which was holding the value of %rcx) is restored for
* the next iteration.
*/
- frame.tf_rip -= frame.tf_err;
- frame.tf_r10 = frame.tf_rcx;
+ frame->tf_rip -= frame->tf_err;
+ frame->tf_r10 = frame->tf_rcx;
td->td_pcb->pcb_flags |= PCB_FULLCTX;
break;
@@ -857,8 +855,8 @@ syscall(frame)
else
error = p->p_sysent->sv_errtbl[error];
}
- frame.tf_rax = error;
- frame.tf_rflags |= PSL_C;
+ frame->tf_rax = error;
+ frame->tf_rflags |= PSL_C;
break;
}
@@ -866,11 +864,11 @@ syscall(frame)
* Traced syscall.
*/
if (orig_tf_rflags & PSL_T) {
- frame.tf_rflags &= ~PSL_T;
+ frame->tf_rflags &= ~PSL_T;
ksiginfo_init_trap(&ksi);
ksi.ksi_signo = SIGTRAP;
ksi.ksi_code = TRAP_TRACE;
- ksi.ksi_addr = (void *)frame.tf_rip;
+ ksi.ksi_addr = (void *)frame->tf_rip;
trapsignal(td, &ksi);
}
@@ -890,7 +888,7 @@ syscall(frame)
/*
* 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,
td->td_proc->p_pid, td->td_proc->p_comm, code);
diff --git a/sys/amd64/ia32/ia32_exception.S b/sys/amd64/ia32/ia32_exception.S
index c65634e..4820f53 100644
--- a/sys/amd64/ia32/ia32_exception.S
+++ b/sys/amd64/ia32/ia32_exception.S
@@ -61,6 +61,7 @@ IDTVEC(int0x80_syscall)
movq %r14,TF_R14(%rsp)
movq %r15,TF_R15(%rsp)
FAKE_MCOUNT(TF_RIP(%rsp))
+ movq %rsp, %rdi
call ia32_syscall
MEXITCOUNT
jmp doreti
diff --git a/sys/amd64/ia32/ia32_syscall.c b/sys/amd64/ia32/ia32_syscall.c
index e007b3a..c51a2be 100644
--- a/sys/amd64/ia32/ia32_syscall.c
+++ b/sys/amd64/ia32/ia32_syscall.c
@@ -86,10 +86,10 @@ __FBSDID("$FreeBSD$");
extern inthand_t IDTVEC(int0x80_syscall), IDTVEC(rsvd);
extern const char *freebsd32_syscallnames[];
-void ia32_syscall(struct trapframe frame); /* Called from asm code */
+void ia32_syscall(struct trapframe *frame); /* Called from asm code */
void
-ia32_syscall(struct trapframe frame)
+ia32_syscall(struct trapframe *frame)
{
caddr_t params;
int i;
@@ -111,18 +111,18 @@ ia32_syscall(struct trapframe frame)
PCPU_LAZY_INC(cnt.v_syscall);
td->td_pticks = 0;
- td->td_frame = &frame;
+ td->td_frame = frame;
if (td->td_ucred != p->p_ucred)
cred_update_thread(td);
- params = (caddr_t)frame.tf_rsp + sizeof(u_int32_t);
- code = frame.tf_rax;
- orig_tf_rflags = frame.tf_rflags;
+ params = (caddr_t)frame->tf_rsp + sizeof(u_int32_t);
+ code = frame->tf_rax;
+ orig_tf_rflags = frame->tf_rflags;
if (p->p_sysent->sv_prepsyscall) {
/*
* 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 {
/*
* Need to check if this is a 32 bit or 64 bit syscall.
@@ -177,7 +177,7 @@ ia32_syscall(struct trapframe frame)
if (error == 0) {
td->td_retval[0] = 0;
- td->td_retval[1] = frame.tf_rdx;
+ td->td_retval[1] = frame->tf_rdx;
STOPEVENT(p, S_SCE, narg);
@@ -190,9 +190,9 @@ ia32_syscall(struct trapframe frame)
switch (error) {
case 0:
- frame.tf_rax = td->td_retval[0];
- frame.tf_rdx = td->td_retval[1];
- frame.tf_rflags &= ~PSL_C;
+ frame->tf_rax = td->td_retval[0];
+ frame->tf_rdx = td->td_retval[1];
+ frame->tf_rflags &= ~PSL_C;
break;
case ERESTART:
@@ -200,7 +200,7 @@ ia32_syscall(struct trapframe frame)
* Reconstruct pc, assuming lcall $X,y is 7 bytes,
* int 0x80 is 2 bytes. We saved this in tf_err.
*/
- frame.tf_rip -= frame.tf_err;
+ frame->tf_rip -= frame->tf_err;
break;
case EJUSTRETURN:
@@ -213,8 +213,8 @@ ia32_syscall(struct trapframe frame)
else
error = p->p_sysent->sv_errtbl[error];
}
- frame.tf_rax = error;
- frame.tf_rflags |= PSL_C;
+ frame->tf_rax = error;
+ frame->tf_rflags |= PSL_C;
break;
}
@@ -222,11 +222,11 @@ ia32_syscall(struct trapframe frame)
* Traced syscall.
*/
if (orig_tf_rflags & PSL_T) {
- frame.tf_rflags &= ~PSL_T;
+ frame->tf_rflags &= ~PSL_T;
ksiginfo_init_trap(&ksi);
ksi.ksi_signo = SIGTRAP;
ksi.ksi_code = TRAP_TRACE;
- ksi.ksi_addr = (void *)frame.tf_rip;
+ ksi.ksi_addr = (void *)frame->tf_rip;
trapsignal(td, &ksi);
}
@@ -246,7 +246,7 @@ ia32_syscall(struct trapframe frame)
/*
* 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,
td->td_proc->p_pid, td->td_proc->p_comm, code);
diff --git a/sys/amd64/include/apicvar.h b/sys/amd64/include/apicvar.h
index 6cc37c6..bd0386b 100644
--- a/sys/amd64/include/apicvar.h
+++ b/sys/amd64/include/apicvar.h
@@ -202,8 +202,8 @@ int lapic_intr_pending(u_int vector);
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(int vector, struct trapframe frame);
-void lapic_handle_timer(struct trapframe frame);
+void lapic_handle_intr(int vector, 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);
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);
diff --git a/sys/amd64/isa/atpic.c b/sys/amd64/isa/atpic.c
index 1115c92..3a88eda 100644
--- a/sys/amd64/isa/atpic.c
+++ b/sys/amd64/isa/atpic.c
@@ -494,7 +494,7 @@ atpic_init(void *dummy __unused)
SYSINIT(atpic_init, SI_SUB_INTR, SI_ORDER_SECOND + 1, atpic_init, NULL)
void
-atpic_handle_intr(u_int vector, struct trapframe frame)
+atpic_handle_intr(u_int vector, struct trapframe *frame)
{
struct intsrc *isrc;
@@ -521,7 +521,7 @@ atpic_handle_intr(u_int vector, struct trapframe frame)
if ((isr & IRQ_MASK(7)) == 0)
return;
}
- intr_execute_handlers(isrc, &frame);
+ intr_execute_handlers(isrc, frame);
}
#ifdef DEV_ISA
diff --git a/sys/amd64/isa/atpic_vector.S b/sys/amd64/isa/atpic_vector.S
index 8cddf43..e7dcbc3 100644
--- a/sys/amd64/isa/atpic_vector.S
+++ b/sys/amd64/isa/atpic_vector.S
@@ -49,6 +49,7 @@
IDTVEC(vec_name) ; \
PUSH_FRAME ; \
FAKE_MCOUNT(TF_RIP(%rsp)) ; \
+ movq %rsp, %rsi ; \
movl $irq_num, %edi; /* pass the IRQ */ \
call atpic_handle_intr ; \
MEXITCOUNT ; \
OpenPOWER on IntegriCloud