diff options
-rw-r--r-- | arch/arm64/include/asm/processor.h | 1 | ||||
-rw-r--r-- | arch/arm64/include/asm/thread_info.h | 1 | ||||
-rw-r--r-- | arch/arm64/kernel/fpsimd.c | 16 |
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 | */ |
112 | static DEFINE_PER_CPU(struct fpsimd_state *, fpsimd_last_state); | 112 | static DEFINE_PER_CPU(struct fpsimd_state *, fpsimd_last_state); |
113 | 113 | ||
114 | /* Default VL for tasks that don't set it explicitly: */ | ||
115 | static 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); |