Sophie

Sophie

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

kernel-2.6.18-128.1.10.el5.src.rpm

From: Tetsu Yamamoto <tyamamot@redhat.com>
Date: Mon, 3 Dec 2007 17:09:46 -0500
Subject: [xen] ia64: running java-vm causes dom0 to hang
Message-id: 20071203170552.EA8A.TYAMAMOT@redhat.com
O-Subject: [RHEL5.2 PATCH][Xen] Running IA32EL or java-vm causes dom0 hung
Bugzilla: 317301

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

This patch is backported from the upstream:
http://xenbits.xensource.com/ext/xen-ia64-unstable.hg?rev/2d1b8ae1548d

On PV domain with metaphysical mode, emulation of itc.d in region 0
doesn't work well and inserts an wrong TC entry.
Because set_one_rr() doesn't set the machine region register.
i.e. metaphyisical_rr0 is used instead of guest's rr[0].
This patch fixes this wrong insertion of TLB entry in region 0.

This bug causes Dom0/U crash when an application uses region 0.
Actually this problem is easily reproduced by running many (about 30)
java-vm processes concurrently.

With kernel-xen-2.6.18-53.el5 applied this patch, I've confirmed that
this problem does not occur.

Please review and ack.

Regards,

Tetsu Yamamoto

Acked-by: Jarod Wilson <jwilson@redhat.com>
Acked-by: Bill Burns <bburns@redhat.com>

diff --git a/arch/ia64/xen/regionreg.c b/arch/ia64/xen/regionreg.c
index c83a91a..d594805 100644
--- a/arch/ia64/xen/regionreg.c
+++ b/arch/ia64/xen/regionreg.c
@@ -270,8 +270,16 @@ int set_one_rr(unsigned long rr, unsigned long val)
 	return 1;
 }
 
+void set_virtual_rr0(void)
+{
+	struct vcpu *v = current;
+
+	ia64_set_rr(0, v->arch.metaphysical_saved_rr0);
+	ia64_srlz_d();
+}
+
 // set rr0 to the passed rid (for metaphysical mode so don't use domain offset
-int set_metaphysical_rr0(void)
+void set_metaphysical_rr0(void)
 {
 	struct vcpu *v = current;
 //	ia64_rr rrv;
@@ -279,7 +287,6 @@ int set_metaphysical_rr0(void)
 //	rrv.ve = 1; 	FIXME: TURN ME BACK ON WHEN VHPT IS WORKING
 	ia64_set_rr(0,v->arch.metaphysical_rr0);
 	ia64_srlz_d();
-	return 1;
 }
 
 void init_all_rr(struct vcpu *v)
diff --git a/arch/ia64/xen/vcpu.c b/arch/ia64/xen/vcpu.c
index 43599f6..fae2520 100644
--- a/arch/ia64/xen/vcpu.c
+++ b/arch/ia64/xen/vcpu.c
@@ -239,7 +239,7 @@ IA64FAULT vcpu_get_ar(VCPU * vcpu, u64 reg, u64 * val)
  VCPU processor status register access routines
 **************************************************************************/
 
-void vcpu_set_metaphysical_mode(VCPU * vcpu, BOOLEAN newmode)
+static void vcpu_set_metaphysical_mode(VCPU * vcpu, BOOLEAN newmode)
 {
 	/* only do something if mode changes */
 	if (!!newmode ^ !!PSCB(vcpu, metaphysical_mode)) {
@@ -247,7 +247,7 @@ void vcpu_set_metaphysical_mode(VCPU * vcpu, BOOLEAN newmode)
 		if (newmode)
 			set_metaphysical_rr0();
 		else if (PSCB(vcpu, rrs[0]) != -1)
-			set_one_rr(0, PSCB(vcpu, rrs[0]));
+			set_virtual_rr0();
 	}
 }
 
@@ -1561,7 +1561,7 @@ vcpu_get_domain_bundle(VCPU * vcpu, REGS * regs, u64 gip,
 		// This may cause tlb miss. see vcpu_translate(). Be careful!
 		swap_rr0 = (!region && PSCB(vcpu, metaphysical_mode));
 		if (swap_rr0) {
-			set_one_rr(0x0, PSCB(vcpu, rrs[0]));
+			set_virtual_rr0();
 		}
 		*bundle = __get_domain_bundle(gip);
 		if (swap_rr0) {
@@ -2208,7 +2208,7 @@ IA64FAULT vcpu_itc_d(VCPU * vcpu, u64 pte, u64 itir, u64 ifa)
 	if (!pteval)
 		return IA64_ILLOP_FAULT;
 	if (swap_rr0)
-		set_one_rr(0x0, PSCB(vcpu, rrs[0]));
+		set_virtual_rr0();
 	vcpu_itc_no_srlz(vcpu, 2, ifa, pteval, pte, logps, &entry);
 	if (swap_rr0)
 		set_metaphysical_rr0();
@@ -2235,7 +2235,7 @@ IA64FAULT vcpu_itc_i(VCPU * vcpu, u64 pte, u64 itir, u64 ifa)
 	if (!pteval)
 		return IA64_ILLOP_FAULT;
 	if (swap_rr0)
-		set_one_rr(0x0, PSCB(vcpu, rrs[0]));
+		set_virtual_rr0();
 	vcpu_itc_no_srlz(vcpu, 1, ifa, pteval, pte, logps, &entry);
 	if (swap_rr0)
 		set_metaphysical_rr0();
diff --git a/include/asm-ia64/regionreg.h b/include/asm-ia64/regionreg.h
index c2e9ecc..73b4cd7 100644
--- a/include/asm-ia64/regionreg.h
+++ b/include/asm-ia64/regionreg.h
@@ -76,7 +76,8 @@ extern int deallocate_rid_range(struct domain *d);
 struct vcpu;
 extern void init_all_rr(struct vcpu *v);
 
-extern int set_metaphysical_rr0(void);
+extern void set_virtual_rr0(void);
+extern void set_metaphysical_rr0(void);
 
 extern void load_region_regs(struct vcpu *v);