[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>
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
index 9386b95..c47c8ac 100644
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -101,15 +101,6 @@
 	return -1;
 }
 
-static void reserve_irq(unsigned int irq)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&vector_lock, flags);
-	irq_status[irq] = IRQ_RSVD;
-	spin_unlock_irqrestore(&vector_lock, flags);
-}
-
 static inline int find_unassigned_irq(void)
 {
 	int irq;
@@ -302,10 +293,14 @@
 
 void destroy_and_reserve_irq(unsigned int irq)
 {
+	unsigned long flags;
+
 	dynamic_irq_cleanup(irq);
 
-	clear_irq_vector(irq);
-	reserve_irq(irq);
+	spin_lock_irqsave(&vector_lock, flags);
+	__clear_irq_vector(irq);
+	irq_status[irq] = IRQ_RSVD;
+	spin_unlock_irqrestore(&vector_lock, flags);
 }
 
 static int __reassign_irq_vector(int irq, int cpu)