x86, ptrace: regset extensions to support xstate
Add the xstate regset support which helps extend the kernel ptrace and the core-dump interfaces to support AVX state etc. This regset interface is designed to support all the future state that gets supported using xsave/xrstor infrastructure. Looking at the memory layout saved by "xsave", one can't say which state is represented in the memory layout. This is because if a particular state is in init state, in the xsave hdr it can be represented by bit '0'. And hence we can't really say by the xsave header wether a state is in init state or the state is not saved in the memory layout. And hence the xsave memory layout available through this regset interface uses SW usable bytes [464..511] to convey what state is represented in the memory layout. First 8 bytes of the sw_usable_bytes[464..467] will be set to OS enabled xstate mask(which is same as the 64bit mask returned by the xgetbv's xCR0). The note NT_X86_XSTATE represents the extended state information in the core file, using the above mentioned memory layout. Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com> LKML-Reference: <20100211195614.802495327@sbs-t61.sc.intel.com> Signed-off-by: Hongjiu Lu <hjl.tools@gmail.com> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
committed by
H. Peter Anvin
parent
676ad58553
commit
5b3efd5008
@@ -164,6 +164,11 @@ int init_fpu(struct task_struct *tsk)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The xstateregs_active() routine is the same as the fpregs_active() routine,
|
||||
* as the "regset->n" for the xstate regset will be updated based on the feature
|
||||
* capabilites supported by the xsave.
|
||||
*/
|
||||
int fpregs_active(struct task_struct *target, const struct user_regset *regset)
|
||||
{
|
||||
return tsk_used_math(target) ? regset->n : 0;
|
||||
@@ -224,6 +229,84 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xstateregs_get(struct task_struct *target, const struct user_regset *regset,
|
||||
unsigned int pos, unsigned int count,
|
||||
void *kbuf, void __user *ubuf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!cpu_has_xsave)
|
||||
return -ENODEV;
|
||||
|
||||
ret = init_fpu(target);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* First copy the fxsave bytes 0..463.
|
||||
*/
|
||||
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
|
||||
&target->thread.xstate->xsave, 0,
|
||||
offsetof(struct user_xstateregs,
|
||||
i387.xstate_fx_sw));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Copy the 48bytes defined by software.
|
||||
*/
|
||||
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
|
||||
xstate_fx_sw_bytes,
|
||||
offsetof(struct user_xstateregs,
|
||||
i387.xstate_fx_sw),
|
||||
offsetof(struct user_xstateregs,
|
||||
xsave_hdr));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Copy the rest of xstate memory layout.
|
||||
*/
|
||||
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
|
||||
&target->thread.xstate->xsave.xsave_hdr,
|
||||
offsetof(struct user_xstateregs,
|
||||
xsave_hdr), -1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xstateregs_set(struct task_struct *target, const struct user_regset *regset,
|
||||
unsigned int pos, unsigned int count,
|
||||
const void *kbuf, const void __user *ubuf)
|
||||
{
|
||||
int ret;
|
||||
struct xsave_hdr_struct *xsave_hdr;
|
||||
|
||||
if (!cpu_has_xsave)
|
||||
return -ENODEV;
|
||||
|
||||
ret = init_fpu(target);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||
&target->thread.xstate->xsave, 0, -1);
|
||||
|
||||
/*
|
||||
* mxcsr reserved bits must be masked to zero for security reasons.
|
||||
*/
|
||||
target->thread.xstate->fxsave.mxcsr &= mxcsr_feature_mask;
|
||||
|
||||
xsave_hdr = &target->thread.xstate->xsave.xsave_hdr;
|
||||
|
||||
xsave_hdr->xstate_bv &= pcntxt_mask;
|
||||
/*
|
||||
* These bits must be zero.
|
||||
*/
|
||||
xsave_hdr->reserved1[0] = xsave_hdr->reserved1[1] = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user