do_notify_resume

asmlinkage void do_notify_resume(struct pt_regs *regs,
                 unsigned long thread_flags)
{
    /*
     * The assembly code enters us with IRQs off, but it hasn't
     * informed the tracing code of that for efficiency reasons.
     * Update the trace code with the current status.
     */
    trace_hardirqs_off();

    do {
        /* Check valid user FS if needed */
        addr_limit_user_check();

        if (thread_flags & _TIF_NEED_RESCHED) {
            /* Unmask Debug and SError for the next task */
            local_daif_restore(DAIF_PROCCTX_NOIRQ);

            schedule();
        } else {
            local_daif_restore(DAIF_PROCCTX);

            if (thread_flags & _TIF_UPROBE)
                uprobe_notify_resume(regs);

            if (thread_flags & _TIF_SIGPENDING)
                do_signal(regs);

            if (thread_flags & _TIF_NOTIFY_RESUME) {
                clear_thread_flag(TIF_NOTIFY_RESUME);
                tracehook_notify_resume(regs);
                rseq_handle_notify_resume(NULL, regs);
            }

            if (thread_flags & _TIF_FOREIGN_FPSTATE)
                fpsimd_restore_current_state();
        }

        local_daif_mask();
        thread_flags = READ_ONCE(current_thread_info()->flags);
    } while (thread_flags & _TIF_WORK_MASK);
}

/*
 * Load the userland FPSIMD state of 'current' from memory, but only if the
 * FPSIMD state already held in the registers is /not/ the most recent FPSIMD
 * state of 'current'
 */
void fpsimd_restore_current_state(void)
{
    /*
     * For the tasks that were created before we detected the absence of
     * FP/SIMD, the TIF_FOREIGN_FPSTATE could be set via fpsimd_thread_switch(),
     * e.g, init. This could be then inherited by the children processes.
     * If we later detect that the system doesn't support FP/SIMD,
     * we must clear the flag for  all the tasks to indicate that the
     * FPSTATE is clean (as we can't have one) to avoid looping for ever in
     * do_notify_resume().
     */
    if (!system_supports_fpsimd()) {
        clear_thread_flag(TIF_FOREIGN_FPSTATE);
        return;
    }

    get_cpu_fpsimd_context();

    if (test_and_clear_thread_flag(TIF_FOREIGN_FPSTATE)) {
        task_fpsimd_load();
        fpsimd_bind_task_to_cpu();
    }

    put_cpu_fpsimd_context();
}

work_pending:
    mov    x0, sp                // 'regs'
    bl    do_notify_resume
#ifdef CONFIG_TRACE_IRQFLAGS
    bl    trace_hardirqs_on        // enabled while in userspace
#endif
    ldr    x1, [tsk, #TSK_TI_FLAGS]    // re-check for single-step
    b    finish_ret_to_user
/*

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值