diff options
| author | Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> | 2007-07-29 22:56:30 -0400 |
|---|---|---|
| committer | Tony Luck <tony.luck@intel.com> | 2007-07-30 19:30:42 -0400 |
| commit | 216fcd29af47ab53ffd87e82139fcc4095e34d91 (patch) | |
| tree | 6dc391ecc05255853d1974feee5d3a36b4ddaa5a | |
| parent | c4c376f7e16deeba8f0542eabcaca19b712e7be1 (diff) | |
[IA64] Fix possible race in destroy_and_reserve_irq()
Currently, destroy_and_reserve_irq() sets irq_status[irq] UNUSED using
clear_irq_vector() and sets irq_status[irq] RSVD using reserve_irq().
But there is a race window because vector_lock is once released between
them. This patch fixes this race window.
Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
| -rw-r--r-- | arch/ia64/kernel/irq_ia64.c | 17 |
1 files changed, 6 insertions, 11 deletions
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 9386b955eed1..c47c8acc96e3 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c | |||
| @@ -101,15 +101,6 @@ int check_irq_used(int irq) | |||
| 101 | return -1; | 101 | return -1; |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | static void reserve_irq(unsigned int irq) | ||
| 105 | { | ||
| 106 | unsigned long flags; | ||
| 107 | |||
| 108 | spin_lock_irqsave(&vector_lock, flags); | ||
| 109 | irq_status[irq] = IRQ_RSVD; | ||
| 110 | spin_unlock_irqrestore(&vector_lock, flags); | ||
| 111 | } | ||
| 112 | |||
| 113 | static inline int find_unassigned_irq(void) | 104 | static inline int find_unassigned_irq(void) |
| 114 | { | 105 | { |
| 115 | int irq; | 106 | int irq; |
| @@ -302,10 +293,14 @@ static cpumask_t vector_allocation_domain(int cpu) | |||
| 302 | 293 | ||
| 303 | void destroy_and_reserve_irq(unsigned int irq) | 294 | void destroy_and_reserve_irq(unsigned int irq) |
| 304 | { | 295 | { |
| 296 | unsigned long flags; | ||
| 297 | |||
| 305 | dynamic_irq_cleanup(irq); | 298 | dynamic_irq_cleanup(irq); |
| 306 | 299 | ||
| 307 | clear_irq_vector(irq); | 300 | spin_lock_irqsave(&vector_lock, flags); |
| 308 | reserve_irq(irq); | 301 | __clear_irq_vector(irq); |
| 302 | irq_status[irq] = IRQ_RSVD; | ||
| 303 | spin_unlock_irqrestore(&vector_lock, flags); | ||
| 309 | } | 304 | } |
| 310 | 305 | ||
| 311 | static int __reassign_irq_vector(int irq, int cpu) | 306 | static int __reassign_irq_vector(int irq, int cpu) |
