ptrace: Fix the timing of save_fp_regs, and Add copy fp_regs to child in clone_thread
refs #702
This commit is contained in:
@@ -1648,13 +1648,11 @@ release_fp_regs(struct thread *thread)
|
|||||||
thread->fp_regs = NULL;
|
thread->fp_regs = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*@
|
static int
|
||||||
@ requires \valid(thread);
|
check_and_allocate_fp_regs(struct thread *thread)
|
||||||
@*/
|
|
||||||
void
|
|
||||||
save_fp_regs(struct thread *thread)
|
|
||||||
{
|
{
|
||||||
int pages;
|
int pages;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
if (!thread->fp_regs) {
|
if (!thread->fp_regs) {
|
||||||
pages = (xsave_size + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
|
pages = (xsave_size + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
|
||||||
@@ -1663,12 +1661,26 @@ save_fp_regs(struct thread *thread)
|
|||||||
|
|
||||||
if (!thread->fp_regs) {
|
if (!thread->fp_regs) {
|
||||||
kprintf("error: allocating fp_regs pages\n");
|
kprintf("error: allocating fp_regs pages\n");
|
||||||
return;
|
result = 1;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(thread->fp_regs, 0, sizeof(fp_regs_struct));
|
|
||||||
memset(thread->fp_regs, 0, pages * PAGE_SIZE);
|
memset(thread->fp_regs, 0, pages * PAGE_SIZE);
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@
|
||||||
|
@ requires \valid(thread);
|
||||||
|
@*/
|
||||||
|
void
|
||||||
|
save_fp_regs(struct thread *thread)
|
||||||
|
{
|
||||||
|
if (check_and_allocate_fp_regs(thread) != 0) {
|
||||||
|
// alloc error
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (xsave_available) {
|
if (xsave_available) {
|
||||||
unsigned int low, high;
|
unsigned int low, high;
|
||||||
@@ -1684,6 +1696,13 @@ save_fp_regs(struct thread *thread)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void copy_fp_regs(struct thread *from, struct thread *to)
|
||||||
|
{
|
||||||
|
if ((from->fp_regs != NULL) && (check_and_allocate_fp_regs(to) == 0)) {
|
||||||
|
memcpy(to->fp_regs, from->fp_regs, sizeof(fp_regs_struct));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef POSTK_DEBUG_TEMP_FIX_19
|
#ifdef POSTK_DEBUG_TEMP_FIX_19
|
||||||
void
|
void
|
||||||
clear_fp_regs(struct thread *thread)
|
clear_fp_regs(struct thread *thread)
|
||||||
|
|||||||
@@ -33,7 +33,6 @@
|
|||||||
void terminate(int, int);
|
void terminate(int, int);
|
||||||
extern long do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact);
|
extern long do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact);
|
||||||
long syscall(int num, ihk_mc_user_context_t *ctx);
|
long syscall(int num, ihk_mc_user_context_t *ctx);
|
||||||
extern void save_fp_regs(struct thread *proc);
|
|
||||||
void set_signal(int sig, void *regs0, siginfo_t *info);
|
void set_signal(int sig, void *regs0, siginfo_t *info);
|
||||||
void check_signal(unsigned long rc, void *regs0, int num);
|
void check_signal(unsigned long rc, void *regs0, int num);
|
||||||
extern unsigned long do_fork(int, unsigned long, unsigned long, unsigned long,
|
extern unsigned long do_fork(int, unsigned long, unsigned long, unsigned long,
|
||||||
@@ -460,7 +459,6 @@ void set_single_step(struct thread *thread)
|
|||||||
|
|
||||||
long ptrace_read_fpregs(struct thread *thread, void *fpregs)
|
long ptrace_read_fpregs(struct thread *thread, void *fpregs)
|
||||||
{
|
{
|
||||||
save_fp_regs(thread);
|
|
||||||
if (thread->fp_regs == NULL) {
|
if (thread->fp_regs == NULL) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
@@ -470,7 +468,6 @@ long ptrace_read_fpregs(struct thread *thread, void *fpregs)
|
|||||||
|
|
||||||
long ptrace_write_fpregs(struct thread *thread, void *fpregs)
|
long ptrace_write_fpregs(struct thread *thread, void *fpregs)
|
||||||
{
|
{
|
||||||
save_fp_regs(thread);
|
|
||||||
if (thread->fp_regs == NULL) {
|
if (thread->fp_regs == NULL) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ static void insert_vm_range_list(struct process_vm *vm,
|
|||||||
static int copy_user_ranges(struct process_vm *vm, struct process_vm *orgvm);
|
static int copy_user_ranges(struct process_vm *vm, struct process_vm *orgvm);
|
||||||
extern void release_fp_regs(struct thread *proc);
|
extern void release_fp_regs(struct thread *proc);
|
||||||
extern void save_fp_regs(struct thread *proc);
|
extern void save_fp_regs(struct thread *proc);
|
||||||
|
extern void copy_fp_regs(struct thread *from, struct thread *to);
|
||||||
extern void restore_fp_regs(struct thread *proc);
|
extern void restore_fp_regs(struct thread *proc);
|
||||||
extern void __runq_add_proc(struct thread *proc, int cpu_id);
|
extern void __runq_add_proc(struct thread *proc, int cpu_id);
|
||||||
extern void terminate_host(int pid);
|
extern void terminate_host(int pid);
|
||||||
@@ -389,6 +390,10 @@ clone_thread(struct thread *org, unsigned long pc, unsigned long sp,
|
|||||||
/* NOTE: sp is the user mode stack! */
|
/* NOTE: sp is the user mode stack! */
|
||||||
ihk_mc_init_user_process(&thread->ctx, &thread->uctx, ((char *)thread) +
|
ihk_mc_init_user_process(&thread->ctx, &thread->uctx, ((char *)thread) +
|
||||||
KERNEL_STACK_NR_PAGES * PAGE_SIZE, pc, sp);
|
KERNEL_STACK_NR_PAGES * PAGE_SIZE, pc, sp);
|
||||||
|
|
||||||
|
/* copy fp_regs from parent */
|
||||||
|
save_fp_regs(org);
|
||||||
|
copy_fp_regs(org, thread);
|
||||||
#ifdef POSTK_DEBUG_ARCH_DEP_23 /* add arch dep. clone_process() function */
|
#ifdef POSTK_DEBUG_ARCH_DEP_23 /* add arch dep. clone_process() function */
|
||||||
arch_clone_thread(org, pc, sp, thread);
|
arch_clone_thread(org, pc, sp, thread);
|
||||||
#endif /* POSTK_DEBUG_ARCH_DEP_23 */
|
#endif /* POSTK_DEBUG_ARCH_DEP_23 */
|
||||||
|
|||||||
Reference in New Issue
Block a user