ia64/xen-unstable

diff xen/arch/ia64/xen/faults.c @ 10786:86e5d8458c08

[IA64] live migration

Shadow mode and live migration.

Virtualize Dirty bit.

Signed-off-by: Tristan Gingold <tristan.gingold@bull.net>
author awilliam@xenbuild.aw
date Wed Jul 26 09:36:36 2006 -0600 (2006-07-26)
parents c8bc76d877e0
children 3d6c1af609bf
line diff
     1.1 --- a/xen/arch/ia64/xen/faults.c	Wed Jul 26 09:02:43 2006 -0600
     1.2 +++ b/xen/arch/ia64/xen/faults.c	Wed Jul 26 09:36:36 2006 -0600
     1.3 @@ -1,4 +1,3 @@
     1.4 -
     1.5  /*
     1.6   * Miscellaneous process/domain related routines
     1.7   * 
     1.8 @@ -29,6 +28,7 @@
     1.9  #include <asm/bundle.h>
    1.10  #include <asm/privop_stat.h>
    1.11  #include <asm/asm-xsi-offsets.h>
    1.12 +#include <asm/shadow.h>
    1.13  
    1.14  extern void die_if_kernel(char *str, struct pt_regs *regs, long err);
    1.15  /* FIXME: where these declarations shold be there ? */
    1.16 @@ -648,3 +648,92 @@ ia64_handle_reflection (unsigned long if
    1.17  	reflect_interruption(isr,regs,vector);
    1.18  }
    1.19  
    1.20 +void
    1.21 +ia64_shadow_fault(unsigned long ifa, unsigned long itir,
    1.22 +                  unsigned long isr, struct pt_regs *regs)
    1.23 +{
    1.24 +	struct vcpu *v = current;
    1.25 +	struct domain *d = current->domain;
    1.26 +	unsigned long gpfn;
    1.27 +	unsigned long pte = 0;
    1.28 +	struct vhpt_lf_entry *vlfe;
    1.29 +
    1.30 +	/* There are 2 jobs to do:
    1.31 +	   -  marking the page as dirty (the metaphysical address must be
    1.32 +	      extracted to do that).
    1.33 +	   -  reflecting or not the fault (the virtual Dirty bit must be
    1.34 +	      extracted to decide).
    1.35 +	   Unfortunatly these informations are not immediatly available!
    1.36 +	*/
    1.37 +
    1.38 +	/* Extract the metaphysical address.
    1.39 +	   Try to get it from VHPT and M2P as we need the flags.  */
    1.40 +	vlfe = (struct vhpt_lf_entry *)ia64_thash(ifa);
    1.41 +	pte = vlfe->page_flags;
    1.42 +	if (vlfe->ti_tag == ia64_ttag(ifa)) {
    1.43 +		/* The VHPT entry is valid.  */
    1.44 +		gpfn = get_gpfn_from_mfn((pte & _PAGE_PPN_MASK) >> PAGE_SHIFT);
    1.45 +		BUG_ON(gpfn == INVALID_M2P_ENTRY);
    1.46 +	}
    1.47 +	else {
    1.48 +		unsigned long itir, iha;
    1.49 +		IA64FAULT fault;
    1.50 +
    1.51 +		/* The VHPT entry is not valid.  */
    1.52 +		vlfe = NULL;
    1.53 +
    1.54 +		/* FIXME: gives a chance to tpa, as the TC was valid.  */
    1.55 +
    1.56 +		fault = vcpu_translate(v, ifa, 1, &pte, &itir, &iha);
    1.57 +
    1.58 +		/* Try again!  */
    1.59 +		if (fault != IA64_NO_FAULT) {
    1.60 +			/* This will trigger a dtlb miss.  */
    1.61 +			ia64_ptcl(ifa, PAGE_SHIFT << 2);
    1.62 +			return;
    1.63 +		}
    1.64 +		gpfn = ((pte & _PAGE_PPN_MASK) >> PAGE_SHIFT);
    1.65 +		if (pte & _PAGE_D)
    1.66 +			pte |= _PAGE_VIRT_D;
    1.67 +	}
    1.68 +
    1.69 +	/* Set the dirty bit in the bitmap.  */
    1.70 +	shadow_mark_page_dirty (d, gpfn);
    1.71 +
    1.72 +	/* Update the local TC/VHPT and decides wether or not the fault should
    1.73 +	   be reflected.
    1.74 +	   SMP note: we almost ignore the other processors.  The shadow_bitmap
    1.75 +	   has been atomically updated.  If the dirty fault happen on another
    1.76 +	   processor, it will do its job.
    1.77 +	*/
    1.78 +
    1.79 +	if (pte != 0) {
    1.80 +		/* We will know how to handle the fault.  */
    1.81 +
    1.82 +		if (pte & _PAGE_VIRT_D) {
    1.83 +			/* Rewrite VHPT entry.
    1.84 +			   There is no race here because only the
    1.85 +			   cpu VHPT owner can write page_flags.  */
    1.86 +			if (vlfe)
    1.87 +				vlfe->page_flags = pte | _PAGE_D;
    1.88 +			
    1.89 +			/* Purge the TC locally.
    1.90 +			   It will be reloaded from the VHPT iff the
    1.91 +			   VHPT entry is still valid.  */
    1.92 +			ia64_ptcl(ifa, PAGE_SHIFT << 2);
    1.93 +
    1.94 +			atomic64_inc(&d->arch.shadow_fault_count);
    1.95 +		}
    1.96 +		else {
    1.97 +			/* Reflect.
    1.98 +			   In this case there is no need to purge.  */
    1.99 +			ia64_handle_reflection(ifa, regs, isr, 0, 8);
   1.100 +		}
   1.101 +	}
   1.102 +	else {
   1.103 +		/* We don't know wether or not the fault must be
   1.104 +		   reflected.  The VHPT entry is not valid.  */
   1.105 +		/* FIXME: in metaphysical mode, we could do an ITC now.  */
   1.106 +		ia64_ptcl(ifa, PAGE_SHIFT << 2);
   1.107 +	}
   1.108 +}