• S
    arm64: nofpsmid: Handle TIF_FOREIGN_FPSTATE flag cleanly · ba08cf93
    Suzuki K Poulose 提交于
    stable inclusion
    from linux-4.19.105
    commit e074c64a27b52b5f97460816c622e6fc74656b52
    
    --------------------------------
    
    commit 52f73c38 upstream
    
    We detect the absence of FP/SIMD after an incapable CPU is brought up,
    and by then we have kernel threads running already with TIF_FOREIGN_FPSTATE set
    which could be set for early userspace applications (e.g, modprobe triggered
    from initramfs) and init. This could cause the applications to loop forever in
    do_nofity_resume() as we never clear the TIF flag, once we now know that
    we don't support FP.
    
    Fix this by making sure that we clear the TIF_FOREIGN_FPSTATE flag
    for tasks which may have them set, as we would have done in the normal
    case, but avoiding touching the hardware state (since we don't support any).
    
    Also to make sure we handle the cases seemlessly we categorise the
    helper functions to two :
     1) Helpers for common core code, which calls into take appropriate
        actions without knowing the current FPSIMD state of the CPU/task.
    
        e.g fpsimd_restore_current_state(), fpsimd_flush_task_state(),
            fpsimd_save_and_flush_cpu_state().
    
        We bail out early for these functions, taking any appropriate actions
        (e.g, clearing the TIF flag) where necessary to hide the handling
        from core code.
    
     2) Helpers used when the presence of FP/SIMD is apparent.
        i.e, save/restore the FP/SIMD register state, modify the CPU/task
        FP/SIMD state.
        e.g,
    
        fpsimd_save(), task_fpsimd_load() - save/restore task FP/SIMD registers
    
        fpsimd_bind_task_to_cpu()  \
                                    - Update the "state" metadata for CPU/task.
        fpsimd_bind_state_to_cpu() /
    
        fpsimd_update_current_state() - Update the fp/simd state for the current
                                        task from memory.
    
        These must not be called in the absence of FP/SIMD. Put in a WARNING
        to make sure they are not invoked in the absence of FP/SIMD.
    
    KVM also uses the TIF_FOREIGN_FPSTATE flag to manage the FP/SIMD state
    on the CPU. However, without FP/SIMD support we trap all accesses and
    inject undefined instruction. Thus we should never "load" guest state.
    Add a sanity check to make sure this is valid.
    
    Cc: stable@vger.kernel.org # v4.19
    Cc: Will Deacon <will@kernel.org>
    Cc: Mark Rutland <mark.rutland@arm.com>
    Reviewed-by: NArd Biesheuvel <ardb@kernel.org>
    Reviewed-by: NCatalin Marinas <catalin.marinas@arm.com>
    Acked-by: NMarc Zyngier <maz@kernel.org>
    Signed-off-by: NSuzuki K Poulose <suzuki.poulose@arm.com>
    Signed-off-by: NWill Deacon <will@kernel.org>
    Signed-off-by: NSasha Levin <sashal@kernel.org>
    Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
    ba08cf93
switch.c 18.7 KB