ia64/xen-unstable

changeset 10430:ea306829506c

[IA64] fix ptc.ga virtualization

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.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author awilliam@xenbuild.aw
date Mon Jun 19 13:45:42 2006 -0600 (2006-06-19)
parents 602f5965e217
children c974a6e3f517
files xen/arch/ia64/vmx/vmmu.c xen/arch/ia64/vmx/vmx_phy_mode.c xen/arch/ia64/vmx/vtlb.c xen/arch/ia64/xen/regionreg.c xen/arch/ia64/xen/vhpt.c xen/include/asm-ia64/regionreg.h xen/include/asm-ia64/vmx.h xen/include/asm-ia64/vmx_phy_mode.h
line diff
     1.1 --- a/xen/arch/ia64/vmx/vmmu.c	Mon Jun 19 13:42:34 2006 -0600
     1.2 +++ b/xen/arch/ia64/vmx/vmmu.c	Mon Jun 19 13:45:42 2006 -0600
     1.3 @@ -544,6 +544,9 @@ IA64FAULT vmx_vcpu_ptc_ga(VCPU *vcpu,UIN
     1.4      vcpu_get_rr(vcpu, va, &args.rid);
     1.5      args.ps = ps;
     1.6      for_each_vcpu (d, v) {
     1.7 +        if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
     1.8 +            continue;
     1.9 +
    1.10          args.vcpu = v;
    1.11          if (v->processor != vcpu->processor) {
    1.12              int proc;
     2.1 --- a/xen/arch/ia64/vmx/vmx_phy_mode.c	Mon Jun 19 13:42:34 2006 -0600
     2.2 +++ b/xen/arch/ia64/vmx/vmx_phy_mode.c	Mon Jun 19 13:45:42 2006 -0600
     2.3 @@ -137,13 +137,14 @@ vmx_init_all_rr(VCPU *vcpu)
     2.4  #endif
     2.5  }
     2.6  
     2.7 +extern void * pal_vaddr;
     2.8 +
     2.9  void
    2.10  vmx_load_all_rr(VCPU *vcpu)
    2.11  {
    2.12  	unsigned long psr;
    2.13  	ia64_rr phy_rr;
    2.14  
    2.15 -	extern void * pal_vaddr;
    2.16  	local_irq_save(psr);
    2.17  
    2.18  
    2.19 @@ -204,6 +205,24 @@ vmx_load_all_rr(VCPU *vcpu)
    2.20  }
    2.21  
    2.22  void
    2.23 +vmx_load_rr7_and_pta(VCPU *vcpu)
    2.24 +{
    2.25 +	unsigned long psr;
    2.26 +
    2.27 +	local_irq_save(psr);
    2.28 +
    2.29 +	vmx_switch_rr7(vrrtomrr(vcpu,VMX(vcpu, vrr[VRN7])),
    2.30 +			(void *)vcpu->domain->shared_info,
    2.31 +			(void *)vcpu->arch.privregs,
    2.32 +			(void *)vcpu->arch.vhpt.hash, pal_vaddr );
    2.33 +	ia64_set_pta(vcpu->arch.arch_vmx.mpta);
    2.34 +
    2.35 +	ia64_srlz_d();
    2.36 +	local_irq_restore(psr);
    2.37 +	ia64_srlz_i();
    2.38 +}
    2.39 +
    2.40 +void
    2.41  switch_to_physical_rid(VCPU *vcpu)
    2.42  {
    2.43      UINT64 psr;
     3.1 --- a/xen/arch/ia64/vmx/vtlb.c	Mon Jun 19 13:42:34 2006 -0600
     3.2 +++ b/xen/arch/ia64/vmx/vtlb.c	Mon Jun 19 13:45:42 2006 -0600
     3.3 @@ -28,8 +28,10 @@
     3.4  #include <asm/gcc_intrin.h>
     3.5  #include <linux/interrupt.h>
     3.6  #include <asm/vmx_vcpu.h>
     3.7 +#include <asm/vmx_phy_mode.h>
     3.8  #include <asm/vmmu.h>
     3.9  #include <asm/tlbflush.h>
    3.10 +#include <asm/regionreg.h>
    3.11  #define  MAX_CCH_LENGTH     40
    3.12  
    3.13  thash_data_t *__alloc_chain(thash_cb_t *);
    3.14 @@ -229,12 +231,13 @@ u64 guest_vhpt_lookup(u64 iha, u64 *pte)
    3.15   *  purge software guest tlb
    3.16   */
    3.17  
    3.18 -static void vtlb_purge(thash_cb_t *hcb, u64 va, u64 ps)
    3.19 +static void vtlb_purge(VCPU *v, u64 va, u64 ps)
    3.20  {
    3.21 +    thash_cb_t *hcb = &v->arch.vtlb;
    3.22      thash_data_t *hash_table, *prev, *next;
    3.23      u64 start, end, size, tag, rid, def_size;
    3.24      ia64_rr vrr;
    3.25 -    vcpu_get_rr(current, va, &vrr.rrval);
    3.26 +    vcpu_get_rr(v, va, &vrr.rrval);
    3.27      rid = vrr.rid;
    3.28      size = PSIZE(ps);
    3.29      start = va & (-size);
    3.30 @@ -263,16 +266,29 @@ static void vtlb_purge(thash_cb_t *hcb, 
    3.31      }
    3.32  //    machine_tlb_purge(va, ps);
    3.33  }
    3.34 +
    3.35 +static void
    3.36 +switch_rr7_and_pta(VCPU* v)
    3.37 +{
    3.38 +    if (VMX_DOMAIN(v))
    3.39 +        vmx_load_rr7_and_pta(v);
    3.40 +    else
    3.41 +        load_region_reg7_and_pta(v);
    3.42 +}
    3.43 +
    3.44  /*
    3.45   *  purge VHPT and machine TLB
    3.46   */
    3.47 -static void vhpt_purge(thash_cb_t *hcb, u64 va, u64 ps)
    3.48 +static void vhpt_purge(VCPU *v, u64 va, u64 ps)
    3.49  {
    3.50 +    //thash_cb_t *hcb = &v->arch.vhpt;
    3.51      thash_data_t *hash_table, *prev, *next;
    3.52      u64 start, end, size, tag;
    3.53      size = PSIZE(ps);
    3.54      start = va & (-size);
    3.55      end = start + size;
    3.56 +    if (current != v)
    3.57 +        switch_rr7_and_pta(v);
    3.58      while(start < end){
    3.59          hash_table = (thash_data_t *)ia64_thash(start);
    3.60          tag = ia64_ttag(start);
    3.61 @@ -294,6 +310,8 @@ static void vhpt_purge(thash_cb_t *hcb, 
    3.62          start += PAGE_SIZE;
    3.63      }
    3.64      machine_tlb_purge(va, ps);
    3.65 +    if (current != v)
    3.66 +        switch_rr7_and_pta(current);
    3.67  }
    3.68  
    3.69  /*
    3.70 @@ -413,8 +431,8 @@ int vtr_find_overlap(VCPU *vcpu, u64 va,
    3.71  void thash_purge_entries(VCPU *v, u64 va, u64 ps)
    3.72  {
    3.73      if(vcpu_quick_region_check(v->arch.tc_regions,va))
    3.74 -        vtlb_purge(&v->arch.vtlb, va, ps);
    3.75 -    vhpt_purge(&v->arch.vhpt, va, ps);
    3.76 +        vtlb_purge(v, va, ps);
    3.77 +    vhpt_purge(v, va, ps);
    3.78  }
    3.79  
    3.80  u64 translate_phy_pte(VCPU *v, u64 *pte, u64 itir, u64 va)
    3.81 @@ -456,17 +474,17 @@ void thash_purge_and_insert(VCPU *v, u64
    3.82          phy_pte = translate_phy_pte(v, &pte, itir, ifa);
    3.83          if(ps==PAGE_SHIFT){
    3.84              if(!(pte&VTLB_PTE_IO)){
    3.85 -                vhpt_purge(&v->arch.vhpt, ifa, ps);
    3.86 +                vhpt_purge(v, ifa, ps);
    3.87                  vmx_vhpt_insert(&v->arch.vhpt, phy_pte, itir, ifa);
    3.88              }
    3.89              else{
    3.90 -                vhpt_purge(&v->arch.vhpt, ifa, ps);
    3.91 +                vhpt_purge(v, ifa, ps);
    3.92                  vtlb_insert(&v->arch.vtlb, pte, itir, ifa);
    3.93                  vcpu_quick_region_set(PSCBX(v,tc_regions),ifa);
    3.94              }
    3.95          }
    3.96          else{
    3.97 -            vhpt_purge(&v->arch.vhpt, ifa, ps);
    3.98 +            vhpt_purge(v, ifa, ps);
    3.99              vtlb_insert(&v->arch.vtlb, pte, itir, ifa);
   3.100              vcpu_quick_region_set(PSCBX(v,tc_regions),ifa);
   3.101              if(!(pte&VTLB_PTE_IO)){
     4.1 --- a/xen/arch/ia64/xen/regionreg.c	Mon Jun 19 13:42:34 2006 -0600
     4.2 +++ b/xen/arch/ia64/xen/regionreg.c	Mon Jun 19 13:45:42 2006 -0600
     4.3 @@ -342,3 +342,16 @@ void load_region_regs(struct vcpu *v)
     4.4  		panic_domain(0,"load_region_regs: can't set! bad=%lx\n",bad);
     4.5  	}
     4.6  }
     4.7 +
     4.8 +void load_region_reg7_and_pta(struct vcpu *v)
     4.9 +{
    4.10 +	unsigned long rr7;
    4.11 +
    4.12 +	ia64_set_pta(VHPT_ADDR | (1 << 8) | (VHPT_SIZE_LOG2 << 2) |
    4.13 +		     VHPT_ENABLED);
    4.14 +
    4.15 +	// TODO: These probably should be validated
    4.16 +	rr7 =  VCPU(v,rrs[7]);
    4.17 +	if (!set_one_rr(0xe000000000000000L, rr7))
    4.18 +		panic_domain(0, "%s: can't set!\n", __func__);
    4.19 +}
     5.1 --- a/xen/arch/ia64/xen/vhpt.c	Mon Jun 19 13:42:34 2006 -0600
     5.2 +++ b/xen/arch/ia64/xen/vhpt.c	Mon Jun 19 13:45:42 2006 -0600
     5.3 @@ -153,7 +153,10 @@ void domain_flush_vtlb_all (void)
     5.4  	int cpu = smp_processor_id ();
     5.5  	struct vcpu *v;
     5.6  
     5.7 -	for_each_vcpu (current->domain, v)
     5.8 +	for_each_vcpu (current->domain, v) {
     5.9 +		if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
    5.10 +			continue;
    5.11 +
    5.12  		if (v->processor == cpu)
    5.13  			vcpu_flush_vtlb_all ();
    5.14  		else
    5.15 @@ -161,6 +164,7 @@ void domain_flush_vtlb_all (void)
    5.16  				(v->processor,
    5.17  				 (void(*)(void *))vcpu_flush_vtlb_all,
    5.18  				 NULL,1,1);
    5.19 +	}
    5.20  }
    5.21  
    5.22  static void cpu_flush_vhpt_range (int cpu, u64 vadr, u64 addr_range)
    5.23 @@ -198,6 +202,9 @@ void domain_flush_vtlb_range (struct dom
    5.24  #endif
    5.25  
    5.26  	for_each_vcpu (d, v) {
    5.27 +		if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
    5.28 +			continue;
    5.29 +
    5.30  		/* Purge TC entries.
    5.31  		   FIXME: clear only if match.  */
    5.32  		vcpu_purge_tr_entry(&PSCBX(v,dtlb));
    5.33 @@ -206,6 +213,9 @@ void domain_flush_vtlb_range (struct dom
    5.34  	smp_mb();
    5.35  
    5.36  	for_each_vcpu (d, v) {
    5.37 +		if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
    5.38 +			continue;
    5.39 +
    5.40  		/* Invalidate VHPT entries.  */
    5.41  		cpu_flush_vhpt_range (v->processor, vadr, addr_range);
    5.42  	}
     6.1 --- a/xen/include/asm-ia64/regionreg.h	Mon Jun 19 13:42:34 2006 -0600
     6.2 +++ b/xen/include/asm-ia64/regionreg.h	Mon Jun 19 13:45:42 2006 -0600
     6.3 @@ -79,5 +79,6 @@ extern void init_all_rr(struct vcpu *v);
     6.4  extern int set_metaphysical_rr0(void);
     6.5  
     6.6  extern void load_region_regs(struct vcpu *v);
     6.7 +extern void load_region_reg7_and_pta(struct vcpu *v);
     6.8  
     6.9  #endif		/* !_REGIONREG_H_ */
     7.1 --- a/xen/include/asm-ia64/vmx.h	Mon Jun 19 13:42:34 2006 -0600
     7.2 +++ b/xen/include/asm-ia64/vmx.h	Mon Jun 19 13:45:42 2006 -0600
     7.3 @@ -37,7 +37,6 @@ extern void vmx_load_state(struct vcpu *
     7.4  extern void vmx_setup_platform(struct domain *d, struct vcpu_guest_context *c);
     7.5  extern void vmx_wait_io(void);
     7.6  extern void vmx_io_assist(struct vcpu *v);
     7.7 -extern void vmx_load_all_rr(struct vcpu *vcpu);
     7.8  extern void panic_domain(struct pt_regs *regs, const char *fmt, ...);
     7.9  extern int ia64_hypercall (struct pt_regs *regs);
    7.10  extern void vmx_save_state(struct vcpu *v);
     8.1 --- a/xen/include/asm-ia64/vmx_phy_mode.h	Mon Jun 19 13:42:34 2006 -0600
     8.2 +++ b/xen/include/asm-ia64/vmx_phy_mode.h	Mon Jun 19 13:45:42 2006 -0600
     8.3 @@ -96,6 +96,7 @@ extern void prepare_if_physical_mode(VCP
     8.4  extern void recover_if_physical_mode(VCPU *vcpu);
     8.5  extern void vmx_init_all_rr(VCPU *vcpu);
     8.6  extern void vmx_load_all_rr(VCPU *vcpu);
     8.7 +extern void vmx_load_rr7_and_pta(VCPU *vcpu);
     8.8  extern void physical_tlb_miss(VCPU *vcpu, u64 vadr);
     8.9  /*
    8.10   * No sanity check here, since all psr changes have been