Hi James,
On 20 August 2014 15:07, James Hogan <[email protected]> wrote:
> Hi Ralf,
>
> On 24/07/14 13:50, Alex Smith wrote:
>> Copy FCSR in the FP regset to match the original pre-regset core dumper.
>> The code paths for where sizeof(union fpureg) == sizeof(elf_fpreg_t)
>> already do so, but they actually copy 4 bytes more than they should do
>> as FCSR is only 32 bits. The not equal code paths do not copy it at all.
>> Therefore change the copy to be done explicitly (with the correct size)
>> for both paths.
>>
>> Additionally, clear the cause bits from FCSR when setting the FP regset
>> to avoid the possibility of causing an FP exception (and an oops) in the
>> kernel.
>>
>> Signed-off-by: Alex Smith <[email protected]>
>> Cc: Paul Burton <[email protected]>
>> Cc: <[email protected]> # v3.13+
>
> This patch seems to have been missed, although all the others in the
> series were included in the main v3.17 merge. Was that intentional?
Ralf emailed me saying he'd dropped the patch because it was causing
warnings, and he didn't respond when I asked what the warnings were
(I'm unable to reproduce any).
Ralf: if you can let me know what warnings you were getting I can send
an updated patch.
Thanks,
Alex
>
> Cheers
> James
>
>> ---
>> Changes in v2:
>> - Zero fill the last 4 bytes in the FP regset.
>> ---
>> arch/mips/kernel/ptrace.c | 73
>> +++++++++++++++++++++++++++++++----------------
>> 1 file changed, 49 insertions(+), 24 deletions(-)
>>
>> diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
>> index 8bd13ed..e082079 100644
>> --- a/arch/mips/kernel/ptrace.c
>> +++ b/arch/mips/kernel/ptrace.c
>> @@ -409,23 +409,35 @@ static int fpr_get(struct task_struct *target,
>> int err;
>> u64 fpr_val;
>>
>> - /* XXX fcr31 */
>> -
>> - if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t))
>> - return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
>> - &target->thread.fpu,
>> - 0, sizeof(elf_fpregset_t));
>> -
>> - for (i = 0; i < NUM_FPU_REGS; i++) {
>> - fpr_val = get_fpr64(&target->thread.fpu.fpr[i], 0);
>> + if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t)) {
>> err = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
>> - &fpr_val, i * sizeof(elf_fpreg_t),
>> - (i + 1) * sizeof(elf_fpreg_t));
>> + &target->thread.fpu.fpr,
>> + 0, NUM_FPU_REGS *
>> sizeof(elf_fpreg_t));
>> if (err)
>> return err;
>> + } else {
>> + for (i = 0; i < NUM_FPU_REGS; i++) {
>> + fpr_val = get_fpr64(&target->thread.fpu.fpr[i], 0);
>> + err = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
>> + &fpr_val,
>> + i * sizeof(elf_fpreg_t),
>> + (i + 1) *
>> sizeof(elf_fpreg_t));
>> + if (err)
>> + return err;
>> + }
>> }
>>
>> - return 0;
>> + err = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
>> + &target->thread.fpu.fcr31,
>> + NUM_FPU_REGS * sizeof(elf_fpreg_t),
>> + (NUM_FPU_REGS * sizeof(elf_fpreg_t)) + sizeof(u32));
>> + if (err)
>> + return err;
>> +
>> + /* Zero fill the remaining 4 bytes. */
>> + return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
>> + (NUM_FPU_REGS * sizeof(elf_fpreg_t)) + sizeof(u32),
>> + sizeof(elf_fpregset_t));
>> }
>>
>> static int fpr_set(struct task_struct *target,
>> @@ -436,24 +448,37 @@ static int fpr_set(struct task_struct *target,
>> unsigned i;
>> int err;
>> u64 fpr_val;
>> + u32 fcr31;
>>
>> - /* XXX fcr31 */
>> -
>> - if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t))
>> - return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
>> - &target->thread.fpu,
>> - 0, sizeof(elf_fpregset_t));
>> -
>> - for (i = 0; i < NUM_FPU_REGS; i++) {
>> + if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t)) {
>> err = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
>> - &fpr_val, i * sizeof(elf_fpreg_t),
>> - (i + 1) * sizeof(elf_fpreg_t));
>> + &target->thread.fpu.fpr,
>> + 0, NUM_FPU_REGS *
>> sizeof(elf_fpreg_t));
>> if (err)
>> return err;
>> - set_fpr64(&target->thread.fpu.fpr[i], 0, fpr_val);
>> + } else {
>> + for (i = 0; i < NUM_FPU_REGS; i++) {
>> + err = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
>> + &fpr_val,
>> + i * sizeof(elf_fpreg_t),
>> + (i + 1) *
>> sizeof(elf_fpreg_t));
>> + if (err)
>> + return err;
>> + set_fpr64(&target->thread.fpu.fpr[i], 0, fpr_val);
>> + }
>> }
>>
>> - return 0;
>> + err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &fcr31,
>> + NUM_FPU_REGS * sizeof(elf_fpreg_t),
>> + (NUM_FPU_REGS * sizeof(elf_fpreg_t)) +
>> sizeof(u32));
>> + if (err)
>> + return err;
>> +
>> + target->thread.fpu.fcr31 = fcr31 & ~FPU_CSR_ALL_X;
>> +
>> + return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
>> + (NUM_FPU_REGS * sizeof(elf_fpreg_t)) + sizeof(u32),
>> + sizeof(elf_fpregset_t));
>> }
>>
>> enum mips_regset {
>>
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html