On Tue, Jul 06, 2021 at 12:18:07PM +0800, Huacai Chen wrote: > + .align 5 /* 32 byte rollback region */ > +SYM_FUNC_START(__arch_cpu_idle) > + /* start of rollback region */ > + LONG_L t0, tp, TI_FLAGS > + nop > + andi t0, t0, _TIF_NEED_RESCHED > + bnez t0, 1f > + nop > + nop > + nop > + idle 0 > + /* end of rollback region */ > +1: > + jirl zero, ra, 0 > +SYM_FUNC_END(__arch_cpu_idle) > +/* > + * Common Vectored Interrupt > + * Complete the register saves and invoke the do_vi() handler > + */ > +SYM_FUNC_START(except_vec_vi_handler) > + la t1, __arch_cpu_idle > + LONG_L t0, sp, PT_EPC > + /* 32 byte rollback region */ > + ori t0, t0, 0x1f > + xori t0, t0, 0x1f > + bne t0, t1, 1f > + LONG_S t0, sp, PT_EPC Seriously, you're having your interrupt handler recover from the idle race? On a *new* architecture? > +1: SAVE_TEMP > + SAVE_STATIC > + CLI > + > + LONG_L s0, tp, TI_REGS > + LONG_S sp, tp, TI_REGS > + > + move s1, sp /* Preserve sp */ > + > + /* Get IRQ stack for this CPU */ > + la t1, irq_stack > + LONG_ADDU t1, t1, x0 > + LONG_L t0, t1, 0 > + > + /* Check if already on IRQ stack */ > + PTR_LI t1, ~(_THREAD_SIZE-1) > + and t1, t1, sp > + beq t0, t1, 2f > + > + /* Switch to IRQ stack */ > + li.w t1, _IRQ_STACK_START > + PTR_ADDU sp, t0, t1 > + > + /* Save task's sp on IRQ stack so that unwinding can follow it */ > + LONG_S s1, sp, 0 > +2: la t0, do_vi > + jirl ra, t0, 0 > + > + move sp, s1 /* Restore sp */ > + la t0, ret_from_irq > + jirl zero, t0, 0 > +SYM_FUNC_END(except_vec_vi_handler)