[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] VMX: cleanup ept_set_entry:
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1278093604 -3600 # Node ID 569b6148a65236d0a60e3dfde82349b1d3a6c339 # Parent 62db52247afe663d21c9f2212231b53511a4ac52 VMX: cleanup ept_set_entry: 1) more strict input parameters checking; 2) better comments; 3) fewer variable; 4) change direct_mmio type to bool_t. Signed-off-by: Xin Li <xin.li@xxxxxxxxx> --- xen/arch/x86/hvm/mtrr.c | 2 - xen/arch/x86/mm/hap/p2m-ept.c | 74 ++++++++++++++++++++++++------------------ xen/include/asm-x86/mtrr.h | 2 - 3 files changed, 45 insertions(+), 33 deletions(-) diff -r 62db52247afe -r 569b6148a652 xen/arch/x86/hvm/mtrr.c --- a/xen/arch/x86/hvm/mtrr.c Fri Jul 02 18:59:36 2010 +0100 +++ b/xen/arch/x86/hvm/mtrr.c Fri Jul 02 19:00:04 2010 +0100 @@ -707,7 +707,7 @@ HVM_REGISTER_SAVE_RESTORE(MTRR, hvm_save 1, HVMSR_PER_VCPU); uint8_t epte_get_entry_emt(struct domain *d, unsigned long gfn, mfn_t mfn, - uint8_t *ipat, int direct_mmio) + uint8_t *ipat, bool_t direct_mmio) { uint8_t gmtrr_mtype, hmtrr_mtype; uint32_t type; diff -r 62db52247afe -r 569b6148a652 xen/arch/x86/mm/hap/p2m-ept.c --- a/xen/arch/x86/mm/hap/p2m-ept.c Fri Jul 02 18:59:36 2010 +0100 +++ b/xen/arch/x86/mm/hap/p2m-ept.c Fri Jul 02 19:00:04 2010 +0100 @@ -229,33 +229,41 @@ static int ept_split_large_page(struct d * by observing whether any gfn->mfn translations are modified. */ static int -ept_set_entry(struct domain *d, unsigned long gfn, mfn_t mfn, +ept_set_entry(struct domain *d, unsigned long gfn, mfn_t mfn, unsigned int order, p2m_type_t p2mt) { - ept_entry_t *table = NULL; + ept_entry_t *table, *ept_entry; unsigned long gfn_remainder = gfn; - unsigned long offset = 0; - ept_entry_t *ept_entry = NULL; + unsigned long offset; u32 index; - int i; + int i, target = order / EPT_TABLE_ORDER; int rv = 0; int ret = 0; - int split_level = 0; - int walk_level = order / EPT_TABLE_ORDER; - int direct_mmio = (p2mt == p2m_mmio_direct); + bool_t direct_mmio = (p2mt == p2m_mmio_direct); uint8_t ipat = 0; int need_modify_vtd_table = 1; int needs_sync = 1; - if ( order != 0 ) - if ( (gfn & ((1UL << order) - 1)) ) - return 1; + /* + * the caller must make sure: + * 1. passing valid gfn and mfn at order boundary. + * 2. gfn not exceeding guest physical address width. + * 3. passing a valid order. + */ + if ( ((gfn | mfn_x(mfn)) & ((1UL << order) - 1)) || + (gfn >> ((ept_get_wl(d) + 1) * EPT_TABLE_ORDER)) || + (order % EPT_TABLE_ORDER) ) + return 0; + + ASSERT((target == 2 && hvm_hap_has_1gb(d)) || + (target == 1 && hvm_hap_has_2mb(d)) || + (target == 0)); table = map_domain_page(ept_get_asr(d)); ASSERT(table != NULL); - for ( i = ept_get_wl(d); i > walk_level; i-- ) + for ( i = ept_get_wl(d); i > target; i-- ) { ret = ept_next_level(d, 0, &table, &gfn_remainder, i * EPT_TABLE_ORDER); if ( !ret ) @@ -264,21 +272,23 @@ ept_set_entry(struct domain *d, unsigned break; } - /* If order == 0, we should only get POD if we have a POD superpage. - * If i > walk_level, we need to split the page; otherwise, - * just behave as normal. */ - ASSERT(ret != GUEST_TABLE_POD_PAGE || i != walk_level); - - index = gfn_remainder >> ( i ? (i * EPT_TABLE_ORDER): order); - offset = (gfn_remainder & ( ((1 << (i*EPT_TABLE_ORDER)) - 1))); - - split_level = i; + ASSERT(ret != GUEST_TABLE_POD_PAGE || i != target); + + index = gfn_remainder >> (i * EPT_TABLE_ORDER); + gfn_remainder &= (1UL << (i * EPT_TABLE_ORDER)) - 1; ept_entry = table + index; - if ( i == walk_level ) - { - /* We reached the level we're looking for */ + offset = gfn_remainder; + + /* + * When we are here, we must be on a leaf ept entry + * with i == target or i > target. + */ + + if ( i == target ) + { + /* We reached the target level. */ /* No need to flush if the old entry wasn't valid */ if ( !is_epte_present(ept_entry) ) @@ -307,12 +317,14 @@ ept_set_entry(struct domain *d, unsigned } else { - int level; + /* We need to split the original page. */ ept_entry_t *split_ept_entry; - for ( level = split_level; level > walk_level ; level-- ) - { - rv = ept_split_large_page(d, &table, &index, gfn, level); + ASSERT(is_epte_superpage(ept_entry)); + + for ( ; i > target; i-- ) + { + rv = ept_split_large_page(d, &table, &index, gfn, i); if ( !rv ) goto out; } @@ -559,7 +571,7 @@ static mfn_t ept_get_entry_current(unsig return ept_get_entry(current->domain, gfn, t, q); } -/* +/* * To test if the new emt type is the same with old, * return 1 to not to reset ept entry. */ @@ -569,14 +581,14 @@ static int need_modify_ept_entry(struct { uint8_t ipat; uint8_t emt; - int direct_mmio = (p2mt == p2m_mmio_direct); + bool_t direct_mmio = (p2mt == p2m_mmio_direct); emt = epte_get_entry_emt(d, gfn, mfn, &ipat, direct_mmio); if ( (emt == o_emt) && (ipat == o_ipat) ) return 0; - return 1; + return 1; } void ept_change_entry_emt_with_range(struct domain *d, unsigned long start_gfn, diff -r 62db52247afe -r 569b6148a652 xen/include/asm-x86/mtrr.h --- a/xen/include/asm-x86/mtrr.h Fri Jul 02 18:59:36 2010 +0100 +++ b/xen/include/asm-x86/mtrr.h Fri Jul 02 19:00:04 2010 +0100 @@ -65,7 +65,7 @@ extern u32 get_pat_flags(struct vcpu *v, extern u32 get_pat_flags(struct vcpu *v, u32 gl1e_flags, paddr_t gpaddr, paddr_t spaddr, uint8_t gmtrr_mtype); extern uint8_t epte_get_entry_emt(struct domain *d, unsigned long gfn, - mfn_t mfn, uint8_t *ipat, int direct_mmio); + mfn_t mfn, uint8_t *ipat, bool_t direct_mmio); extern void ept_change_entry_emt_with_range( struct domain *d, unsigned long start_gfn, unsigned long end_gfn); extern unsigned char pat_type_2_pte_flags(unsigned char pat_type); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |