Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 89877e42827f16fa5f86b1df0c2860b1 > files > 2825

kernel-2.6.18-128.1.10.el5.src.rpm

From: Tetsu Yamamoto <tyamamot@redhat.com>
Date: Thu, 3 Jan 2008 17:22:22 -0500
Subject: [xen] ia64: hv hangs on Corrected Platform Errors
Message-id: 477D601E.1030102@redhat.com
O-Subject: [RHEL5.2 PATCH] [Xen] hypervisor sometimes hangs on Corrected Platform Errors
Bugzilla: 371671

This patch fixes BZ#371671.
https://bugzilla.redhat.com/show_bug.cgi?id=371671

Hypervisor hang is caused by the bug of SAL call emulation,
ia64_sal_get_state_info().  The patch to fix it is backported from  the
upstream.
- [IA64] Fix ia64_sal_get_state_info() emulation bug
http://xenbits.xensource.com/ext/ia64/xen-unstable.hg/rev/42e032f52371

I've tested these patches with kernel-2.6.18-58.el5, and confirmed that
hypervisor does not hang while CPE occurs.

Please review and ACK.

Regards,

Tetsu Yamamoto

# HG changeset patch
# User Alex Williamson <alex.williamson@hp.com>
# Date 1193928603 21600
# Node ID 42e032f52371c2ba1bb048a6215381d7b5ba53ff
# Parent  a07288a8478521002c2302ad18fac52eb6600055
[IA64] Fix ia64_sal_get_state_info() emulation bug

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>

Acked-by: "Stephen C. Tweedie" <sct@redhat.com>
Acked-by: Jarod Wilson <jwilson@redhat.com>
Acked-by: Bill Burns <bburns@redhat.com>

diff --git a/arch/ia64/xen/fw_emul.c b/arch/ia64/xen/fw_emul.c
index bd4b86e..a49ae88 100644
--- a/arch/ia64/xen/fw_emul.c
+++ b/arch/ia64/xen/fw_emul.c
@@ -241,6 +241,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) "
@@ -276,10 +278,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;
@@ -315,10 +319,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);