VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
author: Jeff Dike <jdike@addtoit.com> 2008-02-23 15:23:49 -0800 committer: Linus Torvalds <torvalds@woody.linux-foundation.org> 2008-02-23 17:12:15 -0800 commit: 2f56debd77a8f52f1ac1d3c3d89cc7ce5e083230 parent: e4d06b3f904ddfab4531a1e23f1f5e1bd284b605
Commit Summary:
uml: fix FP register corruption
Diffstat:
3 files changed, 36 insertions, 0 deletions
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index b14829469fae..1e8cba6550a9 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -115,6 +115,14 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi)
 			       sizeof(struct ptrace_faultinfo));
 	}
 	else {
+		unsigned long fpregs[FP_SIZE];
+
+		err = get_fp_registers(pid, fpregs);
+		if (err < 0) {
+			printk(UM_KERN_ERR "save_fp_registers returned %d\n",
+			       err);
+			fatal_sigsegv();
+		}
 		err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV);
 		if (err) {
 			printk(UM_KERN_ERR "Failed to continue stub, pid = %d, "
@@ -128,6 +136,13 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi)
 		 * the stub stack page. We just have to copy it.
 		 */
 		memcpy(fi, (void *)current_stub_stack(), sizeof(*fi));
+
+		err = put_fp_registers(pid, fpregs);
+		if (err < 0) {
+			printk(UM_KERN_ERR "put_fp_registers returned %d\n",
+			       err);
+			fatal_sigsegv();
+		}
 	}
 }
 
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c
index f74d853a0ee0..b613473b3ec1 100644
--- a/arch/um/os-Linux/sys-i386/registers.c
+++ b/arch/um/os-Linux/sys-i386/registers.c
@@ -56,6 +56,22 @@ unsigned long get_thread_reg(int reg, jmp_buf *buf)
 
 int have_fpx_regs = 1;
 
+int get_fp_registers(int pid, unsigned long *regs)
+{
+	if (have_fpx_regs)
+		return save_fpx_registers(pid, regs);
+	else
+		return save_fp_registers(pid, regs);
+}
+
+int put_fp_registers(int pid, unsigned long *regs)
+{
+	if (have_fpx_regs)
+		return restore_fpx_registers(pid, regs);
+	else
+		return restore_fp_registers(pid, regs);
+}
+
 void arch_init_registers(int pid)
 {
 	unsigned long fpx_regs[HOST_XFP_SIZE];
diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c
index a375853337a7..594d97ad02b3 100644
--- a/arch/um/os-Linux/sys-x86_64/registers.c
+++ b/arch/um/os-Linux/sys-x86_64/registers.c
@@ -40,3 +40,13 @@ unsigned long get_thread_reg(int reg, jmp_buf *buf)
 		return 0;
 	}
 }
+
+int get_fp_registers(int pid, unsigned long *regs)
+{
+	return save_fp_registers(pid, regs);
+}
+
+int put_fp_registers(int pid, unsigned long *regs)
+{
+	return restore_fp_registers(pid, regs);
+}