# HG changeset patch # User yamahata@xxxxxxxxxxxxx # Node ID 9c9e526bccb972e7b4c5341e92f02407f3b02703 # Parent 434d71d802722ae27e1fc055c728b1c277ef2181 fix ptc.ga virtualization. Uninitialized vcpu doesn't need tlb flush. ptc_ga_remote_func() calls vmx_vcpu_ptc_l() in IPI context. I.e. vcpu may not equal to current. On the other hand vmx_vcpu_ptc_l() assumes vcpu = current. remove the assumption. PATCHNAME: fix_vcpu_ptc_ga_virtualization Signed-off-by: Isaku Yamahata diff -r 434d71d80272 -r 9c9e526bccb9 xen/arch/ia64/vmx/vmmu.c --- a/xen/arch/ia64/vmx/vmmu.c Mon Jun 19 20:22:31 2006 +0900 +++ b/xen/arch/ia64/vmx/vmmu.c Mon Jun 19 20:48:08 2006 +0900 @@ -545,6 +545,9 @@ IA64FAULT vmx_vcpu_ptc_ga(VCPU *vcpu,UIN vcpu_get_rr(vcpu, va, &args.rid); args.ps = ps; for_each_vcpu (d, v) { + if (!test_bit(_VCPUF_initialised, &v->vcpu_flags)) + continue; + args.vcpu = v; if (v->processor != vcpu->processor) { int proc; diff -r 434d71d80272 -r 9c9e526bccb9 xen/arch/ia64/vmx/vmx_phy_mode.c --- a/xen/arch/ia64/vmx/vmx_phy_mode.c Mon Jun 19 20:22:31 2006 +0900 +++ b/xen/arch/ia64/vmx/vmx_phy_mode.c Mon Jun 19 20:48:08 2006 +0900 @@ -137,13 +137,14 @@ vmx_init_all_rr(VCPU *vcpu) #endif } +extern void * pal_vaddr; + void vmx_load_all_rr(VCPU *vcpu) { unsigned long psr; ia64_rr phy_rr; - extern void * pal_vaddr; local_irq_save(psr); @@ -204,6 +205,24 @@ vmx_load_all_rr(VCPU *vcpu) } void +vmx_load_rr7_and_pta(VCPU *vcpu) +{ + unsigned long psr; + + local_irq_save(psr); + + vmx_switch_rr7(vrrtomrr(vcpu,VMX(vcpu, vrr[VRN7])), + (void *)vcpu->domain->shared_info, + (void *)vcpu->arch.privregs, + (void *)vcpu->arch.vhpt.hash, pal_vaddr ); + ia64_set_pta(vcpu->arch.arch_vmx.mpta); + + ia64_srlz_d(); + local_irq_restore(psr); + ia64_srlz_i(); +} + +void switch_to_physical_rid(VCPU *vcpu) { UINT64 psr; diff -r 434d71d80272 -r 9c9e526bccb9 xen/arch/ia64/vmx/vtlb.c --- a/xen/arch/ia64/vmx/vtlb.c Mon Jun 19 20:22:31 2006 +0900 +++ b/xen/arch/ia64/vmx/vtlb.c Mon Jun 19 20:48:08 2006 +0900 @@ -28,8 +28,10 @@ #include #include #include +#include #include #include +#include #define MAX_CCH_LENGTH 40 thash_data_t *__alloc_chain(thash_cb_t *); @@ -229,12 +231,13 @@ u64 guest_vhpt_lookup(u64 iha, u64 *pte) * purge software guest tlb */ -static void vtlb_purge(thash_cb_t *hcb, u64 va, u64 ps) -{ +static void vtlb_purge(VCPU *v, u64 va, u64 ps) +{ + thash_cb_t *hcb = &v->arch.vtlb; thash_data_t *hash_table, *prev, *next; u64 start, end, size, tag, rid, def_size; ia64_rr vrr; - vcpu_get_rr(current, va, &vrr.rrval); + vcpu_get_rr(v, va, &vrr.rrval); rid = vrr.rid; size = PSIZE(ps); start = va & (-size); @@ -263,16 +266,29 @@ static void vtlb_purge(thash_cb_t *hcb, } // machine_tlb_purge(va, ps); } + +static void +switch_rr7_and_pta(VCPU* v) +{ + if (VMX_DOMAIN(v)) + vmx_load_rr7_and_pta(v); + else + load_region_reg7_and_pta(v); +} + /* * purge VHPT and machine TLB */ -static void vhpt_purge(thash_cb_t *hcb, u64 va, u64 ps) -{ +static void vhpt_purge(VCPU *v, u64 va, u64 ps) +{ + //thash_cb_t *hcb = &v->arch.vhpt; thash_data_t *hash_table, *prev, *next; u64 start, end, size, tag; size = PSIZE(ps); start = va & (-size); end = start + size; + if (current != v) + switch_rr7_and_pta(v); while(start < end){ hash_table = (thash_data_t *)ia64_thash(start); tag = ia64_ttag(start); @@ -294,6 +310,8 @@ static void vhpt_purge(thash_cb_t *hcb, start += PAGE_SIZE; } machine_tlb_purge(va, ps); + if (current != v) + switch_rr7_and_pta(current); } /* @@ -413,8 +431,8 @@ void thash_purge_entries(VCPU *v, u64 va void thash_purge_entries(VCPU *v, u64 va, u64 ps) { if(vcpu_quick_region_check(v->arch.tc_regions,va)) - vtlb_purge(&v->arch.vtlb, va, ps); - vhpt_purge(&v->arch.vhpt, va, ps); + vtlb_purge(v, va, ps); + vhpt_purge(v, va, ps); } u64 translate_phy_pte(VCPU *v, u64 *pte, u64 itir, u64 va) @@ -456,17 +474,17 @@ void thash_purge_and_insert(VCPU *v, u64 phy_pte = translate_phy_pte(v, &pte, itir, ifa); if(ps==PAGE_SHIFT){ if(!(pte&VTLB_PTE_IO)){ - vhpt_purge(&v->arch.vhpt, ifa, ps); + vhpt_purge(v, ifa, ps); vmx_vhpt_insert(&v->arch.vhpt, phy_pte, itir, ifa); } else{ - vhpt_purge(&v->arch.vhpt, ifa, ps); + vhpt_purge(v, ifa, ps); vtlb_insert(&v->arch.vtlb, pte, itir, ifa); vcpu_quick_region_set(PSCBX(v,tc_regions),ifa); } } else{ - vhpt_purge(&v->arch.vhpt, ifa, ps); + vhpt_purge(v, ifa, ps); vtlb_insert(&v->arch.vtlb, pte, itir, ifa); vcpu_quick_region_set(PSCBX(v,tc_regions),ifa); if(!(pte&VTLB_PTE_IO)){ diff -r 434d71d80272 -r 9c9e526bccb9 xen/arch/ia64/xen/regionreg.c --- a/xen/arch/ia64/xen/regionreg.c Mon Jun 19 20:22:31 2006 +0900 +++ b/xen/arch/ia64/xen/regionreg.c Mon Jun 19 20:48:08 2006 +0900 @@ -342,3 +342,16 @@ void load_region_regs(struct vcpu *v) panic_domain(0,"load_region_regs: can't set! bad=%lx\n",bad); } } + +void load_region_reg7_and_pta(struct vcpu *v) +{ + unsigned long rr7; + + ia64_set_pta(VHPT_ADDR | (1 << 8) | (VHPT_SIZE_LOG2 << 2) | + VHPT_ENABLED); + + // TODO: These probably should be validated + rr7 = VCPU(v,rrs[7]); + if (!set_one_rr(0xe000000000000000L, rr7)) + panic_domain(0, "%s: can't set!\n", __func__); +} diff -r 434d71d80272 -r 9c9e526bccb9 xen/arch/ia64/xen/vhpt.c --- a/xen/arch/ia64/xen/vhpt.c Mon Jun 19 20:22:31 2006 +0900 +++ b/xen/arch/ia64/xen/vhpt.c Mon Jun 19 20:48:08 2006 +0900 @@ -153,7 +153,10 @@ void domain_flush_vtlb_all (void) int cpu = smp_processor_id (); struct vcpu *v; - for_each_vcpu (current->domain, v) + for_each_vcpu (current->domain, v) { + if (!test_bit(_VCPUF_initialised, &v->vcpu_flags)) + continue; + if (v->processor == cpu) vcpu_flush_vtlb_all (); else @@ -161,6 +164,7 @@ void domain_flush_vtlb_all (void) (v->processor, (void(*)(void *))vcpu_flush_vtlb_all, NULL,1,1); + } } static void cpu_flush_vhpt_range (int cpu, u64 vadr, u64 addr_range) @@ -198,6 +202,9 @@ void domain_flush_vtlb_range (struct dom #endif for_each_vcpu (d, v) { + if (!test_bit(_VCPUF_initialised, &v->vcpu_flags)) + continue; + /* Purge TC entries. FIXME: clear only if match. */ vcpu_purge_tr_entry(&PSCBX(v,dtlb)); @@ -206,6 +213,9 @@ void domain_flush_vtlb_range (struct dom smp_mb(); for_each_vcpu (d, v) { + if (!test_bit(_VCPUF_initialised, &v->vcpu_flags)) + continue; + /* Invalidate VHPT entries. */ cpu_flush_vhpt_range (v->processor, vadr, addr_range); } diff -r 434d71d80272 -r 9c9e526bccb9 xen/include/asm-ia64/regionreg.h --- a/xen/include/asm-ia64/regionreg.h Mon Jun 19 20:22:31 2006 +0900 +++ b/xen/include/asm-ia64/regionreg.h Mon Jun 19 20:48:08 2006 +0900 @@ -79,5 +79,6 @@ extern int set_metaphysical_rr0(void); extern int set_metaphysical_rr0(void); extern void load_region_regs(struct vcpu *v); +extern void load_region_reg7_and_pta(struct vcpu *v); #endif /* !_REGIONREG_H_ */ diff -r 434d71d80272 -r 9c9e526bccb9 xen/include/asm-ia64/vmx.h --- a/xen/include/asm-ia64/vmx.h Mon Jun 19 20:22:31 2006 +0900 +++ b/xen/include/asm-ia64/vmx.h Mon Jun 19 20:48:08 2006 +0900 @@ -36,7 +36,6 @@ extern void vmx_setup_platform(struct do extern void vmx_setup_platform(struct domain *d, struct vcpu_guest_context *c); extern void vmx_wait_io(void); extern void vmx_io_assist(struct vcpu *v); -extern void vmx_load_all_rr(struct vcpu *vcpu); extern void panic_domain(struct pt_regs *regs, const char *fmt, ...); extern int ia64_hypercall (struct pt_regs *regs); extern void vmx_save_state(struct vcpu *v); diff -r 434d71d80272 -r 9c9e526bccb9 xen/include/asm-ia64/vmx_phy_mode.h --- a/xen/include/asm-ia64/vmx_phy_mode.h Mon Jun 19 20:22:31 2006 +0900 +++ b/xen/include/asm-ia64/vmx_phy_mode.h Mon Jun 19 20:48:08 2006 +0900 @@ -96,6 +96,7 @@ extern void recover_if_physical_mode(VCP extern void recover_if_physical_mode(VCPU *vcpu); extern void vmx_init_all_rr(VCPU *vcpu); extern void vmx_load_all_rr(VCPU *vcpu); +extern void vmx_load_rr7_and_pta(VCPU *vcpu); extern void physical_tlb_miss(VCPU *vcpu, u64 vadr); /* * No sanity check here, since all psr changes have been