summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2008-10-27 11:03:33 +1100
committerStephen Rothwell <sfr@canb.auug.org.au>2008-10-27 11:03:33 +1100
commit231f4be6e1309183fb959efbb8b008b8bee570ca (patch)
tree2d8cf149c607a81c3457130151343c918306f1bd /include
parent6c989f9dc3cd4048d8af5df47825d0bff31d7a87 (diff)
cpumask:check-all-ops-for-limits
It's useful to check that no one is accessing > nr_cpumask_bits for cpumasks. This also allows you to turn on CONFIG_CPUMASKS_OFFSTACK even for smaller CONFIG_NR_CPUS. It's a WARN_ON_ONCE because I *know* that UP-configured Cell processor will currently trip this. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: Mike Travis <travis@sgi.com> Cc: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'include')
-rw-r--r--include/linux/cpumask.h22
1 files changed, 16 insertions, 6 deletions
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index d015af580b36..f54868b1df3c 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -250,23 +250,33 @@ extern cpumask_t _unused_cpumask_arg_;
#define cpu_mask_all (*(cpumask_t *)cpu_all_mask)
/* End deprecated region. */
+/* verify cpu argument to cpumask_* operators */
+static inline unsigned int cpumask_check(unsigned int cpu)
+{
+#ifdef CONFIG_DEBUG_PER_CPU_MAPS
+ WARN_ON_ONCE(cpu >= nr_cpumask_bits);
+#endif /* CONFIG_DEBUG_PER_CPU_MAPS */
+ return cpu;
+}
+
/* cpumask_* operators */
static inline void cpumask_set_cpu(int cpu, volatile struct cpumask *dstp)
{
- set_bit(cpu, cpumask_bits(dstp));
+ set_bit(cpumask_check(cpu), cpumask_bits(dstp));
}
static inline void cpumask_clear_cpu(int cpu, volatile struct cpumask *dstp)
{
- clear_bit(cpu, cpumask_bits(dstp));
+ clear_bit(cpumask_check(cpu), cpumask_bits(dstp));
}
/* No static inline type checking - see Subtlety (1) above. */
-#define cpumask_test_cpu(cpu, cpumask) test_bit((cpu), (cpumask)->bits)
+#define cpumask_test_cpu(cpu, cpumask) \
+ test_bit(cpumask_check(cpu), (cpumask)->bits)
static inline int cpumask_test_and_set_cpu(int cpu, struct cpumask *addr)
{
- return test_and_set_bit(cpu, cpumask_bits(addr));
+ return test_and_set_bit(cpumask_check(cpu), cpumask_bits(addr));
}
static inline void cpumask_setall(struct cpumask *dstp)
@@ -400,8 +410,8 @@ static inline int cpumask_cpuremap(int oldbit,
const struct cpumask *oldp,
const struct cpumask *newp)
{
- return bitmap_bitremap(oldbit, cpumask_bits(oldp), cpumask_bits(newp),
- nr_cpumask_bits);
+ return bitmap_bitremap(cpumask_check(oldbit), cpumask_bits(oldp),
+ cpumask_bits(newp), nr_cpumask_bits);
}
static inline void cpumask_remap(struct cpumask *dstp,