void flush_tmregs_to_thread(struct task_struct *tsk)
{ /* * If task is not current, it will have been flushed already to * its thread_struct during __switch_to(). * * A reclaim flushes ALL the state or if not in TM save TM SPRs * in the appropriate thread structures from live.
*/
if (!cpu_has_feature(CPU_FTR_TM) || tsk != current) return;
/** * tm_cgpr_active - get active number of registers in CGPR * @target: The target task. * @regset: The user regset structure. * * This function checks for the active number of available * regisers in transaction checkpointed GPR category.
*/ int tm_cgpr_active(struct task_struct *target, conststruct user_regset *regset)
{ if (!cpu_has_feature(CPU_FTR_TM)) return -ENODEV;
if (!MSR_TM_ACTIVE(target->thread.regs->msr)) return 0;
return regset->n;
}
/** * tm_cgpr_get - get CGPR registers * @target: The target task. * @regset: The user regset structure. * @to: Destination of copy. * * This function gets transaction checkpointed GPR registers. * * When the transaction is active, 'ckpt_regs' holds all the checkpointed * GPR register values for the current transaction to fall back on if it * aborts in between. This function gets those checkpointed GPR registers. * The userspace interface buffer layout is as follows. * * struct data { * struct pt_regs ckpt_regs; * };
*/ int tm_cgpr_get(struct task_struct *target, conststruct user_regset *regset, struct membuf to)
{ struct membuf to_msr = membuf_at(&to, offsetof(struct pt_regs, msr)); #ifdef CONFIG_PPC64 struct membuf to_softe = membuf_at(&to, offsetof(struct pt_regs, softe)); #endif
if (!cpu_has_feature(CPU_FTR_TM)) return -ENODEV;
if (!MSR_TM_ACTIVE(target->thread.regs->msr)) return -ENODATA;
/* * tm_cgpr_set - set the CGPR registers * @target: The target task. * @regset: The user regset structure. * @pos: The buffer position. * @count: Number of bytes to copy. * @kbuf: Kernel buffer to copy into. * @ubuf: User buffer to copy from. * * This function sets in transaction checkpointed GPR registers. * * When the transaction is active, 'ckpt_regs' holds the checkpointed * GPR register values for the current transaction to fall back on if it * aborts in between. This function sets those checkpointed GPR registers. * The userspace interface buffer layout is as follows. * * struct data { * struct pt_regs ckpt_regs; * };
*/ int tm_cgpr_set(struct task_struct *target, conststruct user_regset *regset, unsignedint pos, unsignedint count, constvoid *kbuf, constvoid __user *ubuf)
{ unsignedlong reg; int ret;
if (!cpu_has_feature(CPU_FTR_TM)) return -ENODEV;
if (!MSR_TM_ACTIVE(target->thread.regs->msr)) return -ENODATA;
/** * tm_cfpr_active - get active number of registers in CFPR * @target: The target task. * @regset: The user regset structure. * * This function checks for the active number of available * regisers in transaction checkpointed FPR category.
*/ int tm_cfpr_active(struct task_struct *target, conststruct user_regset *regset)
{ if (!cpu_has_feature(CPU_FTR_TM)) return -ENODEV;
if (!MSR_TM_ACTIVE(target->thread.regs->msr)) return 0;
return regset->n;
}
/** * tm_cfpr_get - get CFPR registers * @target: The target task. * @regset: The user regset structure. * @to: Destination of copy. * * This function gets in transaction checkpointed FPR registers. * * When the transaction is active 'ckfp_state' holds the checkpointed * values for the current transaction to fall back on if it aborts * in between. This function gets those checkpointed FPR registers. * The userspace interface buffer layout is as follows. * * struct data { * u64 fpr[32]; * u64 fpscr; *};
*/ int tm_cfpr_get(struct task_struct *target, conststruct user_regset *regset, struct membuf to)
{
u64 buf[33]; int i;
if (!cpu_has_feature(CPU_FTR_TM)) return -ENODEV;
if (!MSR_TM_ACTIVE(target->thread.regs->msr)) return -ENODATA;
/* copy to local buffer then write that out */ for (i = 0; i < 32 ; i++)
buf[i] = target->thread.TS_CKFPR(i);
buf[32] = target->thread.ckfp_state.fpscr; return membuf_write(&to, buf, sizeof(buf));
}
/** * tm_cfpr_set - set CFPR registers * @target: The target task. * @regset: The user regset structure. * @pos: The buffer position. * @count: Number of bytes to copy. * @kbuf: Kernel buffer to copy into. * @ubuf: User buffer to copy from. * * This function sets in transaction checkpointed FPR registers. * * When the transaction is active 'ckfp_state' holds the checkpointed * FPR register values for the current transaction to fall back on * if it aborts in between. This function sets these checkpointed * FPR registers. The userspace interface buffer layout is as follows. * * struct data { * u64 fpr[32]; * u64 fpscr; *};
*/ int tm_cfpr_set(struct task_struct *target, conststruct user_regset *regset, unsignedint pos, unsignedint count, constvoid *kbuf, constvoid __user *ubuf)
{
u64 buf[33]; int i;
if (!cpu_has_feature(CPU_FTR_TM)) return -ENODEV;
if (!MSR_TM_ACTIVE(target->thread.regs->msr)) return -ENODATA;
for (i = 0; i < 32; i++)
buf[i] = target->thread.TS_CKFPR(i);
buf[32] = target->thread.ckfp_state.fpscr;
/* copy to local buffer then write that out */
i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1); if (i) return i; for (i = 0; i < 32 ; i++)
target->thread.TS_CKFPR(i) = buf[i];
target->thread.ckfp_state.fpscr = buf[32]; return 0;
}
/** * tm_cvmx_active - get active number of registers in CVMX * @target: The target task. * @regset: The user regset structure. * * This function checks for the active number of available * regisers in checkpointed VMX category.
*/ int tm_cvmx_active(struct task_struct *target, conststruct user_regset *regset)
{ if (!cpu_has_feature(CPU_FTR_TM)) return -ENODEV;
if (!MSR_TM_ACTIVE(target->thread.regs->msr)) return 0;
return regset->n;
}
/** * tm_cvmx_get - get CMVX registers * @target: The target task. * @regset: The user regset structure. * @to: Destination of copy. * * This function gets in transaction checkpointed VMX registers. * * When the transaction is active 'ckvr_state' and 'ckvrsave' hold * the checkpointed values for the current transaction to fall * back on if it aborts in between. The userspace interface buffer * layout is as follows. * * struct data { * vector128 vr[32]; * vector128 vscr; * vector128 vrsave; *};
*/ int tm_cvmx_get(struct task_struct *target, conststruct user_regset *regset, struct membuf to)
{ union {
elf_vrreg_t reg;
u32 word;
} vrsave;
BUILD_BUG_ON(TVSO(vscr) != TVSO(vr[32]));
if (!cpu_has_feature(CPU_FTR_TM)) return -ENODEV;
if (!MSR_TM_ACTIVE(target->thread.regs->msr)) return -ENODATA;
/* Flush the state */
flush_tmregs_to_thread(target);
flush_fp_to_thread(target);
flush_altivec_to_thread(target);
membuf_write(&to, &target->thread.ckvr_state, 33 * sizeof(vector128)); /* * Copy out only the low-order word of vrsave.
*/
memset(&vrsave, 0, sizeof(vrsave));
vrsave.word = target->thread.ckvrsave; return membuf_write(&to, &vrsave, sizeof(vrsave));
}
/** * tm_cvmx_set - set CMVX registers * @target: The target task. * @regset: The user regset structure. * @pos: The buffer position. * @count: Number of bytes to copy. * @kbuf: Kernel buffer to copy into. * @ubuf: User buffer to copy from. * * This function sets in transaction checkpointed VMX registers. * * When the transaction is active 'ckvr_state' and 'ckvrsave' hold * the checkpointed values for the current transaction to fall * back on if it aborts in between. The userspace interface buffer * layout is as follows. * * struct data { * vector128 vr[32]; * vector128 vscr; * vector128 vrsave; *};
*/ int tm_cvmx_set(struct task_struct *target, conststruct user_regset *regset, unsignedint pos, unsignedint count, constvoid *kbuf, constvoid __user *ubuf)
{ int ret;
BUILD_BUG_ON(TVSO(vscr) != TVSO(vr[32]));
if (!cpu_has_feature(CPU_FTR_TM)) return -ENODEV;
if (!MSR_TM_ACTIVE(target->thread.regs->msr)) return -ENODATA;
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &target->thread.ckvr_state,
0, 33 * sizeof(vector128)); if (!ret && count > 0) { /* * We use only the low-order word of vrsave.
*/ union {
elf_vrreg_t reg;
u32 word;
} vrsave;
memset(&vrsave, 0, sizeof(vrsave));
vrsave.word = target->thread.ckvrsave;
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
33 * sizeof(vector128), -1); if (!ret)
target->thread.ckvrsave = vrsave.word;
}
return ret;
}
/** * tm_cvsx_active - get active number of registers in CVSX * @target: The target task. * @regset: The user regset structure. * * This function checks for the active number of available * regisers in transaction checkpointed VSX category.
*/ int tm_cvsx_active(struct task_struct *target, conststruct user_regset *regset)
{ if (!cpu_has_feature(CPU_FTR_TM)) return -ENODEV;
if (!MSR_TM_ACTIVE(target->thread.regs->msr)) return 0;
/** * tm_cvsx_get - get CVSX registers * @target: The target task. * @regset: The user regset structure. * @to: Destination of copy. * * This function gets in transaction checkpointed VSX registers. * * When the transaction is active 'ckfp_state' holds the checkpointed * values for the current transaction to fall back on if it aborts * in between. This function gets those checkpointed VSX registers. * The userspace interface buffer layout is as follows. * * struct data { * u64 vsx[32]; *};
*/ int tm_cvsx_get(struct task_struct *target, conststruct user_regset *regset, struct membuf to)
{
u64 buf[32]; int i;
if (!cpu_has_feature(CPU_FTR_TM)) return -ENODEV;
if (!MSR_TM_ACTIVE(target->thread.regs->msr)) return -ENODATA;
/* Flush the state */
flush_tmregs_to_thread(target);
flush_fp_to_thread(target);
flush_altivec_to_thread(target);
flush_vsx_to_thread(target);
for (i = 0; i < 32 ; i++)
buf[i] = target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET]; return membuf_write(&to, buf, 32 * sizeof(double));
}
/** * tm_cvsx_set - set CFPR registers * @target: The target task. * @regset: The user regset structure. * @pos: The buffer position. * @count: Number of bytes to copy. * @kbuf: Kernel buffer to copy into. * @ubuf: User buffer to copy from. * * This function sets in transaction checkpointed VSX registers. * * When the transaction is active 'ckfp_state' holds the checkpointed * VSX register values for the current transaction to fall back on * if it aborts in between. This function sets these checkpointed * FPR registers. The userspace interface buffer layout is as follows. * * struct data { * u64 vsx[32]; *};
*/ int tm_cvsx_set(struct task_struct *target, conststruct user_regset *regset, unsignedint pos, unsignedint count, constvoid *kbuf, constvoid __user *ubuf)
{
u64 buf[32]; int ret, i;
if (!cpu_has_feature(CPU_FTR_TM)) return -ENODEV;
if (!MSR_TM_ACTIVE(target->thread.regs->msr)) return -ENODATA;
/* Flush the state */
flush_tmregs_to_thread(target);
flush_fp_to_thread(target);
flush_altivec_to_thread(target);
flush_vsx_to_thread(target);
for (i = 0; i < 32 ; i++)
buf[i] = target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET];
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
buf, 0, 32 * sizeof(double)); if (!ret) for (i = 0; i < 32 ; i++)
target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
return ret;
}
/** * tm_spr_active - get active number of registers in TM SPR * @target: The target task. * @regset: The user regset structure. * * This function checks the active number of available * regisers in the transactional memory SPR category.
*/ int tm_spr_active(struct task_struct *target, conststruct user_regset *regset)
{ if (!cpu_has_feature(CPU_FTR_TM)) return -ENODEV;
return regset->n;
}
/** * tm_spr_get - get the TM related SPR registers * @target: The target task. * @regset: The user regset structure. * @to: Destination of copy. * * This function gets transactional memory related SPR registers. * The userspace interface buffer layout is as follows. * * struct { * u64 tm_tfhar; * u64 tm_texasr; * u64 tm_tfiar; * };
*/ int tm_spr_get(struct task_struct *target, conststruct user_regset *regset, struct membuf to)
{ /* Build tests */
BUILD_BUG_ON(TSO(tm_tfhar) + sizeof(u64) != TSO(tm_texasr));
BUILD_BUG_ON(TSO(tm_texasr) + sizeof(u64) != TSO(tm_tfiar));
BUILD_BUG_ON(TSO(tm_tfiar) + sizeof(u64) != TSO(ckpt_regs));
if (!cpu_has_feature(CPU_FTR_TM)) return -ENODEV;
/* Flush the states */
flush_tmregs_to_thread(target);
flush_fp_to_thread(target);
flush_altivec_to_thread(target);
/** * tm_spr_set - set the TM related SPR registers * @target: The target task. * @regset: The user regset structure. * @pos: The buffer position. * @count: Number of bytes to copy. * @kbuf: Kernel buffer to copy into. * @ubuf: User buffer to copy from. * * This function sets transactional memory related SPR registers. * The userspace interface buffer layout is as follows. * * struct { * u64 tm_tfhar; * u64 tm_texasr; * u64 tm_tfiar; * };
*/ int tm_spr_set(struct task_struct *target, conststruct user_regset *regset, unsignedint pos, unsignedint count, constvoid *kbuf, constvoid __user *ubuf)
{ int ret;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.