diff options
| author | Jan Beulich <jbeulich@novell.com> | 2010-11-16 17:55:33 -0500 |
|---|---|---|
| committer | Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> | 2010-11-16 17:58:47 -0500 |
| commit | 1c6969ec8e6328e8d288fc585310e9e52fc9db04 (patch) | |
| tree | 98fb1738fbd2f7a46879ea802e0934861dc7a3be | |
| parent | 7e77506a5918d82cafa2ffa783ab57c23f9e9817 (diff) | |
xen/evtchn: clear secondary CPUs' cpu_evtchn_mask[] after restore
To bind all event channels to CPU#0, it is not sufficient to set all
of its cpu_evtchn_mask[] bits; all other CPUs also need to get their
bits cleared. Otherwise, evtchn_do_upcall() will start handling
interrupts on CPUs they're not intended to run on, which can be
particularly bad for per-CPU ones.
[ linux-2.6.18-xen.hg 7de7453dee36 ]
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
| -rw-r--r-- | drivers/xen/events.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 321a0c8346e..d770b8c8885 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
| @@ -286,9 +286,9 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) | |||
| 286 | 286 | ||
| 287 | static void init_evtchn_cpu_bindings(void) | 287 | static void init_evtchn_cpu_bindings(void) |
| 288 | { | 288 | { |
| 289 | int i; | ||
| 289 | #ifdef CONFIG_SMP | 290 | #ifdef CONFIG_SMP |
| 290 | struct irq_desc *desc; | 291 | struct irq_desc *desc; |
| 291 | int i; | ||
| 292 | 292 | ||
| 293 | /* By default all event channels notify CPU#0. */ | 293 | /* By default all event channels notify CPU#0. */ |
| 294 | for_each_irq_desc(i, desc) { | 294 | for_each_irq_desc(i, desc) { |
| @@ -296,7 +296,10 @@ static void init_evtchn_cpu_bindings(void) | |||
| 296 | } | 296 | } |
| 297 | #endif | 297 | #endif |
| 298 | 298 | ||
| 299 | memset(cpu_evtchn_mask(0), ~0, sizeof(struct cpu_evtchn_s)); | 299 | for_each_possible_cpu(i) |
| 300 | memset(cpu_evtchn_mask(i), | ||
| 301 | (i == 0) ? ~0 : 0, sizeof(struct cpu_evtchn_s)); | ||
| 302 | |||
| 300 | } | 303 | } |
| 301 | 304 | ||
| 302 | static inline void clear_evtchn(int port) | 305 | static inline void clear_evtchn(int port) |
