Merge tag 'for-linus-4.18-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip

Pull xen fixes from Juergen Gross:
"This contains the following fixes/cleanups:

- the removal of a BUG_ON() which wasn't necessary and which could
trigger now due to a recent change

- a correction of a long standing bug happening very rarely in Xen
dom0 when a hypercall buffer from user land was not accessible by
the hypervisor for very short periods of time due to e.g. page
migration or compaction

- usage of EXPORT_SYMBOL_GPL() instead of EXPORT_SYMBOL() in a
Xen-related driver (no breakage possible as using those symbols
without others already exported via EXPORT-SYMBOL_GPL() wouldn't
make any sense)

- a simplification for Xen PVH or Xen ARM guests

- some additional error handling for callers of xenbus_printf()"

* tag 'for-linus-4.18-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
xen: Remove unnecessary BUG_ON from __unbind_from_irq()
xen: add new hypercall buffer mapping device
xen/scsiback: add error handling for xenbus_printf
scsi: xen-scsifront: add error handling for xenbus_printf
xen/grant-table: Export gnttab_{alloc|free}_pages as GPL
xen: add error handling for xenbus_printf
xen: share start flags between PV and PVH

+297 -22
+4 -3
arch/arm/xen/enlighten.c
··· 59 59 60 60 static __read_mostly unsigned int xen_events_irq; 61 61 62 + uint32_t xen_start_flags; 63 + EXPORT_SYMBOL(xen_start_flags); 64 + 62 65 int xen_remap_domain_gfn_array(struct vm_area_struct *vma, 63 66 unsigned long addr, 64 67 xen_pfn_t *gfn, int nr, ··· 296 293 xen_setup_features(); 297 294 298 295 if (xen_feature(XENFEAT_dom0)) 299 - xen_start_info->flags |= SIF_INITDOMAIN|SIF_PRIVILEGED; 300 - else 301 - xen_start_info->flags &= ~(SIF_INITDOMAIN|SIF_PRIVILEGED); 296 + xen_start_flags |= SIF_INITDOMAIN|SIF_PRIVILEGED; 302 297 303 298 if (!console_set_on_cmdline && !xen_initial_domain()) 304 299 add_preferred_console("hvc", 0, NULL);
+7
arch/x86/xen/enlighten.c
··· 65 65 EXPORT_SYMBOL_GPL(xen_have_vector_callback); 66 66 67 67 /* 68 + * NB: needs to live in .data because it's used by xen_prepare_pvh which runs 69 + * before clearing the bss. 70 + */ 71 + uint32_t xen_start_flags __attribute__((section(".data"))) = 0; 72 + EXPORT_SYMBOL(xen_start_flags); 73 + 74 + /* 68 75 * Point at some empty memory to start with. We map the real shared_info 69 76 * page as soon as fixmap is up and running. 70 77 */
+1
arch/x86/xen/enlighten_pv.c
··· 1203 1203 return; 1204 1204 1205 1205 xen_domain_type = XEN_PV_DOMAIN; 1206 + xen_start_flags = xen_start_info->flags; 1206 1207 1207 1208 xen_setup_features(); 1208 1209
+1
arch/x86/xen/enlighten_pvh.c
··· 97 97 } 98 98 99 99 xen_pvh = 1; 100 + xen_start_flags = pvh_start_info.flags; 100 101 101 102 msr = cpuid_ebx(xen_cpuid_base() + 2); 102 103 pfn = __pa(hypercall_page);
+26 -7
drivers/scsi/xen-scsifront.c
··· 654 654 static int scsifront_sdev_configure(struct scsi_device *sdev) 655 655 { 656 656 struct vscsifrnt_info *info = shost_priv(sdev->host); 657 + int err; 657 658 658 - if (info && current == info->curr) 659 - xenbus_printf(XBT_NIL, info->dev->nodename, 659 + if (info && current == info->curr) { 660 + err = xenbus_printf(XBT_NIL, info->dev->nodename, 660 661 info->dev_state_path, "%d", XenbusStateConnected); 662 + if (err) { 663 + xenbus_dev_error(info->dev, err, 664 + "%s: writing dev_state_path", __func__); 665 + return err; 666 + } 667 + } 661 668 662 669 return 0; 663 670 } ··· 672 665 static void scsifront_sdev_destroy(struct scsi_device *sdev) 673 666 { 674 667 struct vscsifrnt_info *info = shost_priv(sdev->host); 668 + int err; 675 669 676 - if (info && current == info->curr) 677 - xenbus_printf(XBT_NIL, info->dev->nodename, 670 + if (info && current == info->curr) { 671 + err = xenbus_printf(XBT_NIL, info->dev->nodename, 678 672 info->dev_state_path, "%d", XenbusStateClosed); 673 + if (err) 674 + xenbus_dev_error(info->dev, err, 675 + "%s: writing dev_state_path", __func__); 676 + } 679 677 } 680 678 681 679 static struct scsi_host_template scsifront_sht = { ··· 1015 1003 1016 1004 if (scsi_add_device(info->host, chn, tgt, lun)) { 1017 1005 dev_err(&dev->dev, "scsi_add_device\n"); 1018 - xenbus_printf(XBT_NIL, dev->nodename, 1006 + err = xenbus_printf(XBT_NIL, dev->nodename, 1019 1007 info->dev_state_path, 1020 1008 "%d", XenbusStateClosed); 1009 + if (err) 1010 + xenbus_dev_error(dev, err, 1011 + "%s: writing dev_state_path", __func__); 1021 1012 } 1022 1013 break; 1023 1014 case VSCSIFRONT_OP_DEL_LUN: ··· 1034 1019 } 1035 1020 break; 1036 1021 case VSCSIFRONT_OP_READD_LUN: 1037 - if (device_state == XenbusStateConnected) 1038 - xenbus_printf(XBT_NIL, dev->nodename, 1022 + if (device_state == XenbusStateConnected) { 1023 + err = xenbus_printf(XBT_NIL, dev->nodename, 1039 1024 info->dev_state_path, 1040 1025 "%d", XenbusStateConnected); 1026 + if (err) 1027 + xenbus_dev_error(dev, err, 1028 + "%s: writing dev_state_path", __func__); 1029 + } 1041 1030 break; 1042 1031 default: 1043 1032 break;
+1 -1
drivers/xen/Makefile
··· 41 41 xen-evtchn-y := evtchn.o 42 42 xen-gntdev-y := gntdev.o 43 43 xen-gntalloc-y := gntalloc.o 44 - xen-privcmd-y := privcmd.o 44 + xen-privcmd-y := privcmd.o privcmd-buf.o
-2
drivers/xen/events/events_base.c
··· 628 628 xen_irq_info_cleanup(info); 629 629 } 630 630 631 - BUG_ON(info_for_irq(irq)->type == IRQT_UNBOUND); 632 - 633 631 xen_free_irq(irq); 634 632 } 635 633
+2 -2
drivers/xen/grant-table.c
··· 799 799 800 800 return 0; 801 801 } 802 - EXPORT_SYMBOL(gnttab_alloc_pages); 802 + EXPORT_SYMBOL_GPL(gnttab_alloc_pages); 803 803 804 804 /** 805 805 * gnttab_free_pages - free pages allocated by gnttab_alloc_pages() ··· 820 820 } 821 821 free_xenballooned_pages(nr_pages, pages); 822 822 } 823 - EXPORT_SYMBOL(gnttab_free_pages); 823 + EXPORT_SYMBOL_GPL(gnttab_free_pages); 824 824 825 825 /* Handling of paged out grant targets (GNTST_eagain) */ 826 826 #define MAX_DELAY 256
+15 -3
drivers/xen/manage.c
··· 289 289 return; 290 290 } 291 291 292 - if (sysrq_key != '\0') 293 - xenbus_printf(xbt, "control", "sysrq", "%c", '\0'); 292 + if (sysrq_key != '\0') { 293 + err = xenbus_printf(xbt, "control", "sysrq", "%c", '\0'); 294 + if (err) { 295 + pr_err("%s: Error %d writing sysrq in control/sysrq\n", 296 + __func__, err); 297 + xenbus_transaction_end(xbt, 1); 298 + return; 299 + } 300 + } 294 301 295 302 err = xenbus_transaction_end(xbt, 0); 296 303 if (err == -EAGAIN) ··· 349 342 continue; 350 343 snprintf(node, FEATURE_PATH_SIZE, "feature-%s", 351 344 shutdown_handlers[idx].command); 352 - xenbus_printf(XBT_NIL, "control", node, "%u", 1); 345 + err = xenbus_printf(XBT_NIL, "control", node, "%u", 1); 346 + if (err) { 347 + pr_err("%s: Error %d writing %s\n", __func__, 348 + err, node); 349 + return err; 350 + } 353 351 } 354 352 355 353 return 0;
+210
drivers/xen/privcmd-buf.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 OR MIT 2 + 3 + /****************************************************************************** 4 + * privcmd-buf.c 5 + * 6 + * Mmap of hypercall buffers. 7 + * 8 + * Copyright (c) 2018 Juergen Gross 9 + */ 10 + 11 + #define pr_fmt(fmt) "xen:" KBUILD_MODNAME ": " fmt 12 + 13 + #include <linux/kernel.h> 14 + #include <linux/module.h> 15 + #include <linux/list.h> 16 + #include <linux/miscdevice.h> 17 + #include <linux/mm.h> 18 + #include <linux/slab.h> 19 + 20 + #include "privcmd.h" 21 + 22 + MODULE_LICENSE("GPL"); 23 + 24 + static unsigned int limit = 64; 25 + module_param(limit, uint, 0644); 26 + MODULE_PARM_DESC(limit, "Maximum number of pages that may be allocated by " 27 + "the privcmd-buf device per open file"); 28 + 29 + struct privcmd_buf_private { 30 + struct mutex lock; 31 + struct list_head list; 32 + unsigned int allocated; 33 + }; 34 + 35 + struct privcmd_buf_vma_private { 36 + struct privcmd_buf_private *file_priv; 37 + struct list_head list; 38 + unsigned int users; 39 + unsigned int n_pages; 40 + struct page *pages[]; 41 + }; 42 + 43 + static int privcmd_buf_open(struct inode *ino, struct file *file) 44 + { 45 + struct privcmd_buf_private *file_priv; 46 + 47 + file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL); 48 + if (!file_priv) 49 + return -ENOMEM; 50 + 51 + mutex_init(&file_priv->lock); 52 + INIT_LIST_HEAD(&file_priv->list); 53 + 54 + file->private_data = file_priv; 55 + 56 + return 0; 57 + } 58 + 59 + static void privcmd_buf_vmapriv_free(struct privcmd_buf_vma_private *vma_priv) 60 + { 61 + unsigned int i; 62 + 63 + vma_priv->file_priv->allocated -= vma_priv->n_pages; 64 + 65 + list_del(&vma_priv->list); 66 + 67 + for (i = 0; i < vma_priv->n_pages; i++) 68 + if (vma_priv->pages[i]) 69 + __free_page(vma_priv->pages[i]); 70 + 71 + kfree(vma_priv); 72 + } 73 + 74 + static int privcmd_buf_release(struct inode *ino, struct file *file) 75 + { 76 + struct privcmd_buf_private *file_priv = file->private_data; 77 + struct privcmd_buf_vma_private *vma_priv; 78 + 79 + mutex_lock(&file_priv->lock); 80 + 81 + while (!list_empty(&file_priv->list)) { 82 + vma_priv = list_first_entry(&file_priv->list, 83 + struct privcmd_buf_vma_private, 84 + list); 85 + privcmd_buf_vmapriv_free(vma_priv); 86 + } 87 + 88 + mutex_unlock(&file_priv->lock); 89 + 90 + kfree(file_priv); 91 + 92 + return 0; 93 + } 94 + 95 + static void privcmd_buf_vma_open(struct vm_area_struct *vma) 96 + { 97 + struct privcmd_buf_vma_private *vma_priv = vma->vm_private_data; 98 + 99 + if (!vma_priv) 100 + return; 101 + 102 + mutex_lock(&vma_priv->file_priv->lock); 103 + vma_priv->users++; 104 + mutex_unlock(&vma_priv->file_priv->lock); 105 + } 106 + 107 + static void privcmd_buf_vma_close(struct vm_area_struct *vma) 108 + { 109 + struct privcmd_buf_vma_private *vma_priv = vma->vm_private_data; 110 + struct privcmd_buf_private *file_priv; 111 + 112 + if (!vma_priv) 113 + return; 114 + 115 + file_priv = vma_priv->file_priv; 116 + 117 + mutex_lock(&file_priv->lock); 118 + 119 + vma_priv->users--; 120 + if (!vma_priv->users) 121 + privcmd_buf_vmapriv_free(vma_priv); 122 + 123 + mutex_unlock(&file_priv->lock); 124 + } 125 + 126 + static vm_fault_t privcmd_buf_vma_fault(struct vm_fault *vmf) 127 + { 128 + pr_debug("fault: vma=%p %lx-%lx, pgoff=%lx, uv=%p\n", 129 + vmf->vma, vmf->vma->vm_start, vmf->vma->vm_end, 130 + vmf->pgoff, (void *)vmf->address); 131 + 132 + return VM_FAULT_SIGBUS; 133 + } 134 + 135 + static const struct vm_operations_struct privcmd_buf_vm_ops = { 136 + .open = privcmd_buf_vma_open, 137 + .close = privcmd_buf_vma_close, 138 + .fault = privcmd_buf_vma_fault, 139 + }; 140 + 141 + static int privcmd_buf_mmap(struct file *file, struct vm_area_struct *vma) 142 + { 143 + struct privcmd_buf_private *file_priv = file->private_data; 144 + struct privcmd_buf_vma_private *vma_priv; 145 + unsigned long count = vma_pages(vma); 146 + unsigned int i; 147 + int ret = 0; 148 + 149 + if (!(vma->vm_flags & VM_SHARED) || count > limit || 150 + file_priv->allocated + count > limit) 151 + return -EINVAL; 152 + 153 + vma_priv = kzalloc(sizeof(*vma_priv) + count * sizeof(void *), 154 + GFP_KERNEL); 155 + if (!vma_priv) 156 + return -ENOMEM; 157 + 158 + vma_priv->n_pages = count; 159 + count = 0; 160 + for (i = 0; i < vma_priv->n_pages; i++) { 161 + vma_priv->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO); 162 + if (!vma_priv->pages[i]) 163 + break; 164 + count++; 165 + } 166 + 167 + mutex_lock(&file_priv->lock); 168 + 169 + file_priv->allocated += count; 170 + 171 + vma_priv->file_priv = file_priv; 172 + vma_priv->users = 1; 173 + 174 + vma->vm_flags |= VM_IO | VM_DONTEXPAND; 175 + vma->vm_ops = &privcmd_buf_vm_ops; 176 + vma->vm_private_data = vma_priv; 177 + 178 + list_add(&vma_priv->list, &file_priv->list); 179 + 180 + if (vma_priv->n_pages != count) 181 + ret = -ENOMEM; 182 + else 183 + for (i = 0; i < vma_priv->n_pages; i++) { 184 + ret = vm_insert_page(vma, vma->vm_start + i * PAGE_SIZE, 185 + vma_priv->pages[i]); 186 + if (ret) 187 + break; 188 + } 189 + 190 + if (ret) 191 + privcmd_buf_vmapriv_free(vma_priv); 192 + 193 + mutex_unlock(&file_priv->lock); 194 + 195 + return ret; 196 + } 197 + 198 + const struct file_operations xen_privcmdbuf_fops = { 199 + .owner = THIS_MODULE, 200 + .open = privcmd_buf_open, 201 + .release = privcmd_buf_release, 202 + .mmap = privcmd_buf_mmap, 203 + }; 204 + EXPORT_SYMBOL_GPL(xen_privcmdbuf_fops); 205 + 206 + struct miscdevice xen_privcmdbuf_dev = { 207 + .minor = MISC_DYNAMIC_MINOR, 208 + .name = "xen/hypercall", 209 + .fops = &xen_privcmdbuf_fops, 210 + };
+9
drivers/xen/privcmd.c
··· 1007 1007 pr_err("Could not register Xen privcmd device\n"); 1008 1008 return err; 1009 1009 } 1010 + 1011 + err = misc_register(&xen_privcmdbuf_dev); 1012 + if (err != 0) { 1013 + pr_err("Could not register Xen hypercall-buf device\n"); 1014 + misc_deregister(&privcmd_dev); 1015 + return err; 1016 + } 1017 + 1010 1018 return 0; 1011 1019 } 1012 1020 1013 1021 static void __exit privcmd_exit(void) 1014 1022 { 1015 1023 misc_deregister(&privcmd_dev); 1024 + misc_deregister(&xen_privcmdbuf_dev); 1016 1025 } 1017 1026 1018 1027 module_init(privcmd_init);
+3
drivers/xen/privcmd.h
··· 1 1 #include <linux/fs.h> 2 2 3 3 extern const struct file_operations xen_privcmd_fops; 4 + extern const struct file_operations xen_privcmdbuf_fops; 5 + 6 + extern struct miscdevice xen_privcmdbuf_dev;
+13 -3
drivers/xen/xen-scsiback.c
··· 1012 1012 { 1013 1013 struct v2p_entry *entry; 1014 1014 unsigned long flags; 1015 + int err; 1015 1016 1016 1017 if (try) { 1017 1018 spin_lock_irqsave(&info->v2p_lock, flags); ··· 1028 1027 scsiback_del_translation_entry(info, vir); 1029 1028 } 1030 1029 } else if (!try) { 1031 - xenbus_printf(XBT_NIL, info->dev->nodename, state, 1030 + err = xenbus_printf(XBT_NIL, info->dev->nodename, state, 1032 1031 "%d", XenbusStateClosed); 1032 + if (err) 1033 + xenbus_dev_error(info->dev, err, 1034 + "%s: writing %s", __func__, state); 1033 1035 } 1034 1036 } 1035 1037 ··· 1071 1067 snprintf(str, sizeof(str), "vscsi-devs/%s/p-dev", ent); 1072 1068 val = xenbus_read(XBT_NIL, dev->nodename, str, NULL); 1073 1069 if (IS_ERR(val)) { 1074 - xenbus_printf(XBT_NIL, dev->nodename, state, 1070 + err = xenbus_printf(XBT_NIL, dev->nodename, state, 1075 1071 "%d", XenbusStateClosed); 1072 + if (err) 1073 + xenbus_dev_error(info->dev, err, 1074 + "%s: writing %s", __func__, state); 1076 1075 return; 1077 1076 } 1078 1077 strlcpy(phy, val, VSCSI_NAMELEN); ··· 1086 1079 err = xenbus_scanf(XBT_NIL, dev->nodename, str, "%u:%u:%u:%u", 1087 1080 &vir.hst, &vir.chn, &vir.tgt, &vir.lun); 1088 1081 if (XENBUS_EXIST_ERR(err)) { 1089 - xenbus_printf(XBT_NIL, dev->nodename, state, 1082 + err = xenbus_printf(XBT_NIL, dev->nodename, state, 1090 1083 "%d", XenbusStateClosed); 1084 + if (err) 1085 + xenbus_dev_error(info->dev, err, 1086 + "%s: writing %s", __func__, state); 1091 1087 return; 1092 1088 } 1093 1089
+5 -1
include/xen/xen.h
··· 25 25 #define xen_hvm_domain() (xen_domain_type == XEN_HVM_DOMAIN) 26 26 #define xen_pvh_domain() (xen_pvh) 27 27 28 + #include <linux/types.h> 29 + 30 + extern uint32_t xen_start_flags; 31 + 28 32 #ifdef CONFIG_XEN_DOM0 29 33 #include <xen/interface/xen.h> 30 34 #include <asm/xen/hypervisor.h> 31 35 32 36 #define xen_initial_domain() (xen_domain() && \ 33 - xen_start_info && xen_start_info->flags & SIF_INITDOMAIN) 37 + (xen_start_flags & SIF_INITDOMAIN)) 34 38 #else /* !CONFIG_XEN_DOM0 */ 35 39 #define xen_initial_domain() (0) 36 40 #endif /* CONFIG_XEN_DOM0 */