@@ -217,23 +217,34 @@ extern cpumask_t _unused_cpumask_arg_;
}
#endif /* CONFIG_NR_CPUS > BITS_PER_LONG */
+/* verify cpu argument to cpumask_* operators */
+static inline unsigned int cpumask_check(unsigned int cpu)
+{
+#ifdef CONFIG_DEBUG_PER_CPU_MAPS
+ /* This breaks at runtime. */
+ BUG_ON(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)
@@ -367,8 +378,8 @@ static inline int cpumask_cpuremap(int o
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,
@@ -766,6 +766,12 @@ config SYSCTL_SYSCALL_CHECK
to properly maintain and use. This enables checks that help
you to keep things correct.
+config DEBUG_PER_CPU_MAPS
+ bool "Cpumask debug checks"
+ ---help---
+ Extra debugging for cpumasks.
+ eg. to make sure accesses to cpumasks are < nr_cpu_ids.
+
source kernel/trace/Kconfig
config PROVIDE_OHCI1394_DMA_INIT
@@ -11,6 +11,9 @@ EXPORT_SYMBOL(cpumask_first);
int cpumask_next(int n, const cpumask_t *srcp)
{
+ /* -1 is a legal arg here. */
+ if (n != -1)
+ cpumask_check(n);
return find_next_bit(cpumask_bits(srcp), nr_cpumask_bits, n+1);
}
EXPORT_SYMBOL(cpumask_next);