ia64/xen-unstable

changeset 17943:eb0fc71cfc72

[IA64] Fix SMP-unsafe with XENMEM_add_to_physmap on HVM

XENMEM_add_to_physmap hypercall on HVM is SMP-unsafe
and may cause a xen crash.
Actually I've met:

(XEN) ia64_fault, vector=0x18, ifa=0xe0000165c98814f0, iip=0xf0000000040a1b80, ipsr=0x0000121008226010, isr=0x0000008000000030
(XEN) General Exception: IA-64 Reserved Register/Field fault (data access).
...
(XEN) ****************************************
(XEN) Panic on CPU 2:
(XEN) Fault in Xen.
(XEN) ****************************************

This patch fixes it.

Signed-off-by: Kouya Shimura <kouya@jp.fujitsu.com>
author Isaku Yamahata <yamahata@valinux.co.jp>
date Tue Jul 08 11:41:43 2008 +0900 (2008-07-08)
parents 00721ef8d8ef
children 400e5d4877ca
files xen/arch/ia64/vmx/vtlb.c xen/arch/ia64/xen/vhpt.c xen/include/asm-ia64/vmmu.h
line diff
     1.1 --- a/xen/arch/ia64/vmx/vtlb.c	Mon Jul 07 10:54:16 2008 +0900
     1.2 +++ b/xen/arch/ia64/vmx/vtlb.c	Tue Jul 08 11:41:43 2008 +0900
     1.3 @@ -623,6 +623,30 @@ void thash_purge_all(VCPU *v)
     1.4      local_flush_tlb_all();
     1.5  }
     1.6  
     1.7 +static void __thash_purge_all(void *arg)
     1.8 +{
     1.9 +    struct vcpu *v = arg;
    1.10 +
    1.11 +    BUG_ON(vcpu_runnable(v) || v->is_running);
    1.12 +    thash_purge_all(v);
    1.13 +}
    1.14 +
    1.15 +void vmx_vcpu_flush_vtlb_all(VCPU *v)
    1.16 +{
    1.17 +    if (v == current) {
    1.18 +        thash_purge_all(v);
    1.19 +        return;
    1.20 +    }
    1.21 +
    1.22 +    /* SMP safe */
    1.23 +    vcpu_pause(v);
    1.24 +    if (v->processor == smp_processor_id())
    1.25 +        __thash_purge_all(v);
    1.26 +    else
    1.27 +        smp_call_function_single(v->processor, __thash_purge_all, v, 1, 1);
    1.28 +    vcpu_unpause(v);
    1.29 +}
    1.30 +
    1.31  
    1.32  /*
    1.33   * Lookup the hash table and its collision chain to find an entry
     2.1 --- a/xen/arch/ia64/xen/vhpt.c	Mon Jul 07 10:54:16 2008 +0900
     2.2 +++ b/xen/arch/ia64/xen/vhpt.c	Tue Jul 08 11:41:43 2008 +0900
     2.3 @@ -249,31 +249,20 @@ domain_purge_swtc_entries_vcpu_dirty_mas
     2.4  // (e.g. vcpu == current), smp_mb() is unnecessary.
     2.5  void vcpu_flush_vtlb_all(struct vcpu *v)
     2.6  {
     2.7 -	if (VMX_DOMAIN(v)) {
     2.8 -		/* This code may be call for remapping shared_info and
     2.9 -		   grant_table share page from guest_physmap_remove_page()
    2.10 -		   in arch_memory_op() XENMEM_add_to_physmap to realize
    2.11 -		   PV-on-HVM feature. */
    2.12 -		/* FIXME: This is not SMP-safe yet about p2m table */
    2.13 -		/* Purge vTLB for VT-i domain */
    2.14 -		thash_purge_all(v);
    2.15 -	}
    2.16 -	else {
    2.17 -		/* First VCPU tlb.  */
    2.18 -		vcpu_purge_tr_entry(&PSCBX(v,dtlb));
    2.19 -		vcpu_purge_tr_entry(&PSCBX(v,itlb));
    2.20 -		smp_mb();
    2.21 +	/* First VCPU tlb.  */
    2.22 +	vcpu_purge_tr_entry(&PSCBX(v,dtlb));
    2.23 +	vcpu_purge_tr_entry(&PSCBX(v,itlb));
    2.24 +	smp_mb();
    2.25  
    2.26 -		/* Then VHPT.  */
    2.27 -		if (HAS_PERVCPU_VHPT(v->domain))
    2.28 -			vcpu_vhpt_flush(v);
    2.29 -		else
    2.30 -			local_vhpt_flush();
    2.31 -		smp_mb();
    2.32 +	/* Then VHPT.  */
    2.33 +	if (HAS_PERVCPU_VHPT(v->domain))
    2.34 +		vcpu_vhpt_flush(v);
    2.35 +	else
    2.36 +		local_vhpt_flush();
    2.37 +	smp_mb();
    2.38  
    2.39 -		/* Then mTLB.  */
    2.40 -		local_flush_tlb_all();
    2.41 -	}
    2.42 +	/* Then mTLB.  */
    2.43 +	local_flush_tlb_all();
    2.44  
    2.45  	/* We could clear bit in d->domain_dirty_cpumask only if domain d in
    2.46  	   not running on this processor.  There is currently no easy way to
    2.47 @@ -297,6 +286,15 @@ void domain_flush_vtlb_all(struct domain
    2.48  		if (!v->is_initialised)
    2.49  			continue;
    2.50  
    2.51 +		if (VMX_DOMAIN(v)) {
    2.52 +			// This code may be called for remapping shared_info
    2.53 +			// and grant_table from guest_physmap_remove_page()
    2.54 +			// in arch_memory_op() XENMEM_add_to_physmap to realize
    2.55 +			// PV-on-HVM feature.
    2.56 +			vmx_vcpu_flush_vtlb_all(v);
    2.57 +			continue;
    2.58 +		}
    2.59 +
    2.60  		if (v->processor == cpu)
    2.61  			vcpu_flush_vtlb_all(v);
    2.62  		else
     3.1 --- a/xen/include/asm-ia64/vmmu.h	Mon Jul 07 10:54:16 2008 +0900
     3.2 +++ b/xen/include/asm-ia64/vmmu.h	Tue Jul 08 11:41:43 2008 +0900
     3.3 @@ -175,6 +175,7 @@ extern int thash_purge_and_insert(struct
     3.4   *
     3.5   */
     3.6  extern void thash_purge_all(struct vcpu *v);
     3.7 +extern void vmx_vcpu_flush_vtlb_all(struct vcpu *v);
     3.8  
     3.9  /*
    3.10   * Lookup the hash table and its collision chain to find an entry