[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] New memory_op subcall XENMEM_translate_gpfn_list.
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 0d10fac284274733fe67cf5384fe032508c13766 # Parent 2b0078f771cc1152a003721e20c3972fe7cf6ea8 New memory_op subcall XENMEM_translate_gpfn_list. Allows translation from GPFNs to MFNs for an auto-translated guest. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> diff -r 2b0078f771cc -r 0d10fac28427 tools/libxc/xc_domain.c --- a/tools/libxc/xc_domain.c Thu Feb 16 16:37:21 2006 +++ b/tools/libxc/xc_domain.c Thu Feb 16 17:52:06 2006 @@ -326,6 +326,53 @@ return err; } +int xc_domain_memory_populate_physmap(int xc_handle, + uint32_t domid, + unsigned long nr_extents, + unsigned int extent_order, + unsigned int address_bits, + unsigned long *extent_start) +{ + int err; + struct xen_memory_reservation reservation = { + .extent_start = extent_start, + .nr_extents = nr_extents, + .extent_order = extent_order, + .address_bits = address_bits, + .domid = domid + }; + + err = xc_memory_op(xc_handle, XENMEM_populate_physmap, &reservation); + if ( err == nr_extents ) + return 0; + + if ( err > 0 ) + { + fprintf(stderr,"Failed deallocation for dom %d: %ld pages order %d\n", + domid, nr_extents, extent_order); + errno = EBUSY; + err = -1; + } + + return err; +} + +int xc_domain_translate_gpfn_list(int xc_handle, + uint32_t domid, + unsigned long nr_gpfns, + unsigned long *gpfn_list, + unsigned long *mfn_list) +{ + struct xen_translate_gpfn_list op = { + .domid = domid, + .nr_gpfns = nr_gpfns, + .gpfn_list = gpfn_list, + .mfn_list = mfn_list + }; + + return xc_memory_op(xc_handle, XENMEM_translate_gpfn_list, &op); +} + int xc_domain_max_vcpus(int xc_handle, uint32_t domid, unsigned int max) { DECLARE_DOM0_OP; diff -r 2b0078f771cc -r 0d10fac28427 tools/libxc/xc_private.c --- a/tools/libxc/xc_private.c Thu Feb 16 16:37:21 2006 +++ b/tools/libxc/xc_private.c Thu Feb 16 17:52:06 2006 @@ -191,6 +191,7 @@ DECLARE_HYPERCALL; struct xen_memory_reservation *reservation = arg; struct xen_machphys_mfn_list *xmml = arg; + struct xen_translate_gpfn_list *trans = arg; long ret = -EINVAL; hypercall.op = __HYPERVISOR_memory_op; @@ -234,6 +235,26 @@ if ( mlock(arg, sizeof(struct xen_reserved_phys_area)) ) { PERROR("Could not mlock"); + goto out1; + } + break; + case XENMEM_translate_gpfn_list: + if ( mlock(trans, sizeof(*trans)) != 0 ) + { + PERROR("Could not mlock"); + goto out1; + } + if ( mlock(trans->gpfn_list, trans->nr_gpfns * sizeof(long)) != 0 ) + { + PERROR("Could not mlock"); + safe_munlock(trans, sizeof(*trans)); + goto out1; + } + if ( mlock(trans->mfn_list, trans->nr_gpfns * sizeof(long)) != 0 ) + { + PERROR("Could not mlock"); + safe_munlock(trans->gpfn_list, trans->nr_gpfns * sizeof(long)); + safe_munlock(trans, sizeof(*trans)); goto out1; } break; @@ -258,6 +279,11 @@ break; case XENMEM_reserved_phys_area: safe_munlock(arg, sizeof(struct xen_reserved_phys_area)); + break; + case XENMEM_translate_gpfn_list: + safe_munlock(trans->mfn_list, trans->nr_gpfns * sizeof(long)); + safe_munlock(trans->gpfn_list, trans->nr_gpfns * sizeof(long)); + safe_munlock(trans, sizeof(*trans)); break; } diff -r 2b0078f771cc -r 0d10fac28427 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Thu Feb 16 16:37:21 2006 +++ b/tools/libxc/xenctrl.h Thu Feb 16 17:52:06 2006 @@ -373,6 +373,19 @@ unsigned int extent_order, unsigned long *extent_start); +int xc_domain_memory_populate_physmap(int xc_handle, + uint32_t domid, + unsigned long nr_extents, + unsigned int extent_order, + unsigned int address_bits, + unsigned long *extent_start); + +int xc_domain_translate_gpfn_list(int xc_handle, + uint32_t domid, + unsigned long nr_gpfns, + unsigned long *gpfn_list, + unsigned long *mfn_list); + int xc_domain_ioport_permission(int xc_handle, uint32_t domid, uint32_t first_port, diff -r 2b0078f771cc -r 0d10fac28427 xen/common/memory.c --- a/xen/common/memory.c Thu Feb 16 16:37:21 2006 +++ b/xen/common/memory.c Thu Feb 16 17:52:06 2006 @@ -19,6 +19,13 @@ #include <asm/current.h> #include <asm/hardirq.h> #include <public/memory.h> + +/* + * To allow safe resume of do_memory_op() after preemption, we need to know + * at what point in the page list to resume. For this purpose I steal the + * high-order bits of the @cmd parameter, which are otherwise unused and zero. + */ +#define START_EXTENT_SHIFT 4 /* cmd[:4] == start_extent */ static long increase_reservation( @@ -188,17 +195,74 @@ return nr_extents; } -/* - * To allow safe resume of do_memory_op() after preemption, we need to know - * at what point in the page list to resume. For this purpose I steal the - * high-order bits of the @cmd parameter, which are otherwise unused and zero. - */ -#define START_EXTENT_SHIFT 4 /* cmd[:4] == start_extent */ - -long do_memory_op(int cmd, void *arg) -{ +static long +translate_gpfn_list( + struct xen_translate_gpfn_list *uop, unsigned long *progress) +{ + struct xen_translate_gpfn_list op; + unsigned long i, gpfn, mfn; struct domain *d; - int rc, start_extent, op, flags = 0, preempted = 0; + + if ( copy_from_user(&op, uop, sizeof(op)) ) + return -EFAULT; + + /* Is size too large for us to encode a continuation? */ + if ( op.nr_gpfns > (ULONG_MAX >> START_EXTENT_SHIFT) ) + return -EINVAL; + + if ( !array_access_ok(op.gpfn_list, op.nr_gpfns, sizeof(*op.gpfn_list)) || + !array_access_ok(op.mfn_list, op.nr_gpfns, sizeof(*op.mfn_list)) ) + return -EFAULT; + + if ( op.domid == DOMID_SELF ) + op.domid = current->domain->domain_id; + else if ( !IS_PRIV(current->domain) ) + return -EPERM; + + if ( (d = find_domain_by_id(op.domid)) == NULL ) + return -ESRCH; + + if ( !shadow_mode_translate(d) ) + { + put_domain(d); + return -EINVAL; + } + + for ( i = *progress; i < op.nr_gpfns; i++ ) + { + if ( hypercall_preempt_check() ) + { + put_domain(d); + *progress = i; + return -EAGAIN; + } + + if ( unlikely(__copy_from_user(&gpfn, &op.gpfn_list[i], + sizeof(gpfn))) ) + { + put_domain(d); + return -EFAULT; + } + + mfn = gmfn_to_mfn(d, gpfn); + + if ( unlikely(__copy_to_user(&op.mfn_list[i], &mfn, + sizeof(mfn))) ) + { + put_domain(d); + return -EFAULT; + } + } + + put_domain(d); + return 0; +} + +long do_memory_op(unsigned long cmd, void *arg) +{ + struct domain *d; + int rc, op, flags = 0, preempted = 0; + unsigned long start_extent, progress; struct xen_memory_reservation reservation; domid_t domid; @@ -211,6 +275,10 @@ case XENMEM_populate_physmap: if ( copy_from_user(&reservation, arg, sizeof(reservation)) ) return -EFAULT; + + /* Is size too large for us to encode a continuation? */ + if ( reservation.nr_extents > (ULONG_MAX >> START_EXTENT_SHIFT) ) + return -EINVAL; start_extent = cmd >> START_EXTENT_SHIFT; if ( unlikely(start_extent > reservation.nr_extents) ) @@ -302,6 +370,16 @@ break; + case XENMEM_translate_gpfn_list: + progress = cmd >> START_EXTENT_SHIFT; + rc = translate_gpfn_list(arg, &progress); + if ( rc == -EAGAIN ) + return hypercall2_create_continuation( + __HYPERVISOR_memory_op, + op | (progress << START_EXTENT_SHIFT), + arg); + break; + default: rc = arch_memory_op(op, arg); break; diff -r 2b0078f771cc -r 0d10fac28427 xen/include/public/memory.h --- a/xen/include/public/memory.h Thu Feb 16 16:37:21 2006 +++ b/xen/include/public/memory.h Thu Feb 16 17:52:06 2006 @@ -101,7 +101,7 @@ */ #define XENMEM_reserved_phys_area 7 typedef struct xen_reserved_phys_area { - /* Which request to report about? */ + /* Which domain to report about? */ domid_t domid; /* @@ -114,6 +114,28 @@ unsigned long first_gpfn, nr_gpfns; } xen_reserved_phys_area_t; +/* + * Translates a list of domain-specific GPFNs into MFNs. Returns a -ve error + * code on failure. This call only works for auto-translated guests. + */ +#define XENMEM_translate_gpfn_list 8 +typedef struct xen_translate_gpfn_list { + /* Which domain to translate for? */ + domid_t domid; + + /* Length of list. */ + unsigned long nr_gpfns; + + /* List of GPFNs to translate. */ + unsigned long *gpfn_list; + + /* + * Output list to contain MFN translations. May be the same as the input + * list (in which case each input GPFN is overwritten with the output MFN). + */ + unsigned long *mfn_list; +} xen_translate_gpfn_list_t; + #endif /* __XEN_PUBLIC_MEMORY_H__ */ /* _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |