| From c9d66999f064947e6b577ceacc1eb2fbca6a8d3c Mon Sep 17 00:00:00 2001 |
| From: Suzuki K Poulose <suzuki.poulose@arm.com> |
| Date: Mon, 13 Jan 2020 23:30:21 +0000 |
| Subject: arm64: ptrace: nofpsimd: Fail FP/SIMD regset operations |
| |
| From: Suzuki K Poulose <suzuki.poulose@arm.com> |
| |
| commit c9d66999f064947e6b577ceacc1eb2fbca6a8d3c upstream. |
| |
| When fp/simd is not supported on the system, fail the operations |
| of FP/SIMD regsets. |
| |
| Fixes: 82e0191a1aa11abf ("arm64: Support systems without FP/ASIMD") |
| Cc: Will Deacon <will@kernel.org> |
| Cc: Mark Rutland <mark.rutland@arm.com> |
| Reviewed-by: Ard Biesheuvel <ardb@kernel.org> |
| Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> |
| Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> |
| Signed-off-by: Will Deacon <will@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/arm64/kernel/ptrace.c | 21 +++++++++++++++++++++ |
| 1 file changed, 21 insertions(+) |
| |
| --- a/arch/arm64/kernel/ptrace.c |
| +++ b/arch/arm64/kernel/ptrace.c |
| @@ -615,6 +615,13 @@ static int gpr_set(struct task_struct *t |
| return 0; |
| } |
| |
| +static int fpr_active(struct task_struct *target, const struct user_regset *regset) |
| +{ |
| + if (!system_supports_fpsimd()) |
| + return -ENODEV; |
| + return regset->n; |
| +} |
| + |
| /* |
| * TODO: update fp accessors for lazy context switching (sync/flush hwstate) |
| */ |
| @@ -637,6 +644,9 @@ static int fpr_get(struct task_struct *t |
| unsigned int pos, unsigned int count, |
| void *kbuf, void __user *ubuf) |
| { |
| + if (!system_supports_fpsimd()) |
| + return -EINVAL; |
| + |
| if (target == current) |
| fpsimd_preserve_current_state(); |
| |
| @@ -676,6 +686,9 @@ static int fpr_set(struct task_struct *t |
| { |
| int ret; |
| |
| + if (!system_supports_fpsimd()) |
| + return -EINVAL; |
| + |
| ret = __fpr_set(target, regset, pos, count, kbuf, ubuf, 0); |
| if (ret) |
| return ret; |
| @@ -1134,6 +1147,7 @@ static const struct user_regset aarch64_ |
| */ |
| .size = sizeof(u32), |
| .align = sizeof(u32), |
| + .active = fpr_active, |
| .get = fpr_get, |
| .set = fpr_set |
| }, |
| @@ -1348,6 +1362,9 @@ static int compat_vfp_get(struct task_st |
| compat_ulong_t fpscr; |
| int ret, vregs_end_pos; |
| |
| + if (!system_supports_fpsimd()) |
| + return -EINVAL; |
| + |
| uregs = &target->thread.uw.fpsimd_state; |
| |
| if (target == current) |
| @@ -1381,6 +1398,9 @@ static int compat_vfp_set(struct task_st |
| compat_ulong_t fpscr; |
| int ret, vregs_end_pos; |
| |
| + if (!system_supports_fpsimd()) |
| + return -EINVAL; |
| + |
| uregs = &target->thread.uw.fpsimd_state; |
| |
| vregs_end_pos = VFP_STATE_SIZE - sizeof(compat_ulong_t); |
| @@ -1438,6 +1458,7 @@ static const struct user_regset aarch32_ |
| .n = VFP_STATE_SIZE / sizeof(compat_ulong_t), |
| .size = sizeof(compat_ulong_t), |
| .align = sizeof(compat_ulong_t), |
| + .active = fpr_active, |
| .get = compat_vfp_get, |
| .set = compat_vfp_set |
| }, |