Fix handling of external interrupts: we weren't calling ast() when
interrupting user mode. The net effect of this bug is that a clock interrupt does not cause rescheduling and processes are not preempted. It only takes a "while (1);" to render the machine useless. This bug was introduced by the context changes and EPC syscall code. Handling of ASTs was moved to C for clarity and ease of maintenance, but was not added for the external interrupt case. This needs to be revisited. We now have calls to do_ast() in trap(), break_syscall() and ivt_External_Interrupt(). A single call in exception_restore covers these 3 places without duplication. This is where we handled ASTs prior to the overhaul, except that the meat has been moved to do_ast(), a C function. This was the goal to begin with. Pointy hat: marcel
This commit is contained in:
parent
69229c2af6
commit
3704dfdebb
@ -1150,28 +1150,65 @@ IVT_ENTRY(External_Interrupt, 0x3000)
|
||||
br.sptk exception_save
|
||||
;;
|
||||
}
|
||||
{ .mmb
|
||||
2: alloc r14=ar.pfs,0,0,2,0 // make a frame for calling with
|
||||
add out1=16,sp
|
||||
nop 0
|
||||
alloc r14=ar.pfs,0,0,2,0
|
||||
;;
|
||||
1:
|
||||
{ .mii
|
||||
mov out0=cr.ivr // Get interrupt vector
|
||||
add out1=16,sp
|
||||
;;
|
||||
cmp.eq p15,p0=15,out0 // check for spurious vector number
|
||||
}
|
||||
|
||||
3: mov out0=cr.ivr // find interrupt vector
|
||||
;;
|
||||
cmp.eq p15,p0=15,out0 // check for spurious vector number
|
||||
(p15) br.dpnt.few exception_restore // if spurious, we are done
|
||||
;;
|
||||
ssm psr.i // re-enable interrupts
|
||||
{ .mbb
|
||||
ssm psr.i // re-enable interrupts
|
||||
(p15) br.dpnt.few 2f // if spurious, we are done
|
||||
br.call.sptk.many rp=interrupt // call high-level handler
|
||||
;;
|
||||
rsm psr.i // disable interrupts
|
||||
}
|
||||
{ .mmi
|
||||
rsm psr.i // disable interrupts
|
||||
;;
|
||||
srlz.d
|
||||
mov cr.eoi=r0 // and ack the interrupt
|
||||
nop 0
|
||||
}
|
||||
{ .mmi
|
||||
mov cr.eoi=r0 // ack the interrupt
|
||||
;;
|
||||
srlz.d
|
||||
br.sptk.few 3b // loop for more
|
||||
nop 0
|
||||
}
|
||||
{ .mfb
|
||||
nop 0
|
||||
nop 0
|
||||
br.sptk 1b // loop for more
|
||||
;;
|
||||
}
|
||||
2:
|
||||
{ .mmi
|
||||
add r14=16+TF_SPECIAL_IIP,sp
|
||||
;;
|
||||
ld8 r14=[r14]
|
||||
add out0=16,sp
|
||||
;;
|
||||
}
|
||||
{ .mii
|
||||
nop 0
|
||||
extr.u r14=r14,61,3
|
||||
;;
|
||||
cmp.ge p15,p0=5,r14
|
||||
}
|
||||
{ .mfb
|
||||
nop 0
|
||||
nop 0
|
||||
(p15) br.call.sptk rp=do_ast
|
||||
;;
|
||||
}
|
||||
{ .mfb
|
||||
nop 0
|
||||
nop 0
|
||||
br.sptk exception_restore
|
||||
;;
|
||||
}
|
||||
IVT_END(External_Interrupt)
|
||||
|
||||
IVT_ENTRY(Reserved_3400, 0x3400)
|
||||
|
@ -112,7 +112,7 @@ ASSYM(TD_PCB, offsetof(struct thread, td_pcb));
|
||||
ASSYM(TDF_ASTPENDING, TDF_ASTPENDING);
|
||||
ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED);
|
||||
|
||||
ASSYM(TF_SPECIAL_NDIRTY, offsetof(struct trapframe, tf_special.ndirty));
|
||||
ASSYM(TF_SPECIAL_IIP, offsetof(struct trapframe, tf_special.iip));
|
||||
|
||||
ASSYM(UC_MCONTEXT, offsetof(ucontext_t, uc_mcontext));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user