]> xenbits.xensource.com Git - xen.git/commitdiff
[IA64] Fix wrong insertion of TLB entry in region 0
authorAlex Williamson <alex.williamson@hp.com>
Mon, 1 Oct 2007 15:57:50 +0000 (09:57 -0600)
committerAlex Williamson <alex.williamson@hp.com>
Mon, 1 Oct 2007 15:57:50 +0000 (09:57 -0600)
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 bug causes Dom0/U crash when an application uses region 0.
Actually I met the crash when I was building open GFW (java uses
region 0).

Signed-off-by: Kouya Shimura <kouya@jp.fujitsu.com>
xen/arch/ia64/xen/regionreg.c
xen/arch/ia64/xen/vcpu.c
xen/include/asm-ia64/regionreg.h

index b1725c36e7f75864f29190b4234508a5db44b643..2588a55d7809508d2cf42c3fc0686a2c51ca26c1 100644 (file)
@@ -271,8 +271,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;
@@ -280,7 +288,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_rid_dt);
        ia64_srlz_d();
-       return 1;
 }
 
 void init_all_rr(struct vcpu *v)
index a95e2117e860500608962efea5cebad74386684a..74aac37b6bcb3b315b04576b4510fb90cec37ee7 100644 (file)
@@ -280,7 +280,7 @@ static void vcpu_pkr_set_psr_handling(VCPU * vcpu)
  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)) {
@@ -288,7 +288,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();
        }
 }
 
@@ -1635,7 +1635,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) {
@@ -2368,7 +2368,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, _itir.itir, &entry);
        if (swap_rr0)
                set_metaphysical_rr0();
@@ -2396,7 +2396,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, _itir.itir, &entry);
        if (swap_rr0)
                set_metaphysical_rr0();
index bb528a3f4129591f54524f96b43bed06cfec589b..9651254a8d35109355ea390661726f8ff2abc9a0 100644 (file)
@@ -80,7 +80,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);