[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2 4/4] x86/shadow: refactor shadow_vram_{get,put}_l1e()
On Wed, Sep 16, 2020 at 03:08:40PM +0200, Jan Beulich wrote: > By passing the functions an MFN and flags, only a single instance of ^ a > each is needed; they were pretty large for being inline functions > anyway. > > While moving the code, also adjust coding style and add const where > sensible / possible. > > Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> > --- > v2: New. > > --- a/xen/arch/x86/mm/shadow/hvm.c > +++ b/xen/arch/x86/mm/shadow/hvm.c > @@ -903,6 +903,104 @@ int shadow_track_dirty_vram(struct domai > return rc; > } > > +void shadow_vram_get_mfn(mfn_t mfn, unsigned int l1f, > + mfn_t sl1mfn, const void *sl1e, > + const struct domain *d) > +{ > + unsigned long gfn; > + struct sh_dirty_vram *dirty_vram = d->arch.hvm.dirty_vram; > + > + ASSERT(is_hvm_domain(d)); > + > + if ( !dirty_vram /* tracking disabled? */ || > + !(l1f & _PAGE_RW) /* read-only mapping? */ || > + !mfn_valid(mfn) /* mfn can be invalid in mmio_direct */) > + return; > + > + gfn = gfn_x(mfn_to_gfn(d, mfn)); > + /* Page sharing not supported on shadow PTs */ > + BUG_ON(SHARED_M2P(gfn)); > + > + if ( (gfn >= dirty_vram->begin_pfn) && (gfn < dirty_vram->end_pfn) ) > + { > + unsigned long i = gfn - dirty_vram->begin_pfn; > + const struct page_info *page = mfn_to_page(mfn); > + > + if ( (page->u.inuse.type_info & PGT_count_mask) == 1 ) > + /* Initial guest reference, record it */ > + dirty_vram->sl1ma[i] = mfn_to_maddr(sl1mfn) | > + PAGE_OFFSET(sl1e); > + } > +} > + > +void shadow_vram_put_mfn(mfn_t mfn, unsigned int l1f, > + mfn_t sl1mfn, const void *sl1e, > + const struct domain *d) > +{ > + unsigned long gfn; > + struct sh_dirty_vram *dirty_vram = d->arch.hvm.dirty_vram; > + > + ASSERT(is_hvm_domain(d)); > + > + if ( !dirty_vram /* tracking disabled? */ || > + !(l1f & _PAGE_RW) /* read-only mapping? */ || > + !mfn_valid(mfn) /* mfn can be invalid in mmio_direct */) > + return; > + > + gfn = gfn_x(mfn_to_gfn(d, mfn)); > + /* Page sharing not supported on shadow PTs */ > + BUG_ON(SHARED_M2P(gfn)); > + > + if ( (gfn >= dirty_vram->begin_pfn) && (gfn < dirty_vram->end_pfn) ) > + { > + unsigned long i = gfn - dirty_vram->begin_pfn; > + const struct page_info *page = mfn_to_page(mfn); > + bool dirty = false; > + paddr_t sl1ma = mfn_to_maddr(sl1mfn) | PAGE_OFFSET(sl1e); > + > + if ( (page->u.inuse.type_info & PGT_count_mask) == 1 ) > + { > + /* Last reference */ > + if ( dirty_vram->sl1ma[i] == INVALID_PADDR ) > + { > + /* We didn't know it was that one, let's say it is dirty */ > + dirty = true; > + } > + else > + { > + ASSERT(dirty_vram->sl1ma[i] == sl1ma); > + dirty_vram->sl1ma[i] = INVALID_PADDR; > + if ( l1f & _PAGE_DIRTY ) > + dirty = true; > + } > + } > + else > + { > + /* We had more than one reference, just consider the page dirty. > */ > + dirty = true; > + /* Check that it's not the one we recorded. */ > + if ( dirty_vram->sl1ma[i] == sl1ma ) > + { > + /* Too bad, we remembered the wrong one... */ > + dirty_vram->sl1ma[i] = INVALID_PADDR; > + } > + else > + { > + /* > + * Ok, our recorded sl1e is still pointing to this page, > let's > + * just hope it will remain. > + */ > + } > + } > + > + if ( dirty ) > + { > + dirty_vram->dirty_bitmap[i / 8] |= 1 << (i % 8); Could you use _set_bit here? > + dirty_vram->last_dirty = NOW(); > + } > + } > +} > + > /* > * Local variables: > * mode: C > --- a/xen/arch/x86/mm/shadow/multi.c > +++ b/xen/arch/x86/mm/shadow/multi.c > @@ -1047,107 +1047,6 @@ static int shadow_set_l2e(struct domain > return flags; > } > > -static inline void shadow_vram_get_l1e(shadow_l1e_t new_sl1e, > - shadow_l1e_t *sl1e, > - mfn_t sl1mfn, > - struct domain *d) > -{ > -#ifdef CONFIG_HVM > - mfn_t mfn = shadow_l1e_get_mfn(new_sl1e); > - int flags = shadow_l1e_get_flags(new_sl1e); > - unsigned long gfn; > - struct sh_dirty_vram *dirty_vram = d->arch.hvm.dirty_vram; > - > - if ( !is_hvm_domain(d) || !dirty_vram /* tracking disabled? */ > - || !(flags & _PAGE_RW) /* read-only mapping? */ > - || !mfn_valid(mfn) ) /* mfn can be invalid in mmio_direct */ > - return; > - > - gfn = gfn_x(mfn_to_gfn(d, mfn)); > - /* Page sharing not supported on shadow PTs */ > - BUG_ON(SHARED_M2P(gfn)); > - > - if ( (gfn >= dirty_vram->begin_pfn) && (gfn < dirty_vram->end_pfn) ) > - { > - unsigned long i = gfn - dirty_vram->begin_pfn; > - struct page_info *page = mfn_to_page(mfn); > - > - if ( (page->u.inuse.type_info & PGT_count_mask) == 1 ) > - /* Initial guest reference, record it */ > - dirty_vram->sl1ma[i] = mfn_to_maddr(sl1mfn) > - | ((unsigned long)sl1e & ~PAGE_MASK); > - } > -#endif > -} > - > -static inline void shadow_vram_put_l1e(shadow_l1e_t old_sl1e, > - shadow_l1e_t *sl1e, > - mfn_t sl1mfn, > - struct domain *d) > -{ > -#ifdef CONFIG_HVM > - mfn_t mfn = shadow_l1e_get_mfn(old_sl1e); > - int flags = shadow_l1e_get_flags(old_sl1e); > - unsigned long gfn; > - struct sh_dirty_vram *dirty_vram = d->arch.hvm.dirty_vram; > - > - if ( !is_hvm_domain(d) || !dirty_vram /* tracking disabled? */ > - || !(flags & _PAGE_RW) /* read-only mapping? */ > - || !mfn_valid(mfn) ) /* mfn can be invalid in mmio_direct */ > - return; > - > - gfn = gfn_x(mfn_to_gfn(d, mfn)); > - /* Page sharing not supported on shadow PTs */ > - BUG_ON(SHARED_M2P(gfn)); > - > - if ( (gfn >= dirty_vram->begin_pfn) && (gfn < dirty_vram->end_pfn) ) > - { > - unsigned long i = gfn - dirty_vram->begin_pfn; > - struct page_info *page = mfn_to_page(mfn); > - int dirty = 0; > - paddr_t sl1ma = mfn_to_maddr(sl1mfn) > - | ((unsigned long)sl1e & ~PAGE_MASK); > - > - if ( (page->u.inuse.type_info & PGT_count_mask) == 1 ) > - { > - /* Last reference */ > - if ( dirty_vram->sl1ma[i] == INVALID_PADDR ) { > - /* We didn't know it was that one, let's say it is dirty */ > - dirty = 1; > - } > - else > - { > - ASSERT(dirty_vram->sl1ma[i] == sl1ma); > - dirty_vram->sl1ma[i] = INVALID_PADDR; > - if ( flags & _PAGE_DIRTY ) > - dirty = 1; > - } > - } > - else > - { > - /* We had more than one reference, just consider the page dirty. > */ > - dirty = 1; > - /* Check that it's not the one we recorded. */ > - if ( dirty_vram->sl1ma[i] == sl1ma ) > - { > - /* Too bad, we remembered the wrong one... */ > - dirty_vram->sl1ma[i] = INVALID_PADDR; > - } > - else > - { > - /* Ok, our recorded sl1e is still pointing to this page, > let's > - * just hope it will remain. */ > - } > - } > - if ( dirty ) > - { > - dirty_vram->dirty_bitmap[i / 8] |= 1 << (i % 8); > - dirty_vram->last_dirty = NOW(); > - } > - } > -#endif > -} > - > static int shadow_set_l1e(struct domain *d, > shadow_l1e_t *sl1e, > shadow_l1e_t new_sl1e, > @@ -1156,6 +1055,7 @@ static int shadow_set_l1e(struct domain > { > int flags = 0; > shadow_l1e_t old_sl1e; > + unsigned int old_sl1f; > #if SHADOW_OPTIMIZATIONS & SHOPT_OUT_OF_SYNC > mfn_t new_gmfn = shadow_l1e_get_mfn(new_sl1e); > #endif > @@ -1194,7 +1094,9 @@ static int shadow_set_l1e(struct domain > new_sl1e = shadow_l1e_flip_flags(new_sl1e, rc); > /* fall through */ > case 0: > - shadow_vram_get_l1e(new_sl1e, sl1e, sl1mfn, d); > + shadow_vram_get_mfn(shadow_l1e_get_mfn(new_sl1e), > + shadow_l1e_get_flags(new_sl1e), > + sl1mfn, sl1e, d); As you have moved this function into a HVM build time file, don't you need to guard this call, or alternatively provide a dummy handler for !CONFIG_HVM in private.h? Same for shadow_vram_put_mfn. Thanks, Roger.
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |