From: Dave.Martin@arm.com (Dave Martin)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC PATCH v2 37/41] arm64/sve: Enable default vector length control via procfs
Date: Wed, 22 Mar 2017 14:51:07 +0000 [thread overview]
Message-ID: <1490194274-30569-38-git-send-email-Dave.Martin@arm.com> (raw)
In-Reply-To: <1490194274-30569-1-git-send-email-Dave.Martin@arm.com>
This patch makes the default SVE vector length at exec() for user tasks
controllable via procfs, in /proc/cpu/sve_default_vector_length.
Limited effort is made to return sensible errors when writing the
procfs file, and anyway the value gets silently clamped to the
maximum VL supported by the platform: users should close and reopen
the file and read back to see the result.
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
---
arch/arm64/kernel/fpsimd.c | 162 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 160 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 982b1d7..ddb651a 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -22,8 +22,12 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/prctl.h>
+#include <linux/proc_fs.h>
#include <linux/sched/signal.h>
+#include <linux/seq_file.h>
#include <linux/signal.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
#include <linux/hardirq.h>
#include <asm/fpsimd.h>
@@ -100,6 +104,8 @@ static DEFINE_PER_CPU(struct fpsimd_state *, fpsimd_last_state);
/* Maximum supported vector length across all CPUs (initially poisoned) */
int sve_max_vl = -1;
+/* Default VL for tasks that don't set it explicitly: */
+int sve_default_vl = -1;
void *__sve_state(struct task_struct *task)
{
@@ -334,13 +340,154 @@ int sve_get_task_vl(struct task_struct *task)
return sve_prctl_status(task);
}
+#ifdef CONFIG_PROC_FS
+
+struct default_vl_write_state {
+ bool invalid;
+ size_t len;
+ char buf[40]; /* enough for "0x" + 64-bit hex integer + NUL */
+};
+
+static int sve_default_vl_show(struct seq_file *s, void *data)
+{
+ seq_printf(s, "%d\n", sve_default_vl);
+ return 0;
+}
+
+static ssize_t sve_default_vl_write(struct file *f, const char __user *buf,
+ size_t size, loff_t *pos)
+{
+ struct default_vl_write_state *state =
+ ((struct seq_file *)f->private_data)->private;
+ long ret;
+
+ if (!size)
+ return 0;
+
+ if (*pos > sizeof(state->buf) ||
+ size >= sizeof(state->buf) - *pos) {
+ ret = -ENOSPC;
+ goto error;
+ }
+
+ ret = copy_from_user(state->buf + *pos, buf, size);
+ if (ret > 0)
+ ret = -EINVAL;
+ if (ret)
+ goto error;
+
+ *pos += size;
+ if (*pos > state->len)
+ state->len = *pos;
+
+ return size;
+
+error:
+ state->invalid = true;
+ return ret;
+}
+
+static int sve_default_vl_release(struct inode *i, struct file *f)
+{
+ int ret = 0;
+ int t;
+ unsigned long value;
+ struct default_vl_write_state *state =
+ ((struct seq_file *)f->private_data)->private;
+
+ if (!(f->f_mode & FMODE_WRITE))
+ goto out;
+
+ if (state->invalid)
+ goto out;
+
+ if (state->len >= sizeof(state->buf)) {
+ WARN_ON(1);
+ state->len = sizeof(state->buf) - 1;
+ }
+
+ state->buf[state->len] = '\0';
+ t = kstrtoul(state->buf, 0, &value);
+ if (t)
+ ret = t;
+
+ if (!sve_vl_valid(value))
+ ret = -EINVAL;
+
+ if (!sve_vl_valid(sve_max_vl)) {
+ WARN_ON(1);
+ ret = -EINVAL;
+ }
+
+ if (value > sve_max_vl)
+ value = sve_max_vl;
+
+ if (!ret)
+ sve_default_vl = value;
+
+out:
+ t = seq_release_private(i, f);
+ return ret ? ret : t;
+}
+
+static int sve_default_vl_open(struct inode *i, struct file *f)
+{
+ struct default_vl_write_state *data = NULL;
+ int ret;
+
+ if (f->f_mode & FMODE_WRITE) {
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->invalid = false;
+ data->len = 0;
+ }
+
+ ret = single_open(f, sve_default_vl_show, data);
+ if (ret)
+ kfree(data);
+
+ return ret;
+}
+
+static const struct file_operations sve_default_vl_fops = {
+ .open = sve_default_vl_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = sve_default_vl_release,
+ .write = sve_default_vl_write,
+};
+
+static int __init sve_procfs_init(void)
+{
+ struct proc_dir_entry *dir;
+
+ /* This should be moved elsewhere is anything else ever uses it: */
+ dir = proc_mkdir("cpu", NULL);
+ if (!dir)
+ return -ENOMEM;
+
+ if (!proc_create("sve_default_vector_length",
+ S_IRUGO | S_IWUSR, dir, &sve_default_vl_fops))
+ return -ENOMEM;
+
+ return 0;
+}
+
+#else /* ! CONFIG_PROC_FS && CONFIG_ARM64_SVE */
+static int __init sve_procfs_init(void) { return 0; }
+#endif /* ! CONFIG_PROC_FS && CONFIG_ARM64_SVE */
+
#else /* ! CONFIG_ARM64_SVE */
/* Dummy declarations for usage protected with IS_ENABLED(CONFIG_ARM64_SVE): */
extern int sve_max_vl;
+extern int sve_default_vl;
extern void clear_sve_regs(struct task_struct *task);
extern void *sve_pffr(struct task_struct *task);
extern void fpsimd_to_sve(struct task_struct *task);
+extern int __init sve_procfs_init(void);
/* Functions that map to no-ops without SVE: */
static void sve_to_fpsimd(struct task_struct *task __always_unused) { }
@@ -489,13 +636,13 @@ void fpsimd_flush_thread(void)
clear_sve_regs(current);
current->thread.sve_vl = current->thread.sve_vl_onexec ?
- current->thread.sve_vl_onexec : sve_max_vl;
+ current->thread.sve_vl_onexec : sve_default_vl;
/*
* User tasks must have a valid vector length set, but tasks
* forked early (e.g., init) may not initially have one.
* By now, we will know what the hardware supports, so
- * sve_max_vl should be valid, and thus the above
+ * sve_default_vl should be valid, and thus the above
* assignment should ensure a valid VL for the task.
* If not, something went badly wrong.
*/
@@ -717,6 +864,14 @@ void __init fpsimd_init_task_struct_size(void)
& 0xf) == 1) {
/* FIXME: This should be the minimum across all CPUs */
sve_max_vl = sve_get_vl();
+ sve_default_vl = sve_max_vl;
+
+ /*
+ * To avoid enlarging the signal frame by default, clamp to
+ * 512 bits until/unless overridden by userspace:
+ */
+ if (sve_default_vl > 512 / 8)
+ sve_default_vl = 512 / 8;
BUG_ON(!sve_vl_valid(sve_max_vl));
vq = sve_vq_from_vl(sve_max_vl);
@@ -746,6 +901,9 @@ static int __init fpsimd_init(void)
if (!(elf_hwcap & HWCAP_SVE))
pr_info("Scalable Vector Extension available\n");
+ if (IS_ENABLED(CONFIG_ARM64_SVE) && (elf_hwcap & HWCAP_SVE))
+ return sve_procfs_init();
+
return 0;
}
late_initcall(fpsimd_init);
--
2.1.4
next prev parent reply other threads:[~2017-03-22 14:51 UTC|newest]
Thread overview: 66+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-03-22 14:50 [RFC PATCH v2 00/41] Scalable Vector Extension (SVE) core support Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 01/41] arm64: signal: Refactor sigcontext parsing in rt_sigreturn Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 02/41] arm64: signal: factor frame layout and population into separate passes Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 03/41] arm64: signal: factor out signal frame record allocation Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 04/41] arm64: signal: Allocate extra sigcontext space as needed Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 05/41] arm64: signal: Parse extra_context during sigreturn Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 06/41] arm64: efi: Add missing Kconfig dependency on KERNEL_MODE_NEON Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 07/41] arm64/sve: Allow kernel-mode NEON to be disabled in Kconfig Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 08/41] arm64/sve: Low-level save/restore code Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 09/41] arm64/sve: Boot-time feature detection and reporting Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 10/41] arm64/sve: Boot-time feature enablement Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 11/41] arm64/sve: Expand task_struct for Scalable Vector Extension state Dave Martin
2017-03-22 16:20 ` Mark Rutland
2017-03-23 10:49 ` Dave Martin
2017-03-23 11:26 ` Mark Rutland
2017-03-22 14:50 ` [RFC PATCH v2 12/41] arm64/sve: Save/restore SVE state on context switch paths Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 13/41] arm64/sve: [BROKEN] Basic support for KERNEL_MODE_NEON Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 14/41] Revert "arm64/sve: Allow kernel-mode NEON to be disabled in Kconfig" Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 15/41] arm64/sve: Restore working FPSIMD save/restore around signals Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 16/41] arm64/sve: signal: Add SVE state record to sigcontext Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 17/41] arm64/sve: signal: Dump Scalable Vector Extension registers to user stack Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 18/41] arm64/sve: signal: Restore FPSIMD/SVE state in rt_sigreturn Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 19/41] arm64/sve: Avoid corruption when replacing the SVE state Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 20/41] arm64/sve: traps: Add descriptive string for SVE exceptions Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 21/41] arm64/sve: Enable SVE on demand for userspace Dave Martin
2017-03-22 16:48 ` Mark Rutland
2017-03-23 11:24 ` Dave Martin
2017-03-23 11:30 ` Suzuki K Poulose
2017-03-23 11:52 ` Mark Rutland
2017-03-23 12:07 ` Dave Martin
2017-03-23 13:40 ` Mark Rutland
2017-03-23 13:45 ` Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 22/41] arm64/sve: Implement FPSIMD-only context for tasks not using SVE Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 23/41] arm64/sve: Move ZEN handling to the common task_fpsimd_load() path Dave Martin
2017-03-22 16:55 ` Mark Rutland
2017-03-23 11:52 ` Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 24/41] arm64/sve: Discard SVE state on system call Dave Martin
2017-03-22 17:03 ` Mark Rutland
2017-03-23 11:59 ` Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 25/41] arm64/sve: Avoid preempt_disable() during sigreturn Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 26/41] arm64/sve: Avoid stale user register state after SVE access exception Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 27/41] arm64/sve: ptrace support Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 28/41] arm64: KVM: Treat SVE use by guests as undefined instruction execution Dave Martin
2017-03-22 17:06 ` Mark Rutland
2017-03-23 12:10 ` Dave Martin
2017-03-22 14:50 ` [RFC PATCH v2 29/41] prctl: Add skeleton for PR_SVE_{SET, GET}_VL controls Dave Martin
2017-03-22 14:51 ` [RFC PATCH v2 30/41] arm64/sve: Track vector length for each task Dave Martin
2017-03-22 14:51 ` [RFC PATCH v2 31/41] arm64/sve: Set CPU vector length to match current task Dave Martin
2017-03-22 14:51 ` [RFC PATCH v2 32/41] arm64/sve: Factor out clearing of tasks' SVE regs Dave Martin
2017-03-22 14:51 ` [RFC PATCH v2 33/41] arm64/sve: Wire up vector length control prctl() calls Dave Martin
2017-03-22 14:51 ` [RFC PATCH v2 34/41] arm64/sve: Disallow VL setting for individual threads by default Dave Martin
2017-03-22 14:51 ` [RFC PATCH v2 35/41] arm64/sve: Add vector length inheritance control Dave Martin
2017-03-22 14:51 ` [RFC PATCH v2 36/41] arm64/sve: ptrace: Wire up vector length control and reporting Dave Martin
2017-03-22 14:51 ` Dave Martin [this message]
2017-03-22 14:51 ` [RFC PATCH v2 38/41] arm64/sve: Detect SVE via the cpufeature framework Dave Martin
2017-03-23 14:11 ` Suzuki K Poulose
2017-03-23 14:37 ` Dave Martin
2017-03-23 14:43 ` Dave Martin
2017-03-22 14:51 ` [RFC PATCH v2 39/41] arm64/sve: Migrate to cpucap based detection for runtime SVE code Dave Martin
2017-03-22 14:51 ` [RFC PATCH v2 40/41] arm64/sve: Allocate task SVE context storage dynamically Dave Martin
2017-03-22 14:51 ` [RFC PATCH v2 41/41] arm64/sve: Documentation: Add overview of the SVE userspace ABI Dave Martin
2017-03-31 15:28 ` [RFC PATCH v2 00/41] Scalable Vector Extension (SVE) core support Ard Biesheuvel
2017-04-03 9:45 ` Dave Martin
2017-04-03 10:01 ` Ard Biesheuvel
2017-04-03 10:51 ` Dave Martin
2017-04-03 10:55 ` Ard Biesheuvel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1490194274-30569-38-git-send-email-Dave.Martin@arm.com \
--to=dave.martin@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).