759 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * PCI Backend Xenbus Setup - handles setup with frontend and xend4 *5 * Author: Ryan Wilson <hap9@epoch.ncsc.mil>6 */7 8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt9 10#include <linux/moduleparam.h>11#include <linux/init.h>12#include <linux/list.h>13#include <linux/vmalloc.h>14#include <linux/workqueue.h>15#include <xen/xenbus.h>16#include <xen/events.h>17#include <xen/pci.h>18#include "pciback.h"19 20#define INVALID_EVTCHN_IRQ (-1)21 22static bool __read_mostly passthrough;23module_param(passthrough, bool, S_IRUGO);24MODULE_PARM_DESC(passthrough,25 "Option to specify how to export PCI topology to guest:\n"\26 " 0 - (default) Hide the true PCI topology and makes the frontend\n"\27 " there is a single PCI bus with only the exported devices on it.\n"\28 " For example, a device at 03:05.0 will be re-assigned to 00:00.0\n"\29 " while second device at 02:1a.1 will be re-assigned to 00:01.1.\n"\30 " 1 - Passthrough provides a real view of the PCI topology to the\n"\31 " frontend (for example, a device at 06:01.b will still appear at\n"\32 " 06:01.b to the frontend). This is similar to how Xen 2.0.x\n"\33 " exposed PCI devices to its driver domains. This may be required\n"\34 " for drivers which depend on finding their hardware in certain\n"\35 " bus/slot locations.");36 37static struct xen_pcibk_device *alloc_pdev(struct xenbus_device *xdev)38{39 struct xen_pcibk_device *pdev;40 41 pdev = kzalloc(sizeof(struct xen_pcibk_device), GFP_KERNEL);42 if (pdev == NULL)43 goto out;44 dev_dbg(&xdev->dev, "allocated pdev @ 0x%p\n", pdev);45 46 pdev->xdev = xdev;47 48 mutex_init(&pdev->dev_lock);49 50 pdev->sh_info = NULL;51 pdev->evtchn_irq = INVALID_EVTCHN_IRQ;52 pdev->be_watching = 0;53 54 INIT_WORK(&pdev->op_work, xen_pcibk_do_op);55 56 if (xen_pcibk_init_devices(pdev)) {57 kfree(pdev);58 pdev = NULL;59 }60 61 dev_set_drvdata(&xdev->dev, pdev);62 63out:64 return pdev;65}66 67static void xen_pcibk_disconnect(struct xen_pcibk_device *pdev)68{69 mutex_lock(&pdev->dev_lock);70 /* Ensure the guest can't trigger our handler before removing devices */71 if (pdev->evtchn_irq != INVALID_EVTCHN_IRQ) {72 unbind_from_irqhandler(pdev->evtchn_irq, pdev);73 pdev->evtchn_irq = INVALID_EVTCHN_IRQ;74 }75 76 /* If the driver domain started an op, make sure we complete it77 * before releasing the shared memory */78 79 flush_work(&pdev->op_work);80 81 if (pdev->sh_info != NULL) {82 xenbus_unmap_ring_vfree(pdev->xdev, pdev->sh_info);83 pdev->sh_info = NULL;84 }85 mutex_unlock(&pdev->dev_lock);86}87 88static void free_pdev(struct xen_pcibk_device *pdev)89{90 if (pdev->be_watching) {91 unregister_xenbus_watch(&pdev->be_watch);92 pdev->be_watching = 0;93 }94 95 xen_pcibk_disconnect(pdev);96 97 /* N.B. This calls pcistub_put_pci_dev which does the FLR on all98 * of the PCIe devices. */99 xen_pcibk_release_devices(pdev);100 101 dev_set_drvdata(&pdev->xdev->dev, NULL);102 pdev->xdev = NULL;103 104 kfree(pdev);105}106 107static int xen_pcibk_do_attach(struct xen_pcibk_device *pdev, int gnt_ref,108 evtchn_port_t remote_evtchn)109{110 int err = 0;111 void *vaddr;112 113 dev_dbg(&pdev->xdev->dev,114 "Attaching to frontend resources - gnt_ref=%d evtchn=%u\n",115 gnt_ref, remote_evtchn);116 117 err = xenbus_map_ring_valloc(pdev->xdev, &gnt_ref, 1, &vaddr);118 if (err < 0) {119 xenbus_dev_fatal(pdev->xdev, err,120 "Error mapping other domain page in ours.");121 goto out;122 }123 124 pdev->sh_info = vaddr;125 126 err = bind_interdomain_evtchn_to_irqhandler_lateeoi(127 pdev->xdev, remote_evtchn, xen_pcibk_handle_event,128 0, DRV_NAME, pdev);129 if (err < 0) {130 xenbus_dev_fatal(pdev->xdev, err,131 "Error binding event channel to IRQ");132 goto out;133 }134 pdev->evtchn_irq = err;135 err = 0;136 137 dev_dbg(&pdev->xdev->dev, "Attached!\n");138out:139 return err;140}141 142static int xen_pcibk_attach(struct xen_pcibk_device *pdev)143{144 int err = 0;145 int gnt_ref;146 evtchn_port_t remote_evtchn;147 char *magic = NULL;148 149 150 mutex_lock(&pdev->dev_lock);151 /* Make sure we only do this setup once */152 if (xenbus_read_driver_state(pdev->xdev->nodename) !=153 XenbusStateInitialised)154 goto out;155 156 /* Wait for frontend to state that it has published the configuration */157 if (xenbus_read_driver_state(pdev->xdev->otherend) !=158 XenbusStateInitialised)159 goto out;160 161 dev_dbg(&pdev->xdev->dev, "Reading frontend config\n");162 163 err = xenbus_gather(XBT_NIL, pdev->xdev->otherend,164 "pci-op-ref", "%u", &gnt_ref,165 "event-channel", "%u", &remote_evtchn,166 "magic", NULL, &magic, NULL);167 if (err) {168 /* If configuration didn't get read correctly, wait longer */169 xenbus_dev_fatal(pdev->xdev, err,170 "Error reading configuration from frontend");171 goto out;172 }173 174 if (magic == NULL || strcmp(magic, XEN_PCI_MAGIC) != 0) {175 xenbus_dev_fatal(pdev->xdev, -EFAULT,176 "version mismatch (%s/%s) with pcifront - "177 "halting " DRV_NAME,178 magic, XEN_PCI_MAGIC);179 err = -EFAULT;180 goto out;181 }182 183 err = xen_pcibk_do_attach(pdev, gnt_ref, remote_evtchn);184 if (err)185 goto out;186 187 dev_dbg(&pdev->xdev->dev, "Connecting...\n");188 189 err = xenbus_switch_state(pdev->xdev, XenbusStateConnected);190 if (err)191 xenbus_dev_fatal(pdev->xdev, err,192 "Error switching to connected state!");193 194 dev_dbg(&pdev->xdev->dev, "Connected? %d\n", err);195out:196 mutex_unlock(&pdev->dev_lock);197 198 kfree(magic);199 200 return err;201}202 203static int xen_pcibk_publish_pci_dev(struct xen_pcibk_device *pdev,204 unsigned int domain, unsigned int bus,205 unsigned int devfn, unsigned int devid)206{207 int err;208 int len;209 char str[64];210 211 len = snprintf(str, sizeof(str), "vdev-%d", devid);212 if (unlikely(len >= (sizeof(str) - 1))) {213 err = -ENOMEM;214 goto out;215 }216 217 /* Note: The PV protocol uses %02x, don't change it */218 err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, str,219 "%04x:%02x:%02x.%02x", domain, bus,220 PCI_SLOT(devfn), PCI_FUNC(devfn));221 222out:223 return err;224}225 226static int xen_pcibk_export_device(struct xen_pcibk_device *pdev,227 int domain, int bus, int slot, int func,228 int devid)229{230 struct pci_dev *dev;231 int err = 0;232 233 dev_dbg(&pdev->xdev->dev, "exporting dom %x bus %x slot %x func %x\n",234 domain, bus, slot, func);235 236 dev = pcistub_get_pci_dev_by_slot(pdev, domain, bus, slot, func);237 if (!dev) {238 err = -EINVAL;239 xenbus_dev_fatal(pdev->xdev, err,240 "Couldn't locate PCI device "241 "(%04x:%02x:%02x.%d)! "242 "perhaps already in-use?",243 domain, bus, slot, func);244 goto out;245 }246 247 err = xen_pcibk_add_pci_dev(pdev, dev, devid,248 xen_pcibk_publish_pci_dev);249 if (err)250 goto out;251 252 dev_info(&dev->dev, "registering for %d\n", pdev->xdev->otherend_id);253 if (xen_register_device_domain_owner(dev,254 pdev->xdev->otherend_id) != 0) {255 dev_err(&dev->dev, "Stealing ownership from dom%d.\n",256 xen_find_device_domain_owner(dev));257 xen_unregister_device_domain_owner(dev);258 xen_register_device_domain_owner(dev, pdev->xdev->otherend_id);259 }260 261 /* TODO: It'd be nice to export a bridge and have all of its children262 * get exported with it. This may be best done in xend (which will263 * have to calculate resource usage anyway) but we probably want to264 * put something in here to ensure that if a bridge gets given to a265 * driver domain, that all devices under that bridge are not given266 * to other driver domains (as he who controls the bridge can disable267 * it and stop the other devices from working).268 */269out:270 return err;271}272 273static int xen_pcibk_remove_device(struct xen_pcibk_device *pdev,274 int domain, int bus, int slot, int func)275{276 int err = 0;277 struct pci_dev *dev;278 279 dev_dbg(&pdev->xdev->dev, "removing dom %x bus %x slot %x func %x\n",280 domain, bus, slot, func);281 282 dev = xen_pcibk_get_pci_dev(pdev, domain, bus, PCI_DEVFN(slot, func));283 if (!dev) {284 err = -EINVAL;285 dev_dbg(&pdev->xdev->dev, "Couldn't locate PCI device "286 "(%04x:%02x:%02x.%d)! not owned by this domain\n",287 domain, bus, slot, func);288 goto out;289 }290 291 dev_dbg(&dev->dev, "unregistering for %d\n", pdev->xdev->otherend_id);292 xen_unregister_device_domain_owner(dev);293 294 /* N.B. This ends up calling pcistub_put_pci_dev which ends up295 * doing the FLR. */296 xen_pcibk_release_pci_dev(pdev, dev, true /* use the lock. */);297 298out:299 return err;300}301 302static int xen_pcibk_publish_pci_root(struct xen_pcibk_device *pdev,303 unsigned int domain, unsigned int bus)304{305 unsigned int d, b;306 int i, root_num, len, err;307 char str[64];308 309 dev_dbg(&pdev->xdev->dev, "Publishing pci roots\n");310 311 err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename,312 "root_num", "%d", &root_num);313 if (err == 0 || err == -ENOENT)314 root_num = 0;315 else if (err < 0)316 goto out;317 318 /* Verify that we haven't already published this pci root */319 for (i = 0; i < root_num; i++) {320 len = snprintf(str, sizeof(str), "root-%d", i);321 if (unlikely(len >= (sizeof(str) - 1))) {322 err = -ENOMEM;323 goto out;324 }325 326 err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename,327 str, "%x:%x", &d, &b);328 if (err < 0)329 goto out;330 if (err != 2) {331 err = -EINVAL;332 goto out;333 }334 335 if (d == domain && b == bus) {336 err = 0;337 goto out;338 }339 }340 341 len = snprintf(str, sizeof(str), "root-%d", root_num);342 if (unlikely(len >= (sizeof(str) - 1))) {343 err = -ENOMEM;344 goto out;345 }346 347 dev_dbg(&pdev->xdev->dev, "writing root %d at %04x:%02x\n",348 root_num, domain, bus);349 350 err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, str,351 "%04x:%02x", domain, bus);352 if (err)353 goto out;354 355 err = xenbus_printf(XBT_NIL, pdev->xdev->nodename,356 "root_num", "%d", (root_num + 1));357 358out:359 return err;360}361 362static int xen_pcibk_reconfigure(struct xen_pcibk_device *pdev,363 enum xenbus_state state)364{365 int err = 0;366 int num_devs;367 int domain, bus, slot, func;368 unsigned int substate;369 int i, len;370 char state_str[64];371 char dev_str[64];372 373 374 dev_dbg(&pdev->xdev->dev, "Reconfiguring device ...\n");375 376 mutex_lock(&pdev->dev_lock);377 if (xenbus_read_driver_state(pdev->xdev->nodename) != state)378 goto out;379 380 err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, "num_devs", "%d",381 &num_devs);382 if (err != 1) {383 if (err >= 0)384 err = -EINVAL;385 xenbus_dev_fatal(pdev->xdev, err,386 "Error reading number of devices");387 goto out;388 }389 390 for (i = 0; i < num_devs; i++) {391 len = snprintf(state_str, sizeof(state_str), "state-%d", i);392 if (unlikely(len >= (sizeof(state_str) - 1))) {393 err = -ENOMEM;394 xenbus_dev_fatal(pdev->xdev, err,395 "String overflow while reading "396 "configuration");397 goto out;398 }399 substate = xenbus_read_unsigned(pdev->xdev->nodename, state_str,400 XenbusStateUnknown);401 402 switch (substate) {403 case XenbusStateInitialising:404 dev_dbg(&pdev->xdev->dev, "Attaching dev-%d ...\n", i);405 406 len = snprintf(dev_str, sizeof(dev_str), "dev-%d", i);407 if (unlikely(len >= (sizeof(dev_str) - 1))) {408 err = -ENOMEM;409 xenbus_dev_fatal(pdev->xdev, err,410 "String overflow while "411 "reading configuration");412 goto out;413 }414 err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename,415 dev_str, "%x:%x:%x.%x",416 &domain, &bus, &slot, &func);417 if (err < 0) {418 xenbus_dev_fatal(pdev->xdev, err,419 "Error reading device "420 "configuration");421 goto out;422 }423 if (err != 4) {424 err = -EINVAL;425 xenbus_dev_fatal(pdev->xdev, err,426 "Error parsing pci device "427 "configuration");428 goto out;429 }430 431 err = xen_pcibk_export_device(pdev, domain, bus, slot,432 func, i);433 if (err)434 goto out;435 436 /* Publish pci roots. */437 err = xen_pcibk_publish_pci_roots(pdev,438 xen_pcibk_publish_pci_root);439 if (err) {440 xenbus_dev_fatal(pdev->xdev, err,441 "Error while publish PCI root"442 "buses for frontend");443 goto out;444 }445 446 err = xenbus_printf(XBT_NIL, pdev->xdev->nodename,447 state_str, "%d",448 XenbusStateInitialised);449 if (err) {450 xenbus_dev_fatal(pdev->xdev, err,451 "Error switching substate of "452 "dev-%d\n", i);453 goto out;454 }455 break;456 457 case XenbusStateClosing:458 dev_dbg(&pdev->xdev->dev, "Detaching dev-%d ...\n", i);459 460 len = snprintf(dev_str, sizeof(dev_str), "vdev-%d", i);461 if (unlikely(len >= (sizeof(dev_str) - 1))) {462 err = -ENOMEM;463 xenbus_dev_fatal(pdev->xdev, err,464 "String overflow while "465 "reading configuration");466 goto out;467 }468 err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename,469 dev_str, "%x:%x:%x.%x",470 &domain, &bus, &slot, &func);471 if (err < 0) {472 xenbus_dev_fatal(pdev->xdev, err,473 "Error reading device "474 "configuration");475 goto out;476 }477 if (err != 4) {478 err = -EINVAL;479 xenbus_dev_fatal(pdev->xdev, err,480 "Error parsing pci device "481 "configuration");482 goto out;483 }484 485 err = xen_pcibk_remove_device(pdev, domain, bus, slot,486 func);487 if (err)488 goto out;489 490 /* TODO: If at some point we implement support for pci491 * root hot-remove on pcifront side, we'll need to492 * remove unnecessary xenstore nodes of pci roots here.493 */494 495 break;496 497 default:498 break;499 }500 }501 502 if (state != XenbusStateReconfiguring)503 /* Make sure we only reconfigure once. */504 goto out;505 506 err = xenbus_switch_state(pdev->xdev, XenbusStateReconfigured);507 if (err) {508 xenbus_dev_fatal(pdev->xdev, err,509 "Error switching to reconfigured state!");510 goto out;511 }512 513out:514 mutex_unlock(&pdev->dev_lock);515 return 0;516}517 518static void xen_pcibk_frontend_changed(struct xenbus_device *xdev,519 enum xenbus_state fe_state)520{521 struct xen_pcibk_device *pdev = dev_get_drvdata(&xdev->dev);522 523 dev_dbg(&xdev->dev, "fe state changed %d\n", fe_state);524 525 switch (fe_state) {526 case XenbusStateInitialised:527 xen_pcibk_attach(pdev);528 break;529 530 case XenbusStateReconfiguring:531 xen_pcibk_reconfigure(pdev, XenbusStateReconfiguring);532 break;533 534 case XenbusStateConnected:535 /* pcifront switched its state from reconfiguring to connected.536 * Then switch to connected state.537 */538 xenbus_switch_state(xdev, XenbusStateConnected);539 break;540 541 case XenbusStateClosing:542 xen_pcibk_disconnect(pdev);543 xenbus_switch_state(xdev, XenbusStateClosing);544 break;545 546 case XenbusStateClosed:547 xen_pcibk_disconnect(pdev);548 xenbus_switch_state(xdev, XenbusStateClosed);549 if (xenbus_dev_is_online(xdev))550 break;551 fallthrough; /* if not online */552 case XenbusStateUnknown:553 dev_dbg(&xdev->dev, "frontend is gone! unregister device\n");554 device_unregister(&xdev->dev);555 break;556 557 default:558 break;559 }560}561 562static int xen_pcibk_setup_backend(struct xen_pcibk_device *pdev)563{564 /* Get configuration from xend (if available now) */565 int domain, bus, slot, func;566 int err = 0;567 int i, num_devs;568 char dev_str[64];569 char state_str[64];570 571 mutex_lock(&pdev->dev_lock);572 /* It's possible we could get the call to setup twice, so make sure573 * we're not already connected.574 */575 if (xenbus_read_driver_state(pdev->xdev->nodename) !=576 XenbusStateInitWait)577 goto out;578 579 dev_dbg(&pdev->xdev->dev, "getting be setup\n");580 581 err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, "num_devs", "%d",582 &num_devs);583 if (err != 1) {584 if (err >= 0)585 err = -EINVAL;586 xenbus_dev_fatal(pdev->xdev, err,587 "Error reading number of devices");588 goto out;589 }590 591 for (i = 0; i < num_devs; i++) {592 int l = snprintf(dev_str, sizeof(dev_str), "dev-%d", i);593 if (unlikely(l >= (sizeof(dev_str) - 1))) {594 err = -ENOMEM;595 xenbus_dev_fatal(pdev->xdev, err,596 "String overflow while reading "597 "configuration");598 goto out;599 }600 601 err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, dev_str,602 "%x:%x:%x.%x", &domain, &bus, &slot, &func);603 if (err < 0) {604 xenbus_dev_fatal(pdev->xdev, err,605 "Error reading device configuration");606 goto out;607 }608 if (err != 4) {609 err = -EINVAL;610 xenbus_dev_fatal(pdev->xdev, err,611 "Error parsing pci device "612 "configuration");613 goto out;614 }615 616 err = xen_pcibk_export_device(pdev, domain, bus, slot, func, i);617 if (err)618 goto out;619 620 /* Switch substate of this device. */621 l = snprintf(state_str, sizeof(state_str), "state-%d", i);622 if (unlikely(l >= (sizeof(state_str) - 1))) {623 err = -ENOMEM;624 xenbus_dev_fatal(pdev->xdev, err,625 "String overflow while reading "626 "configuration");627 goto out;628 }629 err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, state_str,630 "%d", XenbusStateInitialised);631 if (err) {632 xenbus_dev_fatal(pdev->xdev, err, "Error switching "633 "substate of dev-%d\n", i);634 goto out;635 }636 }637 638 err = xen_pcibk_publish_pci_roots(pdev, xen_pcibk_publish_pci_root);639 if (err) {640 xenbus_dev_fatal(pdev->xdev, err,641 "Error while publish PCI root buses "642 "for frontend");643 goto out;644 }645 646 err = xenbus_switch_state(pdev->xdev, XenbusStateInitialised);647 if (err)648 xenbus_dev_fatal(pdev->xdev, err,649 "Error switching to initialised state!");650 651out:652 mutex_unlock(&pdev->dev_lock);653 if (!err)654 /* see if pcifront is already configured (if not, we'll wait) */655 xen_pcibk_attach(pdev);656 return err;657}658 659static void xen_pcibk_be_watch(struct xenbus_watch *watch,660 const char *path, const char *token)661{662 struct xen_pcibk_device *pdev =663 container_of(watch, struct xen_pcibk_device, be_watch);664 665 switch (xenbus_read_driver_state(pdev->xdev->nodename)) {666 case XenbusStateInitWait:667 xen_pcibk_setup_backend(pdev);668 break;669 670 case XenbusStateInitialised:671 /*672 * We typically move to Initialised when the first device was673 * added. Hence subsequent devices getting added may need674 * reconfiguring.675 */676 xen_pcibk_reconfigure(pdev, XenbusStateInitialised);677 break;678 679 default:680 break;681 }682}683 684static int xen_pcibk_xenbus_probe(struct xenbus_device *dev,685 const struct xenbus_device_id *id)686{687 int err = 0;688 struct xen_pcibk_device *pdev = alloc_pdev(dev);689 690 if (pdev == NULL) {691 err = -ENOMEM;692 xenbus_dev_fatal(dev, err,693 "Error allocating xen_pcibk_device struct");694 goto out;695 }696 697 /* wait for xend to configure us */698 err = xenbus_switch_state(dev, XenbusStateInitWait);699 if (err)700 goto out;701 702 /* watch the backend node for backend configuration information */703 err = xenbus_watch_path(dev, dev->nodename, &pdev->be_watch,704 NULL, xen_pcibk_be_watch);705 if (err)706 goto out;707 708 pdev->be_watching = 1;709 710 /* We need to force a call to our callback here in case711 * xend already configured us!712 */713 xen_pcibk_be_watch(&pdev->be_watch, NULL, NULL);714 715out:716 return err;717}718 719static void xen_pcibk_xenbus_remove(struct xenbus_device *dev)720{721 struct xen_pcibk_device *pdev = dev_get_drvdata(&dev->dev);722 723 if (pdev != NULL)724 free_pdev(pdev);725}726 727static const struct xenbus_device_id xen_pcibk_ids[] = {728 {"pci"},729 {""},730};731 732static struct xenbus_driver xen_pcibk_driver = {733 .name = DRV_NAME,734 .ids = xen_pcibk_ids,735 .probe = xen_pcibk_xenbus_probe,736 .remove = xen_pcibk_xenbus_remove,737 .otherend_changed = xen_pcibk_frontend_changed,738};739 740const struct xen_pcibk_backend *__read_mostly xen_pcibk_backend;741 742int __init xen_pcibk_xenbus_register(void)743{744 if (!xen_pcibk_pv_support())745 return 0;746 747 xen_pcibk_backend = &xen_pcibk_vpci_backend;748 if (passthrough)749 xen_pcibk_backend = &xen_pcibk_passthrough_backend;750 pr_info("backend is %s\n", xen_pcibk_backend->name);751 return xenbus_register_backend(&xen_pcibk_driver);752}753 754void __exit xen_pcibk_xenbus_unregister(void)755{756 if (xen_pcibk_pv_support())757 xenbus_unregister_driver(&xen_pcibk_driver);758}759