diff options
author | Jan Beulich <jbeulich@suse.com> | 2012-10-29 09:03:17 +0100 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2012-10-29 09:03:17 +0100 |
commit | c6cdb76cbdf9b60e97c32cb72350c89e7026fad8 (patch) | |
tree | f08386678ab38bd67072cb7b775eec685ec16a31 | |
parent | 42f8e580bcc2c7585c9ebdaec09c8079bd5fb2ef (diff) | |
download | xen-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.c | 18 |
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> |