int spinning = 0;
KKASSERT(gd->gd_processing_ipiq == 0);
+ KKASSERT(td->td_flags & TDF_RUNNING);
/*
* Switching from within a 'fast' (non thread switched) interrupt or IPI
*
* We are responsible for marking ntd as TDF_RUNNING.
*/
+ KKASSERT((ntd->td_flags & TDF_RUNNING) == 0);
++switch_count;
KTR_LOG(ctxsw_sw, gd->gd_cpuid, ntd);
ntd->td_flags |= TDF_RUNNING;
return;
}
#ifdef SMP
+ if (td->td_cscount) {
+ ++preempt_miss;
+ return;
+ }
if (ntd->td_gd != gd) {
++preempt_miss;
return;
KTR_LOG(ctxsw_pre, gd->gd_cpuid, ntd);
save_gd_intr_nesting_level = gd->gd_intr_nesting_level;
gd->gd_intr_nesting_level = 0;
+
+ KKASSERT((ntd->td_flags & TDF_RUNNING) == 0);
ntd->td_flags |= TDF_RUNNING;
xtd = td->td_switch(ntd);
KKASSERT(xtd == ntd);
pushl $0
movl %ecx,%cr3
andl $~TDF_RUNNING,TD_FLAGS(%ebx)
-#if 0
- orl $TDF_RUNNING,TD_FLAGS(%eax)
-#endif
+ orl $TDF_RUNNING,TD_FLAGS(%eax) /* manual, no switch_return */
#ifdef SMP
cmpl $0,PCPU(cpuid)
je 1f
/*
* bcopy family
- * void bzero(void *buf, u_int len)
+ * void bzero(void *buf, size_t len)
*/
/* done */
*/
ENTRY(cpu_heavy_restore)
+ movq TD_PCB(%rax),%rdx /* RDX = PCB */
+ movq %rdx, PCPU(common_tss) + TSS_RSP0
popfq
#if defined(SWTCH_OPTIM_STATS)
*/
btq $CPUMASK_BIT,%rax /* test interlock */
jnc 1f
+
+#if 0
+ movq TD_PCB(%r12),%rdx /* XXX debugging unconditional */
+ movq PCB_CR3(%rdx),%rdx /* reloading of %cr3 */
+ movq %rdx,%cr3
+#endif
+
movq %rcx,%rdi /* (found to be set) */
call pmap_interlock_wait /* pmap_interlock_wait(%rdi:vm) */
pushq $0
movq %rcx,%cr3
andl $~TDF_RUNNING,TD_FLAGS(%rbx)
-#if 0
- orl $TDF_RUNNING,TD_FLAGS(%rax)
-#endif
+ orl $TDF_RUNNING,TD_FLAGS(%rax) /* manual, no switch_return */
#ifdef SMP
cmpl $0,PCPU(cpuid)
je 1f
movq %rcx,%cr3
1:
/*
+ * Safety, clear RSP0 in the tss so it isn't pointing at the
+ * previous thread's kstack (if a heavy weight user thread).
+ * RSP0 should only be used in ring 3 transitions and kernel
+ * threads run in ring 0 so there should be none.
+ */
+ xorq %rdx,%rdx
+ movq %rdx, PCPU(common_tss) + TSS_RSP0
+
+ /*
* NOTE: %rbx is the previous thread and %rax is the new thread.
* %rbx is retained throughout so we can return it.
*
movl $0,%ebp
pushl $0
andl $~TDF_RUNNING,TD_FLAGS(%ebx)
-#if 0
- orl $TDF_RUNNING,TD_FLAGS(%eax)
-#endif
+ orl $TDF_RUNNING,TD_FLAGS(%eax) /* manual, no switch_return */
#ifdef SMP
cmpl $0,PCPU(cpuid)
je 1f
/* JG push RBP? */
pushq $0
andl $~TDF_RUNNING,TD_FLAGS(%rbx)
-#if 0
- orl $TDF_RUNNING,TD_FLAGS(%rax)
-#endif
+ orl $TDF_RUNNING,TD_FLAGS(%rax) /* manual, no switch_return */
#ifdef SMP
cmpl $0,PCPU(cpuid)
je 1f