aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Martin <Dave.Martin@arm.com>2017-10-31 11:51:06 -0400
committerWill Deacon <will.deacon@arm.com>2017-11-03 11:24:16 -0400
commit79ab047c75d6a9f95d8840d94f405e20cbacac4b (patch)
treee31e3590d82ebb0c15fe4a57585162c52d1112dc
parentbc0ee476036478a85beeed51f0d94c8729fd0544 (diff)
arm64/sve: Support vector length resetting for new processes
It's desirable to be able to reset the vector length to some sane default for new processes, since the new binary and its libraries may or may not be SVE-aware. This patch tracks the desired post-exec vector length (if any) in a new thread member sve_vl_onexec, and adds a new thread flag TIF_SVE_VL_INHERIT to control whether to inherit or reset the vector length. Currently these are inactive. Subsequent patches will provide the capability to configure them. Signed-off-by: Dave Martin <Dave.Martin@arm.com> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
-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);