Skip to content

Commit

Permalink
[PATCH] uml: initialize process FP registers properly
Browse files Browse the repository at this point in the history
We weren't making sure that we initialized the FP registers of new processes
to sane values.

This patch also moves some defines in the affected area closer to where they
are used.

Signed-off-by: Jeff Dike <jdike@addtoit.com>
Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Jeff Dike authored and Linus Torvalds committed Feb 8, 2006
1 parent 43b00fd commit e2216fe
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 12 deletions.
2 changes: 1 addition & 1 deletion arch/um/include/registers.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ extern int restore_fp_registers(int pid, unsigned long *fp_regs);
extern void save_registers(int pid, union uml_pt_regs *regs);
extern void restore_registers(int pid, union uml_pt_regs *regs);
extern void 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 void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer);

#endif
2 changes: 1 addition & 1 deletion arch/um/os-Linux/skas/mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)

multi_count++;

get_safe_registers(regs);
get_safe_registers(regs, NULL);
regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
((unsigned long) &batch_syscall_stub -
(unsigned long) &__syscall_stub_start);
Expand Down
21 changes: 14 additions & 7 deletions arch/um/os-Linux/skas/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,16 +310,12 @@ void userspace(union uml_pt_regs *regs)
}
}
}
#define INIT_JMP_NEW_THREAD 0
#define INIT_JMP_REMOVE_SIGSTACK 1
#define INIT_JMP_CALLBACK 2
#define INIT_JMP_HALT 3
#define INIT_JMP_REBOOT 4

int copy_context_skas0(unsigned long new_stack, int pid)
{
int err;
unsigned long regs[MAX_REG_NR];
unsigned long regs[HOST_FRAME_SIZE];
unsigned long fp_regs[HOST_FP_SIZE];
unsigned long current_stack = current_stub_stack();
struct stub_data *data = (struct stub_data *) current_stack;
struct stub_data *child_data = (struct stub_data *) new_stack;
Expand All @@ -334,7 +330,7 @@ int copy_context_skas0(unsigned long new_stack, int pid)
.timer = ((struct itimerval)
{ { 0, 1000000 / hz() },
{ 0, 1000000 / hz() }})});
get_safe_registers(regs);
get_safe_registers(regs, fp_regs);

/* Set parent's instruction pointer to start of clone-stub */
regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
Expand All @@ -350,6 +346,11 @@ int copy_context_skas0(unsigned long new_stack, int pid)
panic("copy_context_skas0 : PTRACE_SETREGS failed, "
"pid = %d, errno = %d\n", pid, errno);

err = ptrace_setfpregs(pid, fp_regs);
if(err < 0)
panic("copy_context_skas0 : PTRACE_SETFPREGS failed, "
"pid = %d, errno = %d\n", pid, errno);

/* set a well known return code for detection of child write failure */
child_data->err = 12345678;

Expand Down Expand Up @@ -457,6 +458,12 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
set_signals(flags);
}

#define INIT_JMP_NEW_THREAD 0
#define INIT_JMP_REMOVE_SIGSTACK 1
#define INIT_JMP_CALLBACK 2
#define INIT_JMP_HALT 3
#define INIT_JMP_REBOOT 4

void thread_wait(void *sw, void *fb)
{
sigjmp_buf buf, **switch_buf = sw, *fork_buf;
Expand Down
5 changes: 4 additions & 1 deletion arch/um/os-Linux/sys-i386/registers.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,12 @@ void init_registers(int pid)
err);
}

void get_safe_registers(unsigned long *regs)
void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
{
memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
if(fp_regs != NULL)
memcpy(fp_regs, exec_fp_regs,
HOST_FP_SIZE * sizeof(unsigned long));
}

void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer)
Expand Down
5 changes: 4 additions & 1 deletion arch/um/os-Linux/sys-x86_64/registers.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,12 @@ void init_registers(int pid)
err);
}

void get_safe_registers(unsigned long *regs)
void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
{
memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
if(fp_regs != NULL)
memcpy(fp_regs, exec_fp_regs,
HOST_FP_SIZE * sizeof(unsigned long));
}

void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer)
Expand Down
7 changes: 7 additions & 0 deletions arch/um/sys-x86_64/ptrace_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ int ptrace_setregs(long pid, unsigned long *regs)
return(0);
}

int ptrace_setfpregs(long pid, unsigned long *regs)
{
if (ptrace(PTRACE_SETFPREGS, pid, 0, regs) < 0)
return -errno;
return 0;
}

void ptrace_pokeuser(unsigned long addr, unsigned long data)
{
panic("ptrace_pokeuser");
Expand Down
2 changes: 1 addition & 1 deletion arch/um/sys-x86_64/user-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ void foo(void)
#endif

DEFINE_LONGS(HOST_FRAME_SIZE, FRAME_SIZE);
DEFINE(HOST_FP_SIZE, 0);
DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long));
DEFINE(HOST_XFP_SIZE, 0);
DEFINE_LONGS(HOST_RBX, RBX);
DEFINE_LONGS(HOST_RCX, RCX);
Expand Down

0 comments on commit e2216fe

Please sign in to comment.