summaryrefslogtreecommitdiffstats
path: root/arch/riscv
diff options
context:
space:
mode:
authorAndy Chiu <andy.chiu@sifive.com>2023-06-05 11:07:19 +0000
committerPalmer Dabbelt <palmer@rivosinc.com>2023-06-08 07:16:54 -0700
commit7ca7a7b9b635dbf8428f8e3bb8ea9e9ff5c79bfc (patch)
tree07b9144f6154f04666faf9f08dc3c35187c1e9d7 /arch/riscv
parent1fd96a3e9d5d4febe1a8486590ad52c048d1be77 (diff)
downloadlinux-stable-7ca7a7b9b635dbf8428f8e3bb8ea9e9ff5c79bfc.tar.gz
linux-stable-7ca7a7b9b635dbf8428f8e3bb8ea9e9ff5c79bfc.tar.bz2
linux-stable-7ca7a7b9b635dbf8428f8e3bb8ea9e9ff5c79bfc.zip
riscv: Add sysctl to set the default vector rule for new processes
To support Vector extension, the series exports variable-length vector registers on the signal frame. However, this potentially breaks abi if processing vector registers is required in the signal handler for old binaries. For example, there is such need if user-level context switch is triggerred via signals[1]. For this reason, it is best to leave a decision to distro maintainers, where the enablement of userspace Vector for new launching programs can be controlled. Developers may also need the switch to experiment with. The parameter is configurable through sysctl interface so a distro may turn off Vector early at init script if the break really happens in the wild. The switch will only take effects on new execve() calls once set. This will not effect existing processes that do not call execve(), nor processes which has been set with a non-default vstate_ctrl by making explicit PR_RISCV_V_SET_CONTROL prctl() calls. Link: https://lore.kernel.org/all/87cz4048rp.fsf@all.your.base.are.belong.to.us/ Signed-off-by: Andy Chiu <andy.chiu@sifive.com> Reviewed-by: Greentime Hu <greentime.hu@sifive.com> Reviewed-by: Vincent Chen <vincent.chen@sifive.com> Reviewed-by: Björn Töpel <bjorn@rivosinc.com> Link: https://lore.kernel.org/r/20230605110724.21391-23-andy.chiu@sifive.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
Diffstat (limited to 'arch/riscv')
-rw-r--r--arch/riscv/kernel/vector.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/arch/riscv/kernel/vector.c b/arch/riscv/kernel/vector.c
index a7dec9230164..f9c8e19ab301 100644
--- a/arch/riscv/kernel/vector.c
+++ b/arch/riscv/kernel/vector.c
@@ -180,7 +180,7 @@ void riscv_v_vstate_ctrl_init(struct task_struct *tsk)
next = riscv_v_ctrl_get_next(tsk);
if (!next) {
- if (riscv_v_implicit_uacc)
+ if (READ_ONCE(riscv_v_implicit_uacc))
cur = PR_RISCV_V_VSTATE_CTRL_ON;
else
cur = PR_RISCV_V_VSTATE_CTRL_OFF;
@@ -243,3 +243,34 @@ long riscv_v_vstate_ctrl_set_current(unsigned long arg)
return -EINVAL;
}
+
+#ifdef CONFIG_SYSCTL
+
+static struct ctl_table riscv_v_default_vstate_table[] = {
+ {
+ .procname = "riscv_v_default_allow",
+ .data = &riscv_v_implicit_uacc,
+ .maxlen = sizeof(riscv_v_implicit_uacc),
+ .mode = 0644,
+ .proc_handler = proc_dobool,
+ },
+ { }
+};
+
+static int __init riscv_v_sysctl_init(void)
+{
+ if (has_vector())
+ if (!register_sysctl("abi", riscv_v_default_vstate_table))
+ return -EINVAL;
+ return 0;
+}
+
+#else /* ! CONFIG_SYSCTL */
+static int __init riscv_v_sysctl_init(void) { return 0; }
+#endif /* ! CONFIG_SYSCTL */
+
+static int riscv_v_init(void)
+{
+ return riscv_v_sysctl_init();
+}
+core_initcall(riscv_v_init);