/* * This routine is called on return from interrupt if any of the * TIF_WORK_MASK flags are set in thread_info->flags. It is * entered with interrupts disabled so we don't miss an event * that modified the thread_info flags. If any flag is set, we * handle it and return, and the calling assembly code will * re-disable interrupts, reload the thread flags, and call back * if more flags need to be handled. * * We return whether we need to check the thread_info flags again * or not. Note that we don't clear TIF_SINGLESTEP here, so it's * important that it be tested last, and then claim that we don't * need to recheck the flags. */ int do_work_pending(struct pt_regs *regs, u32 thread_info_flags) { if (thread_info_flags & _TIF_NEED_RESCHED) { schedule(); return 1; } #if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() if (thread_info_flags & _TIF_ASYNC_TLB) { do_async_page_fault(regs); return 1; } #endif if (thread_info_flags & _TIF_SIGPENDING) { do_signal(regs); return 1; } if (thread_info_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); if (current->replacement_session_keyring) key_replace_session_keyring(); return 1; } if (thread_info_flags & _TIF_SINGLESTEP) { if ((regs->ex1 & SPR_EX_CONTEXT_1_1__PL_MASK) == 0) single_step_once(regs); return 0; } panic("work_pending: bad flags %#x\n", thread_info_flags); }
/* * This routine is called on return from interrupt if any of the * TIF_WORK_MASK flags are set in thread_info->flags. It is * entered with interrupts disabled so we don't miss an event * that modified the thread_info flags. If any flag is set, we * handle it and return, and the calling assembly code will * re-disable interrupts, reload the thread flags, and call back * if more flags need to be handled. * * We return whether we need to check the thread_info flags again * or not. Note that we don't clear TIF_SINGLESTEP here, so it's * important that it be tested last, and then claim that we don't * need to recheck the flags. */ int do_work_pending(struct pt_regs *regs, u32 thread_info_flags) { /* If we enter in kernel mode, do nothing and exit the caller loop. */ if (!user_mode(regs)) return 0; if (thread_info_flags & _TIF_NEED_RESCHED) { schedule(); return 1; } #if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() if (thread_info_flags & _TIF_ASYNC_TLB) { do_async_page_fault(regs); return 1; } #endif if (thread_info_flags & _TIF_SIGPENDING) { do_signal(regs); return 1; } if (thread_info_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); if (current->replacement_session_keyring) key_replace_session_keyring(); return 1; } if (thread_info_flags & _TIF_SINGLESTEP) { single_step_once(regs); return 0; } panic("work_pending: bad flags %#x\n", thread_info_flags); }