diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index f75011e..cca64b8 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -4714,9 +4714,29 @@ long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg) return -EPERM; } - xenmem_add_to_physmap(d, xatp); + if ( xatp.space != XENMAPSPACE_gmfn_range ) + xatp.size = 1; + + for ( ; xatp.size > 0; xatp.size-- ) + { + if ( hypercall_preempt_check() ) + { + rc = -EAGAIN; + break; + } + xenmem_add_to_physmap(d, xatp); + xatp.idx++; + xatp.gpfn++; + } rcu_unlock_domain(d); + if ( rc == -EAGAIN ) + { + if ( copy_to_guest(arg, &xatp, 1) ) + return -EFAULT; + rc = hypercall_create_continuation( + __HYPERVISOR_memory_op, "ih", op, arg); + } return rc; } diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h index 08355e3..8bc8272 100644 --- a/xen/include/public/memory.h +++ b/xen/include/public/memory.h @@ -208,10 +208,14 @@ struct xen_add_to_physmap { /* Which domain to change the mapping for. */ domid_t domid; + /* Number of pages to go through for gmfn_range */ + uint16_t size; + /* Source mapping space. */ #define XENMAPSPACE_shared_info 0 /* shared info page */ #define XENMAPSPACE_grant_table 1 /* grant table page */ #define XENMAPSPACE_gmfn 2 /* GMFN */ +#define XENMAPSPACE_gmfn_range 3 /* GMFN_range */ unsigned int space; #define XENMAPIDX_grant_table_status 0x80000000