compat wrapper for XENMEM_add_to_physmap_batch Signed-off-by: Jan Beulich --- a/xen/common/compat/memory.c +++ b/xen/common/compat/memory.c @@ -27,12 +27,14 @@ int compat_memory_op(unsigned int cmd, X struct xen_memory_reservation *rsrv; struct xen_memory_exchange *xchg; struct xen_add_to_physmap *atp; + struct xen_add_to_physmap_batch *atpb; struct xen_remove_from_physmap *xrfp; } nat; union { struct compat_memory_reservation rsrv; struct compat_memory_exchange xchg; struct compat_add_to_physmap atp; + struct compat_add_to_physmap_batch atpb; } cmp; set_xen_guest_handle(nat.hnd, COMPAT_ARG_XLAT_VIRT_BASE); @@ -200,6 +202,60 @@ int compat_memory_op(unsigned int cmd, X break; + case XENMEM_add_to_physmap_batch: + { + unsigned int limit = (COMPAT_ARG_XLAT_SIZE - sizeof(*nat.atpb)) + / (sizeof(nat.atpb->idxs.p) + sizeof(nat.atpb->gpfns.p)); + xen_ulong_t *idxs = (void *)(nat.atpb + 1); + xen_pfn_t *gpfns = (void *)(idxs + limit); + + if ( copy_from_guest(&cmp.atpb, compat, 1) || + !compat_handle_okay(cmp.atpb.idxs, cmp.atpb.size) || + !compat_handle_okay(cmp.atpb.gpfns, cmp.atpb.size) || + !compat_handle_okay(cmp.atpb.errs, cmp.atpb.size) ) + return -EFAULT; + + end_extent = start_extent + limit; + if ( end_extent > cmp.atpb.size ) + end_extent = cmp.atpb.size; + + idxs -= start_extent; + gpfns -= start_extent; + + for ( i = start_extent; i < end_extent; ++i ) + { + compat_ulong_t idx; + compat_pfn_t gpfn; + + if ( __copy_from_compat_offset(&idx, cmp.atpb.idxs, i, 1) || + __copy_from_compat_offset(&gpfn, cmp.atpb.gpfns, i, 1) ) + return -EFAULT; + idxs[i] = idx; + gpfns[i] = gpfn; + } + +#define XLAT_add_to_physmap_batch_HNDL_idxs(_d_, _s_) \ + set_xen_guest_handle((_d_)->idxs, idxs) +#define XLAT_add_to_physmap_batch_HNDL_gpfns(_d_, _s_) \ + set_xen_guest_handle((_d_)->gpfns, gpfns) +#define XLAT_add_to_physmap_batch_HNDL_errs(_d_, _s_) \ + guest_from_compat_handle((_d_)->errs, (_s_)->errs) + + XLAT_add_to_physmap_batch(nat.atpb, &cmp.atpb); + +#undef XLAT_add_to_physmap_batch_HNDL_errs +#undef XLAT_add_to_physmap_batch_HNDL_gpfns +#undef XLAT_add_to_physmap_batch_HNDL_idxs + + if ( end_extent < cmp.atpb.size ) + { + nat.atpb->size = end_extent; + ++split; + } + + break; + } + case XENMEM_remove_from_physmap: { struct compat_remove_from_physmap cmp; @@ -321,6 +377,10 @@ int compat_memory_op(unsigned int cmd, X break; } + case XENMEM_add_to_physmap_batch: + start_extent = end_extent; + break; + case XENMEM_maximum_ram_page: case XENMEM_current_reservation: case XENMEM_maximum_reservation: --- a/xen/include/xlat.lst +++ b/xen/include/xlat.lst @@ -55,6 +55,7 @@ ! kexec_image kexec.h ! kexec_range kexec.h ! add_to_physmap memory.h +! add_to_physmap_batch memory.h ! foreign_memory_map memory.h ! memory_exchange memory.h ! memory_map memory.h