fbfe9c847e
Some time ago Jeff prepared 42daba3165
("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@nod.at: 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@gmx.de>
Signed-off-by: Richard Weinberger <richard@nod.at>
Reported-by: <gunnarlindroth@hotmail.com>
Tested-by: <gunnarlindroth@hotmail.com>
Cc: Stanislav Meduna <stano@meduna.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
24 lines
861 B
C
24 lines
861 B
C
/*
|
|
* Copyright (C) 2004 PathScale, Inc
|
|
* Licensed under the GPL
|
|
*/
|
|
|
|
#ifndef __REGISTERS_H
|
|
#define __REGISTERS_H
|
|
|
|
#include "sysdep/ptrace.h"
|
|
#include "sysdep/archsetjmp.h"
|
|
|
|
extern int save_fp_registers(int pid, unsigned long *fp_regs);
|
|
extern int restore_fp_registers(int pid, unsigned long *fp_regs);
|
|
extern int save_fpx_registers(int pid, unsigned long *fp_regs);
|
|
extern int restore_fpx_registers(int pid, unsigned long *fp_regs);
|
|
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, 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);
|
|
|
|
#endif
|