summaryrefslogtreecommitdiffstats
path: root/arch/arm64/kernel/fpsimd.c
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2017-12-15 17:07:22 +0100
committerWill Deacon <will.deacon@arm.com>2017-12-15 17:12:35 +0100
commita4544831370618cb3627e27ffcc27d1cc857868f (patch)
tree6db0189ca49e20a47b14b2fd46c741adfaa24064 /arch/arm64/kernel/fpsimd.c
parentarm64/sve: Report SVE to userspace via CPUID only if supported (diff)
downloadlinux-a4544831370618cb3627e27ffcc27d1cc857868f.tar.xz
linux-a4544831370618cb3627e27ffcc27d1cc857868f.zip
arm64: fpsimd: Fix copying of FP state from signal frame into task struct
Commit 9de52a755cfb6da5 ("arm64: fpsimd: Fix failure to restore FPSIMD state after signals") fixed an issue reported in our FPSIMD signal restore code but inadvertently introduced another issue which tends to manifest as random SEGVs in userspace. The problem is that when we copy the struct fpsimd_state from the kernel stack (populated from the signal frame) into the struct held in the current thread_struct, we blindly copy uninitialised stack into the "cpu" field, which means that context-switching of the FP registers is no longer reliable. This patch fixes the problem by copying only the user_fpsimd member of struct fpsimd_state. We should really rework the function prototypes to take struct user_fpsimd_state * instead, but let's just get this fixed for now. Cc: Dave Martin <Dave.Martin@arm.com> Fixes: 9de52a755cfb6da5 ("arm64: fpsimd: Fix failure to restore FPSIMD state after signals") Reported-by: Geert Uytterhoeven <geert@linux-m68k.org> Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to '')
-rw-r--r--arch/arm64/kernel/fpsimd.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 540a1e010eb5..fae81f7964b4 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1043,7 +1043,7 @@ void fpsimd_update_current_state(struct fpsimd_state *state)
local_bh_disable();
- current->thread.fpsimd_state = *state;
+ current->thread.fpsimd_state.user_fpsimd = state->user_fpsimd;
if (system_supports_sve() && test_thread_flag(TIF_SVE))
fpsimd_to_sve(current);