78 lines
3.0 KiB
Diff
78 lines
3.0 KiB
Diff
Date: Mon, 6 Feb 2017 13:24:42 -0500
|
|
From: Tejun Heo <tj@kernel.org>
|
|
Subject: cpumask: use nr_cpumask_bits for parsing functions
|
|
Bug-Debian: https://bugs.debian.org/848682
|
|
Origin: https://lkml.org/lkml/2017/2/6/720
|
|
|
|
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.
|
|
|
|
Signed-off-by: Tejun Heo <tj@kernel.org>
|
|
Fixes: 513e3d2d11c9 ("cpumask: always use nr_cpu_ids in formatting and parsing functions")
|
|
Cc: stable@vger.kernel.org # v4.0+
|
|
Reported-by: Martin Steigerwald <martin.steigerwald@teamix.de>
|
|
Debugged-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
|
|
---
|
|
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);
|
|
}
|
|
|
|
/**
|