Introduce new domctl xc_domain_iommu_map_batch to modify the iommu mapping without changing the cpu mapping. Signed-off-by: Jean Guyader --- diff -r 48256256333b tools/libxc/xc_domain.c --- a/tools/libxc/xc_domain.c Mon Nov 15 11:54:43 2010 +0000 +++ b/tools/libxc/xc_domain.c Mon Nov 15 17:45:09 2010 +0000 @@ -1342,6 +1342,31 @@ return do_domctl(xch, &domctl); } +int xc_domain_iommu_map_batch( + xc_interface *xch, + uint32_t domid, + unsigned long gfn, + unsigned long nr, + uint64_t *mfns) +{ + DECLARE_DOMCTL; + DECLARE_HYPERCALL_BOUNCE(mfns, nr * sizeof (*mfns), XC_HYPERCALL_BUFFER_BOUNCE_IN); + + domctl.cmd = XEN_DOMCTL_iommu_map_batch; + domctl.domain = domid; + domctl.u.iommu_map_batch.gfn = gfn; + domctl.u.iommu_map_batch.nr= nr; + + if ( xc_hypercall_bounce_pre(xch, mfns) ) + { + PERROR("Could not bounce memory for XEN_DOMCTL_iommu_map_batch hypercall"); + return -1; + } + set_xen_guest_handle(domctl.u.iommu_map_batch.mfns, mfns); + + return do_domctl(xch, &domctl); +} + int xc_domain_ioport_mapping( xc_interface *xch, uint32_t domid, diff -r 48256256333b tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Mon Nov 15 11:54:43 2010 +0000 +++ b/tools/libxc/xenctrl.h Mon Nov 15 17:45:09 2010 +0000 @@ -1461,6 +1461,12 @@ uint32_t nr_ports, uint32_t add_mapping); +int xc_domain_iommu_map_batch(xc_interface *xch, + uint32_t domid, + unsigned long gfn, + unsigned long nr, + uint64_t *mfn); + int xc_domain_update_msi_irq( xc_interface *xch, uint32_t domid, diff -r 48256256333b xen/arch/x86/domctl.c --- a/xen/arch/x86/domctl.c Mon Nov 15 11:54:43 2010 +0000 +++ b/xen/arch/x86/domctl.c Mon Nov 15 17:45:09 2010 +0000 @@ -953,6 +953,44 @@ } break; + case XEN_DOMCTL_iommu_map_batch: + { + struct domain *d; + unsigned long gfn = domctl->u.iommu_map_batch.gfn; + unsigned long nr = domctl->u.iommu_map_batch.nr; + unsigned long mfn; + int i = 0; + + printk("iommu_map_batch: domid_to:%d gfn:0x%lx size:0x%lx\n", + domctl->domain, gfn, nr); + + ret = -EINVAL; + if ( (gfn + nr - 1) < gfn) /* wrap? */ + break; + + ret = -ESRCH; + if ( unlikely((d = rcu_lock_domain_by_id(domctl->domain)) == NULL) ) + break; + + if (d != current->domain) + domain_pause(d); + for ( i = 0; i < nr; i++) + { + ret = -EFAULT; + if (copy_from_guest_offset(&mfn, domctl->u.iommu_map_batch.mfns, i, 1)) + break; + if ((ret = iommu_set_entry(d, gfn + i, mfn, IOMMUF_readable|IOMMUF_writable, 1)) != 0) + break; + } + if (i) + iommu_flush_iotlb(d, gfn, nr - ( nr - i)); + if (d != current->domain) + domain_unpause(d); + + rcu_unlock_domain(d); + } + break; + case XEN_DOMCTL_memory_mapping: { struct domain *d; diff -r 48256256333b xen/include/public/domctl.h --- a/xen/include/public/domctl.h Mon Nov 15 11:54:43 2010 +0000 +++ b/xen/include/public/domctl.h Mon Nov 15 17:45:09 2010 +0000 @@ -517,6 +517,13 @@ typedef struct xen_domctl_memory_mapping xen_domctl_memory_mapping_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_memory_mapping_t); +struct xen_domctl_iommu_map_batch { + uint64_aligned_t gfn; + uint64_aligned_t nr; + XEN_GUEST_HANDLE_64(uint64) mfns; +}; +typedef struct xen_domctl_iommu_map_batch xen_domctl_iommu_map_batch_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_iommu_map_batch_t); /* Bind machine I/O port range -> HVM I/O port range. */ /* XEN_DOMCTL_ioport_mapping */ @@ -868,6 +875,7 @@ #define XEN_DOMCTL_getpageframeinfo3 61 #define XEN_DOMCTL_setvcpuextstate 62 #define XEN_DOMCTL_getvcpuextstate 63 +#define XEN_DOMCTL_iommu_map_batch 64 #define XEN_DOMCTL_gdbsx_guestmemio 1000 #define XEN_DOMCTL_gdbsx_pausevcpu 1001 #define XEN_DOMCTL_gdbsx_unpausevcpu 1002 @@ -907,6 +915,7 @@ struct xen_domctl_assign_device assign_device; struct xen_domctl_bind_pt_irq bind_pt_irq; struct xen_domctl_memory_mapping memory_mapping; + struct xen_domctl_iommu_map_batch iommu_map_batch; struct xen_domctl_ioport_mapping ioport_mapping; struct xen_domctl_pin_mem_cacheattr pin_mem_cacheattr; struct xen_domctl_ext_vcpucontext ext_vcpucontext;