| From 4d59b6ccf000862beed6fc0765d3209f98a8d8a2 Mon Sep 17 00:00:00 2001 |
| From: Tejun Heo <tj@kernel.org> |
| Date: Wed, 8 Feb 2017 14:30:56 -0800 |
| Subject: cpumask: use nr_cpumask_bits for parsing functions |
| |
| From: Tejun Heo <tj@kernel.org> |
| |
| commit 4d59b6ccf000862beed6fc0765d3209f98a8d8a2 upstream. |
| |
| Commit 513e3d2d11c9 ("cpumask: always use nr_cpu_ids in formatting and |
| parsing functions") converted both cpumask printing and parsing |
| functions to use nr_cpu_ids instead of nr_cpumask_bits. While this was |
| okay for the printing functions as it just picked one of the two output |
| formats that we were alternating between depending on a kernel config, |
| doing the same for parsing wasn't okay. |
| |
| nr_cpumask_bits can be either nr_cpu_ids or NR_CPUS. We can always use |
| nr_cpu_ids but that is a variable while NR_CPUS is a constant, so it can |
| be more efficient to use NR_CPUS when we can get away with it. |
| Converting the printing functions to nr_cpu_ids makes sense because it |
| affects how the masks get presented to userspace and doesn't break |
| anything; however, using nr_cpu_ids for parsing functions can |
| incorrectly leave the higher bits uninitialized while reading in these |
| masks from userland. As all testing and comparison functions use |
| nr_cpumask_bits which can be larger than nr_cpu_ids, the parsed cpumasks |
| can erroneously yield false negative results. |
| |
| This made the taskstats interface incorrectly return -EINVAL even when |
| the inputs were correct. |
| |
| Fix it by restoring the parse functions to use nr_cpumask_bits instead |
| of nr_cpu_ids. |
| |
| Link: http://lkml.kernel.org/r/20170206182442.GB31078@htj.duckdns.org |
| Fixes: 513e3d2d11c9 ("cpumask: always use nr_cpu_ids in formatting and parsing functions") |
| Signed-off-by: Tejun Heo <tj@kernel.org> |
| Reported-by: Martin Steigerwald <martin.steigerwald@teamix.de> |
| Debugged-by: Ben Hutchings <ben.hutchings@codethink.co.uk> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| include/linux/cpumask.h | 8 ++++---- |
| 1 file changed, 4 insertions(+), 4 deletions(-) |
| |
| --- a/include/linux/cpumask.h |
| +++ b/include/linux/cpumask.h |
| @@ -560,7 +560,7 @@ static inline void cpumask_copy(struct c |
| static inline int cpumask_parse_user(const char __user *buf, int len, |
| struct cpumask *dstp) |
| { |
| - return bitmap_parse_user(buf, len, cpumask_bits(dstp), nr_cpu_ids); |
| + return bitmap_parse_user(buf, len, cpumask_bits(dstp), nr_cpumask_bits); |
| } |
| |
| /** |
| @@ -575,7 +575,7 @@ static inline int cpumask_parselist_user |
| struct cpumask *dstp) |
| { |
| return bitmap_parselist_user(buf, len, cpumask_bits(dstp), |
| - nr_cpu_ids); |
| + nr_cpumask_bits); |
| } |
| |
| /** |
| @@ -590,7 +590,7 @@ static inline int cpumask_parse(const ch |
| char *nl = strchr(buf, '\n'); |
| unsigned int len = nl ? (unsigned int)(nl - buf) : strlen(buf); |
| |
| - return bitmap_parse(buf, len, cpumask_bits(dstp), nr_cpu_ids); |
| + return bitmap_parse(buf, len, cpumask_bits(dstp), nr_cpumask_bits); |
| } |
| |
| /** |
| @@ -602,7 +602,7 @@ static inline int cpumask_parse(const ch |
| */ |
| static inline int cpulist_parse(const char *buf, struct cpumask *dstp) |
| { |
| - return bitmap_parselist(buf, cpumask_bits(dstp), nr_cpu_ids); |
| + return bitmap_parselist(buf, cpumask_bits(dstp), nr_cpumask_bits); |
| } |
| |
| /** |