[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Ping: [PATCH v2 3/6] x86/mem-paging: use guest handle for XENMEM_paging_op_prep
On 23.04.2020 10:38, Jan Beulich wrote: > While it should have been this way from the beginning, not doing so will > become an actual problem with PVH Dom0. The interface change is binary > compatible, but requires tools side producers to be re-built. > > Drop the bogus/unnecessary page alignment restriction on the input > buffer at the same time. > > Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> May I ask for a libxc side ack or otherwise, please? Thanks, Jan > --- a/tools/libxc/xc_mem_paging.c > +++ b/tools/libxc/xc_mem_paging.c > @@ -26,15 +26,33 @@ static int xc_mem_paging_memop(xc_interf > unsigned int op, uint64_t gfn, void *buffer) > { > xen_mem_paging_op_t mpo; > + DECLARE_HYPERCALL_BOUNCE(buffer, XC_PAGE_SIZE, > + XC_HYPERCALL_BUFFER_BOUNCE_IN); > + int rc; > > memset(&mpo, 0, sizeof(mpo)); > > mpo.op = op; > mpo.domain = domain_id; > mpo.gfn = gfn; > - mpo.buffer = (unsigned long) buffer; > > - return do_memory_op(xch, XENMEM_paging_op, &mpo, sizeof(mpo)); > + if ( buffer ) > + { > + if ( xc_hypercall_bounce_pre(xch, buffer) ) > + { > + PERROR("Could not bounce memory for XENMEM_paging_op %u", op); > + return -1; > + } > + > + set_xen_guest_handle(mpo.buffer, buffer); > + } > + > + rc = do_memory_op(xch, XENMEM_paging_op, &mpo, sizeof(mpo)); > + > + if ( buffer ) > + xc_hypercall_bounce_post(xch, buffer); > + > + return rc; > } > > int xc_mem_paging_enable(xc_interface *xch, uint32_t domain_id, > @@ -92,28 +110,13 @@ int xc_mem_paging_prep(xc_interface *xch > int xc_mem_paging_load(xc_interface *xch, uint32_t domain_id, > uint64_t gfn, void *buffer) > { > - int rc, old_errno; > - > errno = EINVAL; > > if ( !buffer ) > return -1; > > - if ( ((unsigned long) buffer) & (XC_PAGE_SIZE - 1) ) > - return -1; > - > - if ( mlock(buffer, XC_PAGE_SIZE) ) > - return -1; > - > - rc = xc_mem_paging_memop(xch, domain_id, > - XENMEM_paging_op_prep, > - gfn, buffer); > - > - old_errno = errno; > - munlock(buffer, XC_PAGE_SIZE); > - errno = old_errno; > - > - return rc; > + return xc_mem_paging_memop(xch, domain_id, XENMEM_paging_op_prep, > + gfn, buffer); > } > > > --- a/xen/arch/x86/mm/p2m.c > +++ b/xen/arch/x86/mm/p2m.c > @@ -1779,7 +1779,8 @@ void p2m_mem_paging_populate(struct doma > * mfn if populate was called for gfn which was nominated but not evicted. > In > * this case only the p2mt needs to be forwarded. > */ > -int p2m_mem_paging_prep(struct domain *d, unsigned long gfn_l, uint64_t > buffer) > +int p2m_mem_paging_prep(struct domain *d, unsigned long gfn_l, > + XEN_GUEST_HANDLE_64(const_uint8) buffer) > { > struct page_info *page = NULL; > p2m_type_t p2mt; > @@ -1788,13 +1789,9 @@ int p2m_mem_paging_prep(struct domain *d > mfn_t mfn; > struct p2m_domain *p2m = p2m_get_hostp2m(d); > int ret, page_extant = 1; > - const void *user_ptr = (const void *) buffer; > > - if ( user_ptr ) > - /* Sanity check the buffer and bail out early if trouble */ > - if ( (buffer & (PAGE_SIZE - 1)) || > - (!access_ok(user_ptr, PAGE_SIZE)) ) > - return -EINVAL; > + if ( !guest_handle_okay(buffer, PAGE_SIZE) ) > + return -EINVAL; > > gfn_lock(p2m, gfn, 0); > > @@ -1812,7 +1809,7 @@ int p2m_mem_paging_prep(struct domain *d > > /* If the user did not provide a buffer, we disallow */ > ret = -EINVAL; > - if ( unlikely(user_ptr == NULL) ) > + if ( unlikely(guest_handle_is_null(buffer)) ) > goto out; > /* Get a free page */ > ret = -ENOMEM; > @@ -1834,7 +1831,7 @@ int p2m_mem_paging_prep(struct domain *d > > ASSERT( mfn_valid(mfn) ); > guest_map = map_domain_page(mfn); > - ret = copy_from_user(guest_map, user_ptr, PAGE_SIZE); > + ret = copy_from_guest(guest_map, buffer, PAGE_SIZE); > unmap_domain_page(guest_map); > if ( ret ) > { > --- a/xen/include/asm-x86/p2m.h > +++ b/xen/include/asm-x86/p2m.h > @@ -741,7 +741,8 @@ void p2m_mem_paging_drop_page(struct dom > /* Start populating a paged out frame */ > void p2m_mem_paging_populate(struct domain *d, unsigned long gfn); > /* Prepare the p2m for paging a frame in */ > -int p2m_mem_paging_prep(struct domain *d, unsigned long gfn, uint64_t > buffer); > +int p2m_mem_paging_prep(struct domain *d, unsigned long gfn, > + XEN_GUEST_HANDLE_64(const_uint8) buffer); > /* Resume normal operation (in case a domain was paused) */ > struct vm_event_st; > void p2m_mem_paging_resume(struct domain *d, struct vm_event_st *rsp); > --- a/xen/include/public/memory.h > +++ b/xen/include/public/memory.h > @@ -396,10 +396,10 @@ struct xen_mem_paging_op { > uint8_t op; /* XENMEM_paging_op_* */ > domid_t domain; > > - /* PAGING_PREP IN: buffer to immediately fill page in */ > - uint64_aligned_t buffer; > - /* Other OPs */ > - uint64_aligned_t gfn; /* IN: gfn of page being operated on > */ > + /* IN: (XENMEM_paging_op_prep) buffer to immediately fill page from */ > + XEN_GUEST_HANDLE_64(const_uint8) buffer; > + /* IN: gfn of page being operated on */ > + uint64_aligned_t gfn; > }; > typedef struct xen_mem_paging_op xen_mem_paging_op_t; > DEFINE_XEN_GUEST_HANDLE(xen_mem_paging_op_t); > >
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |