From f529f8d46b4381cb5969ccd1701234b8993b07ad Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Mon, 1 Oct 2007 09:57:50 -0600 Subject: [PATCH] [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/arch/ia64/xen/regionreg.c | 11 +++++++++-- xen/arch/ia64/xen/vcpu.c | 10 +++++----- xen/include/asm-ia64/regionreg.h | 3 ++- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/xen/arch/ia64/xen/regionreg.c b/xen/arch/ia64/xen/regionreg.c index b1725c36e7..2588a55d78 100644 --- a/xen/arch/ia64/xen/regionreg.c +++ b/xen/arch/ia64/xen/regionreg.c @@ -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) diff --git a/xen/arch/ia64/xen/vcpu.c b/xen/arch/ia64/xen/vcpu.c index a95e2117e8..74aac37b6b 100644 --- a/xen/arch/ia64/xen/vcpu.c +++ b/xen/arch/ia64/xen/vcpu.c @@ -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(); diff --git a/xen/include/asm-ia64/regionreg.h b/xen/include/asm-ia64/regionreg.h index bb528a3f41..9651254a8d 100644 --- a/xen/include/asm-ia64/regionreg.h +++ b/xen/include/asm-ia64/regionreg.h @@ -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); -- 2.39.5