aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm64/include/asm/processor.h1
-rw-r--r--arch/arm64/include/asm/thread_info.h1
-rw-r--r--arch/arm64/kernel/fpsimd.c16
3 files changed, 14 insertions, 4 deletions
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index e2f575dbdddd..c6fddb005dc2 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -107,6 +107,7 @@ struct thread_struct {
107 struct fpsimd_state fpsimd_state; 107 struct fpsimd_state fpsimd_state;
108 void *sve_state; /* SVE registers, if any */ 108 void *sve_state; /* SVE registers, if any */
109 unsigned int sve_vl; /* SVE vector length */ 109 unsigned int sve_vl; /* SVE vector length */
110 unsigned int sve_vl_onexec; /* SVE vl after next exec */
110 unsigned long fault_address; /* fault info */ 111 unsigned long fault_address; /* fault info */
111 unsigned long fault_code; /* ESR_EL1 value */ 112 unsigned long fault_code; /* ESR_EL1 value */
112 struct debug_info debug; /* debugging */ 113 struct debug_info debug; /* debugging */
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 92b7b48576c8..eb431286bacd 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -95,6 +95,7 @@ void arch_release_task_struct(struct task_struct *tsk);
95#define TIF_SINGLESTEP 21 95#define TIF_SINGLESTEP 21
96#define TIF_32BIT 22 /* 32bit process */ 96#define TIF_32BIT 22 /* 32bit process */
97#define TIF_SVE 23 /* Scalable Vector Extension in use */ 97#define TIF_SVE 23 /* Scalable Vector Extension in use */
98#define TIF_SVE_VL_INHERIT 24 /* Inherit sve_vl_onexec across exec */
98 99
99#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) 100#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
100#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) 101#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 000b5f9215c6..c7531b85b303 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -111,6 +111,9 @@
111 */ 111 */
112static DEFINE_PER_CPU(struct fpsimd_state *, fpsimd_last_state); 112static DEFINE_PER_CPU(struct fpsimd_state *, fpsimd_last_state);
113 113
114/* Default VL for tasks that don't set it explicitly: */
115static int sve_default_vl = SVE_VL_MIN;
116
114/* 117/*
115 * Call __sve_free() directly only if you know task can't be scheduled 118 * Call __sve_free() directly only if you know task can't be scheduled
116 * or preempted. 119 * or preempted.
@@ -474,15 +477,20 @@ void fpsimd_flush_thread(void)
474 * If a bug causes this to go wrong, we make some noise and 477 * If a bug causes this to go wrong, we make some noise and
475 * try to fudge thread.sve_vl to a safe value here. 478 * try to fudge thread.sve_vl to a safe value here.
476 */ 479 */
477 vl = current->thread.sve_vl; 480 vl = current->thread.sve_vl_onexec ?
478 481 current->thread.sve_vl_onexec : sve_default_vl;
479 if (vl == 0)
480 vl = SVE_VL_MIN;
481 482
482 if (WARN_ON(!sve_vl_valid(vl))) 483 if (WARN_ON(!sve_vl_valid(vl)))
483 vl = SVE_VL_MIN; 484 vl = SVE_VL_MIN;
484 485
485 current->thread.sve_vl = vl; 486 current->thread.sve_vl = vl;
487
488 /*
489 * If the task is not set to inherit, ensure that the vector
490 * length will be reset by a subsequent exec:
491 */
492 if (!test_thread_flag(TIF_SVE_VL_INHERIT))
493 current->thread.sve_vl_onexec = 0;
486 } 494 }
487 495
488 set_thread_flag(TIF_FOREIGN_FPSTATE); 496 set_thread_flag(TIF_FOREIGN_FPSTATE);