]> xenbits.xensource.com Git - xen.git/commitdiff
[IA64] Fix ia64_sal_get_state_info() emulation bug
authorAlex Williamson <alex.williamson@hp.com>
Thu, 1 Nov 2007 14:50:03 +0000 (08:50 -0600)
committerAlex Williamson <alex.williamson@hp.com>
Thu, 1 Nov 2007 14:50:03 +0000 (08:50 -0600)
It is possible to double-free the sal queue entry when multiple
ia64_sal_get_state_info() from Dom0 are called simultaniously.
In the worst case, the kernel might panic.

Signed-off-by: Kazuhiro Suzuki <kaz@jp.fujitsu.com>
xen/arch/ia64/xen/fw_emul.c

index 8b00e62ea4ad1449783e197419b6bbfb336766ef..b6e9f8754bf0170a842f00d62a9538eb39dba970 100644 (file)
@@ -242,6 +242,8 @@ sal_emulator (long index, unsigned long in1, unsigned long in2,
                        }
                        e = list_entry(sal_queue[in1].next,
                                       sal_queue_entry_t, list);
+
+                       list_del(&e->list);
                        spin_unlock_irqrestore(&sal_queue_lock, flags);
 
                        IA64_SAL_DEBUG("SAL_GET_STATE_INFO(%s <= %s) "
@@ -277,10 +279,12 @@ sal_emulator (long index, unsigned long in1, unsigned long in2,
                        r9 = arg.ret;
                        status = arg.status;
                        if (r9 == 0) {
+                               xfree(e);
+                       } else {
+                               /* Re-add the entry to sal_queue */
                                spin_lock_irqsave(&sal_queue_lock, flags);
-                               list_del(&e->list);
+                               list_add(&e->list, &sal_queue[in1]);
                                spin_unlock_irqrestore(&sal_queue_lock, flags);
-                               xfree(e);
                        }
                } else {
                        status = IA64_SAL_NO_INFORMATION_AVAILABLE;
@@ -316,10 +320,10 @@ sal_emulator (long index, unsigned long in1, unsigned long in2,
                                       "on CPU#%d.\n",
                                       rec_name[e->sal_info_type],
                                       rec_name[in1], e->cpuid);
-                       
 
                        arg.type = e->sal_info_type;
                        arg.status = 0;
+
                        if (e->cpuid == smp_processor_id()) {
                                IA64_SAL_DEBUG("SAL_CLEAR_STATE_INFO: local\n");
                                clear_state_info_on(&arg);