diff --git a/arch/x86/kernel/cpu.c b/arch/x86/kernel/cpu.c index 105c5f7c..08d4efcf 100644 --- a/arch/x86/kernel/cpu.c +++ b/arch/x86/kernel/cpu.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -984,6 +985,42 @@ int ihk_mc_interrupt_cpu(int cpu, int vector) return 0; } +void +release_fp_regs(struct process *proc) +{ + int pages; + + if (!proc->fp_regs) + return; + pages = (sizeof(fp_regs_struct) + 4095) >> 12; + ihk_mc_free_pages(proc->fp_regs, 1); + proc->fp_regs = NULL; +} + +void +save_fp_regs(struct process *proc) +{ + int pages; + + if (proc->fp_regs) + return; + pages = (sizeof(fp_regs_struct) + 4095) >> 12; + proc->fp_regs = ihk_mc_alloc_pages(pages, IHK_MC_AP_NOWAIT); + if(!proc->fp_regs) + return; + memset(proc->fp_regs, 0, sizeof(fp_regs_struct)); + // TODO: do xsave +} + +void +restore_fp_regs(struct process *proc) +{ + if (!proc->fp_regs) + return; + // TODO: do xrstor + release_fp_regs(proc); +} + ihk_mc_user_context_t *lookup_user_context(struct process *proc) { ihk_mc_user_context_t *uctx = proc->uctx; diff --git a/arch/x86/kernel/include/registers.h b/arch/x86/kernel/include/registers.h index 507e1097..e73c1d2b 100644 --- a/arch/x86/kernel/include/registers.h +++ b/arch/x86/kernel/include/registers.h @@ -223,4 +223,68 @@ enum x86_pf_error_code { PF_POPULATE = 1 << 30, }; +struct i387_fxsave_struct { + unsigned short cwd; + unsigned short swd; + unsigned short twd; + unsigned short fop; + union { + struct { + unsigned long rip; + unsigned long rdp; + }; + struct { + unsigned int fip; + unsigned int fcs; + unsigned int foo; + unsigned int fos; + }; + }; + unsigned int mxcsr; + unsigned int mxcsr_mask; + unsigned int st_space[32]; + unsigned int xmm_space[64]; + unsigned int padding[12]; + union { + unsigned int padding1[12]; + unsigned int sw_reserved[12]; + }; + +} __attribute__((aligned(16))); + +struct ymmh_struct { + unsigned int ymmh_space[64]; +}; + +struct lwp_struct { + unsigned char reserved[128]; +}; + +struct bndreg { + unsigned long lower_bound; + unsigned long upper_bound; +} __attribute__((packed)); + +struct bndcsr { + unsigned long bndcfgu; + unsigned long bndstatus; +} __attribute__((packed)); + +struct xsave_hdr_struct { + unsigned long xstate_bv; + unsigned long xcomp_bv; + unsigned long reserved[6]; +} __attribute__((packed)); + +struct xsave_struct { + struct i387_fxsave_struct i387; + struct xsave_hdr_struct xsave_hdr; + struct ymmh_struct ymmh; + struct lwp_struct lwp; + struct bndreg bndreg[4]; + struct bndcsr bndcsr; +} __attribute__ ((packed, aligned (64))); + +typedef struct xsave_struct fp_regs_struct; + #endif diff --git a/kernel/include/process.h b/kernel/include/process.h index f8fcaeea..3c68f087 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -388,6 +388,7 @@ struct process { unsigned long *ptrace_debugreg; /* debug registers for ptrace */ struct sig_pending *ptrace_recvsig; struct sig_pending *ptrace_sendsig; + fp_regs_struct *fp_regs; }; struct process_vm { diff --git a/kernel/process.c b/kernel/process.c index 53808c71..8b2aedbe 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -51,6 +51,9 @@ extern void clear_single_step(struct process *proc); static void insert_vm_range_list(struct process_vm *vm, struct vm_range *newrange); static int copy_user_ranges(struct process *proc, struct process *org); +extern void release_fp_regs(struct process *proc); +extern void save_fp_regs(struct process *proc); +extern void restore_fp_regs(struct process *proc); void settid(struct process *proc, int mode, int newcpuid, int oldcpuid); int refcount_fork_tree_node(struct fork_tree_node *ftn) @@ -1974,6 +1977,9 @@ void destroy_process(struct process *proc) if (proc->ptrace_sendsig) { kfree(proc->ptrace_sendsig); } + if (proc->fp_regs) { + release_fp_regs(proc); + } ihk_mc_free_pages(proc, KERNEL_STACK_NR_PAGES); }