Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * PCI Backend - Provides a Virtual PCI bus (with real devices)
0004  *               to the frontend
0005  *
0006  *   Author: Ryan Wilson <hap9@epoch.ncsc.mil>
0007  */
0008 
0009 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0010 #define dev_fmt pr_fmt
0011 
0012 #include <linux/list.h>
0013 #include <linux/slab.h>
0014 #include <linux/pci.h>
0015 #include <linux/mutex.h>
0016 #include "pciback.h"
0017 
0018 #define PCI_SLOT_MAX 32
0019 
0020 struct vpci_dev_data {
0021     /* Access to dev_list must be protected by lock */
0022     struct list_head dev_list[PCI_SLOT_MAX];
0023     struct mutex lock;
0024 };
0025 
0026 static inline struct list_head *list_first(struct list_head *head)
0027 {
0028     return head->next;
0029 }
0030 
0031 static struct pci_dev *__xen_pcibk_get_pci_dev(struct xen_pcibk_device *pdev,
0032                            unsigned int domain,
0033                            unsigned int bus,
0034                            unsigned int devfn)
0035 {
0036     struct pci_dev_entry *entry;
0037     struct pci_dev *dev = NULL;
0038     struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
0039 
0040     if (domain != 0 || bus != 0)
0041         return NULL;
0042 
0043     if (PCI_SLOT(devfn) < PCI_SLOT_MAX) {
0044         mutex_lock(&vpci_dev->lock);
0045 
0046         list_for_each_entry(entry,
0047                     &vpci_dev->dev_list[PCI_SLOT(devfn)],
0048                     list) {
0049             if (PCI_FUNC(entry->dev->devfn) == PCI_FUNC(devfn)) {
0050                 dev = entry->dev;
0051                 break;
0052             }
0053         }
0054 
0055         mutex_unlock(&vpci_dev->lock);
0056     }
0057     return dev;
0058 }
0059 
0060 static inline int match_slot(struct pci_dev *l, struct pci_dev *r)
0061 {
0062     if (pci_domain_nr(l->bus) == pci_domain_nr(r->bus)
0063         && l->bus == r->bus && PCI_SLOT(l->devfn) == PCI_SLOT(r->devfn))
0064         return 1;
0065 
0066     return 0;
0067 }
0068 
0069 static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev,
0070                    struct pci_dev *dev, int devid,
0071                    publish_pci_dev_cb publish_cb)
0072 {
0073     int err = 0, slot, func = PCI_FUNC(dev->devfn);
0074     struct pci_dev_entry *t, *dev_entry;
0075     struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
0076 
0077     if ((dev->class >> 24) == PCI_BASE_CLASS_BRIDGE) {
0078         err = -EFAULT;
0079         xenbus_dev_fatal(pdev->xdev, err,
0080                  "Can't export bridges on the virtual PCI bus");
0081         goto out;
0082     }
0083 
0084     dev_entry = kmalloc(sizeof(*dev_entry), GFP_KERNEL);
0085     if (!dev_entry) {
0086         err = -ENOMEM;
0087         xenbus_dev_fatal(pdev->xdev, err,
0088                  "Error adding entry to virtual PCI bus");
0089         goto out;
0090     }
0091 
0092     dev_entry->dev = dev;
0093 
0094     mutex_lock(&vpci_dev->lock);
0095 
0096     /*
0097      * Keep multi-function devices together on the virtual PCI bus, except
0098      * that we want to keep virtual functions at func 0 on their own. They
0099      * aren't multi-function devices and hence their presence at func 0
0100      * may cause guests to not scan the other functions.
0101      */
0102     if (!dev->is_virtfn || func) {
0103         for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
0104             if (list_empty(&vpci_dev->dev_list[slot]))
0105                 continue;
0106 
0107             t = list_entry(list_first(&vpci_dev->dev_list[slot]),
0108                        struct pci_dev_entry, list);
0109             if (t->dev->is_virtfn && !PCI_FUNC(t->dev->devfn))
0110                 continue;
0111 
0112             if (match_slot(dev, t->dev)) {
0113                 dev_info(&dev->dev, "vpci: assign to virtual slot %d func %d\n",
0114                      slot, func);
0115                 list_add_tail(&dev_entry->list,
0116                           &vpci_dev->dev_list[slot]);
0117                 goto unlock;
0118             }
0119         }
0120     }
0121 
0122     /* Assign to a new slot on the virtual PCI bus */
0123     for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
0124         if (list_empty(&vpci_dev->dev_list[slot])) {
0125             dev_info(&dev->dev, "vpci: assign to virtual slot %d\n",
0126                  slot);
0127             list_add_tail(&dev_entry->list,
0128                       &vpci_dev->dev_list[slot]);
0129             goto unlock;
0130         }
0131     }
0132 
0133     err = -ENOMEM;
0134     xenbus_dev_fatal(pdev->xdev, err,
0135              "No more space on root virtual PCI bus");
0136 
0137 unlock:
0138     mutex_unlock(&vpci_dev->lock);
0139 
0140     /* Publish this device. */
0141     if (!err)
0142         err = publish_cb(pdev, 0, 0, PCI_DEVFN(slot, func), devid);
0143     else
0144         kfree(dev_entry);
0145 
0146 out:
0147     return err;
0148 }
0149 
0150 static void __xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
0151                     struct pci_dev *dev, bool lock)
0152 {
0153     int slot;
0154     struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
0155     struct pci_dev *found_dev = NULL;
0156 
0157     mutex_lock(&vpci_dev->lock);
0158 
0159     for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
0160         struct pci_dev_entry *e;
0161 
0162         list_for_each_entry(e, &vpci_dev->dev_list[slot], list) {
0163             if (e->dev == dev) {
0164                 list_del(&e->list);
0165                 found_dev = e->dev;
0166                 kfree(e);
0167                 goto out;
0168             }
0169         }
0170     }
0171 
0172 out:
0173     mutex_unlock(&vpci_dev->lock);
0174 
0175     if (found_dev) {
0176         if (lock)
0177             device_lock(&found_dev->dev);
0178         pcistub_put_pci_dev(found_dev);
0179         if (lock)
0180             device_unlock(&found_dev->dev);
0181     }
0182 }
0183 
0184 static int __xen_pcibk_init_devices(struct xen_pcibk_device *pdev)
0185 {
0186     int slot;
0187     struct vpci_dev_data *vpci_dev;
0188 
0189     vpci_dev = kmalloc(sizeof(*vpci_dev), GFP_KERNEL);
0190     if (!vpci_dev)
0191         return -ENOMEM;
0192 
0193     mutex_init(&vpci_dev->lock);
0194 
0195     for (slot = 0; slot < PCI_SLOT_MAX; slot++)
0196         INIT_LIST_HEAD(&vpci_dev->dev_list[slot]);
0197 
0198     pdev->pci_dev_data = vpci_dev;
0199 
0200     return 0;
0201 }
0202 
0203 static int __xen_pcibk_publish_pci_roots(struct xen_pcibk_device *pdev,
0204                      publish_pci_root_cb publish_cb)
0205 {
0206     /* The Virtual PCI bus has only one root */
0207     return publish_cb(pdev, 0, 0);
0208 }
0209 
0210 static void __xen_pcibk_release_devices(struct xen_pcibk_device *pdev)
0211 {
0212     int slot;
0213     struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
0214 
0215     for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
0216         struct pci_dev_entry *e, *tmp;
0217         list_for_each_entry_safe(e, tmp, &vpci_dev->dev_list[slot],
0218                      list) {
0219             struct pci_dev *dev = e->dev;
0220             list_del(&e->list);
0221             device_lock(&dev->dev);
0222             pcistub_put_pci_dev(dev);
0223             device_unlock(&dev->dev);
0224             kfree(e);
0225         }
0226     }
0227 
0228     kfree(vpci_dev);
0229     pdev->pci_dev_data = NULL;
0230 }
0231 
0232 static int __xen_pcibk_get_pcifront_dev(struct pci_dev *pcidev,
0233                     struct xen_pcibk_device *pdev,
0234                     unsigned int *domain, unsigned int *bus,
0235                     unsigned int *devfn)
0236 {
0237     struct pci_dev_entry *entry;
0238     struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
0239     int found = 0, slot;
0240 
0241     mutex_lock(&vpci_dev->lock);
0242     for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
0243         list_for_each_entry(entry,
0244                 &vpci_dev->dev_list[slot],
0245                 list) {
0246             if (entry->dev == pcidev) {
0247                 found = 1;
0248                 *domain = 0;
0249                 *bus = 0;
0250                 *devfn = PCI_DEVFN(slot,
0251                      PCI_FUNC(pcidev->devfn));
0252             }
0253         }
0254     }
0255     mutex_unlock(&vpci_dev->lock);
0256     return found;
0257 }
0258 
0259 const struct xen_pcibk_backend xen_pcibk_vpci_backend = {
0260     .name       = "vpci",
0261     .init       = __xen_pcibk_init_devices,
0262     .free       = __xen_pcibk_release_devices,
0263     .find       = __xen_pcibk_get_pcifront_dev,
0264     .publish    = __xen_pcibk_publish_pci_roots,
0265     .release    = __xen_pcibk_release_pci_dev,
0266     .add        = __xen_pcibk_add_pci_dev,
0267     .get        = __xen_pcibk_get_pci_dev,
0268 };