[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC PATCH 2/16]: PVH xen: add XENMEM_add_to_physmap_range
In this patch we add a new function xenmem_add_to_physmap_range(), and change xenmem_add_to_physmap_once parameters so it can be called from xenmem_add_to_physmap_range. There is no PVH specific change here. BTW, there are 16 patches and not 15. Sorry, corrected the subject. Signed-off-by: Mukesh Rathor <mukesh.rathor@xxxxxxxxxx> diff -r 278d7a933d88 -r ede1afe68962 xen/arch/x86/mm.c --- a/xen/arch/x86/mm.c Fri Jan 11 16:19:40 2013 -0800 +++ b/xen/arch/x86/mm.c Fri Jan 11 16:20:38 2013 -0800 @@ -4218,8 +4218,8 @@ static int handle_iomem_range(unsigned l } static int xenmem_add_to_physmap_once( - struct domain *d, - const struct xen_add_to_physmap *xatp) + struct domain *d, uint16_t xatp_space, domid_t foreign_domid, + unsigned long xatp_idx, unsigned long xatp_gpfn) { struct page_info *page = NULL; unsigned long gfn = 0; /* gcc ... */ @@ -4227,10 +4227,10 @@ static int xenmem_add_to_physmap_once( int rc; p2m_type_t p2mt; - switch ( xatp->space ) + switch ( xatp_space ) { case XENMAPSPACE_shared_info: - if ( xatp->idx == 0 ) + if ( xatp_idx == 0 ) mfn = virt_to_mfn(d->shared_info); break; case XENMAPSPACE_grant_table: @@ -4239,9 +4239,9 @@ static int xenmem_add_to_physmap_once( if ( d->grant_table->gt_version == 0 ) d->grant_table->gt_version = 1; - idx = xatp->idx; + idx = xatp_idx; if ( d->grant_table->gt_version == 2 && - (xatp->idx & XENMAPIDX_grant_table_status) ) + (xatp_idx & XENMAPIDX_grant_table_status) ) { idx &= ~XENMAPIDX_grant_table_status; if ( idx < nr_status_frames(d->grant_table) ) @@ -4263,9 +4263,9 @@ static int xenmem_add_to_physmap_once( case XENMAPSPACE_gmfn: { p2m_type_t p2mt; - gfn = xatp->idx; - - idx = mfn_x(get_gfn_unshare(d, xatp->idx, &p2mt)); + gfn = xatp_idx; + + idx = mfn_x(get_gfn_unshare(d, xatp_idx, &p2mt)); /* If the page is still shared, exit early */ if ( p2m_is_shared(p2mt) ) { @@ -4286,8 +4286,8 @@ static int xenmem_add_to_physmap_once( { if ( page ) put_page(page); - if ( xatp->space == XENMAPSPACE_gmfn || - xatp->space == XENMAPSPACE_gmfn_range ) + if ( xatp_space == XENMAPSPACE_gmfn || + xatp_space == XENMAPSPACE_gmfn_range ) put_gfn(d, gfn); return -EINVAL; } @@ -4298,41 +4298,41 @@ static int xenmem_add_to_physmap_once( put_page(page); /* Remove previously mapped page if it was present. */ - prev_mfn = mfn_x(get_gfn(d, xatp->gpfn, &p2mt)); + prev_mfn = mfn_x(get_gfn(d, xatp_gpfn, &p2mt)); if ( mfn_valid(prev_mfn) ) { if ( is_xen_heap_mfn(prev_mfn) ) /* Xen heap frames are simply unhooked from this phys slot. */ - guest_physmap_remove_page(d, xatp->gpfn, prev_mfn, PAGE_ORDER_4K); + guest_physmap_remove_page(d, xatp_gpfn, prev_mfn, PAGE_ORDER_4K); else /* Normal domain memory is freed, to avoid leaking memory. */ - guest_remove_page(d, xatp->gpfn); + guest_remove_page(d, xatp_gpfn); } /* In the XENMAPSPACE_gmfn case we still hold a ref on the old page. */ - put_gfn(d, xatp->gpfn); + put_gfn(d, xatp_gpfn); /* Unmap from old location, if any. */ gpfn = get_gpfn_from_mfn(mfn); ASSERT( gpfn != SHARED_M2P_ENTRY ); - if ( xatp->space == XENMAPSPACE_gmfn || - xatp->space == XENMAPSPACE_gmfn_range ) + if ( xatp_space == XENMAPSPACE_gmfn || + xatp_space == XENMAPSPACE_gmfn_range ) ASSERT( gpfn == gfn ); if ( gpfn != INVALID_M2P_ENTRY ) guest_physmap_remove_page(d, gpfn, mfn, PAGE_ORDER_4K); /* Map at new location. */ - rc = guest_physmap_add_page(d, xatp->gpfn, mfn, PAGE_ORDER_4K); + rc = guest_physmap_add_page(d, xatp_gpfn, mfn, PAGE_ORDER_4K); /* In the XENMAPSPACE_gmfn, we took a ref of the gfn at the top */ - if ( xatp->space == XENMAPSPACE_gmfn || - xatp->space == XENMAPSPACE_gmfn_range ) + if ( xatp_space == XENMAPSPACE_gmfn || + xatp_space == XENMAPSPACE_gmfn_range ) put_gfn(d, gfn); domain_unlock(d); return rc; } -static int xenmem_add_to_physmap(struct domain *d, +static noinline int xenmem_add_to_physmap(struct domain *d, struct xen_add_to_physmap *xatp) { struct xen_add_to_physmap start_xatp; @@ -4346,7 +4346,8 @@ static int xenmem_add_to_physmap(struct start_xatp = *xatp; while ( xatp->size > 0 ) { - rc = xenmem_add_to_physmap_once(d, xatp); + rc = xenmem_add_to_physmap_once(d, xatp->space, -1, + xatp->idx, xatp->gpfn); if ( rc < 0 ) return rc; @@ -4372,7 +4373,50 @@ static int xenmem_add_to_physmap(struct return rc; } - return xenmem_add_to_physmap_once(d, xatp); + return xenmem_add_to_physmap_once(d, xatp->space, -1, + xatp->idx, xatp->gpfn); +} + +static noinline int xenmem_add_to_physmap_range(struct domain *d, + struct xen_add_to_physmap_range *xatpr) +{ + int rc; + + /* Process entries in reverse order to allow continuations */ + while ( xatpr->size > 0 ) + { + xen_ulong_t idx; + xen_pfn_t gpfn; + + rc = copy_from_guest_offset(&idx, xatpr->idxs, xatpr->size-1, 1); + if ( rc < 0 ) + goto out; + + rc = copy_from_guest_offset(&gpfn, xatpr->gpfns, xatpr->size-1, 1); + if ( rc < 0 ) + goto out; + + rc = xenmem_add_to_physmap_once(d, xatpr->space, xatpr->foreign_domid, + idx, gpfn); + + if (rc) + goto out; + + xatpr->size--; + + /* Check for continuation if it's not the last interation */ + if ( xatpr->size > 0 && hypercall_preempt_check() ) + { + rc = -EAGAIN; + goto out; + } + } + + rc = 0; + +out: + return rc; + } long arch_memory_op(int op, XEN_GUEST_HANDLE_PARAM(void) arg) @@ -4389,6 +4433,10 @@ long arch_memory_op(int op, XEN_GUEST_HA if ( copy_from_guest(&xatp, arg, 1) ) return -EFAULT; + /* This one is only supported for add_to_physmap_range */ + if ( xatp.space == XENMAPSPACE_gmfn_foreign ) + return -EINVAL; + rc = rcu_lock_target_domain_by_id(xatp.domid, &d); if ( rc != 0 ) return rc; @@ -4416,6 +4464,32 @@ long arch_memory_op(int op, XEN_GUEST_HA return rc; } + case XENMEM_add_to_physmap_range: + { + struct xen_add_to_physmap_range xatpr; + struct domain *d; + + if ( copy_from_guest(&xatpr, arg, 1) ) + return -EFAULT; + + rc = rcu_lock_target_domain_by_id(xatpr.domid, &d); + if ( rc != 0 ) + return rc; + + rc = xenmem_add_to_physmap_range(d, &xatpr); + + rcu_unlock_domain(d); + + if ( rc && copy_to_guest(arg, &xatpr, 1) ) + rc = -EFAULT; + + if ( rc == -EAGAIN ) + rc = hypercall_create_continuation( + __HYPERVISOR_memory_op, "ih", op, arg); + + return rc; + } + case XENMEM_set_memory_map: { struct xen_foreign_memory_map fmap; _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |