18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 1994 Linus Torvalds 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Pentium III FXSR, SSE support 68c2ecf20Sopenharmony_ci * General FPU state handling cleanups 78c2ecf20Sopenharmony_ci * Gareth Hughes <gareth@valinux.com>, May 2000 88c2ecf20Sopenharmony_ci * x86-64 work by Andi Kleen 2002 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#ifndef _ASM_X86_FPU_API_H 128c2ecf20Sopenharmony_ci#define _ASM_X86_FPU_API_H 138c2ecf20Sopenharmony_ci#include <linux/bottom_half.h> 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci/* 168c2ecf20Sopenharmony_ci * Use kernel_fpu_begin/end() if you intend to use FPU in kernel context. It 178c2ecf20Sopenharmony_ci * disables preemption so be careful if you intend to use it for long periods 188c2ecf20Sopenharmony_ci * of time. 198c2ecf20Sopenharmony_ci * If you intend to use the FPU in irq/softirq you need to check first with 208c2ecf20Sopenharmony_ci * irq_fpu_usable() if it is possible. 218c2ecf20Sopenharmony_ci */ 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci/* Kernel FPU states to initialize in kernel_fpu_begin_mask() */ 248c2ecf20Sopenharmony_ci#define KFPU_387 _BITUL(0) /* 387 state will be initialized */ 258c2ecf20Sopenharmony_ci#define KFPU_MXCSR _BITUL(1) /* MXCSR will be initialized */ 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ciextern void kernel_fpu_begin_mask(unsigned int kfpu_mask); 288c2ecf20Sopenharmony_ciextern void kernel_fpu_end(void); 298c2ecf20Sopenharmony_ciextern bool irq_fpu_usable(void); 308c2ecf20Sopenharmony_ciextern void fpregs_mark_activate(void); 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci/* Code that is unaware of kernel_fpu_begin_mask() can use this */ 338c2ecf20Sopenharmony_cistatic inline void kernel_fpu_begin(void) 348c2ecf20Sopenharmony_ci{ 358c2ecf20Sopenharmony_ci kernel_fpu_begin_mask(KFPU_387 | KFPU_MXCSR); 368c2ecf20Sopenharmony_ci} 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci/* 398c2ecf20Sopenharmony_ci * Use fpregs_lock() while editing CPU's FPU registers or fpu->state. 408c2ecf20Sopenharmony_ci * A context switch will (and softirq might) save CPU's FPU registers to 418c2ecf20Sopenharmony_ci * fpu->state and set TIF_NEED_FPU_LOAD leaving CPU's FPU registers in 428c2ecf20Sopenharmony_ci * a random state. 438c2ecf20Sopenharmony_ci */ 448c2ecf20Sopenharmony_cistatic inline void fpregs_lock(void) 458c2ecf20Sopenharmony_ci{ 468c2ecf20Sopenharmony_ci preempt_disable(); 478c2ecf20Sopenharmony_ci local_bh_disable(); 488c2ecf20Sopenharmony_ci} 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_cistatic inline void fpregs_unlock(void) 518c2ecf20Sopenharmony_ci{ 528c2ecf20Sopenharmony_ci local_bh_enable(); 538c2ecf20Sopenharmony_ci preempt_enable(); 548c2ecf20Sopenharmony_ci} 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_DEBUG_FPU 578c2ecf20Sopenharmony_ciextern void fpregs_assert_state_consistent(void); 588c2ecf20Sopenharmony_ci#else 598c2ecf20Sopenharmony_cistatic inline void fpregs_assert_state_consistent(void) { } 608c2ecf20Sopenharmony_ci#endif 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci/* 638c2ecf20Sopenharmony_ci * Load the task FPU state before returning to userspace. 648c2ecf20Sopenharmony_ci */ 658c2ecf20Sopenharmony_ciextern void switch_fpu_return(void); 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci/* 688c2ecf20Sopenharmony_ci * Query the presence of one or more xfeatures. Works on any legacy CPU as well. 698c2ecf20Sopenharmony_ci * 708c2ecf20Sopenharmony_ci * If 'feature_name' is set then put a human-readable description of 718c2ecf20Sopenharmony_ci * the feature there as well - this can be used to print error (or success) 728c2ecf20Sopenharmony_ci * messages. 738c2ecf20Sopenharmony_ci */ 748c2ecf20Sopenharmony_ciextern int cpu_has_xfeatures(u64 xfeatures_mask, const char **feature_name); 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci/* 778c2ecf20Sopenharmony_ci * Tasks that are not using SVA have mm->pasid set to zero to note that they 788c2ecf20Sopenharmony_ci * will not have the valid bit set in MSR_IA32_PASID while they are running. 798c2ecf20Sopenharmony_ci */ 808c2ecf20Sopenharmony_ci#define PASID_DISABLED 0 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_cistatic inline void update_pasid(void) { } 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci#endif /* _ASM_X86_FPU_API_H */ 85