diff options
author | Vasily Gorbik <gor@linux.ibm.com> | 2018-06-24 06:28:46 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2018-07-06 02:47:53 -0400 |
commit | 196851bed5221a7670024e3ad39704c6d92b2014 (patch) | |
tree | fa2ee6a6ab285514eea75ae451ec8de29e475039 | |
parent | f149371e9e02d23495fc796c09075adeb376a375 (diff) |
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>
-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); | |||
579 | static int topology_ctl_handler(struct ctl_table *ctl, int write, | 579 | static int topology_ctl_handler(struct ctl_table *ctl, int write, |
580 | void __user *buffer, size_t *lenp, loff_t *ppos) | 580 | void __user *buffer, size_t *lenp, loff_t *ppos) |
581 | { | 581 | { |
582 | unsigned int len; | 582 | int enabled = topology_is_enabled(); |
583 | int new_mode; | 583 | int new_mode; |
584 | char buf[2]; | 584 | int zero = 0; |
585 | int one = 1; | ||
586 | int rc; | ||
587 | struct ctl_table ctl_entry = { | ||
588 | .procname = ctl->procname, | ||
589 | .data = &enabled, | ||
590 | .maxlen = sizeof(int), | ||
591 | .extra1 = &zero, | ||
592 | .extra2 = &one, | ||
593 | }; | ||
594 | |||
595 | rc = proc_douintvec_minmax(&ctl_entry, write, buffer, lenp, ppos); | ||
596 | if (rc < 0 || !write) | ||
597 | return rc; | ||
585 | 598 | ||
586 | if (!*lenp || *ppos) { | ||
587 | *lenp = 0; | ||
588 | return 0; | ||
589 | } | ||
590 | if (!write) { | ||
591 | memcpy(buf, topology_is_enabled() ? "1\n" : "0\n", ARRAY_SIZE(buf)); | ||
592 | len = strnlen(buf, ARRAY_SIZE(buf)); | ||
593 | if (len > *lenp) | ||
594 | len = *lenp; | ||
595 | if (copy_to_user(buffer, buf, len)) | ||
596 | return -EFAULT; | ||
597 | goto out; | ||
598 | } | ||
599 | len = *lenp; | ||
600 | if (copy_from_user(buf, buffer, len > sizeof(buf) ? sizeof(buf) : len)) | ||
601 | return -EFAULT; | ||
602 | if (buf[0] != '0' && buf[0] != '1') | ||
603 | return -EINVAL; | ||
604 | mutex_lock(&smp_cpu_state_mutex); | 599 | mutex_lock(&smp_cpu_state_mutex); |
605 | new_mode = topology_get_mode(buf[0] == '1'); | 600 | new_mode = topology_get_mode(enabled); |
606 | if (topology_mode != new_mode) { | 601 | if (topology_mode != new_mode) { |
607 | topology_mode = new_mode; | 602 | topology_mode = new_mode; |
608 | topology_schedule_update(); | 603 | topology_schedule_update(); |
609 | } | 604 | } |
610 | mutex_unlock(&smp_cpu_state_mutex); | 605 | mutex_unlock(&smp_cpu_state_mutex); |
611 | topology_flush_work(); | 606 | topology_flush_work(); |
612 | out: | 607 | |
613 | *lenp = len; | 608 | return rc; |
614 | *ppos += len; | ||
615 | return 0; | ||
616 | } | 609 | } |
617 | 610 | ||
618 | static struct ctl_table topology_ctl_table[] = { | 611 | static struct ctl_table topology_ctl_table[] = { |