summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2003-09-05 22:50:10 +0000
committermarcel <marcel@FreeBSD.org>2003-09-05 22:50:10 +0000
commitb7c5acb1f2e86b904562f74ec1b5735eba81e26e (patch)
tree1dc1bd893e34c0b32d5201dadc20bfb36748a909
parentd1c253ce2300f067eb3c66f503932b0b7b05a583 (diff)
downloadFreeBSD-src-b7c5acb1f2e86b904562f74ec1b5735eba81e26e.zip
FreeBSD-src-b7c5acb1f2e86b904562f74ec1b5735eba81e26e.tar.gz
Fix a place where I forgot to change the code that checks whether
we return to kernel or userland. This triggered a panic in a KSE application when TDF_USTATCLOCK was set in the case userland was interrupted, but we never called ast() on our way out. As such, we called ast() at some other time. Unfortunately, TDF_USTATCLOCK handling assumes running in the interrupt thread. This was not the case anymore. To avoid making the same mistake later, interrupt() now returns to its caller whether we interrupted userland or not. This avoids that we have to duplicate the check in assembly, where it's bound to fall off the scope. Now we simply check the return value and call ast() if appropriate. Run into this: davidxu
-rw-r--r--sys/ia64/ia64/exception.S22
-rw-r--r--sys/ia64/ia64/genassym.c2
-rw-r--r--sys/ia64/ia64/interrupt.c4
-rw-r--r--sys/ia64/include/md_var.h2
4 files changed, 9 insertions, 21 deletions
diff --git a/sys/ia64/ia64/exception.S b/sys/ia64/ia64/exception.S
index fbbf7b6..2105203 100644
--- a/sys/ia64/ia64/exception.S
+++ b/sys/ia64/ia64/exception.S
@@ -1151,6 +1151,7 @@ IVT_ENTRY(External_Interrupt, 0x3000)
;;
}
alloc r14=ar.pfs,0,0,2,0
+ cmp4.eq p14,p0=0,r0
;;
1:
{ .mii
@@ -1178,29 +1179,16 @@ IVT_ENTRY(External_Interrupt, 0x3000)
nop 0
}
{ .mfb
- nop 0
+ cmp4.eq p14,p0=0,r8 // Return to kernel mode?
nop 0
br.sptk 1b // loop for more
;;
}
2:
-{ .mmi
- add r14=16+TF_SPECIAL_IIP,sp
- ;;
- ld8 r14=[r14]
+{ .mbb
add out0=16,sp
- ;;
-}
-{ .mii
- nop 0
- extr.u r14=r14,61,3
- ;;
- cmp.gt p15,p0=5,r14
-}
-{ .mfb
- nop 0
- nop 0
-(p15) br.call.sptk rp=do_ast
+(p14) br.sptk exception_restore
+ br.call.sptk rp=do_ast
;;
}
{ .mfb
diff --git a/sys/ia64/ia64/genassym.c b/sys/ia64/ia64/genassym.c
index 0c0ec81..9679f3f 100644
--- a/sys/ia64/ia64/genassym.c
+++ b/sys/ia64/ia64/genassym.c
@@ -112,8 +112,6 @@ ASSYM(TD_PCB, offsetof(struct thread, td_pcb));
ASSYM(TDF_ASTPENDING, TDF_ASTPENDING);
ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED);
-ASSYM(TF_SPECIAL_IIP, offsetof(struct trapframe, tf_special.iip));
-
ASSYM(UC_MCONTEXT, offsetof(ucontext_t, uc_mcontext));
ASSYM(VM_MAX_ADDRESS, VM_MAX_ADDRESS);
diff --git a/sys/ia64/ia64/interrupt.c b/sys/ia64/ia64/interrupt.c
index e7b5367..b43306b 100644
--- a/sys/ia64/ia64/interrupt.c
+++ b/sys/ia64/ia64/interrupt.c
@@ -51,6 +51,7 @@
#include <sys/sysctl.h>
#include <machine/clock.h>
+#include <machine/cpu.h>
#include <machine/frame.h>
#include <machine/intr.h>
#include <machine/md_var.h>
@@ -122,7 +123,7 @@ static int adjust_ticks = 0;
SYSCTL_INT(_debug, OID_AUTO, clock_adjust_ticks, CTLFLAG_RW,
&adjust_ticks, 0, "Total number of ITC interrupts with adjustment");
-void
+int
interrupt(u_int64_t vector, struct trapframe *framep)
{
struct thread *td;
@@ -230,6 +231,7 @@ interrupt(u_int64_t vector, struct trapframe *framep)
}
atomic_subtract_int(&td->td_intr_nesting_level, 1);
+ return (TRAPF_USERMODE(framep));
}
/*
diff --git a/sys/ia64/include/md_var.h b/sys/ia64/include/md_var.h
index 3301f34..792742d 100644
--- a/sys/ia64/include/md_var.h
+++ b/sys/ia64/include/md_var.h
@@ -61,7 +61,7 @@ int ia64_highfp_load(struct thread *);
int ia64_highfp_save(struct thread *);
void ia64_init(void);
void ia64_probe_sapics(void);
-void interrupt(uint64_t, struct trapframe *);
+int interrupt(uint64_t, struct trapframe *);
void map_gateway_page(void);
void map_pal_code(void);
void map_port_space(void);
OpenPOWER on IntegriCloud