Do not qualify the mcontext_t *mcp argument for set_mcontext(9) as
const. On x86, even after the machine context is supposedly read into the struct ucontext, lazy FPU state save code might only mark the FPU data as hardware-owned. Later, set_fpcontext() needs to fetch the state from hardware, modifying the *mcp. The set_mcontext(9) is called from sigreturn(2) and setcontext(2) implementations and old create_thread(2) interface, which throw the *mcp out after the set_mcontext() call. Reported by: dim Discussed with: jhb Sponsored by: The FreeBSD Foundation MFC after: 1 week
This commit is contained in:
parent
e0a60ae16a
commit
206f09eb46
@ -157,7 +157,7 @@ extern u_int64_t hammer_time(u_int64_t, u_int64_t);
|
||||
static void cpu_startup(void *);
|
||||
static void get_fpcontext(struct thread *td, mcontext_t *mcp,
|
||||
char *xfpusave, size_t xfpusave_len);
|
||||
static int set_fpcontext(struct thread *td, const mcontext_t *mcp,
|
||||
static int set_fpcontext(struct thread *td, mcontext_t *mcp,
|
||||
char *xfpustate, size_t xfpustate_len);
|
||||
SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
|
||||
|
||||
@ -2480,7 +2480,7 @@ get_mcontext(struct thread *td, mcontext_t *mcp, int flags)
|
||||
* touch the cs selector.
|
||||
*/
|
||||
int
|
||||
set_mcontext(struct thread *td, const mcontext_t *mcp)
|
||||
set_mcontext(struct thread *td, mcontext_t *mcp)
|
||||
{
|
||||
struct pcb *pcb;
|
||||
struct trapframe *tp;
|
||||
@ -2567,7 +2567,7 @@ get_fpcontext(struct thread *td, mcontext_t *mcp, char *xfpusave,
|
||||
}
|
||||
|
||||
static int
|
||||
set_fpcontext(struct thread *td, const mcontext_t *mcp, char *xfpustate,
|
||||
set_fpcontext(struct thread *td, mcontext_t *mcp, char *xfpustate,
|
||||
size_t xfpustate_len)
|
||||
{
|
||||
struct savefpu *fpstate;
|
||||
|
@ -118,7 +118,7 @@ ia32_get_fpcontext(struct thread *td, struct ia32_mcontext *mcp,
|
||||
}
|
||||
|
||||
static int
|
||||
ia32_set_fpcontext(struct thread *td, const struct ia32_mcontext *mcp,
|
||||
ia32_set_fpcontext(struct thread *td, struct ia32_mcontext *mcp,
|
||||
char *xfpustate, size_t xfpustate_len)
|
||||
{
|
||||
int error;
|
||||
@ -197,7 +197,7 @@ ia32_get_mcontext(struct thread *td, struct ia32_mcontext *mcp, int flags)
|
||||
* touch the cs selector.
|
||||
*/
|
||||
static int
|
||||
ia32_set_mcontext(struct thread *td, const struct ia32_mcontext *mcp)
|
||||
ia32_set_mcontext(struct thread *td, struct ia32_mcontext *mcp)
|
||||
{
|
||||
struct trapframe *tp;
|
||||
char *xfpustate;
|
||||
|
@ -700,7 +700,7 @@ get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret)
|
||||
* touch the cs selector.
|
||||
*/
|
||||
int
|
||||
set_mcontext(struct thread *td, const mcontext_t *mcp)
|
||||
set_mcontext(struct thread *td, mcontext_t *mcp)
|
||||
{
|
||||
struct trapframe *tf = td->td_frame;
|
||||
const __greg_t *gr = mcp->__gregs;
|
||||
|
@ -195,7 +195,7 @@ static void cpu_startup(void *);
|
||||
static void fpstate_drop(struct thread *td);
|
||||
static void get_fpcontext(struct thread *td, mcontext_t *mcp,
|
||||
char *xfpusave, size_t xfpusave_len);
|
||||
static int set_fpcontext(struct thread *td, const mcontext_t *mcp,
|
||||
static int set_fpcontext(struct thread *td, mcontext_t *mcp,
|
||||
char *xfpustate, size_t xfpustate_len);
|
||||
#ifdef CPU_ENABLE_SSE
|
||||
static void set_fpregs_xmm(struct save87 *, struct savexmm *);
|
||||
@ -3856,7 +3856,7 @@ get_mcontext(struct thread *td, mcontext_t *mcp, int flags)
|
||||
* touch the cs selector.
|
||||
*/
|
||||
int
|
||||
set_mcontext(struct thread *td, const mcontext_t *mcp)
|
||||
set_mcontext(struct thread *td, mcontext_t *mcp)
|
||||
{
|
||||
struct trapframe *tp;
|
||||
char *xfpustate;
|
||||
@ -3934,7 +3934,7 @@ get_fpcontext(struct thread *td, mcontext_t *mcp, char *xfpusave,
|
||||
}
|
||||
|
||||
static int
|
||||
set_fpcontext(struct thread *td, const mcontext_t *mcp, char *xfpustate,
|
||||
set_fpcontext(struct thread *td, mcontext_t *mcp, char *xfpustate,
|
||||
size_t xfpustate_len)
|
||||
{
|
||||
union savefpu *fpstate;
|
||||
|
@ -68,7 +68,7 @@
|
||||
|
||||
static void freebsd32_exec_setregs(struct thread *, struct image_params *, u_long);
|
||||
static int get_mcontext32(struct thread *, mcontext32_t *, int);
|
||||
static int set_mcontext32(struct thread *, const mcontext32_t *);
|
||||
static int set_mcontext32(struct thread *, mcontext32_t *);
|
||||
static void freebsd32_sendsig(sig_t, ksiginfo_t *, sigset_t *);
|
||||
|
||||
extern const char *freebsd32_syscallnames[];
|
||||
@ -227,7 +227,7 @@ get_mcontext32(struct thread *td, mcontext32_t *mcp, int flags)
|
||||
}
|
||||
|
||||
static int
|
||||
set_mcontext32(struct thread *td, const mcontext32_t *mcp)
|
||||
set_mcontext32(struct thread *td, mcontext32_t *mcp)
|
||||
{
|
||||
mcontext_t mcp64;
|
||||
unsigned i;
|
||||
|
@ -375,7 +375,7 @@ get_mcontext(struct thread *td, mcontext_t *mcp, int flags)
|
||||
}
|
||||
|
||||
int
|
||||
set_mcontext(struct thread *td, const mcontext_t *mcp)
|
||||
set_mcontext(struct thread *td, mcontext_t *mcp)
|
||||
{
|
||||
struct trapframe *tp;
|
||||
|
||||
|
@ -442,7 +442,7 @@ get_mcontext(struct thread *td, mcontext_t *mcp, int flags)
|
||||
}
|
||||
|
||||
int
|
||||
set_mcontext(struct thread *td, const mcontext_t *mcp)
|
||||
set_mcontext(struct thread *td, mcontext_t *mcp)
|
||||
{
|
||||
struct pcb *pcb;
|
||||
struct trapframe *tf;
|
||||
@ -739,7 +739,7 @@ get_mcontext32(struct thread *td, mcontext32_t *mcp, int flags)
|
||||
}
|
||||
|
||||
static int
|
||||
set_mcontext32(struct thread *td, const mcontext32_t *mcp)
|
||||
set_mcontext32(struct thread *td, mcontext32_t *mcp)
|
||||
{
|
||||
mcontext_t mcp64;
|
||||
int i, error;
|
||||
|
@ -811,7 +811,7 @@ get_mcontext(struct thread *td, mcontext_t *mc, int flags)
|
||||
}
|
||||
|
||||
int
|
||||
set_mcontext(struct thread *td, const mcontext_t *mc)
|
||||
set_mcontext(struct thread *td, mcontext_t *mc)
|
||||
{
|
||||
struct trapframe *tf;
|
||||
struct pcb *pcb;
|
||||
|
@ -99,7 +99,7 @@ struct thread;
|
||||
|
||||
/* Machine-dependent functions: */
|
||||
int get_mcontext(struct thread *, mcontext_t *, int);
|
||||
int set_mcontext(struct thread *, const mcontext_t *);
|
||||
int set_mcontext(struct thread *, mcontext_t *);
|
||||
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user