|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v3 3/3] xen: rework paging_log_dirty_op to work with hvm guests
>>> On 10.04.15 at 19:29, <roger.pau@xxxxxxxxxx> wrote:
> --- a/xen/arch/x86/mm/paging.c
> +++ b/xen/arch/x86/mm/paging.c
> @@ -397,6 +397,53 @@ int paging_mfn_is_dirty(struct domain *d, mfn_t gmfn)
> return rv;
> }
>
> +static inline void *map_dirty_bitmap(XEN_GUEST_HANDLE_64(uint8) dirty_bitmap,
> + unsigned long pages,
> + struct page_info **page,
> + unsigned long *mapped_page)
> +{
> + p2m_type_t p2mt;
> + uint32_t pfec;
> + unsigned long gfn;
> +
> + gfn = paging_gva_to_gfn(current,
> + (paddr_t)(((char *)dirty_bitmap.p) + (pages >>
> 3)),
I'd suggest dropping the parentheses around the inner cast - they
make this more difficult to read, and I think any C programmer
should know that unary ops have precedence over binary ones.
> + &pfec);
> + if ( gfn == INVALID_GFN )
> + return NULL;
> +
> + *page = get_page_from_gfn(current->domain, gfn, &p2mt, P2M_UNSHARE);
> +
> + if ( !p2m_is_ram(p2mt) )
> + {
> + put_page(*page);
> + return NULL;
> + }
> + if ( p2m_is_paging(p2mt) )
> + {
> + put_page(*page);
> + p2m_mem_paging_populate(current->domain, gfn);
> + return NULL;
> + }
> + if ( p2m_is_shared(p2mt) || p2m_is_discard_write(p2mt) )
> + {
> + put_page(*page);
> + return NULL;
> + }
> +
> + *mapped_page = pages;
You only ever store the passed in value of "pages" into
"*mapped_pages" - what's the point of this? If the caller needs
to track the value it passes here, it should simple make a copy
itself if so needed.
Apart from that both parameter names don't really seem to
express their purpose.
> @@ -409,9 +456,23 @@ static int paging_log_dirty_op(struct domain *d,
> mfn_t *l4 = NULL, *l3 = NULL, *l2 = NULL;
> unsigned long *l1 = NULL;
> int i4, i3, i2;
> + uint8_t *dirty_bitmap = NULL;
Pointless initializer.
> + struct page_info *page;
> + unsigned long index_mapped = 0;
>
> if ( !resuming )
> domain_pause(d);
> +
> + dirty_bitmap = map_dirty_bitmap(sc->dirty_bitmap,
> + resuming ?
> +
> d->arch.paging.preempt.log_dirty.done :
> + 0,
> + &page, &index_mapped);
> + if ( dirty_bitmap == NULL )
> + {
> + domain_unpause(d);
> + return -EFAULT;
> + }
> paging_lock(d);
Blank line above that one please.
> @@ -471,15 +534,29 @@ static int paging_log_dirty_op(struct domain *d,
> bytes = (unsigned int)((sc->pages - pages + 7) >> 3);
> if ( likely(peek) )
> {
> - if ( (l1 ? copy_to_guest_offset(sc->dirty_bitmap,
> - pages >> 3, (uint8_t
> *)l1,
> - bytes)
> - : clear_guest_offset(sc->dirty_bitmap,
> - pages >> 3, bytes)) != 0 )
> + if ( pages >> (3 + PAGE_SHIFT) !=
> + index_mapped >> (3 + PAGE_SHIFT) )
> {
> - rv = -EFAULT;
> - goto out;
> + /* We need to map next page */
> + paging_unlock(d);
> + unmap_dirty_bitmap(dirty_bitmap, page);
> + dirty_bitmap = map_dirty_bitmap(sc->dirty_bitmap,
> pages,
> + &page,
> &index_mapped);
> + paging_lock(d);
> + if ( dirty_bitmap == NULL )
> + {
> + rv = -EFAULT;
> + goto out;
> + }
> + goto again;
This won't work: The paging lock protects all of
d->arch.paging.preempt.log_dirty, of which you hold cached values
in local variables.
> + BUG_ON(((pages >> 3) % PAGE_SIZE) + bytes > PAGE_SIZE);
I don't seem to be able to spot the original for this one. If there
was none, please make this an ASSERT() instead.
> + if ( l1 )
> + memcpy(dirty_bitmap + ((pages >> 3) % PAGE_SIZE),
> + (uint8_t *)l1, bytes);
Pointless cast.
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |