aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2012-10-29 09:03:17 +0100
committerJan Beulich <jbeulich@suse.com>2012-10-29 09:03:17 +0100
commitc6cdb76cbdf9b60e97c32cb72350c89e7026fad8 (patch)
treef08386678ab38bd67072cb7b775eec685ec16a31
parent42f8e580bcc2c7585c9ebdaec09c8079bd5fb2ef (diff)
downloadxen-c6cdb76cbdf9b60e97c32cb72350c89e7026fad8.tar.gz
xen-c6cdb76cbdf9b60e97c32cb72350c89e7026fad8.tar.bz2
xen-c6cdb76cbdf9b60e97c32cb72350c89e7026fad8.zip
x86/HPET: obtain proper lock for changing IRQ affinity
The IRQ descriptor lock should be held while adjusting the affinity of any IRQ; the HPET channel lock isn't sufficient to protect namely against races with moving the IRQ to a different CPU. Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org> xen-unstable changeset: 26063:1f4be6ee4619 xen-unstable date: Wed Oct 17 12:13:20 UTC 2012
-rw-r--r--xen/arch/x86/hpet.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/xen/arch/x86/hpet.c b/xen/arch/x86/hpet.c
index fecc02cd14..7ee7730c20 100644
--- a/xen/arch/x86/hpet.c
+++ b/xen/arch/x86/hpet.c
@@ -493,6 +493,16 @@ static struct hpet_event_channel *hpet_get_channel(int cpu)
return ch;
}
+static void set_channel_irq_affinity(const struct hpet_event_channel *ch)
+{
+ struct irq_desc *desc = irq_to_desc(ch->irq);
+
+ ASSERT(!local_irq_is_enabled());
+ spin_lock(&desc->lock);
+ desc->handler->set_affinity(ch->irq, cpumask_of_cpu(ch->cpu));
+ spin_unlock(&desc->lock);
+}
+
static void hpet_attach_channel(int cpu, struct hpet_event_channel *ch)
{
ASSERT(spin_is_locked(&ch->lock));
@@ -506,9 +516,7 @@ static void hpet_attach_channel(int cpu, struct hpet_event_channel *ch)
if ( ch->cpu != cpu )
return;
- /* set irq affinity */
- irq_desc[ch->irq].handler->
- set_affinity(ch->irq, cpumask_of_cpu(ch->cpu));
+ set_channel_irq_affinity(ch);
}
static void hpet_detach_channel(int cpu, struct hpet_event_channel *ch)
@@ -529,9 +537,7 @@ static void hpet_detach_channel(int cpu, struct hpet_event_channel *ch)
}
ch->cpu = first_cpu(ch->cpumask);
- /* set irq affinity */
- irq_desc[ch->irq].handler->
- set_affinity(ch->irq, cpumask_of_cpu(ch->cpu));
+ set_channel_irq_affinity(ch);
}
#include <asm/mc146818rtc.h>