diff options
Diffstat (limited to 'debian/patches-rt/arm64-fpsimd-use-preemp_disable-in-addition-to-local.patch')
-rw-r--r-- | debian/patches-rt/arm64-fpsimd-use-preemp_disable-in-addition-to-local.patch | 130 |
1 files changed, 12 insertions, 118 deletions
diff --git a/debian/patches-rt/arm64-fpsimd-use-preemp_disable-in-addition-to-local.patch b/debian/patches-rt/arm64-fpsimd-use-preemp_disable-in-addition-to-local.patch index fc914a91b..bc7ef382b 100644 --- a/debian/patches-rt/arm64-fpsimd-use-preemp_disable-in-addition-to-local.patch +++ b/debian/patches-rt/arm64-fpsimd-use-preemp_disable-in-addition-to-local.patch @@ -1,25 +1,21 @@ From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Wed, 25 Jul 2018 14:02:38 +0200 -Subject: [PATCH] arm64: fpsimd: use preemp_disable in addition to - local_bh_disable() -Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/5.2/older/patches-5.2.17-rt9.tar.xz +Subject: [PATCH] arm64: fpsimd: Delay freeing memory in fpsimd_flush_thread() +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/5.4/older/patches-5.4.3-rt1.tar.xz -In v4.16-RT I noticed a number of warnings from task_fpsimd_load(). The -code disables BH and expects that it is not preemptible. On -RT the -task remains preemptible but remains the same CPU. This may corrupt the -content of the SIMD registers if the task is preempted during -saving/restoring those registers. +fpsimd_flush_thread() invokes kfree() via sve_free() within a preempt disabled +section which is not working on -RT. -Add preempt_disable()/enable() to enfore the required semantic on -RT. +Delay freeing of memory until preemption is enabled again. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - arch/arm64/kernel/fpsimd.c | 31 +++++++++++++++++++++++++++++-- - 1 file changed, 29 insertions(+), 2 deletions(-) + arch/arm64/kernel/fpsimd.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c -@@ -162,6 +162,16 @@ static void sve_free(struct task_struct +@@ -213,6 +213,16 @@ static void sve_free(struct task_struct __sve_free(task); } @@ -36,43 +32,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* * TIF_SVE controls whether a task can use SVE without trapping while * in userspace, and also the way a task's FPSIMD/SVE state is stored -@@ -557,6 +567,7 @@ int sve_set_vector_length(struct task_st - * non-SVE thread. - */ - if (task == current) { -+ preempt_disable(); - local_bh_disable(); - - fpsimd_save(); -@@ -566,8 +577,10 @@ int sve_set_vector_length(struct task_st - if (test_and_clear_tsk_thread_flag(task, TIF_SVE)) - sve_to_fpsimd(task); - -- if (task == current) -+ if (task == current) { - local_bh_enable(); -+ preempt_enable(); -+ } - - /* - * Force reallocation of task SVE state to the correct size -@@ -880,6 +893,7 @@ asmlinkage void do_sve_acc(unsigned int - - sve_alloc(current); - -+ preempt_disable(); - local_bh_disable(); - - fpsimd_save(); -@@ -892,6 +906,7 @@ asmlinkage void do_sve_acc(unsigned int - WARN_ON(1); /* SVE access shouldn't have trapped */ - - local_bh_enable(); -+ preempt_enable(); - } - - /* -@@ -954,10 +969,12 @@ void fpsimd_thread_switch(struct task_st +@@ -1008,6 +1018,7 @@ void fpsimd_thread_switch(struct task_st void fpsimd_flush_thread(void) { int vl, supported_vl; @@ -80,12 +40,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (!system_supports_fpsimd()) return; - -+ preempt_disable(); - local_bh_disable(); - - fpsimd_flush_task_state(current); -@@ -966,7 +983,7 @@ void fpsimd_flush_thread(void) +@@ -1020,7 +1031,7 @@ void fpsimd_flush_thread(void) if (system_supports_sve()) { clear_thread_flag(TIF_SVE); @@ -94,72 +49,11 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* * Reset the task vector length as required. -@@ -1000,6 +1017,8 @@ void fpsimd_flush_thread(void) +@@ -1054,6 +1065,7 @@ void fpsimd_flush_thread(void) } - local_bh_enable(); -+ preempt_enable(); + put_cpu_fpsimd_context(); + kfree(mem); } /* -@@ -1011,9 +1030,11 @@ void fpsimd_preserve_current_state(void) - if (!system_supports_fpsimd()) - return; - -+ preempt_disable(); - local_bh_disable(); - fpsimd_save(); - local_bh_enable(); -+ preempt_enable(); - } - - /* -@@ -1076,6 +1097,7 @@ void fpsimd_restore_current_state(void) - if (!system_supports_fpsimd()) - return; - -+ preempt_disable(); - local_bh_disable(); - - if (test_and_clear_thread_flag(TIF_FOREIGN_FPSTATE)) { -@@ -1084,6 +1106,7 @@ void fpsimd_restore_current_state(void) - } - - local_bh_enable(); -+ preempt_enable(); - } - - /* -@@ -1096,6 +1119,7 @@ void fpsimd_update_current_state(struct - if (!system_supports_fpsimd()) - return; - -+ preempt_disable(); - local_bh_disable(); - - current->thread.uw.fpsimd_state = *state; -@@ -1108,6 +1132,7 @@ void fpsimd_update_current_state(struct - clear_thread_flag(TIF_FOREIGN_FPSTATE); - - local_bh_enable(); -+ preempt_enable(); - } - - /* -@@ -1170,6 +1195,7 @@ void kernel_neon_begin(void) - - BUG_ON(!may_use_simd()); - -+ preempt_disable(); - local_bh_disable(); - - __this_cpu_write(kernel_neon_busy, true); -@@ -1183,6 +1209,7 @@ void kernel_neon_begin(void) - preempt_disable(); - - local_bh_enable(); -+ preempt_enable(); - } - EXPORT_SYMBOL(kernel_neon_begin); - |