[merged] um-save-fpu-registers-between-task-switches.patch removed from -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled
     um: Save FPU registers between task switches
has been removed from the -mm tree.  Its filename was
     um-save-fpu-registers-between-task-switches.patch

This patch was dropped because it was merged into mainline or a subsystem tree

The current -mm tree may be found at http://userweb.kernel.org/~akpm/mmotm/

------------------------------------------------------
Subject: um: Save FPU registers between task switches
From: Ingo van Lil <inguin@xxxxxx>

Some time ago Jeff prepared 42daba3 ("uml: stop saving process FP state")
for UML to stop saving the process FP state between task switches.  The
assumption was that since with SKAS0 every guest process runs inside a
host process context the host OS will take care of keeping the proper FP
state.  Unfortunately this is not true for multi-threaded applications,
where all guest threads share a single host process context yet all may
use the FPU on their own.  Although I haven't verified it I suspect things
to be even worse in SKAS3 mode where all guest processes run inside a
single host process.

The patch reintroduces the saving and restoring of the FP context between
task switches.

[richard@xxxxxx: Ingo posted this patch in 2009, sadly it was never applied
and got lost. Now in 2011 the problem was reported by Gunnar.]

Signed-off-by: Ingo van Lil <inguin@xxxxxx>
Signed-off-by: Richard Weinberger <richard@xxxxxx>
Reported-by: <gunnarlindroth@xxxxxxxxxxx>
Tested-by: <gunnarlindroth@xxxxxxxxxxx>
Cc: Stanislav Meduna <stano@xxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
---

 arch/um/include/shared/registers.h        |    2 +-
 arch/um/kernel/process.c                  |    2 +-
 arch/um/os-Linux/registers.c              |    9 ++++++++-
 arch/um/os-Linux/skas/mem.c               |    2 +-
 arch/um/os-Linux/skas/process.c           |   19 ++++++++++++++++++-
 arch/um/sys-i386/shared/sysdep/ptrace.h   |    1 +
 arch/um/sys-x86_64/shared/sysdep/ptrace.h |    1 +
 7 files changed, 31 insertions(+), 5 deletions(-)

diff -puN arch/um/include/shared/registers.h~um-save-fpu-registers-between-task-switches arch/um/include/shared/registers.h
--- a/arch/um/include/shared/registers.h~um-save-fpu-registers-between-task-switches
+++ a/arch/um/include/shared/registers.h
@@ -16,7 +16,7 @@ extern int restore_fpx_registers(int pid
 extern int save_registers(int pid, struct uml_pt_regs *regs);
 extern int restore_registers(int pid, struct uml_pt_regs *regs);
 extern int init_registers(int pid);
-extern void get_safe_registers(unsigned long *regs);
+extern void get_safe_registers(unsigned long *regs, unsigned long *fp_regs);
 extern unsigned long get_thread_reg(int reg, jmp_buf *buf);
 extern int get_fp_registers(int pid, unsigned long *regs);
 extern int put_fp_registers(int pid, unsigned long *regs);
diff -puN arch/um/kernel/process.c~um-save-fpu-registers-between-task-switches arch/um/kernel/process.c
--- a/arch/um/kernel/process.c~um-save-fpu-registers-between-task-switches
+++ a/arch/um/kernel/process.c
@@ -202,7 +202,7 @@ int copy_thread(unsigned long clone_flag
 		arch_copy_thread(&current->thread.arch, &p->thread.arch);
 	}
 	else {
-		get_safe_registers(p->thread.regs.regs.gp);
+		get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp);
 		p->thread.request.u.thread = current->thread.request.u.thread;
 		handler = new_thread_handler;
 	}
diff -puN arch/um/os-Linux/registers.c~um-save-fpu-registers-between-task-switches arch/um/os-Linux/registers.c
--- a/arch/um/os-Linux/registers.c~um-save-fpu-registers-between-task-switches
+++ a/arch/um/os-Linux/registers.c
@@ -8,6 +8,8 @@
 #include <string.h>
 #include <sys/ptrace.h>
 #include "sysdep/ptrace.h"
+#include "sysdep/ptrace_user.h"
+#include "registers.h"
 
 int save_registers(int pid, struct uml_pt_regs *regs)
 {
@@ -32,6 +34,7 @@ int restore_registers(int pid, struct um
 /* This is set once at boot time and not changed thereafter */
 
 static unsigned long exec_regs[MAX_REG_NR];
+static unsigned long exec_fp_regs[FP_SIZE];
 
 int init_registers(int pid)
 {
@@ -42,10 +45,14 @@ int init_registers(int pid)
 		return -errno;
 
 	arch_init_registers(pid);
+	get_fp_registers(pid, exec_fp_regs);
 	return 0;
 }
 
-void get_safe_registers(unsigned long *regs)
+void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
 {
 	memcpy(regs, exec_regs, sizeof(exec_regs));
+
+	if (fp_regs)
+		memcpy(fp_regs, exec_fp_regs, sizeof(exec_fp_regs));
 }
diff -puN arch/um/os-Linux/skas/mem.c~um-save-fpu-registers-between-task-switches arch/um/os-Linux/skas/mem.c
--- a/arch/um/os-Linux/skas/mem.c~um-save-fpu-registers-between-task-switches
+++ a/arch/um/os-Linux/skas/mem.c
@@ -39,7 +39,7 @@ static unsigned long syscall_regs[MAX_RE
 
 static int __init init_syscall_regs(void)
 {
-	get_safe_registers(syscall_regs);
+	get_safe_registers(syscall_regs, NULL);
 	syscall_regs[REGS_IP_INDEX] = STUB_CODE +
 		((unsigned long) &batch_syscall_stub -
 		 (unsigned long) &__syscall_stub_start);
diff -puN arch/um/os-Linux/skas/process.c~um-save-fpu-registers-between-task-switches arch/um/os-Linux/skas/process.c
--- a/arch/um/os-Linux/skas/process.c~um-save-fpu-registers-between-task-switches
+++ a/arch/um/os-Linux/skas/process.c
@@ -373,6 +373,9 @@ void userspace(struct uml_pt_regs *regs)
 		if (ptrace(PTRACE_SETREGS, pid, 0, regs->gp))
 			fatal_sigsegv();
 
+		if (put_fp_registers(pid, regs->fp))
+			fatal_sigsegv();
+
 		/* Now we set local_using_sysemu to be used for one loop */
 		local_using_sysemu = get_using_sysemu();
 
@@ -399,6 +402,12 @@ void userspace(struct uml_pt_regs *regs)
 			fatal_sigsegv();
 		}
 
+		if (get_fp_registers(pid, regs->fp)) {
+			printk(UM_KERN_ERR "userspace -  get_fp_registers failed, "
+			       "errno = %d\n", errno);
+			fatal_sigsegv();
+		}
+
 		UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
 
 		if (WIFSTOPPED(status)) {
@@ -457,10 +466,11 @@ void userspace(struct uml_pt_regs *regs)
 }
 
 static unsigned long thread_regs[MAX_REG_NR];
+static unsigned long thread_fp_regs[FP_SIZE];
 
 static int __init init_thread_regs(void)
 {
-	get_safe_registers(thread_regs);
+	get_safe_registers(thread_regs, thread_fp_regs);
 	/* Set parent's instruction pointer to start of clone-stub */
 	thread_regs[REGS_IP_INDEX] = STUB_CODE +
 				(unsigned long) stub_clone_handler -
@@ -503,6 +513,13 @@ int copy_context_skas0(unsigned long new
 		return err;
 	}
 
+	err = put_fp_registers(pid, thread_fp_regs);
+	if (err < 0) {
+		printk(UM_KERN_ERR "copy_context_skas0 : put_fp_registers "
+		       "failed, pid = %d, err = %d\n", pid, err);
+		return err;
+	}
+
 	/* set a well known return code for detection of child write failure */
 	child_data->err = 12345678;
 
diff -puN arch/um/sys-i386/shared/sysdep/ptrace.h~um-save-fpu-registers-between-task-switches arch/um/sys-i386/shared/sysdep/ptrace.h
--- a/arch/um/sys-i386/shared/sysdep/ptrace.h~um-save-fpu-registers-between-task-switches
+++ a/arch/um/sys-i386/shared/sysdep/ptrace.h
@@ -53,6 +53,7 @@ extern int sysemu_supported;
 
 struct uml_pt_regs {
 	unsigned long gp[MAX_REG_NR];
+	unsigned long fp[HOST_FPX_SIZE];
 	struct faultinfo faultinfo;
 	long syscall;
 	int is_user;
diff -puN arch/um/sys-x86_64/shared/sysdep/ptrace.h~um-save-fpu-registers-between-task-switches arch/um/sys-x86_64/shared/sysdep/ptrace.h
--- a/arch/um/sys-x86_64/shared/sysdep/ptrace.h~um-save-fpu-registers-between-task-switches
+++ a/arch/um/sys-x86_64/shared/sysdep/ptrace.h
@@ -85,6 +85,7 @@
 
 struct uml_pt_regs {
 	unsigned long gp[MAX_REG_NR];
+	unsigned long fp[HOST_FP_SIZE];
 	struct faultinfo faultinfo;
 	long syscall;
 	int is_user;
_

Patches currently in -mm which might be from inguin@xxxxxx are

origin.patch

--
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux