ia64/xen-unstable

changeset 14780:fb0463b6094d

[HAP] Install P2M entries in monitor table under PAE mode
This patch installs P2M table entries in monitor table when Xen is
running under PAE mode. Without it, hypervisor might have trouble of
accessing guests' high memory.

Signed-off-by: Wei Huang <wei.huang2@amd.com>
author "Huang2, Wei" <Wei.Huang2@amd.com>
date Tue Apr 10 10:26:31 2007 +0100 (2007-04-10)
parents 400a3dca237e
children e51e99c5b10e
files xen/arch/x86/mm/hap/hap.c
line diff
     1.1 --- a/xen/arch/x86/mm/hap/hap.c	Mon Apr 09 12:05:26 2007 +0100
     1.2 +++ b/xen/arch/x86/mm/hap/hap.c	Tue Apr 10 10:26:31 2007 +0100
     1.3 @@ -443,6 +443,7 @@ void hap_final_teardown(struct domain *d
     1.4          hap_teardown(d);
     1.5  
     1.6      p2m_teardown(d);
     1.7 +    ASSERT( d->arch.paging.hap.p2m_pages == 0 );
     1.8  }
     1.9  
    1.10  void hap_teardown(struct domain *d)
    1.11 @@ -635,12 +636,60 @@ void hap_update_paging_modes(struct vcpu
    1.12      hap_unlock(d);
    1.13  }
    1.14  
    1.15 +#if CONFIG_PAGING_LEVELS == 3
    1.16 +static void p2m_install_entry_in_monitors(struct domain *d, l3_pgentry_t *l3e) 
    1.17 +/* Special case, only used for external-mode domains on PAE hosts:
    1.18 + * update the mapping of the p2m table.  Once again, this is trivial in
    1.19 + * other paging modes (one top-level entry points to the top-level p2m,
    1.20 + * no maintenance needed), but PAE makes life difficult by needing a
    1.21 + * copy l3es of the p2m table in eight l2h slots in the monitor table.  This 
    1.22 + * function makes fresh copies when a p2m l3e changes. */
    1.23 +{
    1.24 +    l2_pgentry_t *ml2e;
    1.25 +    struct vcpu *v;
    1.26 +    unsigned int index;
    1.27 +    
    1.28 +    index = ((unsigned long)l3e & ~PAGE_MASK) / sizeof(l3_pgentry_t);
    1.29 +    ASSERT(index < MACHPHYS_MBYTES>>1);
    1.30 +    
    1.31 +    for_each_vcpu(d, v) {
    1.32 +	if ( pagetable_get_pfn(v->arch.monitor_table) == 0 ) 
    1.33 +	    continue;
    1.34 +
    1.35 +	ASSERT(paging_mode_external(v->domain));
    1.36 +
    1.37 +        if ( v == current ) /* OK to use linear map of monitor_table */
    1.38 +	    ml2e = __linear_l2_table + l2_linear_offset(RO_MPT_VIRT_START);
    1.39 +        else {
    1.40 +	    l3_pgentry_t *ml3e;
    1.41 +            ml3e = hap_map_domain_page(pagetable_get_mfn(v->arch.monitor_table));
    1.42 +	    ASSERT(l3e_get_flags(ml3e[3]) & _PAGE_PRESENT);
    1.43 +            ml2e = hap_map_domain_page(_mfn(l3e_get_pfn(ml3e[3])));
    1.44 +            ml2e += l2_table_offset(RO_MPT_VIRT_START);
    1.45 +	    hap_unmap_domain_page(ml3e);
    1.46 +        }
    1.47 +	ml2e[index] = l2e_from_pfn(l3e_get_pfn(*l3e), __PAGE_HYPERVISOR);
    1.48 +        if ( v != current )
    1.49 +            hap_unmap_domain_page(ml2e);
    1.50 +    }
    1.51 +}
    1.52 +#endif
    1.53 +
    1.54  void 
    1.55  hap_write_p2m_entry(struct vcpu *v, unsigned long gfn, l1_pgentry_t *p,
    1.56                      l1_pgentry_t new, unsigned int level)
    1.57  {
    1.58      hap_lock(v->domain);
    1.59      safe_write_pte(p, new);
    1.60 +#if CONFIG_PAGING_LEVELS == 3
    1.61 +    /* install P2M in monitor table for PAE Xen */
    1.62 +    if ( level == 3 ) {
    1.63 +	/* We have written to the p2m l3: need to sync the per-vcpu
    1.64 +         * copies of it in the monitor tables */
    1.65 +	p2m_install_entry_in_monitors(v->domain, (l3_pgentry_t *)p);
    1.66 +	
    1.67 +    }
    1.68 +#endif
    1.69      hap_unlock(v->domain);
    1.70  }
    1.71