summaryrefslogtreecommitdiffstats
path: root/arch/riscv/kernel/process.c
diff options
context:
space:
mode:
authorLinus Torvalds2019-08-17 19:36:47 +0200
committerLinus Torvalds2019-08-17 19:36:47 +0200
commit2f478b60118f48bf66eaddcca0d23e80f87a682d (patch)
tree9a4e6341f103e0e758f58b9db3e3d3a325145737 /arch/riscv/kernel/process.c
parentMerge tag 'xtensa-20190816' of git://github.com/jcmvbkbc/linux-xtensa (diff)
parentriscv: Make __fstate_clean() work correctly. (diff)
downloadkernel-qcow2-linux-2f478b60118f48bf66eaddcca0d23e80f87a682d.tar.gz
kernel-qcow2-linux-2f478b60118f48bf66eaddcca0d23e80f87a682d.tar.xz
kernel-qcow2-linux-2f478b60118f48bf66eaddcca0d23e80f87a682d.zip
Merge tag 'riscv/for-v5.3-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux
Pull RISC-V fixes from Paul Walmsley: - Two patches to fix significant bugs in floating point register context handling - A minor fix in RISC-V flush_tlb_page(), to supply a valid end address to flush_tlb_range() - Two minor defconfig additions: to build the virtio hwrng driver by default (for QEMU targets), and to partially synchronize the 32-bit defconfig with the 64-bit defconfig * tag 'riscv/for-v5.3-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux: riscv: Make __fstate_clean() work correctly. riscv: Correct the initialized flow of FP register riscv: defconfig: Update the defconfig riscv: rv32_defconfig: Update the defconfig riscv: fix flush_tlb_range() end address for flush_tlb_page()
Diffstat (limited to 'arch/riscv/kernel/process.c')
-rw-r--r--arch/riscv/kernel/process.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index f23794bd1e90..fb3a082362eb 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -64,8 +64,14 @@ void start_thread(struct pt_regs *regs, unsigned long pc,
unsigned long sp)
{
regs->sstatus = SR_SPIE;
- if (has_fpu)
+ if (has_fpu) {
regs->sstatus |= SR_FS_INITIAL;
+ /*
+ * Restore the initial value to the FP register
+ * before starting the user program.
+ */
+ fstate_restore(current, regs);
+ }
regs->sepc = pc;
regs->sp = sp;
set_fs(USER_DS);
@@ -75,10 +81,11 @@ void flush_thread(void)
{
#ifdef CONFIG_FPU
/*
- * Reset FPU context
+ * Reset FPU state and context
* frm: round to nearest, ties to even (IEEE default)
* fflags: accrued exceptions cleared
*/
+ fstate_off(current, task_pt_regs(current));
memset(&current->thread.fstate, 0, sizeof(current->thread.fstate));
#endif
}