From 4bf2cc9645599382e34b7d0cbe5a13d0de98194e Mon Sep 17 00:00:00 2001 From: Souptick Joarder Date: Sun, 15 Apr 2018 00:45:42 +0530 Subject: xen: Change return type to vm_fault_t Use new return type vm_fault_t for fault handler in struct vm_operations_struct. Signed-off-by: Souptick Joarder Reviewed-by: Matthew Wilcox Reviewed-by: Juergen Gross Signed-off-by: Juergen Gross --- drivers/xen/privcmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c index 1c909183c42a..0a778d30d333 100644 --- a/drivers/xen/privcmd.c +++ b/drivers/xen/privcmd.c @@ -801,7 +801,7 @@ static void privcmd_close(struct vm_area_struct *vma) kfree(pages); } -static int privcmd_fault(struct vm_fault *vmf) +static vm_fault_t privcmd_fault(struct vm_fault *vmf) { printk(KERN_DEBUG "privcmd_fault: vma=%p %lx-%lx, pgoff=%lx, uv=%p\n", vmf->vma, vmf->vma->vm_start, vmf->vma->vm_end, -- cgit v1.2.3 From 3ad0876554cafa368f574d4d408468510543e9ff Mon Sep 17 00:00:00 2001 From: Paul Durrant Date: Wed, 9 May 2018 14:16:12 +0100 Subject: xen/privcmd: add IOCTL_PRIVCMD_MMAP_RESOURCE My recent Xen patch series introduces a new HYPERVISOR_memory_op to support direct priv-mapping of certain guest resources (such as ioreq pages, used by emulators) by a tools domain, rather than having to access such resources via the guest P2M. This patch adds the necessary infrastructure to the privcmd driver and Xen MMU code to support direct resource mapping. NOTE: The adjustment in the MMU code is partially cosmetic. Xen will now allow a PV tools domain to map guest pages either by GFN or MFN, thus the term 'mfn' has been swapped for 'pfn' in the lower layers of the remap code. Signed-off-by: Paul Durrant Reviewed-by: Boris Ostrovsky Signed-off-by: Juergen Gross --- drivers/xen/privcmd.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) (limited to 'drivers') diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c index 0a778d30d333..8ae0349d9f0a 100644 --- a/drivers/xen/privcmd.c +++ b/drivers/xen/privcmd.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -722,6 +723,134 @@ static long privcmd_ioctl_restrict(struct file *file, void __user *udata) return 0; } +struct remap_pfn { + struct mm_struct *mm; + struct page **pages; + pgprot_t prot; + unsigned long i; +}; + +static int remap_pfn_fn(pte_t *ptep, pgtable_t token, unsigned long addr, + void *data) +{ + struct remap_pfn *r = data; + struct page *page = r->pages[r->i]; + pte_t pte = pte_mkspecial(pfn_pte(page_to_pfn(page), r->prot)); + + set_pte_at(r->mm, addr, ptep, pte); + r->i++; + + return 0; +} + +static long privcmd_ioctl_mmap_resource(struct file *file, void __user *udata) +{ + struct privcmd_data *data = file->private_data; + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + struct privcmd_mmap_resource kdata; + xen_pfn_t *pfns = NULL; + struct xen_mem_acquire_resource xdata; + int rc; + + if (copy_from_user(&kdata, udata, sizeof(kdata))) + return -EFAULT; + + /* If restriction is in place, check the domid matches */ + if (data->domid != DOMID_INVALID && data->domid != kdata.dom) + return -EPERM; + + down_write(&mm->mmap_sem); + + vma = find_vma(mm, kdata.addr); + if (!vma || vma->vm_ops != &privcmd_vm_ops) { + rc = -EINVAL; + goto out; + } + + pfns = kcalloc(kdata.num, sizeof(*pfns), GFP_KERNEL); + if (!pfns) { + rc = -ENOMEM; + goto out; + } + + if (xen_feature(XENFEAT_auto_translated_physmap)) { + unsigned int nr = DIV_ROUND_UP(kdata.num, XEN_PFN_PER_PAGE); + struct page **pages; + unsigned int i; + + rc = alloc_empty_pages(vma, nr); + if (rc < 0) + goto out; + + pages = vma->vm_private_data; + for (i = 0; i < kdata.num; i++) { + xen_pfn_t pfn = + page_to_xen_pfn(pages[i / XEN_PFN_PER_PAGE]); + + pfns[i] = pfn + (i % XEN_PFN_PER_PAGE); + } + } else + vma->vm_private_data = PRIV_VMA_LOCKED; + + memset(&xdata, 0, sizeof(xdata)); + xdata.domid = kdata.dom; + xdata.type = kdata.type; + xdata.id = kdata.id; + xdata.frame = kdata.idx; + xdata.nr_frames = kdata.num; + set_xen_guest_handle(xdata.frame_list, pfns); + + xen_preemptible_hcall_begin(); + rc = HYPERVISOR_memory_op(XENMEM_acquire_resource, &xdata); + xen_preemptible_hcall_end(); + + if (rc) + goto out; + + if (xen_feature(XENFEAT_auto_translated_physmap)) { + struct remap_pfn r = { + .mm = vma->vm_mm, + .pages = vma->vm_private_data, + .prot = vma->vm_page_prot, + }; + + rc = apply_to_page_range(r.mm, kdata.addr, + kdata.num << PAGE_SHIFT, + remap_pfn_fn, &r); + } else { + unsigned int domid = + (xdata.flags & XENMEM_rsrc_acq_caller_owned) ? + DOMID_SELF : kdata.dom; + int num; + + num = xen_remap_domain_mfn_array(vma, + kdata.addr & PAGE_MASK, + pfns, kdata.num, (int *)pfns, + vma->vm_page_prot, + domid, + vma->vm_private_data); + if (num < 0) + rc = num; + else if (num != kdata.num) { + unsigned int i; + + for (i = 0; i < num; i++) { + rc = pfns[i]; + if (rc < 0) + break; + } + } else + rc = 0; + } + +out: + up_write(&mm->mmap_sem); + kfree(pfns); + + return rc; +} + static long privcmd_ioctl(struct file *file, unsigned int cmd, unsigned long data) { @@ -753,6 +882,10 @@ static long privcmd_ioctl(struct file *file, ret = privcmd_ioctl_restrict(file, udata); break; + case IOCTL_PRIVCMD_MMAP_RESOURCE: + ret = privcmd_ioctl_mmap_resource(file, udata); + break; + default: break; } -- cgit v1.2.3 From 24a94b3c1268635d64333ce58e7cc31ee5932125 Mon Sep 17 00:00:00 2001 From: Luc Van Oostenryck Date: Tue, 24 Apr 2018 15:18:14 +0200 Subject: xen-netfront: fix xennet_start_xmit()'s return type The method ndo_start_xmit() is defined as returning an 'netdev_tx_t', which is a typedef for an enum type, but the implementation in this driver returns an 'int'. Fix this by returning 'netdev_tx_t' in this driver too. Signed-off-by: Luc Van Oostenryck Reviewed-by: Wei Liu Signed-off-by: Juergen Gross --- drivers/net/xen-netfront.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 4dd0668003e7..679da1abd73c 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -564,7 +564,7 @@ static u16 xennet_select_queue(struct net_device *dev, struct sk_buff *skb, #define MAX_XEN_SKB_FRAGS (65536 / XEN_PAGE_SIZE + 1) -static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct netfront_info *np = netdev_priv(dev); struct netfront_stats *tx_stats = this_cpu_ptr(np->tx_stats); -- cgit v1.2.3 From 515e6541f54e90513fe4cd91f69d737a891f1c79 Mon Sep 17 00:00:00 2001 From: Roger Pau Monne Date: Wed, 9 May 2018 11:21:28 +0100 Subject: xen/store: do not store local values in xen_start_info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's no need to store the xenstore page or event channel in xen_start_info if they are locally initialized. This also fixes PVH local xenstore initialization due to the lack of xen_start_info in that case. Signed-off-by: Boris Ostrovsky Signed-off-by: Roger Pau Monné Reviewed-by: Juergen Gross Signed-off-by: Juergen Gross --- drivers/xen/xenbus/xenbus_probe.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index ec9eb4fba59c..f2088838f690 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c @@ -710,7 +710,7 @@ static int __init xenstored_local_init(void) if (!page) goto out_err; - xen_store_gfn = xen_start_info->store_mfn = virt_to_gfn((void *)page); + xen_store_gfn = virt_to_gfn((void *)page); /* Next allocate a local port which xenstored can bind to */ alloc_unbound.dom = DOMID_SELF; @@ -722,8 +722,7 @@ static int __init xenstored_local_init(void) goto out_err; BUG_ON(err); - xen_store_evtchn = xen_start_info->store_evtchn = - alloc_unbound.port; + xen_store_evtchn = alloc_unbound.port; return 0; -- cgit v1.2.3