ia64/xen-unstable
changeset 12475:11a93cc59159
[XEN] Track high-water-mark of p2m map
and so avoid some unnecessary __copy_from_user faults.
Also tidy the p2m functions generally.
Signed-off-by: Tim Deegan <Tim.Deegan@xensource.com>
and so avoid some unnecessary __copy_from_user faults.
Also tidy the p2m functions generally.
Signed-off-by: Tim Deegan <Tim.Deegan@xensource.com>
author | Tim Deegan <Tim.Deegan@xensource.com> |
---|---|
date | Wed Nov 15 14:36:10 2006 +0000 (2006-11-15) |
parents | 6e22ba721720 |
children | 85f331c7af76 |
files | xen/arch/x86/mm/shadow/common.c xen/arch/x86/mm/shadow/types.h xen/include/asm-x86/domain.h xen/include/asm-x86/hvm/io.h xen/include/asm-x86/mm.h xen/include/asm-x86/shadow.h |
line diff
1.1 --- a/xen/arch/x86/mm/shadow/common.c Wed Nov 15 09:44:12 2006 +0000 1.2 +++ b/xen/arch/x86/mm/shadow/common.c Wed Nov 15 14:36:10 2006 +0000 1.3 @@ -1047,6 +1047,10 @@ shadow_set_p2m_entry(struct domain *d, u 1.4 else 1.5 *p2m_entry = l1e_empty(); 1.6 1.7 + /* Track the highest gfn for which we have ever had a valid mapping */ 1.8 + if ( valid_mfn(mfn) && (gfn > d->arch.max_mapped_pfn) ) 1.9 + d->arch.max_mapped_pfn = gfn; 1.10 + 1.11 /* The P2M can be shadowed: keep the shadows synced */ 1.12 if ( d->vcpu[0] != NULL ) 1.13 (void)__shadow_validate_guest_entry( 1.14 @@ -1142,12 +1146,9 @@ sh_gfn_to_mfn_foreign(struct domain *d, 1.15 mfn = pagetable_get_mfn(d->arch.phys_table); 1.16 1.17 1.18 -#if CONFIG_PAGING_LEVELS > 2 1.19 - if ( gpfn >= (RO_MPT_VIRT_END-RO_MPT_VIRT_START) / sizeof(l1_pgentry_t) ) 1.20 - /* This pfn is higher than the p2m map can hold */ 1.21 + if ( gpfn > d->arch.max_mapped_pfn ) 1.22 + /* This pfn is higher than the highest the p2m map currently holds */ 1.23 return _mfn(INVALID_MFN); 1.24 -#endif 1.25 - 1.26 1.27 #if CONFIG_PAGING_LEVELS >= 4 1.28 { 1.29 @@ -3333,13 +3334,14 @@ void shadow_audit_p2m(struct domain *d) 1.30 set_gpfn_from_mfn(mfn, INVALID_M2P_ENTRY); 1.31 } 1.32 1.33 - if ( test_linear ) 1.34 + if ( test_linear && (gfn <= d->arch.max_mapped_pfn) ) 1.35 { 1.36 - lp2mfn = get_mfn_from_gpfn(gfn); 1.37 - if ( lp2mfn != mfn_x(p2mfn) ) 1.38 + lp2mfn = gfn_to_mfn_current(gfn); 1.39 + if ( mfn_x(lp2mfn) != mfn_x(p2mfn) ) 1.40 { 1.41 SHADOW_PRINTK("linear mismatch gfn %#lx -> mfn %#lx " 1.42 - "(!= mfn %#lx)\n", gfn, lp2mfn, p2mfn); 1.43 + "(!= mfn %#lx)\n", gfn, 1.44 + mfn_x(lp2mfn), mfn_x(p2mfn)); 1.45 } 1.46 } 1.47
2.1 --- a/xen/arch/x86/mm/shadow/types.h Wed Nov 15 09:44:12 2006 +0000 2.2 +++ b/xen/arch/x86/mm/shadow/types.h Wed Nov 15 14:36:10 2006 +0000 2.3 @@ -416,9 +416,7 @@ vcpu_gfn_to_mfn(struct vcpu *v, gfn_t gf 2.4 { 2.5 if ( !shadow_vcpu_mode_translate(v) ) 2.6 return _mfn(gfn_x(gfn)); 2.7 - if ( likely(current->domain == v->domain) ) 2.8 - return _mfn(get_mfn_from_gpfn(gfn_x(gfn))); 2.9 - return sh_gfn_to_mfn_foreign(v->domain, gfn_x(gfn)); 2.10 + return sh_gfn_to_mfn(v->domain, gfn_x(gfn)); 2.11 } 2.12 2.13 static inline gfn_t
3.1 --- a/xen/include/asm-x86/domain.h Wed Nov 15 09:44:12 2006 +0000 3.2 +++ b/xen/include/asm-x86/domain.h Wed Nov 15 14:36:10 2006 +0000 3.3 @@ -111,6 +111,8 @@ struct arch_domain 3.4 3.5 /* Shadow translated domain: P2M mapping */ 3.6 pagetable_t phys_table; 3.7 + /* Highest guest frame that's ever been mapped in the p2m */ 3.8 + unsigned long max_mapped_pfn; 3.9 3.10 } __cacheline_aligned; 3.11
4.1 --- a/xen/include/asm-x86/hvm/io.h Wed Nov 15 09:44:12 2006 +0000 4.2 +++ b/xen/include/asm-x86/hvm/io.h Wed Nov 15 14:36:10 2006 +0000 4.3 @@ -151,8 +151,5 @@ extern void pic_irq_request(void *data, 4.4 extern int cpu_get_interrupt(struct vcpu *v, int *type); 4.5 extern int cpu_has_pending_irq(struct vcpu *v); 4.6 4.7 -// XXX - think about this, maybe use bit 30 of the mfn to signify an MMIO frame. 4.8 -#define mmio_space(gpa) (!VALID_MFN(get_mfn_from_gpfn((gpa) >> PAGE_SHIFT))) 4.9 - 4.10 #endif /* __ASM_X86_HVM_IO_H__ */ 4.11
5.1 --- a/xen/include/asm-x86/mm.h Wed Nov 15 09:44:12 2006 +0000 5.2 +++ b/xen/include/asm-x86/mm.h Wed Nov 15 14:36:10 2006 +0000 5.3 @@ -304,37 +304,9 @@ int check_descriptor(struct desc_struct 5.4 5.5 #define gmfn_to_mfn(_d, gpfn) mfn_x(sh_gfn_to_mfn(_d, gpfn)) 5.6 5.7 - 5.8 -/* 5.9 - * The phys_to_machine_mapping is the reversed mapping of MPT for full 5.10 - * virtualization. It is only used by shadow_mode_translate()==true 5.11 - * guests, so we steal the address space that would have normally 5.12 - * been used by the read-only MPT map. 5.13 - */ 5.14 -#define phys_to_machine_mapping ((l1_pgentry_t *)RO_MPT_VIRT_START) 5.15 #define INVALID_MFN (~0UL) 5.16 #define VALID_MFN(_mfn) (!((_mfn) & (1U<<31))) 5.17 5.18 -static inline unsigned long get_mfn_from_gpfn(unsigned long pfn) 5.19 -{ 5.20 - l1_pgentry_t l1e = l1e_empty(); 5.21 - int ret; 5.22 - 5.23 -#if CONFIG_PAGING_LEVELS > 2 5.24 - if ( pfn >= (RO_MPT_VIRT_END - RO_MPT_VIRT_START) / sizeof(l1_pgentry_t) ) 5.25 - /* This pfn is higher than the p2m map can hold */ 5.26 - return INVALID_MFN; 5.27 -#endif 5.28 - 5.29 - ret = __copy_from_user(&l1e, 5.30 - &phys_to_machine_mapping[pfn], 5.31 - sizeof(l1e)); 5.32 - 5.33 - if ( (ret == 0) && (l1e_get_flags(l1e) & _PAGE_PRESENT) ) 5.34 - return l1e_get_pfn(l1e); 5.35 - 5.36 - return INVALID_MFN; 5.37 -} 5.38 5.39 #ifdef MEMORY_GUARD 5.40 void memguard_init(void);
6.1 --- a/xen/include/asm-x86/shadow.h Wed Nov 15 09:44:12 2006 +0000 6.2 +++ b/xen/include/asm-x86/shadow.h Wed Nov 15 14:36:10 2006 +0000 6.3 @@ -663,12 +663,40 @@ struct shadow_walk_cache { 6.4 6.5 6.6 /**************************************************************************/ 6.7 -/* Guest physmap (p2m) support */ 6.8 +/* Guest physmap (p2m) support 6.9 + * 6.10 + * The phys_to_machine_mapping is the reversed mapping of MPT for full 6.11 + * virtualization. It is only used by shadow_mode_translate()==true 6.12 + * guests, so we steal the address space that would have normally 6.13 + * been used by the read-only MPT map. 6.14 + */ 6.15 + 6.16 +#define phys_to_machine_mapping ((l1_pgentry_t *)RO_MPT_VIRT_START) 6.17 + 6.18 +/* Read the current domain's P2M table. */ 6.19 +static inline mfn_t sh_gfn_to_mfn_current(unsigned long gfn) 6.20 +{ 6.21 + l1_pgentry_t l1e = l1e_empty(); 6.22 + int ret; 6.23 + 6.24 + if ( gfn > current->domain->arch.max_mapped_pfn ) 6.25 + return _mfn(INVALID_MFN); 6.26 + 6.27 + /* Don't read off the end of the p2m table */ 6.28 + ASSERT(gfn < (RO_MPT_VIRT_END - RO_MPT_VIRT_START) / sizeof(l1_pgentry_t)); 6.29 + 6.30 + ret = __copy_from_user(&l1e, 6.31 + &phys_to_machine_mapping[gfn], 6.32 + sizeof(l1e)); 6.33 + 6.34 + if ( (ret == 0) && (l1e_get_flags(l1e) & _PAGE_PRESENT) ) 6.35 + return _mfn(l1e_get_pfn(l1e)); 6.36 + 6.37 + return _mfn(INVALID_MFN); 6.38 +} 6.39 6.40 /* Walk another domain's P2M table, mapping pages as we go */ 6.41 -extern mfn_t 6.42 -sh_gfn_to_mfn_foreign(struct domain *d, unsigned long gpfn); 6.43 - 6.44 +extern mfn_t sh_gfn_to_mfn_foreign(struct domain *d, unsigned long gpfn); 6.45 6.46 /* General conversion function from gfn to mfn */ 6.47 static inline mfn_t 6.48 @@ -676,12 +704,19 @@ sh_gfn_to_mfn(struct domain *d, unsigned 6.49 { 6.50 if ( !shadow_mode_translate(d) ) 6.51 return _mfn(gfn); 6.52 - else if ( likely(current->domain == d) ) 6.53 - return _mfn(get_mfn_from_gpfn(gfn)); 6.54 - else 6.55 + if ( likely(current->domain == d) ) 6.56 + return sh_gfn_to_mfn_current(gfn); 6.57 + else 6.58 return sh_gfn_to_mfn_foreign(d, gfn); 6.59 } 6.60 6.61 +/* Compatibility function for HVM code */ 6.62 +static inline unsigned long get_mfn_from_gpfn(unsigned long pfn) 6.63 +{ 6.64 + return mfn_x(sh_gfn_to_mfn_current(pfn)); 6.65 +} 6.66 + 6.67 +/* General conversion function from mfn to gfn */ 6.68 static inline unsigned long 6.69 sh_mfn_to_gfn(struct domain *d, mfn_t mfn) 6.70 { 6.71 @@ -691,6 +726,14 @@ sh_mfn_to_gfn(struct domain *d, mfn_t mf 6.72 return mfn_x(mfn); 6.73 } 6.74 6.75 +/* Is this guest address an mmio one? (i.e. not defined in p2m map) */ 6.76 +static inline int 6.77 +mmio_space(paddr_t gpa) 6.78 +{ 6.79 + unsigned long gfn = gpa >> PAGE_SHIFT; 6.80 + return !VALID_MFN(mfn_x(sh_gfn_to_mfn_current(gfn))); 6.81 +} 6.82 + 6.83 static inline l1_pgentry_t 6.84 gl1e_to_ml1e(struct domain *d, l1_pgentry_t l1e) 6.85 {