riscv: Add support for kernel-mode FPU

This is needed to support recent hardware in the amdgpu DRM driver. The
FPU code in that driver is not performance-critical, so only provide the
minimal support.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
This commit is contained in:
Samuel Holland 2023-11-21 19:05:13 -08:00 committed by Xiaoguang Xing
parent d650996db8
commit d3b593b59a
2 changed files with 17 additions and 0 deletions

View File

@ -61,6 +61,20 @@ static __always_inline bool has_fpu(void)
{ {
return static_branch_likely(&riscv_isa_ext_keys[RISCV_ISA_EXT_KEY_FPU]); return static_branch_likely(&riscv_isa_ext_keys[RISCV_ISA_EXT_KEY_FPU]);
} }
static inline void kernel_fpu_begin(void)
{
preempt_disable();
fstate_save(current, task_pt_regs(current));
csr_set(CSR_SSTATUS, SR_FS);
}
static inline void kernel_fpu_end(void)
{
csr_clear(CSR_SSTATUS, SR_FS);
fstate_restore(current, task_pt_regs(current));
preempt_enable();
}
#else #else
static __always_inline bool has_fpu(void) { return false; } static __always_inline bool has_fpu(void) { return false; }
#define fstate_save(task, regs) do { } while (0) #define fstate_save(task, regs) do { } while (0)

View File

@ -195,3 +195,6 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
p->thread.sp = (unsigned long)childregs; /* kernel sp */ p->thread.sp = (unsigned long)childregs; /* kernel sp */
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(__fstate_save);
EXPORT_SYMBOL_GPL(__fstate_restore);