diff options
-rw-r--r-- | arch/arm64/include/asm/fpsimd.h | 3 | ||||
-rw-r--r-- | arch/arm64/kernel/fpsimd.c | 20 | ||||
-rw-r--r-- | arch/arm64/kernel/process.c | 2 | ||||
-rw-r--r-- | arch/arm64/kernel/signal.c | 9 | ||||
-rw-r--r-- | arch/arm64/kernel/signal32.c | 9 |
5 files changed, 30 insertions, 13 deletions
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h index c43b4ac13008..f4e524b67e91 100644 --- a/arch/arm64/include/asm/fpsimd.h +++ b/arch/arm64/include/asm/fpsimd.h | |||
@@ -58,6 +58,9 @@ extern void fpsimd_load_state(struct fpsimd_state *state); | |||
58 | extern void fpsimd_thread_switch(struct task_struct *next); | 58 | extern void fpsimd_thread_switch(struct task_struct *next); |
59 | extern void fpsimd_flush_thread(void); | 59 | extern void fpsimd_flush_thread(void); |
60 | 60 | ||
61 | extern void fpsimd_preserve_current_state(void); | ||
62 | extern void fpsimd_update_current_state(struct fpsimd_state *state); | ||
63 | |||
61 | #endif | 64 | #endif |
62 | 65 | ||
63 | #endif | 66 | #endif |
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index 4aef42a04bdc..8a97163debc7 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c | |||
@@ -87,6 +87,26 @@ void fpsimd_flush_thread(void) | |||
87 | preempt_enable(); | 87 | preempt_enable(); |
88 | } | 88 | } |
89 | 89 | ||
90 | /* | ||
91 | * Save the userland FPSIMD state of 'current' to memory | ||
92 | */ | ||
93 | void fpsimd_preserve_current_state(void) | ||
94 | { | ||
95 | preempt_disable(); | ||
96 | fpsimd_save_state(¤t->thread.fpsimd_state); | ||
97 | preempt_enable(); | ||
98 | } | ||
99 | |||
100 | /* | ||
101 | * Load an updated userland FPSIMD state for 'current' from memory | ||
102 | */ | ||
103 | void fpsimd_update_current_state(struct fpsimd_state *state) | ||
104 | { | ||
105 | preempt_disable(); | ||
106 | fpsimd_load_state(state); | ||
107 | preempt_enable(); | ||
108 | } | ||
109 | |||
90 | #ifdef CONFIG_KERNEL_MODE_NEON | 110 | #ifdef CONFIG_KERNEL_MODE_NEON |
91 | 111 | ||
92 | /* | 112 | /* |
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 6391485f342d..c5693163408c 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c | |||
@@ -205,7 +205,7 @@ void release_thread(struct task_struct *dead_task) | |||
205 | 205 | ||
206 | int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) | 206 | int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) |
207 | { | 207 | { |
208 | fpsimd_save_state(¤t->thread.fpsimd_state); | 208 | fpsimd_preserve_current_state(); |
209 | *dst = *src; | 209 | *dst = *src; |
210 | return 0; | 210 | return 0; |
211 | } | 211 | } |
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index 890a591f75dd..06448a77ff53 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c | |||
@@ -51,7 +51,7 @@ static int preserve_fpsimd_context(struct fpsimd_context __user *ctx) | |||
51 | int err; | 51 | int err; |
52 | 52 | ||
53 | /* dump the hardware registers to the fpsimd_state structure */ | 53 | /* dump the hardware registers to the fpsimd_state structure */ |
54 | fpsimd_save_state(fpsimd); | 54 | fpsimd_preserve_current_state(); |
55 | 55 | ||
56 | /* copy the FP and status/control registers */ | 56 | /* copy the FP and status/control registers */ |
57 | err = __copy_to_user(ctx->vregs, fpsimd->vregs, sizeof(fpsimd->vregs)); | 57 | err = __copy_to_user(ctx->vregs, fpsimd->vregs, sizeof(fpsimd->vregs)); |
@@ -86,11 +86,8 @@ static int restore_fpsimd_context(struct fpsimd_context __user *ctx) | |||
86 | __get_user_error(fpsimd.fpcr, &ctx->fpcr, err); | 86 | __get_user_error(fpsimd.fpcr, &ctx->fpcr, err); |
87 | 87 | ||
88 | /* load the hardware registers from the fpsimd_state structure */ | 88 | /* load the hardware registers from the fpsimd_state structure */ |
89 | if (!err) { | 89 | if (!err) |
90 | preempt_disable(); | 90 | fpsimd_update_current_state(&fpsimd); |
91 | fpsimd_load_state(&fpsimd); | ||
92 | preempt_enable(); | ||
93 | } | ||
94 | 91 | ||
95 | return err ? -EFAULT : 0; | 92 | return err ? -EFAULT : 0; |
96 | } | 93 | } |
diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c index b3fc9f5ec6d3..ac7e237d0bda 100644 --- a/arch/arm64/kernel/signal32.c +++ b/arch/arm64/kernel/signal32.c | |||
@@ -219,7 +219,7 @@ static int compat_preserve_vfp_context(struct compat_vfp_sigframe __user *frame) | |||
219 | * Note that this also saves V16-31, which aren't visible | 219 | * Note that this also saves V16-31, which aren't visible |
220 | * in AArch32. | 220 | * in AArch32. |
221 | */ | 221 | */ |
222 | fpsimd_save_state(fpsimd); | 222 | fpsimd_preserve_current_state(); |
223 | 223 | ||
224 | /* Place structure header on the stack */ | 224 | /* Place structure header on the stack */ |
225 | __put_user_error(magic, &frame->magic, err); | 225 | __put_user_error(magic, &frame->magic, err); |
@@ -282,11 +282,8 @@ static int compat_restore_vfp_context(struct compat_vfp_sigframe __user *frame) | |||
282 | * We don't need to touch the exception register, so | 282 | * We don't need to touch the exception register, so |
283 | * reload the hardware state. | 283 | * reload the hardware state. |
284 | */ | 284 | */ |
285 | if (!err) { | 285 | if (!err) |
286 | preempt_disable(); | 286 | fpsimd_update_current_state(&fpsimd); |
287 | fpsimd_load_state(&fpsimd); | ||
288 | preempt_enable(); | ||
289 | } | ||
290 | 287 | ||
291 | return err ? -EFAULT : 0; | 288 | return err ? -EFAULT : 0; |
292 | } | 289 | } |