diff options
Diffstat (limited to 'arch/mips/kernel/ptrace.c')
| -rw-r--r-- | arch/mips/kernel/ptrace.c | 18 | 
1 files changed, 16 insertions, 2 deletions
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 0b23b1ad99e6..aede42990f08 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -463,7 +463,7 @@ static int fpr_get_msa(struct task_struct *target,  /*   * Copy the floating-point context to the supplied NT_PRFPREG buffer.   * Choose the appropriate helper for general registers, and then copy - * the FCSR register separately. + * the FCSR and FIR registers separately.   */  static int fpr_get(struct task_struct *target,  		   const struct user_regset *regset, @@ -471,6 +471,7 @@ static int fpr_get(struct task_struct *target,  		   void *kbuf, void __user *ubuf)  {  	const int fcr31_pos = NUM_FPU_REGS * sizeof(elf_fpreg_t); +	const int fir_pos = fcr31_pos + sizeof(u32);  	int err;  	if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t)) @@ -483,6 +484,12 @@ static int fpr_get(struct task_struct *target,  	err = user_regset_copyout(&pos, &count, &kbuf, &ubuf,  				  &target->thread.fpu.fcr31,  				  fcr31_pos, fcr31_pos + sizeof(u32)); +	if (err) +		return err; + +	err = user_regset_copyout(&pos, &count, &kbuf, &ubuf, +				  &boot_cpu_data.fpu_id, +				  fir_pos, fir_pos + sizeof(u32));  	return err;  } @@ -531,7 +538,8 @@ static int fpr_set_msa(struct task_struct *target,  /*   * Copy the supplied NT_PRFPREG buffer to the floating-point context.   * Choose the appropriate helper for general registers, and then copy - * the FCSR register separately. + * the FCSR register separately.  Ignore the incoming FIR register + * contents though, as the register is read-only.   *   * We optimize for the case where `count % sizeof(elf_fpreg_t) == 0',   * which is supposed to have been guaranteed by the kernel before @@ -545,6 +553,7 @@ static int fpr_set(struct task_struct *target,  		   const void *kbuf, const void __user *ubuf)  {  	const int fcr31_pos = NUM_FPU_REGS * sizeof(elf_fpreg_t); +	const int fir_pos = fcr31_pos + sizeof(u32);  	u32 fcr31;  	int err; @@ -572,6 +581,11 @@ static int fpr_set(struct task_struct *target,  		ptrace_setfcr31(target, fcr31);  	} +	if (count > 0) +		err = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, +						fir_pos, +						fir_pos + sizeof(u32)); +  	return err;  }  | 
