Not only disable/enable interrupts, do it for FIQs as well, when needed.

This commit is contained in:
Olivier Houchard 2006-04-09 20:16:47 +00:00
parent 174329aff2
commit 43293c6937
3 changed files with 24 additions and 11 deletions

View File

@ -467,7 +467,7 @@ ENTRY(fork_trampoline)
bl _C_LABEL(fork_exit)
/* Kill irq"s */
mrs r0, cpsr
orr r0, r0, #(I32_bit)
orr r0, r0, #(I32_bit|F32_bit)
msr cpsr_c, r0
DO_AST
PULLFRAME

View File

@ -271,9 +271,13 @@ data_abort_handler(trapframe_t *tf)
/* Grab the current pcb */
pcb = td->td_pcb;
/* Re-enable interrupts if they were enabled previously */
if (td->td_md.md_spinlock_count == 0 &&
__predict_true(tf->tf_spsr & I32_bit) == 0)
enable_interrupts(I32_bit);
if (td->td_md.md_spinlock_count == 0) {
if (__predict_true(tf->tf_spsr & I32_bit) == 0)
enable_interrupts(I32_bit);
if (__predict_true(tf->tf_spsr & F32_bit) == 0)
enable_interrupts(F32_bit);
}
/* Invoke the appropriate handler, if necessary */
if (__predict_false(data_aborts[fsr & FAULT_TYPE_MASK].func != NULL)) {
@ -487,6 +491,7 @@ dab_fatal(trapframe_t *tf, u_int fsr, u_int far, struct thread *td, struct ksig
mode = TRAP_USERMODE(tf) ? "user" : "kernel";
disable_interrupts(I32_bit|F32_bit);
if (td != NULL) {
printf("Fatal %s mode data abort: '%s'\n", mode,
data_aborts[fsr & FAULT_TYPE_MASK].desc);
@ -730,9 +735,13 @@ prefetch_abort_handler(trapframe_t *tf)
thread_user_enter(td);
}
fault_pc = tf->tf_pc;
if (td->td_md.md_spinlock_count == 0 &&
__predict_true((tf->tf_spsr & I32_bit) == 0))
enable_interrupts(I32_bit);
if (td->td_md.md_spinlock_count == 0) {
if (__predict_true(tf->tf_spsr & I32_bit) == 0)
enable_interrupts(I32_bit);
if (__predict_true(tf->tf_spsr & F32_bit) == 0)
enable_interrupts(F32_bit);
}
/* See if the cpu state needs to be fixed up */
@ -1012,9 +1021,13 @@ swi_handler(trapframe_t *frame)
* Since all syscalls *should* come from user mode it will always
* be safe to enable them, but check anyway.
*/
if (td->td_md.md_spinlock_count == 0 && !(frame->tf_spsr & I32_bit))
enable_interrupts(I32_bit);
if (td->td_md.md_spinlock_count == 0) {
if (__predict_true(frame->tf_spsr & I32_bit) == 0)
enable_interrupts(I32_bit);
if (__predict_true(frame->tf_spsr & F32_bit) == 0)
enable_interrupts(F32_bit);
}
syscall(td, frame, insn);
}

View File

@ -189,7 +189,7 @@ undefinedinstruction(trapframe_t *frame)
/* Enable interrupts if they were enabled before the exception. */
if (!(frame->tf_spsr & I32_bit))
enable_interrupts(I32_bit);
enable_interrupts(I32_bit|F32_bit);
frame->tf_pc -= INSN_SIZE;
PCPU_LAZY_INC(cnt.v_trap);