summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/arm/arm/swtch.S2
-rw-r--r--sys/arm/arm/trap.c31
-rw-r--r--sys/arm/arm/undefined.c2
3 files changed, 24 insertions, 11 deletions
diff --git a/sys/arm/arm/swtch.S b/sys/arm/arm/swtch.S
index 2b54874..111f459 100644
--- a/sys/arm/arm/swtch.S
+++ b/sys/arm/arm/swtch.S
@@ -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
diff --git a/sys/arm/arm/trap.c b/sys/arm/arm/trap.c
index 0c439d2..b1534fe 100644
--- a/sys/arm/arm/trap.c
+++ b/sys/arm/arm/trap.c
@@ -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);
}
diff --git a/sys/arm/arm/undefined.c b/sys/arm/arm/undefined.c
index 21973ce..25246a0 100644
--- a/sys/arm/arm/undefined.c
+++ b/sys/arm/arm/undefined.c
@@ -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);
OpenPOWER on IntegriCloud