History

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

Pull xen updates from Juergen Gross: - two small cleanup patches - a fix for PCI passthrough under Xen - a four patch series speeding up virtio under Xen with user space backends * tag 'for-linus-6.7-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: xen-pciback: Consider INTx disabled when MSI/MSI-X is enabled xen: privcmd: Add support for ioeventfd xen: evtchn: Allow shared registration of IRQ handers xen: irqfd: Use _IOW instead of the internal _IOC() macro xen: Make struct privcmd_irqfd's layout architecture independent xen/xenbus: Add __counted_by for struct read_buffer and use struct_size() xenbus: fix error exit in xenbus_init()

Linus Torvalds committed 3 years ago

Commit ca995ce2 parents 8999ad9 2c269f411 files · +508 −39Browse files

Unified · Split

11 files
  1. drivers/xen/Kconfig +4 −4
  2. drivers/xen/events/events_base.c +2 −1
  3. drivers/xen/evtchn.c +1 −1
  4. drivers/xen/privcmd.c +404 −3
  5. drivers/xen/xen-pciback/conf_space.c +13 −6
  6. drivers/xen/xen-pciback/conf_space_capability.c +7 −1
  7. drivers/xen/xen-pciback/conf_space_header.c +3 −18
  8. drivers/xen/xenbus/xenbus_dev_frontend.c +2 −2
  9. drivers/xen/xenbus/xenbus_probe.c +1 −1
  10. include/uapi/xen/privcmd.h +20 −2
  11. include/xen/interface/hvm/ioreq.h +51 −0
drivers/xen/Kconfig+4−4
@@ -269,12 +269,12 @@ config XEN_PRIVCMD · 268 unmodified lines
269 disaggregated Xen setups this driver might be needed for other269 disaggregated Xen setups this driver might be needed for other
270 domains, too.270 domains, too.
271 271
272config XEN_PRIVCMD_IRQFD272config XEN_PRIVCMD_EVENTFD
273 bool "Xen irqfd support"273 bool "Xen Ioeventfd and irqfd support"
274 depends on XEN_PRIVCMD && XEN_VIRTIO && EVENTFD274 depends on XEN_PRIVCMD && XEN_VIRTIO && EVENTFD
275 help275 help
276 Using the irqfd mechanism a virtio backend running in a daemon can276 Using the ioeventfd / irqfd mechanism a virtio backend running in a
277 speed up interrupt injection into a guest.277 daemon can speed up interrupt delivery from / to a guest.
278 278
279config XEN_ACPI_PROCESSOR279config XEN_ACPI_PROCESSOR
280 tristate "Xen ACPI processor"280 tristate "Xen ACPI processor"
drivers/xen/events/events_base.c+2−1
@@ -1229,7 +1229,8 @@ static int bind_evtchn_to_irq_chip(evtchn_port_t evtchn, struct irq_chip *chip, · 1228 unmodified lines
1229 bind_evtchn_to_cpu(evtchn, 0, false);1229 bind_evtchn_to_cpu(evtchn, 0, false);
1230 } else {1230 } else {
1231 struct irq_info *info = info_for_irq(irq);1231 struct irq_info *info = info_for_irq(irq);
1232 WARN_ON(info == NULL || info->type != IRQT_EVTCHN);1232 if (!WARN_ON(!info || info->type != IRQT_EVTCHN))
1233 info->refcnt++;
1233 }1234 }
1234 1235
1235out:1236out:
drivers/xen/evtchn.c+1−1
@@ -397,7 +397,7 @@ static int evtchn_bind_to_user(struct per_user_data *u, evtchn_port_t port, · 396 unmodified lines
397 if (rc < 0)397 if (rc < 0)
398 goto err;398 goto err;
399 399
400 rc = bind_evtchn_to_irqhandler_lateeoi(port, evtchn_interrupt, 0,400 rc = bind_evtchn_to_irqhandler_lateeoi(port, evtchn_interrupt, IRQF_SHARED,
401 u->name, evtchn);401 u->name, evtchn);
402 if (rc < 0)402 if (rc < 0)
403 goto err;403 goto err;
drivers/xen/privcmd.c+404−3
@@ -29,15 +29,18 @@ · 28 unmodified lines
29#include <linux/seq_file.h>29#include <linux/seq_file.h>
30#include <linux/miscdevice.h>30#include <linux/miscdevice.h>
31#include <linux/moduleparam.h>31#include <linux/moduleparam.h>
32#include <linux/virtio_mmio.h>
32 33
33#include <asm/xen/hypervisor.h>34#include <asm/xen/hypervisor.h>
34#include <asm/xen/hypercall.h>35#include <asm/xen/hypercall.h>
35 36
36#include <xen/xen.h>37#include <xen/xen.h>
38#include <xen/events.h>
37#include <xen/privcmd.h>39#include <xen/privcmd.h>
38#include <xen/interface/xen.h>40#include <xen/interface/xen.h>
39#include <xen/interface/memory.h>41#include <xen/interface/memory.h>
40#include <xen/interface/hvm/dm_op.h>42#include <xen/interface/hvm/dm_op.h>
43#include <xen/interface/hvm/ioreq.h>
41#include <xen/features.h>44#include <xen/features.h>
42#include <xen/page.h>45#include <xen/page.h>
43#include <xen/xen-ops.h>46#include <xen/xen-ops.h>
@@ -782,6 +785,7 @@ static long privcmd_ioctl_mmap_resource(struct file *file, · 738 unmodified lines
782 goto out;785 goto out;
783 786
784 pages = vma->vm_private_data;787 pages = vma->vm_private_data;
788
785 for (i = 0; i < kdata.num; i++) {789 for (i = 0; i < kdata.num; i++) {
786 xen_pfn_t pfn =790 xen_pfn_t pfn =
787 page_to_xen_pfn(pages[i / XEN_PFN_PER_PAGE]);791 page_to_xen_pfn(pages[i / XEN_PFN_PER_PAGE]);
@@ -838,7 +842,7 @@ out: · 50 unmodified lines
838 return rc;842 return rc;
839}843}
840 844
841#ifdef CONFIG_XEN_PRIVCMD_IRQFD845#ifdef CONFIG_XEN_PRIVCMD_EVENTFD
842/* Irqfd support */846/* Irqfd support */
843static struct workqueue_struct *irqfd_cleanup_wq;847static struct workqueue_struct *irqfd_cleanup_wq;
844static DEFINE_MUTEX(irqfds_lock);848static DEFINE_MUTEX(irqfds_lock);
@@ -935,7 +939,7 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd) · 90 unmodified lines
935 return -ENOMEM;939 return -ENOMEM;
936 dm_op = kirqfd + 1;940 dm_op = kirqfd + 1;
937 941
938 if (copy_from_user(dm_op, irqfd->dm_op, irqfd->size)) {942 if (copy_from_user(dm_op, u64_to_user_ptr(irqfd->dm_op), irqfd->size)) {
939 ret = -EFAULT;943 ret = -EFAULT;
940 goto error_kfree;944 goto error_kfree;
941 }945 }
@@ -1079,6 +1083,389 @@ static void privcmd_irqfd_exit(void) · 137 unmodified lines
1079 1083
1080 destroy_workqueue(irqfd_cleanup_wq);1084 destroy_workqueue(irqfd_cleanup_wq);
1081}1085}
1086
1087/* Ioeventfd Support */
1088#define QUEUE_NOTIFY_VQ_MASK 0xFFFF
1089
1090static DEFINE_MUTEX(ioreq_lock);
1091static LIST_HEAD(ioreq_list);
1092
1093/* per-eventfd structure */
1094struct privcmd_kernel_ioeventfd {
1095 struct eventfd_ctx *eventfd;
1096 struct list_head list;
1097 u64 addr;
1098 unsigned int addr_len;
1099 unsigned int vq;
1100};
1101
1102/* per-guest CPU / port structure */
1103struct ioreq_port {
1104 int vcpu;
1105 unsigned int port;
1106 struct privcmd_kernel_ioreq *kioreq;
1107};
1108
1109/* per-guest structure */
1110struct privcmd_kernel_ioreq {
1111 domid_t dom;
1112 unsigned int vcpus;
1113 u64 uioreq;
1114 struct ioreq *ioreq;
1115 spinlock_t lock; /* Protects ioeventfds list */
1116 struct list_head ioeventfds;
1117 struct list_head list;
1118 struct ioreq_port ports[0];
1119};
1120
1121static irqreturn_t ioeventfd_interrupt(int irq, void *dev_id)
1122{
1123 struct ioreq_port *port = dev_id;
1124 struct privcmd_kernel_ioreq *kioreq = port->kioreq;
1125 struct ioreq *ioreq = &kioreq->ioreq[port->vcpu];
1126 struct privcmd_kernel_ioeventfd *kioeventfd;
1127 unsigned int state = STATE_IOREQ_READY;
1128
1129 if (ioreq->state != STATE_IOREQ_READY ||
1130 ioreq->type != IOREQ_TYPE_COPY || ioreq->dir != IOREQ_WRITE)
1131 return IRQ_NONE;
1132
1133 /*
1134 * We need a barrier, smp_mb(), here to ensure reads are finished before
1135 * `state` is updated. Since the lock implementation ensures that
1136 * appropriate barrier will be added anyway, we can avoid adding
1137 * explicit barrier here.
1138 *
1139 * Ideally we don't need to update `state` within the locks, but we do
1140 * that here to avoid adding explicit barrier.
1141 */
1142
1143 spin_lock(&kioreq->lock);
1144 ioreq->state = STATE_IOREQ_INPROCESS;
1145
1146 list_for_each_entry(kioeventfd, &kioreq->ioeventfds, list) {
1147 if (ioreq->addr == kioeventfd->addr + VIRTIO_MMIO_QUEUE_NOTIFY &&
1148 ioreq->size == kioeventfd->addr_len &&
1149 (ioreq->data & QUEUE_NOTIFY_VQ_MASK) == kioeventfd->vq) {
1150 eventfd_signal(kioeventfd->eventfd, 1);
1151 state = STATE_IORESP_READY;
1152 break;
1153 }
1154 }
1155 spin_unlock(&kioreq->lock);
1156
1157 /*
1158 * We need a barrier, smp_mb(), here to ensure writes are finished
1159 * before `state` is updated. Since the lock implementation ensures that
1160 * appropriate barrier will be added anyway, we can avoid adding
1161 * explicit barrier here.
1162 */
1163
1164 ioreq->state = state;
1165
1166 if (state == STATE_IORESP_READY) {
1167 notify_remote_via_evtchn(port->port);
1168 return IRQ_HANDLED;
1169 }
1170
1171 return IRQ_NONE;
1172}
1173
1174static void ioreq_free(struct privcmd_kernel_ioreq *kioreq)
1175{
1176 struct ioreq_port *ports = kioreq->ports;
1177 int i;
1178
1179 lockdep_assert_held(&ioreq_lock);
1180
1181 list_del(&kioreq->list);
1182
1183 for (i = kioreq->vcpus - 1; i >= 0; i--)
1184 unbind_from_irqhandler(irq_from_evtchn(ports[i].port), &ports[i]);
1185
1186 kfree(kioreq);
1187}
1188
1189static
1190struct privcmd_kernel_ioreq *alloc_ioreq(struct privcmd_ioeventfd *ioeventfd)
1191{
1192 struct privcmd_kernel_ioreq *kioreq;
1193 struct mm_struct *mm = current->mm;
1194 struct vm_area_struct *vma;
1195 struct page **pages;
1196 unsigned int *ports;
1197 int ret, size, i;
1198
1199 lockdep_assert_held(&ioreq_lock);
1200
1201 size = struct_size(kioreq, ports, ioeventfd->vcpus);
1202 kioreq = kzalloc(size, GFP_KERNEL);
1203 if (!kioreq)
1204 return ERR_PTR(-ENOMEM);
1205
1206 kioreq->dom = ioeventfd->dom;
1207 kioreq->vcpus = ioeventfd->vcpus;
1208 kioreq->uioreq = ioeventfd->ioreq;
1209 spin_lock_init(&kioreq->lock);
1210 INIT_LIST_HEAD(&kioreq->ioeventfds);
1211
1212 /* The memory for ioreq server must have been mapped earlier */
1213 mmap_write_lock(mm);
1214 vma = find_vma(mm, (unsigned long)ioeventfd->ioreq);
1215 if (!vma) {
1216 pr_err("Failed to find vma for ioreq page!\n");
1217 mmap_write_unlock(mm);
1218 ret = -EFAULT;
1219 goto error_kfree;
1220 }
1221
1222 pages = vma->vm_private_data;
1223 kioreq->ioreq = (struct ioreq *)(page_to_virt(pages[0]));
1224 mmap_write_unlock(mm);
1225
1226 size = sizeof(*ports) * kioreq->vcpus;
1227 ports = kzalloc(size, GFP_KERNEL);
1228 if (!ports) {
1229 ret = -ENOMEM;
1230 goto error_kfree;
1231 }
1232
1233 if (copy_from_user(ports, u64_to_user_ptr(ioeventfd->ports), size)) {
1234 ret = -EFAULT;
1235 goto error_kfree_ports;
1236 }
1237
1238 for (i = 0; i < kioreq->vcpus; i++) {
1239 kioreq->ports[i].vcpu = i;
1240 kioreq->ports[i].port = ports[i];
1241 kioreq->ports[i].kioreq = kioreq;
1242
1243 ret = bind_evtchn_to_irqhandler_lateeoi(ports[i],
1244 ioeventfd_interrupt, IRQF_SHARED, "ioeventfd",
1245 &kioreq->ports[i]);
1246 if (ret < 0)
1247 goto error_unbind;
1248 }
1249
1250 kfree(ports);
1251
1252 list_add_tail(&kioreq->list, &ioreq_list);
1253
1254 return kioreq;
1255
1256error_unbind:
1257 while (--i >= 0)
1258 unbind_from_irqhandler(irq_from_evtchn(ports[i]), &kioreq->ports[i]);
1259error_kfree_ports:
1260 kfree(ports);
1261error_kfree:
1262 kfree(kioreq);
1263 return ERR_PTR(ret);
1264}
1265
1266static struct privcmd_kernel_ioreq *
1267get_ioreq(struct privcmd_ioeventfd *ioeventfd, struct eventfd_ctx *eventfd)
1268{
1269 struct privcmd_kernel_ioreq *kioreq;
1270 unsigned long flags;
1271
1272 list_for_each_entry(kioreq, &ioreq_list, list) {
1273 struct privcmd_kernel_ioeventfd *kioeventfd;
1274
1275 /*
1276 * kioreq fields can be accessed here without a lock as they are
1277 * never updated after being added to the ioreq_list.
1278 */
1279 if (kioreq->uioreq != ioeventfd->ioreq) {
1280 continue;
1281 } else if (kioreq->dom != ioeventfd->dom ||
1282 kioreq->vcpus != ioeventfd->vcpus) {
1283 pr_err("Invalid ioeventfd configuration mismatch, dom (%u vs %u), vcpus (%u vs %u)\n",
1284 kioreq->dom, ioeventfd->dom, kioreq->vcpus,
1285 ioeventfd->vcpus);
1286 return ERR_PTR(-EINVAL);
1287 }
1288
1289 /* Look for a duplicate eventfd for the same guest */
1290 spin_lock_irqsave(&kioreq->lock, flags);
1291 list_for_each_entry(kioeventfd, &kioreq->ioeventfds, list) {
1292 if (eventfd == kioeventfd->eventfd) {
1293 spin_unlock_irqrestore(&kioreq->lock, flags);
1294 return ERR_PTR(-EBUSY);
1295 }
1296 }
1297 spin_unlock_irqrestore(&kioreq->lock, flags);
1298
1299 return kioreq;
1300 }
1301
1302 /* Matching kioreq isn't found, allocate a new one */
1303 return alloc_ioreq(ioeventfd);
1304}
1305
1306static void ioeventfd_free(struct privcmd_kernel_ioeventfd *kioeventfd)
1307{
1308 list_del(&kioeventfd->list);
1309 eventfd_ctx_put(kioeventfd->eventfd);
1310 kfree(kioeventfd);
1311}
1312
1313static int privcmd_ioeventfd_assign(struct privcmd_ioeventfd *ioeventfd)
1314{
1315 struct privcmd_kernel_ioeventfd *kioeventfd;
1316 struct privcmd_kernel_ioreq *kioreq;
1317 unsigned long flags;
1318 struct fd f;
1319 int ret;
1320
1321 /* Check for range overflow */
1322 if (ioeventfd->addr + ioeventfd->addr_len < ioeventfd->addr)
1323 return -EINVAL;
1324
1325 /* Vhost requires us to support length 1, 2, 4, and 8 */
1326 if (!(ioeventfd->addr_len == 1 || ioeventfd->addr_len == 2 ||
1327 ioeventfd->addr_len == 4 || ioeventfd->addr_len == 8))
1328 return -EINVAL;
1329
1330 /* 4096 vcpus limit enough ? */
1331 if (!ioeventfd->vcpus || ioeventfd->vcpus > 4096)
1332 return -EINVAL;
1333
1334 kioeventfd = kzalloc(sizeof(*kioeventfd), GFP_KERNEL);
1335 if (!kioeventfd)
1336 return -ENOMEM;
1337
1338 f = fdget(ioeventfd->event_fd);
1339 if (!f.file) {
1340 ret = -EBADF;
1341 goto error_kfree;
1342 }
1343
1344 kioeventfd->eventfd = eventfd_ctx_fileget(f.file);
1345 fdput(f);
1346
1347 if (IS_ERR(kioeventfd->eventfd)) {
1348 ret = PTR_ERR(kioeventfd->eventfd);
1349 goto error_kfree;
1350 }
1351
1352 kioeventfd->addr = ioeventfd->addr;
1353 kioeventfd->addr_len = ioeventfd->addr_len;
1354 kioeventfd->vq = ioeventfd->vq;
1355
1356 mutex_lock(&ioreq_lock);
1357 kioreq = get_ioreq(ioeventfd, kioeventfd->eventfd);
1358 if (IS_ERR(kioreq)) {
1359 mutex_unlock(&ioreq_lock);
1360 ret = PTR_ERR(kioreq);
1361 goto error_eventfd;
1362 }
1363
1364 spin_lock_irqsave(&kioreq->lock, flags);
1365 list_add_tail(&kioeventfd->list, &kioreq->ioeventfds);
1366 spin_unlock_irqrestore(&kioreq->lock, flags);
1367
1368 mutex_unlock(&ioreq_lock);
1369
1370 return 0;
1371
1372error_eventfd:
1373 eventfd_ctx_put(kioeventfd->eventfd);
1374
1375error_kfree:
1376 kfree(kioeventfd);
1377 return ret;
1378}
1379
1380static int privcmd_ioeventfd_deassign(struct privcmd_ioeventfd *ioeventfd)
1381{
1382 struct privcmd_kernel_ioreq *kioreq, *tkioreq;
1383 struct eventfd_ctx *eventfd;
1384 unsigned long flags;
1385 int ret = 0;
1386
1387 eventfd = eventfd_ctx_fdget(ioeventfd->event_fd);
1388 if (IS_ERR(eventfd))
1389 return PTR_ERR(eventfd);
1390
1391 mutex_lock(&ioreq_lock);
1392 list_for_each_entry_safe(kioreq, tkioreq, &ioreq_list, list) {
1393 struct privcmd_kernel_ioeventfd *kioeventfd, *tmp;
1394 /*
1395 * kioreq fields can be accessed here without a lock as they are
1396 * never updated after being added to the ioreq_list.
1397 */
1398 if (kioreq->dom != ioeventfd->dom ||
1399 kioreq->uioreq != ioeventfd->ioreq ||
1400 kioreq->vcpus != ioeventfd->vcpus)
1401 continue;
1402
1403 spin_lock_irqsave(&kioreq->lock, flags);
1404 list_for_each_entry_safe(kioeventfd, tmp, &kioreq->ioeventfds, list) {
1405 if (eventfd == kioeventfd->eventfd) {
1406 ioeventfd_free(kioeventfd);
1407 spin_unlock_irqrestore(&kioreq->lock, flags);
1408
1409 if (list_empty(&kioreq->ioeventfds))
1410 ioreq_free(kioreq);
1411 goto unlock;
1412 }
1413 }
1414 spin_unlock_irqrestore(&kioreq->lock, flags);
1415 break;
1416 }
1417
1418 pr_err("Ioeventfd isn't already assigned, dom: %u, addr: %llu\n",
1419 ioeventfd->dom, ioeventfd->addr);
1420 ret = -ENODEV;
1421
1422unlock:
1423 mutex_unlock(&ioreq_lock);
1424 eventfd_ctx_put(eventfd);
1425
1426 return ret;
1427}
1428
1429static long privcmd_ioctl_ioeventfd(struct file *file, void __user *udata)
1430{
1431 struct privcmd_data *data = file->private_data;
1432 struct privcmd_ioeventfd ioeventfd;
1433
1434 if (copy_from_user(&ioeventfd, udata, sizeof(ioeventfd)))
1435 return -EFAULT;
1436
1437 /* No other flags should be set */
1438 if (ioeventfd.flags & ~PRIVCMD_IOEVENTFD_FLAG_DEASSIGN)
1439 return -EINVAL;
1440
1441 /* If restriction is in place, check the domid matches */
1442 if (data->domid != DOMID_INVALID && data->domid != ioeventfd.dom)
1443 return -EPERM;
1444
1445 if (ioeventfd.flags & PRIVCMD_IOEVENTFD_FLAG_DEASSIGN)
1446 return privcmd_ioeventfd_deassign(&ioeventfd);
1447
1448 return privcmd_ioeventfd_assign(&ioeventfd);
1449}
1450
1451static void privcmd_ioeventfd_exit(void)
1452{
1453 struct privcmd_kernel_ioreq *kioreq, *tmp;
1454 unsigned long flags;
1455
1456 mutex_lock(&ioreq_lock);
1457 list_for_each_entry_safe(kioreq, tmp, &ioreq_list, list) {
1458 struct privcmd_kernel_ioeventfd *kioeventfd, *tmp;
1459
1460 spin_lock_irqsave(&kioreq->lock, flags);
1461 list_for_each_entry_safe(kioeventfd, tmp, &kioreq->ioeventfds, list)
1462 ioeventfd_free(kioeventfd);
1463 spin_unlock_irqrestore(&kioreq->lock, flags);
1464
1465 ioreq_free(kioreq);
1466 }
1467 mutex_unlock(&ioreq_lock);
1468}
1082#else1469#else
1083static inline long privcmd_ioctl_irqfd(struct file *file, void __user *udata)1470static inline long privcmd_ioctl_irqfd(struct file *file, void __user *udata)
1084{1471{
@@ -1093,7 +1480,16 @@ static inline int privcmd_irqfd_init(void) · 8 unmodified lines
1093static inline void privcmd_irqfd_exit(void)1480static inline void privcmd_irqfd_exit(void)
1094{1481{
1095}1482}
1096#endif /* CONFIG_XEN_PRIVCMD_IRQFD */1483
1484static inline long privcmd_ioctl_ioeventfd(struct file *file, void __user *udata)
1485{
1486 return -EOPNOTSUPP;
1487}
1488
1489static inline void privcmd_ioeventfd_exit(void)
1490{
1491}
1492#endif /* CONFIG_XEN_PRIVCMD_EVENTFD */
1097 1493
1098static long privcmd_ioctl(struct file *file,1494static long privcmd_ioctl(struct file *file,
1099 unsigned int cmd, unsigned long data)1495 unsigned int cmd, unsigned long data)
@@ -1134,6 +1530,10 @@ static long privcmd_ioctl(struct file *file, · 34 unmodified lines
1134 ret = privcmd_ioctl_irqfd(file, udata);1530 ret = privcmd_ioctl_irqfd(file, udata);
1135 break;1531 break;
1136 1532
1533 case IOCTL_PRIVCMD_IOEVENTFD:
1534 ret = privcmd_ioctl_ioeventfd(file, udata);
1535 break;
1536
1137 default:1537 default:
1138 break;1538 break;
1139 }1539 }
@@ -1278,6 +1678,7 @@ err_privcmdbuf: · 138 unmodified lines
1278 1678
1279static void __exit privcmd_exit(void)1679static void __exit privcmd_exit(void)
1280{1680{
1681 privcmd_ioeventfd_exit();
1281 privcmd_irqfd_exit();1682 privcmd_irqfd_exit();
1282 misc_deregister(&privcmd_dev);1683 misc_deregister(&privcmd_dev);
1283 misc_deregister(&xen_privcmdbuf_dev);1684 misc_deregister(&xen_privcmdbuf_dev);
drivers/xen/xen-pciback/conf_space.c+13−6
@@ -288,12 +288,6 @@ int xen_pcibk_get_interrupt_type(struct pci_dev *dev) · 287 unmodified lines
288 u16 val;288 u16 val;
289 int ret = 0;289 int ret = 0;
290 290
291 err = pci_read_config_word(dev, PCI_COMMAND, &val);
292 if (err)
293 return err;
294 if (!(val & PCI_COMMAND_INTX_DISABLE))
295 ret |= INTERRUPT_TYPE_INTX;
296
297 /*291 /*
298 * Do not trust dev->msi(x)_enabled here, as enabling could be done292 * Do not trust dev->msi(x)_enabled here, as enabling could be done
299 * bypassing the pci_*msi* functions, by the qemu.293 * bypassing the pci_*msi* functions, by the qemu.
@@ -316,6 +310,19 @@ int xen_pcibk_get_interrupt_type(struct pci_dev *dev) · 16 unmodified lines
316 if (val & PCI_MSIX_FLAGS_ENABLE)310 if (val & PCI_MSIX_FLAGS_ENABLE)
317 ret |= INTERRUPT_TYPE_MSIX;311 ret |= INTERRUPT_TYPE_MSIX;
318 }312 }
313
314 /*
315 * PCIe spec says device cannot use INTx if MSI/MSI-X is enabled,
316 * so check for INTx only when both are disabled.
317 */
318 if (!ret) {
319 err = pci_read_config_word(dev, PCI_COMMAND, &val);
320 if (err)
321 return err;
322 if (!(val & PCI_COMMAND_INTX_DISABLE))
323 ret |= INTERRUPT_TYPE_INTX;
324 }
325
319 return ret ?: INTERRUPT_TYPE_NONE;326 return ret ?: INTERRUPT_TYPE_NONE;
320}327}
321 328
drivers/xen/xen-pciback/conf_space_capability.c+7−1
@@ -236,10 +236,16 @@ static int msi_msix_flags_write(struct pci_dev *dev, int offset, u16 new_value, · 235 unmodified lines
236 return PCIBIOS_SET_FAILED;236 return PCIBIOS_SET_FAILED;
237 237
238 if (new_value & field_config->enable_bit) {238 if (new_value & field_config->enable_bit) {
239 /* don't allow enabling together with other interrupt types */239 /*
240 * Don't allow enabling together with other interrupt type, but do
241 * allow enabling MSI(-X) while INTx is still active to please Linuxes
242 * MSI(-X) startup sequence. It is safe to do, as according to PCI
243 * spec, device with enabled MSI(-X) shouldn't use INTx.
244 */
240 int int_type = xen_pcibk_get_interrupt_type(dev);245 int int_type = xen_pcibk_get_interrupt_type(dev);
241 246
242 if (int_type == INTERRUPT_TYPE_NONE ||247 if (int_type == INTERRUPT_TYPE_NONE ||
248 int_type == INTERRUPT_TYPE_INTX ||
243 int_type == field_config->int_type)249 int_type == field_config->int_type)
244 goto write;250 goto write;
245 return PCIBIOS_SET_FAILED;251 return PCIBIOS_SET_FAILED;
drivers/xen/xen-pciback/conf_space_header.c+3−18
@@ -104,24 +104,9 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data) · 103 unmodified lines
104 pci_clear_mwi(dev);104 pci_clear_mwi(dev);
105 }105 }
106 106
107 if (dev_data && dev_data->allow_interrupt_control) {107 if (dev_data && dev_data->allow_interrupt_control &&
108 if ((cmd->val ^ value) & PCI_COMMAND_INTX_DISABLE) {108 ((cmd->val ^ value) & PCI_COMMAND_INTX_DISABLE))
109 if (value & PCI_COMMAND_INTX_DISABLE) {109 pci_intx(dev, !(value & PCI_COMMAND_INTX_DISABLE));
110 pci_intx(dev, 0);
111 } else {
112 /* Do not allow enabling INTx together with MSI or MSI-X. */
113 switch (xen_pcibk_get_interrupt_type(dev)) {
114 case INTERRUPT_TYPE_NONE:
115 pci_intx(dev, 1);
116 break;
117 case INTERRUPT_TYPE_INTX:
118 break;
119 default:
120 return PCIBIOS_SET_FAILED;
121 }
122 }
123 }
124 }
125 110
126 cmd->val = value;111 cmd->val = value;
127 112
drivers/xen/xenbus/xenbus_dev_frontend.c+2−2
@@ -82,7 +82,7 @@ struct read_buffer { · 81 unmodified lines
82 struct list_head list;82 struct list_head list;
83 unsigned int cons;83 unsigned int cons;
84 unsigned int len;84 unsigned int len;
85 char msg[];85 char msg[] __counted_by(len);
86};86};
87 87
88struct xenbus_file_priv {88struct xenbus_file_priv {
@@ -195,7 +195,7 @@ static int queue_reply(struct list_head *queue, const void *data, size_t len) · 106 unmodified lines
195 if (len > XENSTORE_PAYLOAD_MAX)195 if (len > XENSTORE_PAYLOAD_MAX)
196 return -EINVAL;196 return -EINVAL;
197 197
198 rb = kmalloc(sizeof(*rb) + len, GFP_KERNEL);198 rb = kmalloc(struct_size(rb, msg, len), GFP_KERNEL);
199 if (rb == NULL)199 if (rb == NULL)
200 return -ENOMEM;200 return -ENOMEM;
201 201
drivers/xen/xenbus/xenbus_probe.c+1−1
@@ -1025,7 +1025,7 @@ static int __init xenbus_init(void) · 1024 unmodified lines
1025 if (err < 0) {1025 if (err < 0) {
1026 pr_err("xenstore_late_init couldn't bind irq err=%d\n",1026 pr_err("xenstore_late_init couldn't bind irq err=%d\n",
1027 err);1027 err);
1028 return err;1028 goto out_error;
1029 }1029 }
1030 1030
1031 xs_init_irq = err;1031 xs_init_irq = err;
include/uapi/xen/privcmd.h+20−2
@@ -102,7 +102,7 @@ struct privcmd_mmap_resource { · 101 unmodified lines
102#define PRIVCMD_IRQFD_FLAG_DEASSIGN (1 << 0)102#define PRIVCMD_IRQFD_FLAG_DEASSIGN (1 << 0)
103 103
104struct privcmd_irqfd {104struct privcmd_irqfd {
105 void __user *dm_op;105 __u64 dm_op;
106 __u32 size; /* Size of structure pointed by dm_op */106 __u32 size; /* Size of structure pointed by dm_op */
107 __u32 fd;107 __u32 fd;
108 __u32 flags;108 __u32 flags;
@@ -110,6 +110,22 @@ struct privcmd_irqfd { · 1 unmodified line
110 __u8 pad[2];110 __u8 pad[2];
111};111};
112 112
113/* For privcmd_ioeventfd::flags */
114#define PRIVCMD_IOEVENTFD_FLAG_DEASSIGN (1 << 0)
115
116struct privcmd_ioeventfd {
117 __u64 ioreq;
118 __u64 ports;
119 __u64 addr;
120 __u32 addr_len;
121 __u32 event_fd;
122 __u32 vcpus;
123 __u32 vq;
124 __u32 flags;
125 domid_t dom;
126 __u8 pad[2];
127};
128
113/*129/*
114 * @cmd: IOCTL_PRIVCMD_HYPERCALL130 * @cmd: IOCTL_PRIVCMD_HYPERCALL
115 * @arg: &privcmd_hypercall_t131 * @arg: &privcmd_hypercall_t
@@ -138,6 +154,8 @@ struct privcmd_irqfd { · 22 unmodified lines
138#define IOCTL_PRIVCMD_MMAP_RESOURCE \154#define IOCTL_PRIVCMD_MMAP_RESOURCE \
139 _IOC(_IOC_NONE, 'P', 7, sizeof(struct privcmd_mmap_resource))155 _IOC(_IOC_NONE, 'P', 7, sizeof(struct privcmd_mmap_resource))
140#define IOCTL_PRIVCMD_IRQFD \156#define IOCTL_PRIVCMD_IRQFD \
141 _IOC(_IOC_NONE, 'P', 8, sizeof(struct privcmd_irqfd))157 _IOW('P', 8, struct privcmd_irqfd)
158#define IOCTL_PRIVCMD_IOEVENTFD \
159 _IOW('P', 9, struct privcmd_ioeventfd)
142 160
143#endif /* __LINUX_PUBLIC_PRIVCMD_H__ */161#endif /* __LINUX_PUBLIC_PRIVCMD_H__ */
include/xen/interface/hvm/ioreq.h+51−0
@@ -0,0 +1,51 @@
1/* SPDX-License-Identifier: MIT */
2/*
3 * ioreq.h: I/O request definitions for device models
4 * Copyright (c) 2004, Intel Corporation.
5 */
6
7#ifndef __XEN_PUBLIC_HVM_IOREQ_H__
8#define __XEN_PUBLIC_HVM_IOREQ_H__
9
10#define IOREQ_READ 1
11#define IOREQ_WRITE 0
12
13#define STATE_IOREQ_NONE 0
14#define STATE_IOREQ_READY 1
15#define STATE_IOREQ_INPROCESS 2
16#define STATE_IORESP_READY 3
17
18#define IOREQ_TYPE_PIO 0 /* pio */
19#define IOREQ_TYPE_COPY 1 /* mmio ops */
20#define IOREQ_TYPE_PCI_CONFIG 2
21#define IOREQ_TYPE_TIMEOFFSET 7
22#define IOREQ_TYPE_INVALIDATE 8 /* mapcache */
23
24/*
25 * VMExit dispatcher should cooperate with instruction decoder to
26 * prepare this structure and notify service OS and DM by sending
27 * virq.
28 *
29 * For I/O type IOREQ_TYPE_PCI_CONFIG, the physical address is formatted
30 * as follows:
31 *
32 * 63....48|47..40|39..35|34..32|31........0
33 * SEGMENT |BUS |DEV |FN |OFFSET
34 */
35struct ioreq {
36 uint64_t addr; /* physical address */
37 uint64_t data; /* data (or paddr of data) */
38 uint32_t count; /* for rep prefixes */
39 uint32_t size; /* size in bytes */
40 uint32_t vp_eport; /* evtchn for notifications to/from device model */
41 uint16_t _pad0;
42 uint8_t state:4;
43 uint8_t data_is_ptr:1; /* if 1, data above is the guest paddr
44 * of the real data to use. */
45 uint8_t dir:1; /* 1=read, 0=write */
46 uint8_t df:1;
47 uint8_t _pad1:1;
48 uint8_t type; /* I/O type */
49};
50
51#endif /* __XEN_PUBLIC_HVM_IOREQ_H__ */