summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2020-08-30 19:07:53 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-09-03 11:27:06 +0200
commit927aa9a10f126be74cc11e7d39f41adff704b565 (patch)
treeb34b1bd9ce6e7c4b30a160551ccc8240322463cb /kernel
parent70957a10e1dbc72382994a8c630b7a0c0b55b515 (diff)
downloadlinux-stable-927aa9a10f126be74cc11e7d39f41adff704b565.tar.gz
linux-stable-927aa9a10f126be74cc11e7d39f41adff704b565.tar.bz2
linux-stable-927aa9a10f126be74cc11e7d39f41adff704b565.zip
genirq/matrix: Deal with the sillyness of for_each_cpu() on UP
commit 784a0830377d0761834e385975bc46861fea9fa0 upstream. Most of the CPU mask operations behave the same way, but for_each_cpu() and it's variants ignore the cpumask argument and claim that CPU0 is always in the mask. This is historical, inconsistent and annoying behaviour. The matrix allocator uses for_each_cpu() and can be called on UP with an empty cpumask. The calling code does not expect that this succeeds but until commit e027fffff799 ("x86/irq: Unbreak interrupt affinity setting") this went unnoticed. That commit added a WARN_ON() to catch cases which move an interrupt from one vector to another on the same CPU. The warning triggers on UP. Add a check for the cpumask being empty to prevent this. Fixes: 2f75d9e1c905 ("genirq: Implement bitmap matrix allocator") Reported-by: kernel test robot <rong.a.chen@intel.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/irq/matrix.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/kernel/irq/matrix.c b/kernel/irq/matrix.c
index 30cc217b8631..651a4ad6d711 100644
--- a/kernel/irq/matrix.c
+++ b/kernel/irq/matrix.c
@@ -380,6 +380,13 @@ int irq_matrix_alloc(struct irq_matrix *m, const struct cpumask *msk,
unsigned int cpu, bit;
struct cpumap *cm;
+ /*
+ * Not required in theory, but matrix_find_best_cpu() uses
+ * for_each_cpu() which ignores the cpumask on UP .
+ */
+ if (cpumask_empty(msk))
+ return -EINVAL;
+
cpu = matrix_find_best_cpu(m, msk);
if (cpu == UINT_MAX)
return -ENOSPC;