diff options
author | Vasily Gorbik <gor@linux.ibm.com> | 2018-06-24 13:28:46 +0300 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2018-07-06 09:47:53 +0300 |
commit | 196851bed5221a7670024e3ad39704c6d92b2014 (patch) | |
tree | fa2ee6a6ab285514eea75ae451ec8de29e475039 /arch | |
parent | f149371e9e02d23495fc796c09075adeb376a375 (diff) | |
download | linux-196851bed5221a7670024e3ad39704c6d92b2014.tar.xz |
s390/topology: correct topology mode proc handler
Reuse proc_douintvec_minmax to simplify topology mode proc handler.
This also enforces correct range of 0-1 on proc writes and correctly
handles numbers starting with 0 or spaces.
Before:
$ echo 01 > /proc/sys/s390/topology
$ cat /proc/sys/s390/topology
0
$ echo ' 1' > /proc/sys/s390/topology
-bash: echo: write error: Invalid argument
$ echo 2 > /proc/sys/s390/topology
-bash: echo: write error: Invalid argument
$ echo 12 > /proc/sys/s390/topology
$ cat /proc/sys/s390/topology
1
After:
$ echo 01 > /proc/sys/s390/topology
$ cat /proc/sys/s390/topology
1
$ echo ' 1' > /proc/sys/s390/topology
$ cat /proc/sys/s390/topology
1
$ echo 2 > /proc/sys/s390/topology
-bash: echo: write error: Invalid argument
$ echo 12 > /proc/sys/s390/topology
-bash: echo: write error: Invalid argument
$ echo ' 0' > /proc/sys/s390/topology
$ cat /proc/sys/s390/topology
0
Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/s390/kernel/topology.c | 43 |
1 files changed, 18 insertions, 25 deletions
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index 33ebb423c613..e8184a15578a 100644 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c @@ -579,40 +579,33 @@ early_param("topology", topology_setup); static int topology_ctl_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { - unsigned int len; + int enabled = topology_is_enabled(); int new_mode; - char buf[2]; + int zero = 0; + int one = 1; + int rc; + struct ctl_table ctl_entry = { + .procname = ctl->procname, + .data = &enabled, + .maxlen = sizeof(int), + .extra1 = &zero, + .extra2 = &one, + }; + + rc = proc_douintvec_minmax(&ctl_entry, write, buffer, lenp, ppos); + if (rc < 0 || !write) + return rc; - if (!*lenp || *ppos) { - *lenp = 0; - return 0; - } - if (!write) { - memcpy(buf, topology_is_enabled() ? "1\n" : "0\n", ARRAY_SIZE(buf)); - len = strnlen(buf, ARRAY_SIZE(buf)); - if (len > *lenp) - len = *lenp; - if (copy_to_user(buffer, buf, len)) - return -EFAULT; - goto out; - } - len = *lenp; - if (copy_from_user(buf, buffer, len > sizeof(buf) ? sizeof(buf) : len)) - return -EFAULT; - if (buf[0] != '0' && buf[0] != '1') - return -EINVAL; mutex_lock(&smp_cpu_state_mutex); - new_mode = topology_get_mode(buf[0] == '1'); + new_mode = topology_get_mode(enabled); if (topology_mode != new_mode) { topology_mode = new_mode; topology_schedule_update(); } mutex_unlock(&smp_cpu_state_mutex); topology_flush_work(); -out: - *lenp = len; - *ppos += len; - return 0; + + return rc; } static struct ctl_table topology_ctl_table[] = { |