jne 5f
incl TD_CRITCOUNT(%ebx) /* force all ints to pending */
doreti_next:
- sti /* allow new interrupts */
+ cli /* re-assert cli on loop */
movl %eax,%ecx /* irq mask unavailable due to BGL */
notl %ecx
- cli /* disallow YYY remove */
#ifdef SMP
testl $RQF_IPIQ,PCPU(reqflags)
jnz doreti_ipiq
doreti_iret:
iret
+ /*
+ * Interrupts are likely disabled due to the above interlock
+ * between cli/iretq. We must enable them before calling any
+ * high level function.
+ */
ALIGN_TEXT
.globl doreti_iret_fault
doreti_iret_fault:
pushl %gs
.globl doreti_popl_gs_fault
doreti_popl_gs_fault:
+ sti
movl $0,TF_ERR(%esp) /* XXX should be the error code */
movl $T_PROTFLT,TF_TRAPNO(%esp)
jmp alltraps_with_regs_pushed
ALIGN_TEXT
doreti_fast:
andl PCPU(fpending),%ecx /* only check fast ints */
+ sti
bsfl %ecx, %ecx /* locate the next dispatchable int */
btrl %ecx, PCPU(fpending) /* is it really still pending? */
jnc doreti_next
*/
ALIGN_TEXT
doreti_soft:
+ sti
bsfl %ecx,%ecx /* locate the next pending softint */
btrl %ecx,PCPU(spending) /* make sure its still pending */
jnc doreti_next
movl %eax,%esi /* save cpl (can't use stack) */
incl PCPU(intr_nesting_level)
andl $~RQF_IPIQ,PCPU(reqflags)
+ sti
subl $8,%esp /* add dummy vec and ppl */
pushl %esp /* pass frame by reference */
call lwkt_process_ipiq_frame
movl %eax,%esi /* save cpl (can't use stack) */
incl PCPU(intr_nesting_level)
andl $~RQF_TIMER,PCPU(reqflags)
+ sti
subl $8,%esp /* add dummy vec and ppl */
pushl %esp /* pass frame by reference */
call lapic_timer_process_frame
ALIGN_TEXT
splz_fast:
andl PCPU(fpending),%ecx /* only check fast ints */
+ sti
bsfl %ecx, %ecx /* locate the next dispatchable int */
btrl %ecx, PCPU(fpending) /* is it really still pending? */
jnc splz_next
*/
ALIGN_TEXT
splz_soft:
+ sti
bsfl %ecx,%ecx /* locate the next pending softint */
btrl %ecx,PCPU(spending) /* make sure its still pending */
jnc splz_next
addl $FIRST_SOFTINT,%ecx /* actual intr number */
- sti
pushl %eax
pushl %ecx
decl TD_CRITCOUNT(%ebx)
#ifdef SMP
splz_ipiq:
andl $~RQF_IPIQ,PCPU(reqflags)
+ sti
pushl %eax
call lwkt_process_ipiq
popl %eax
splz_timer:
andl $~RQF_TIMER,PCPU(reqflags)
+ sti
pushl %eax
call lapic_timer_process
popl %eax
* - We have to be careful in regards to local interrupts
* occuring simultaniously with our doreti and splz
* processing.
+ *
+ * - Interrupts must be enabled when calling higher level
+ * functions in order to avoid deadlocking against things
+ * like smp_invltlb.
*/
/*
jne 5f
incl TD_CRITCOUNT(%rbx) /* force all ints to pending */
doreti_next:
- sti /* allow new interrupts */
+ cli /* re-assert cli on loop */
movl %eax,%ecx /* irq mask unavailable due to BGL */
notl %ecx
- cli /* disallow YYY remove */
#ifdef SMP
testl $RQF_IPIQ,PCPU(reqflags)
jnz doreti_ipiq
MEXITCOUNT
/*
+ * (interrupts are disabled here)
+ *
* Restore register and iret. iret can fault on %rip (which is
* really stupid). If this occurs we re-fault and vector to
* doreti_iret_fault().
* (sys/platform/pc64/x86_64/trap.c) catches this specific * case,
* sends the process a signal and continues in the corresponding
* place in the code below.
+ *
+ * Interrupts are likely disabled due to the above interlock
+ * between cli/iretq. We must enable them before calling any
+ * high level function.
*/
ALIGN_TEXT
.globl doreti_iret_fault
doreti_iret_fault:
PUSH_FRAME_NOSWAP
- testq $PSL_I,TF_RFLAGS(%rsp)
- jz 2f
sti
-2:
movq $T_PROTFLT,TF_TRAPNO(%rsp)
movq $0,TF_ERR(%rsp) /* XXX should be the error code */
movq $0,TF_ADDR(%rsp)
ALIGN_TEXT
doreti_fast:
andl PCPU(fpending),%ecx /* only check fast ints */
+ sti
bsfl %ecx, %ecx /* locate the next dispatchable int */
btrl %ecx, PCPU(fpending) /* is it really still pending? */
jnc doreti_next
pushq %rax /* save IRQ mask unavailable for BGL */
/* NOTE: is also CPL in frame */
-#if 0
-#ifdef SMP
- pushq %rcx /* save ecx */
- call try_mplock
- popq %rcx
- testl %eax,%eax
- jz 1f
- /* MP lock successful */
-#endif
-#endif
call dofastunpend /* unpend fast intr %ecx */
-#if 0
-#ifdef SMP
- call rel_mplock
-#endif
-#endif
popq %rax
jmp doreti_next
-1:
- btsl %ecx, PCPU(fpending) /* oops, couldn't get the MP lock */
- popq %rax /* add to temp. cpl mask to ignore */
- orl PCPU(fpending),%eax
- jmp doreti_next
/*
* SOFT interrupt pending
*/
ALIGN_TEXT
doreti_soft:
+ sti
bsfl %ecx,%ecx /* locate the next pending softint */
btrl %ecx,PCPU(spending) /* make sure its still pending */
jnc doreti_next
movl %eax,%r12d /* save cpl (can't use stack) */
incl PCPU(intr_nesting_level)
andl $~RQF_IPIQ,PCPU(reqflags)
+ sti
subq $8,%rsp /* trapframe->intrframe */
movq %rsp,%rdi /* pass frame by ref (C arg) */
call lwkt_process_ipiq_frame
movl %eax,%r12d /* save cpl (can't use stack) */
incl PCPU(intr_nesting_level)
andl $~RQF_TIMER,PCPU(reqflags)
+ sti
subq $8,%rsp /* trapframe->intrframe */
movq %rsp,%rdi /* pass frame by ref (C arg) */
call lapic_timer_process_frame
ALIGN_TEXT
splz_fast:
andl PCPU(fpending),%ecx /* only check fast ints */
+ sti
bsfl %ecx, %ecx /* locate the next dispatchable int */
btrl %ecx, PCPU(fpending) /* is it really still pending? */
jnc splz_next
pushq %rax
-#if 0
-#ifdef SMP
- movl %ecx,%edi /* argument to try_mplock */
- call try_mplock
- testl %eax,%eax
- jz 1f
-#endif
-#endif
call dofastunpend /* unpend fast intr %ecx */
-#if 0
-#ifdef SMP
- call rel_mplock
-#endif
-#endif
popq %rax
jmp splz_next
1:
*/
ALIGN_TEXT
splz_soft:
+ sti
bsfl %ecx,%ecx /* locate the next pending softint */
btrl %ecx,PCPU(spending) /* make sure its still pending */
jnc splz_next
sti
pushq %rax
movl %ecx,%edi /* C argument */
- decl TD_CRITCOUNT(%rbx)
incl TD_NEST_COUNT(%rbx) /* prevent doreti/splz nesting */
+ decl TD_CRITCOUNT(%rbx)
call sched_ithd /* YYY must pull in imasks */
incl TD_CRITCOUNT(%rbx)
decl TD_NEST_COUNT(%rbx) /* prevent doreti/splz nesting */
#ifdef SMP
splz_ipiq:
andl $~RQF_IPIQ,PCPU(reqflags)
+ sti
pushq %rax
call lwkt_process_ipiq
popq %rax
splz_timer:
andl $~RQF_TIMER,PCPU(reqflags)
+ sti
pushq %rax
call lapic_timer_process
popq %rax