# HG changeset patch # User Alex Williamson # Date 1191254270 21600 # Node ID 2d1b8ae1548d139f9f8532c90a1e61fc199a3394 # Parent 3874bdc782044e5fe9e4181a411b07f2a4bc0155 [IA64] Fix wrong insertion of TLB entry in region 0 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 xen-unstable changeset: 16042:2d1b8ae1548d139f9f8532c90a1e61fc199a3394 xen-unstable date: Mon Oct 01 09:57:50 2007 -0600 diff -r 3874bdc78204 -r 2d1b8ae1548d xen/arch/ia64/xen/regionreg.c --- a/xen/arch/ia64/xen/regionreg.c Mon Oct 01 09:53:48 2007 -0600 +++ b/xen/arch/ia64/xen/regionreg.c Mon Oct 01 09:57:50 2007 -0600 @@ -271,8 +271,16 @@ int set_one_rr(unsigned long rr, unsigne 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) diff -r 3874bdc78204 -r 2d1b8ae1548d xen/arch/ia64/xen/vcpu.c --- a/xen/arch/ia64/xen/vcpu.c Mon Oct 01 09:53:48 2007 -0600 +++ b/xen/arch/ia64/xen/vcpu.c Mon Oct 01 09:57:50 2007 -0600 @@ -280,7 +280,7 @@ static void vcpu_pkr_set_psr_handling(VC 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 * v 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 // 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 pt 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(); @@ -2396,7 +2396,7 @@ IA64FAULT vcpu_itc_i(VCPU * vcpu, u64 pt 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 -r 3874bdc78204 -r 2d1b8ae1548d xen/include/asm-ia64/regionreg.h --- a/xen/include/asm-ia64/regionreg.h Mon Oct 01 09:53:48 2007 -0600 +++ b/xen/include/asm-ia64/regionreg.h Mon Oct 01 09:57:50 2007 -0600 @@ -80,7 +80,8 @@ struct vcpu; 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);