ia64/xen-unstable

changeset 18084:0b72d16e794b

[IA64] kexec: Unpin the correct VHPT TR in ia64_do_tlb_purge

GET_VA_VCPU_VHPT_MADDR(r2,r3) does not give the value of the VHPT
pinned into the TLB. I believe that this is because
current is changed between pinning and calling play_dead,
though I am not sure of the exact scemantics.

In any case, by recording the pinned value in a percpu variable,
and unpinning this value, the TR entry is removed and all is well.

Cc: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Simon Horman <horms@verge.net.au>
author Isaku Yamahata <yamahata@valinux.co.jp>
date Tue Jul 22 12:15:02 2008 +0900 (2008-07-22)
parents b2d2bc30a04b
children 4f0428e4dd15
files xen/arch/ia64/linux-xen/mca_asm.S xen/arch/ia64/vmx/vmx_vcpu.c xen/arch/ia64/xen/regionreg.c xen/include/asm-ia64/regionreg.h
line diff
     1.1 --- a/xen/arch/ia64/linux-xen/mca_asm.S	Tue Jul 22 12:15:02 2008 +0900
     1.2 +++ b/xen/arch/ia64/linux-xen/mca_asm.S	Tue Jul 22 12:15:02 2008 +0900
     1.3 @@ -321,8 +321,13 @@ 4:
     1.4  	;;
     1.5  #ifdef XEN
     1.6  	// 5. VHPT
     1.7 -#if VHPT_ENABLED
     1.8 -	GET_VA_VCPU_VHPT_MADDR(r2,r3);;
     1.9 +	// GET_VA_VCPU_VHPT_MADDR() may not give the
    1.10 +	// value of the VHPT currently pinned into the TLB
    1.11 +	GET_THIS_PADDR(r2, inserted_vhpt);;
    1.12 +	;;
    1.13 +	cmp.eq p7,p0=r2,r0
    1.14 +	;;
    1.15 +(p7)	br.cond.sptk .vhpt_not_mapped
    1.16  	dep r16=0,r2,0,IA64_GRANULE_SHIFT
    1.17  	mov r18=IA64_GRANULE_SHIFT<<2
    1.18  	;;
    1.19 @@ -330,7 +335,7 @@ 4:
    1.20  	;;
    1.21  	srlz.d
    1.22  	;;
    1.23 -#endif
    1.24 +.vhpt_not_mapped:
    1.25  #endif
    1.26  	// Now branch away to caller.
    1.27  	br.sptk.many b1
     2.1 --- a/xen/arch/ia64/vmx/vmx_vcpu.c	Tue Jul 22 12:15:02 2008 +0900
     2.2 +++ b/xen/arch/ia64/vmx/vmx_vcpu.c	Tue Jul 22 12:15:02 2008 +0900
     2.3 @@ -199,6 +199,7 @@ void vmx_vcpu_set_rr_fast(VCPU *vcpu, u6
     2.4  void vmx_switch_rr7(unsigned long rid, void *guest_vhpt,
     2.5                      void *pal_vaddr, void *shared_arch_info)
     2.6  {
     2.7 +    __get_cpu_var(inserted_vhpt) = (unsigned long)guest_vhpt;
     2.8      __vmx_switch_rr7(rid, guest_vhpt, pal_vaddr, shared_arch_info);
     2.9  }
    2.10  
     3.1 --- a/xen/arch/ia64/xen/regionreg.c	Tue Jul 22 12:15:02 2008 +0900
     3.2 +++ b/xen/arch/ia64/xen/regionreg.c	Tue Jul 22 12:15:02 2008 +0900
     3.3 @@ -15,6 +15,7 @@
     3.4  #include <asm/regionreg.h>
     3.5  #include <asm/vhpt.h>
     3.6  #include <asm/vcpu.h>
     3.7 +#include <asm/percpu.h>
     3.8  
     3.9  /* Defined in xemasm.S  */
    3.10  extern void ia64_new_rr7(unsigned long rid, void *shared_info, void *shared_arch_info, unsigned long shared_info_va, unsigned long va_vhpt);
    3.11 @@ -47,6 +48,8 @@ extern void ia64_new_rr7(unsigned long r
    3.12  static unsigned int domain_rid_bits_default = IA64_MIN_IMPL_RID_BITS;
    3.13  integer_param("dom_rid_bits", domain_rid_bits_default); 
    3.14  
    3.15 +DEFINE_PER_CPU(unsigned long, inserted_vhpt);
    3.16 +
    3.17  #if 0
    3.18  // following already defined in include/asm-ia64/gcc_intrin.h
    3.19  // it should probably be ifdef'd out from there to ensure all region
    3.20 @@ -260,6 +263,9 @@ int set_one_rr(unsigned long rr, unsigne
    3.21  		if (!PSCB(v,metaphysical_mode))
    3.22  			set_rr(rr,newrrv.rrval);
    3.23  	} else if (rreg == 7) {
    3.24 +#if VHPT_ENABLED
    3.25 +		__get_cpu_var(inserted_vhpt) = __va_ul(vcpu_vhpt_maddr(v));
    3.26 +#endif
    3.27  		ia64_new_rr7(vmMangleRID(newrrv.rrval),v->domain->shared_info,
    3.28  			     v->arch.privregs, v->domain->arch.shared_info_va,
    3.29  		             __va_ul(vcpu_vhpt_maddr(v)));
     4.1 --- a/xen/include/asm-ia64/regionreg.h	Tue Jul 22 12:15:02 2008 +0900
     4.2 +++ b/xen/include/asm-ia64/regionreg.h	Tue Jul 22 12:15:02 2008 +0900
     4.3 @@ -36,6 +36,7 @@ typedef union ia64_rr {
     4.4  #define RR_RID(arg)     (((arg) & 0x0000000000ffffff) << 8)
     4.5  #define RR_RID_MASK     0x00000000ffffff00L
     4.6  
     4.7 +DECLARE_PER_CPU(unsigned long, inserted_vhpt);
     4.8  
     4.9  int set_one_rr(unsigned long rr, unsigned long val);
    4.10