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
This commit is contained in:
Marcel Moolenaar 2003-09-05 22:50:10 +00:00
parent 45276e4aa4
commit 8d8d970db1
4 changed files with 9 additions and 21 deletions

View File

@ -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

View File

@ -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);

View File

@ -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));
}
/*

View File

@ -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);