ia64/xen-unstable

changeset 10267:43d9c8042ab6

[IA64] add seqlock to protect vtlb

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author awilliam@xenbuild.aw
date Fri Jun 09 10:35:43 2006 -0600 (2006-06-09)
parents bc76ad9d6270
children 99abd54a02d9
files xen/arch/ia64/xen/domain.c xen/arch/ia64/xen/faults.c xen/arch/ia64/xen/vhpt.c xen/include/asm-ia64/domain.h
line diff
     1.1 --- a/xen/arch/ia64/xen/domain.c	Fri Jun 09 10:35:42 2006 -0600
     1.2 +++ b/xen/arch/ia64/xen/domain.c	Fri Jun 09 10:35:43 2006 -0600
     1.3 @@ -300,6 +300,7 @@ int arch_domain_create(struct domain *d)
     1.4  	d->xen_vaend = XEN_END_ADDR;
     1.5  	d->arch.shared_info_va = SHAREDINFO_ADDR;
     1.6  	d->arch.breakimm = 0x1000;
     1.7 +	seqlock_init(&d->arch.vtlb_lock);
     1.8  
     1.9  	if (is_idle_domain(d))
    1.10  	    return 0;
     2.1 --- a/xen/arch/ia64/xen/faults.c	Fri Jun 09 10:35:42 2006 -0600
     2.2 +++ b/xen/arch/ia64/xen/faults.c	Fri Jun 09 10:35:43 2006 -0600
     2.3 @@ -214,6 +214,8 @@ void ia64_do_page_fault (unsigned long a
     2.4  	// FIXME should validate address here
     2.5  	unsigned long pteval;
     2.6  	unsigned long is_data = !((isr >> IA64_ISR_X_BIT) & 1UL);
     2.7 +	seqlock_t* vtlb_lock = &current->domain->arch.vtlb_lock;
     2.8 +	unsigned long seq;
     2.9  	IA64FAULT fault;
    2.10  
    2.11  	if ((isr & IA64_ISR_IR) && handle_lazy_cover(current, regs)) return;
    2.12 @@ -230,15 +232,15 @@ void ia64_do_page_fault (unsigned long a
    2.13  	}
    2.14  
    2.15   again:
    2.16 +	seq = read_seqbegin(vtlb_lock);
    2.17  	fault = vcpu_translate(current,address,is_data,&pteval,&itir,&iha);
    2.18  	if (fault == IA64_NO_FAULT || fault == IA64_USE_TLB) {
    2.19  		u64 logps;
    2.20  		pteval = translate_domain_pte(pteval, address, itir, &logps);
    2.21  		vcpu_itc_no_srlz(current,is_data?2:1,address,pteval,-1UL,logps);
    2.22 -		if (fault == IA64_USE_TLB && !current->arch.dtlb.pte.p) {
    2.23 -			/* dtlb has been purged in-between.  This dtlb was
    2.24 -			   matching.  Undo the work.  */
    2.25 -			vcpu_flush_tlb_vhpt_range (address, 1);
    2.26 +		if (read_seqretry(vtlb_lock, seq)) {
    2.27 +			vcpu_flush_tlb_vhpt_range(address & ((1 << logps) - 1),
    2.28 +			                          logps);
    2.29  			goto again;
    2.30  		}
    2.31  		return;
     3.1 --- a/xen/arch/ia64/xen/vhpt.c	Fri Jun 09 10:35:42 2006 -0600
     3.2 +++ b/xen/arch/ia64/xen/vhpt.c	Fri Jun 09 10:35:43 2006 -0600
     3.3 @@ -152,7 +152,9 @@ void domain_flush_vtlb_all (void)
     3.4  {
     3.5  	int cpu = smp_processor_id ();
     3.6  	struct vcpu *v;
     3.7 +	seqlock_t* vtlb_lock = &current->domain->arch.vtlb_lock;
     3.8  
     3.9 +	write_seqlock(vtlb_lock);
    3.10  	for_each_vcpu (current->domain, v)
    3.11  		if (v->processor == cpu)
    3.12  			vcpu_flush_vtlb_all ();
    3.13 @@ -161,6 +163,7 @@ void domain_flush_vtlb_all (void)
    3.14  				(v->processor,
    3.15  				 (void(*)(void *))vcpu_flush_vtlb_all,
    3.16  				 NULL,1,1);
    3.17 +	write_sequnlock(vtlb_lock);
    3.18  }
    3.19  
    3.20  static void cpu_flush_vhpt_range (int cpu, u64 vadr, u64 addr_range)
    3.21 @@ -187,6 +190,7 @@ void vcpu_flush_tlb_vhpt_range (u64 vadr
    3.22  
    3.23  void domain_flush_vtlb_range (struct domain *d, u64 vadr, u64 addr_range)
    3.24  {
    3.25 +	seqlock_t* vtlb_lock = &d->arch.vtlb_lock;
    3.26  	struct vcpu *v;
    3.27  
    3.28  #if 0
    3.29 @@ -197,6 +201,7 @@ void domain_flush_vtlb_range (struct dom
    3.30  	}
    3.31  #endif
    3.32  
    3.33 +	write_seqlock(vtlb_lock);
    3.34  	for_each_vcpu (d, v) {
    3.35  		/* Purge TC entries.
    3.36  		   FIXME: clear only if match.  */
    3.37 @@ -213,6 +218,7 @@ void domain_flush_vtlb_range (struct dom
    3.38  
    3.39  	/* ptc.ga  */
    3.40  	ia64_global_tlb_purge(vadr,vadr+addr_range,PAGE_SHIFT);
    3.41 +	write_sequnlock(vtlb_lock);
    3.42  }
    3.43  
    3.44  static void flush_tlb_vhpt_all (struct domain *d)
    3.45 @@ -224,6 +230,8 @@ static void flush_tlb_vhpt_all (struct d
    3.46  	local_flush_tlb_all ();
    3.47  }
    3.48  
    3.49 +// this is called when a domain is destroyed
    3.50 +// so that there is no race.
    3.51  void domain_flush_destroy (struct domain *d)
    3.52  {
    3.53  	/* Very heavy...  */
    3.54 @@ -233,8 +241,10 @@ void domain_flush_destroy (struct domain
    3.55  
    3.56  void flush_tlb_mask(cpumask_t mask)
    3.57  {
    3.58 +    seqlock_t* vtlb_lock = &current->domain->arch.vtlb_lock;
    3.59      int cpu;
    3.60  
    3.61 +    write_seqlock(vtlb_lock);
    3.62      cpu = smp_processor_id();
    3.63      if (cpu_isset (cpu, mask)) {
    3.64          cpu_clear(cpu, mask);
    3.65 @@ -242,11 +252,13 @@ void flush_tlb_mask(cpumask_t mask)
    3.66      }
    3.67  
    3.68      if (cpus_empty(mask))
    3.69 -        return;
    3.70 +        goto out;
    3.71  
    3.72      for_each_cpu_mask (cpu, mask)
    3.73          smp_call_function_single
    3.74              (cpu, (void (*)(void *))flush_tlb_vhpt_all, NULL, 1, 1);
    3.75 +out:
    3.76 +    write_sequnlock(vtlb_lock);
    3.77  }
    3.78  
    3.79  void zero_vhpt_stats(void)
     4.1 --- a/xen/include/asm-ia64/domain.h	Fri Jun 09 10:35:42 2006 -0600
     4.2 +++ b/xen/include/asm-ia64/domain.h	Fri Jun 09 10:35:43 2006 -0600
     4.3 @@ -76,6 +76,9 @@ struct arch_domain {
     4.4      void *efi_runtime;
     4.5      /* Metaphysical address to fpswa_interface_t in domain firmware memory is set. */
     4.6      void *fpswa_inf;
     4.7 +
     4.8 +    // protect v->itlb, v->dtlb and vhpt
     4.9 +    seqlock_t   vtlb_lock ____cacheline_aligned_in_smp;
    4.10  };
    4.11  #define xen_vastart arch.xen_vastart
    4.12  #define xen_vaend arch.xen_vaend