| From 28e4213dd331e944e7fca1954a946829162ed9d4 Mon Sep 17 00:00:00 2001 |
| From: "Maciej W. Rozycki" <macro@mips.com> |
| Date: Tue, 15 May 2018 23:04:44 +0100 |
| Subject: MIPS: prctl: Disallow FRE without FR with PR_SET_FP_MODE requests |
| |
| From: Maciej W. Rozycki <macro@mips.com> |
| |
| commit 28e4213dd331e944e7fca1954a946829162ed9d4 upstream. |
| |
| Having PR_FP_MODE_FRE (i.e. Config5.FRE) set without PR_FP_MODE_FR (i.e. |
| Status.FR) is not supported as the lone purpose of Config5.FRE is to |
| emulate Status.FR=0 handling on FPU hardware that has Status.FR=1 |
| hardwired[1][2]. Also we do not handle this case elsewhere, and assume |
| throughout our code that TIF_HYBRID_FPREGS and TIF_32BIT_FPREGS cannot |
| be set both at once for a task, leading to inconsistent behaviour if |
| this does happen. |
| |
| Return unsuccessfully then from prctl(2) PR_SET_FP_MODE calls requesting |
| PR_FP_MODE_FRE to be set with PR_FP_MODE_FR clear. This corresponds to |
| modes allowed by `mips_set_personality_fp'. |
| |
| References: |
| |
| [1] "MIPS Architecture For Programmers, Vol. III: MIPS32 / microMIPS32 |
| Privileged Resource Architecture", Imagination Technologies, |
| Document Number: MD00090, Revision 6.02, July 10, 2015, Table 9.69 |
| "Config5 Register Field Descriptions", p. 262 |
| |
| [2] "MIPS Architecture For Programmers, Volume III: MIPS64 / microMIPS64 |
| Privileged Resource Architecture", Imagination Technologies, |
| Document Number: MD00091, Revision 6.03, December 22, 2015, Table |
| 9.72 "Config5 Register Field Descriptions", p. 288 |
| |
| Fixes: 9791554b45a2 ("MIPS,prctl: add PR_[GS]ET_FP_MODE prctl options for MIPS") |
| Signed-off-by: Maciej W. Rozycki <macro@mips.com> |
| Cc: Ralf Baechle <ralf@linux-mips.org> |
| Cc: linux-mips@linux-mips.org |
| Cc: <stable@vger.kernel.org> # 4.0+ |
| Patchwork: https://patchwork.linux-mips.org/patch/19327/ |
| Signed-off-by: James Hogan <jhogan@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/mips/kernel/process.c | 4 ++++ |
| 1 file changed, 4 insertions(+) |
| |
| --- a/arch/mips/kernel/process.c |
| +++ b/arch/mips/kernel/process.c |
| @@ -680,6 +680,10 @@ int mips_set_process_fp_mode(struct task |
| if (value & ~known_bits) |
| return -EOPNOTSUPP; |
| |
| + /* Setting FRE without FR is not supported. */ |
| + if ((value & (PR_FP_MODE_FR | PR_FP_MODE_FRE)) == PR_FP_MODE_FRE) |
| + return -EOPNOTSUPP; |
| + |
| /* Avoid inadvertently triggering emulation */ |
| if ((value & PR_FP_MODE_FR) && raw_cpu_has_fpu && |
| !(raw_current_cpu_data.fpu_id & MIPS_FPIR_F64)) |