1 /* 2 * PCI Backend - Provides a Virtual PCI bus (with real devices) 3 * to the frontend 4 * 5 * Author: Ryan Wilson <hap9@epoch.ncsc.mil> 6 */ 7 8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 9 10 #include <linux/list.h> 11 #include <linux/slab.h> 12 #include <linux/pci.h> 13 #include <linux/mutex.h> 14 #include "pciback.h" 15 16 #define PCI_SLOT_MAX 32 17 18 struct vpci_dev_data { 19 /* Access to dev_list must be protected by lock */ 20 struct list_head dev_list[PCI_SLOT_MAX]; 21 struct mutex lock; 22 }; 23 24 static inline struct list_head *list_first(struct list_head *head) 25 { 26 return head->next; 27 } 28 29 static struct pci_dev *__xen_pcibk_get_pci_dev(struct xen_pcibk_device *pdev, 30 unsigned int domain, 31 unsigned int bus, 32 unsigned int devfn) 33 { 34 struct pci_dev_entry *entry; 35 struct pci_dev *dev = NULL; 36 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; 37 38 if (domain != 0 || bus != 0) 39 return NULL; 40 41 if (PCI_SLOT(devfn) < PCI_SLOT_MAX) { 42 mutex_lock(&vpci_dev->lock); 43 44 list_for_each_entry(entry, 45 &vpci_dev->dev_list[PCI_SLOT(devfn)], 46 list) { 47 if (PCI_FUNC(entry->dev->devfn) == PCI_FUNC(devfn)) { 48 dev = entry->dev; 49 break; 50 } 51 } 52 53 mutex_unlock(&vpci_dev->lock); 54 } 55 return dev; 56 } 57 58 static inline int match_slot(struct pci_dev *l, struct pci_dev *r) 59 { 60 if (pci_domain_nr(l->bus) == pci_domain_nr(r->bus) 61 && l->bus == r->bus && PCI_SLOT(l->devfn) == PCI_SLOT(r->devfn)) 62 return 1; 63 64 return 0; 65 } 66 67 static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, 68 struct pci_dev *dev, int devid, 69 publish_pci_dev_cb publish_cb) 70 { 71 int err = 0, slot, func = -1; 72 struct pci_dev_entry *t, *dev_entry; 73 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; 74 75 if ((dev->class >> 24) == PCI_BASE_CLASS_BRIDGE) { 76 err = -EFAULT; 77 xenbus_dev_fatal(pdev->xdev, err, 78 "Can't export bridges on the virtual PCI bus"); 79 goto out; 80 } 81 82 dev_entry = kmalloc(sizeof(*dev_entry), GFP_KERNEL); 83 if (!dev_entry) { 84 err = -ENOMEM; 85 xenbus_dev_fatal(pdev->xdev, err, 86 "Error adding entry to virtual PCI bus"); 87 goto out; 88 } 89 90 dev_entry->dev = dev; 91 92 mutex_lock(&vpci_dev->lock); 93 94 /* 95 * Keep multi-function devices together on the virtual PCI bus, except 96 * virtual functions. 97 */ 98 if (!dev->is_virtfn) { 99 for (slot = 0; slot < PCI_SLOT_MAX; slot++) { 100 if (list_empty(&vpci_dev->dev_list[slot])) 101 continue; 102 103 t = list_entry(list_first(&vpci_dev->dev_list[slot]), 104 struct pci_dev_entry, list); 105 106 if (match_slot(dev, t->dev)) { 107 pr_info("vpci: %s: assign to virtual slot %d func %d\n", 108 pci_name(dev), slot, 109 PCI_FUNC(dev->devfn)); 110 list_add_tail(&dev_entry->list, 111 &vpci_dev->dev_list[slot]); 112 func = PCI_FUNC(dev->devfn); 113 goto unlock; 114 } 115 } 116 } 117 118 /* Assign to a new slot on the virtual PCI bus */ 119 for (slot = 0; slot < PCI_SLOT_MAX; slot++) { 120 if (list_empty(&vpci_dev->dev_list[slot])) { 121 pr_info("vpci: %s: assign to virtual slot %d\n", 122 pci_name(dev), slot); 123 list_add_tail(&dev_entry->list, 124 &vpci_dev->dev_list[slot]); 125 func = dev->is_virtfn ? 0 : PCI_FUNC(dev->devfn); 126 goto unlock; 127 } 128 } 129 130 err = -ENOMEM; 131 xenbus_dev_fatal(pdev->xdev, err, 132 "No more space on root virtual PCI bus"); 133 134 unlock: 135 mutex_unlock(&vpci_dev->lock); 136 137 /* Publish this device. */ 138 if (!err) 139 err = publish_cb(pdev, 0, 0, PCI_DEVFN(slot, func), devid); 140 141 out: 142 return err; 143 } 144 145 static void __xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev, 146 struct pci_dev *dev) 147 { 148 int slot; 149 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; 150 struct pci_dev *found_dev = NULL; 151 152 mutex_lock(&vpci_dev->lock); 153 154 for (slot = 0; slot < PCI_SLOT_MAX; slot++) { 155 struct pci_dev_entry *e; 156 157 list_for_each_entry(e, &vpci_dev->dev_list[slot], list) { 158 if (e->dev == dev) { 159 list_del(&e->list); 160 found_dev = e->dev; 161 kfree(e); 162 goto out; 163 } 164 } 165 } 166 167 out: 168 mutex_unlock(&vpci_dev->lock); 169 170 if (found_dev) 171 pcistub_put_pci_dev(found_dev); 172 } 173 174 static int __xen_pcibk_init_devices(struct xen_pcibk_device *pdev) 175 { 176 int slot; 177 struct vpci_dev_data *vpci_dev; 178 179 vpci_dev = kmalloc(sizeof(*vpci_dev), GFP_KERNEL); 180 if (!vpci_dev) 181 return -ENOMEM; 182 183 mutex_init(&vpci_dev->lock); 184 185 for (slot = 0; slot < PCI_SLOT_MAX; slot++) 186 INIT_LIST_HEAD(&vpci_dev->dev_list[slot]); 187 188 pdev->pci_dev_data = vpci_dev; 189 190 return 0; 191 } 192 193 static int __xen_pcibk_publish_pci_roots(struct xen_pcibk_device *pdev, 194 publish_pci_root_cb publish_cb) 195 { 196 /* The Virtual PCI bus has only one root */ 197 return publish_cb(pdev, 0, 0); 198 } 199 200 static void __xen_pcibk_release_devices(struct xen_pcibk_device *pdev) 201 { 202 int slot; 203 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; 204 205 for (slot = 0; slot < PCI_SLOT_MAX; slot++) { 206 struct pci_dev_entry *e, *tmp; 207 list_for_each_entry_safe(e, tmp, &vpci_dev->dev_list[slot], 208 list) { 209 list_del(&e->list); 210 pcistub_put_pci_dev(e->dev); 211 kfree(e); 212 } 213 } 214 215 kfree(vpci_dev); 216 pdev->pci_dev_data = NULL; 217 } 218 219 static int __xen_pcibk_get_pcifront_dev(struct pci_dev *pcidev, 220 struct xen_pcibk_device *pdev, 221 unsigned int *domain, unsigned int *bus, 222 unsigned int *devfn) 223 { 224 struct pci_dev_entry *entry; 225 struct pci_dev *dev = NULL; 226 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; 227 int found = 0, slot; 228 229 mutex_lock(&vpci_dev->lock); 230 for (slot = 0; slot < PCI_SLOT_MAX; slot++) { 231 list_for_each_entry(entry, 232 &vpci_dev->dev_list[slot], 233 list) { 234 dev = entry->dev; 235 if (dev && dev->bus->number == pcidev->bus->number 236 && pci_domain_nr(dev->bus) == 237 pci_domain_nr(pcidev->bus) 238 && dev->devfn == pcidev->devfn) { 239 found = 1; 240 *domain = 0; 241 *bus = 0; 242 *devfn = PCI_DEVFN(slot, 243 PCI_FUNC(pcidev->devfn)); 244 } 245 } 246 } 247 mutex_unlock(&vpci_dev->lock); 248 return found; 249 } 250 251 const struct xen_pcibk_backend xen_pcibk_vpci_backend = { 252 .name = "vpci", 253 .init = __xen_pcibk_init_devices, 254 .free = __xen_pcibk_release_devices, 255 .find = __xen_pcibk_get_pcifront_dev, 256 .publish = __xen_pcibk_publish_pci_roots, 257 .release = __xen_pcibk_release_pci_dev, 258 .add = __xen_pcibk_add_pci_dev, 259 .get = __xen_pcibk_get_pci_dev, 260 }; 261