1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
230edc14bSKonrad Rzeszutek Wilk /*
330edc14bSKonrad Rzeszutek Wilk * PCI Backend - Provides a Virtual PCI bus (with real devices)
430edc14bSKonrad Rzeszutek Wilk * to the frontend
530edc14bSKonrad Rzeszutek Wilk *
630edc14bSKonrad Rzeszutek Wilk * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
730edc14bSKonrad Rzeszutek Wilk */
830edc14bSKonrad Rzeszutek Wilk
9283c0972SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1069049454SBjorn Helgaas #define dev_fmt pr_fmt
11283c0972SJoe Perches
1230edc14bSKonrad Rzeszutek Wilk #include <linux/list.h>
1330edc14bSKonrad Rzeszutek Wilk #include <linux/slab.h>
1430edc14bSKonrad Rzeszutek Wilk #include <linux/pci.h>
1574d33dedSKonrad Rzeszutek Wilk #include <linux/mutex.h>
1630edc14bSKonrad Rzeszutek Wilk #include "pciback.h"
1730edc14bSKonrad Rzeszutek Wilk
1830edc14bSKonrad Rzeszutek Wilk #define PCI_SLOT_MAX 32
1930edc14bSKonrad Rzeszutek Wilk
2030edc14bSKonrad Rzeszutek Wilk struct vpci_dev_data {
2130edc14bSKonrad Rzeszutek Wilk /* Access to dev_list must be protected by lock */
2230edc14bSKonrad Rzeszutek Wilk struct list_head dev_list[PCI_SLOT_MAX];
2374d33dedSKonrad Rzeszutek Wilk struct mutex lock;
2430edc14bSKonrad Rzeszutek Wilk };
2530edc14bSKonrad Rzeszutek Wilk
list_first(struct list_head * head)2630edc14bSKonrad Rzeszutek Wilk static inline struct list_head *list_first(struct list_head *head)
2730edc14bSKonrad Rzeszutek Wilk {
2830edc14bSKonrad Rzeszutek Wilk return head->next;
2930edc14bSKonrad Rzeszutek Wilk }
3030edc14bSKonrad Rzeszutek Wilk
__xen_pcibk_get_pci_dev(struct xen_pcibk_device * pdev,unsigned int domain,unsigned int bus,unsigned int devfn)312ebdc426SKonrad Rzeszutek Wilk static struct pci_dev *__xen_pcibk_get_pci_dev(struct xen_pcibk_device *pdev,
322ebdc426SKonrad Rzeszutek Wilk unsigned int domain,
332ebdc426SKonrad Rzeszutek Wilk unsigned int bus,
3430edc14bSKonrad Rzeszutek Wilk unsigned int devfn)
3530edc14bSKonrad Rzeszutek Wilk {
3630edc14bSKonrad Rzeszutek Wilk struct pci_dev_entry *entry;
3730edc14bSKonrad Rzeszutek Wilk struct pci_dev *dev = NULL;
3830edc14bSKonrad Rzeszutek Wilk struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
3930edc14bSKonrad Rzeszutek Wilk
4030edc14bSKonrad Rzeszutek Wilk if (domain != 0 || bus != 0)
4130edc14bSKonrad Rzeszutek Wilk return NULL;
4230edc14bSKonrad Rzeszutek Wilk
4330edc14bSKonrad Rzeszutek Wilk if (PCI_SLOT(devfn) < PCI_SLOT_MAX) {
4474d33dedSKonrad Rzeszutek Wilk mutex_lock(&vpci_dev->lock);
4530edc14bSKonrad Rzeszutek Wilk
4630edc14bSKonrad Rzeszutek Wilk list_for_each_entry(entry,
4730edc14bSKonrad Rzeszutek Wilk &vpci_dev->dev_list[PCI_SLOT(devfn)],
4830edc14bSKonrad Rzeszutek Wilk list) {
4930edc14bSKonrad Rzeszutek Wilk if (PCI_FUNC(entry->dev->devfn) == PCI_FUNC(devfn)) {
5030edc14bSKonrad Rzeszutek Wilk dev = entry->dev;
5130edc14bSKonrad Rzeszutek Wilk break;
5230edc14bSKonrad Rzeszutek Wilk }
5330edc14bSKonrad Rzeszutek Wilk }
5430edc14bSKonrad Rzeszutek Wilk
5574d33dedSKonrad Rzeszutek Wilk mutex_unlock(&vpci_dev->lock);
5630edc14bSKonrad Rzeszutek Wilk }
5730edc14bSKonrad Rzeszutek Wilk return dev;
5830edc14bSKonrad Rzeszutek Wilk }
5930edc14bSKonrad Rzeszutek Wilk
match_slot(struct pci_dev * l,struct pci_dev * r)6030edc14bSKonrad Rzeszutek Wilk static inline int match_slot(struct pci_dev *l, struct pci_dev *r)
6130edc14bSKonrad Rzeszutek Wilk {
6230edc14bSKonrad Rzeszutek Wilk if (pci_domain_nr(l->bus) == pci_domain_nr(r->bus)
6330edc14bSKonrad Rzeszutek Wilk && l->bus == r->bus && PCI_SLOT(l->devfn) == PCI_SLOT(r->devfn))
6430edc14bSKonrad Rzeszutek Wilk return 1;
6530edc14bSKonrad Rzeszutek Wilk
6630edc14bSKonrad Rzeszutek Wilk return 0;
6730edc14bSKonrad Rzeszutek Wilk }
6830edc14bSKonrad Rzeszutek Wilk
__xen_pcibk_add_pci_dev(struct xen_pcibk_device * pdev,struct pci_dev * dev,int devid,publish_pci_dev_cb publish_cb)692ebdc426SKonrad Rzeszutek Wilk static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev,
702ebdc426SKonrad Rzeszutek Wilk struct pci_dev *dev, int devid,
712ebdc426SKonrad Rzeszutek Wilk publish_pci_dev_cb publish_cb)
7230edc14bSKonrad Rzeszutek Wilk {
73*4ba50e7cSJan Beulich int err = 0, slot, func = PCI_FUNC(dev->devfn);
7430edc14bSKonrad Rzeszutek Wilk struct pci_dev_entry *t, *dev_entry;
7530edc14bSKonrad Rzeszutek Wilk struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
7630edc14bSKonrad Rzeszutek Wilk
7730edc14bSKonrad Rzeszutek Wilk if ((dev->class >> 24) == PCI_BASE_CLASS_BRIDGE) {
7830edc14bSKonrad Rzeszutek Wilk err = -EFAULT;
7930edc14bSKonrad Rzeszutek Wilk xenbus_dev_fatal(pdev->xdev, err,
8030edc14bSKonrad Rzeszutek Wilk "Can't export bridges on the virtual PCI bus");
8130edc14bSKonrad Rzeszutek Wilk goto out;
8230edc14bSKonrad Rzeszutek Wilk }
8330edc14bSKonrad Rzeszutek Wilk
8430edc14bSKonrad Rzeszutek Wilk dev_entry = kmalloc(sizeof(*dev_entry), GFP_KERNEL);
8530edc14bSKonrad Rzeszutek Wilk if (!dev_entry) {
8630edc14bSKonrad Rzeszutek Wilk err = -ENOMEM;
8730edc14bSKonrad Rzeszutek Wilk xenbus_dev_fatal(pdev->xdev, err,
8830edc14bSKonrad Rzeszutek Wilk "Error adding entry to virtual PCI bus");
8930edc14bSKonrad Rzeszutek Wilk goto out;
9030edc14bSKonrad Rzeszutek Wilk }
9130edc14bSKonrad Rzeszutek Wilk
9230edc14bSKonrad Rzeszutek Wilk dev_entry->dev = dev;
9330edc14bSKonrad Rzeszutek Wilk
9474d33dedSKonrad Rzeszutek Wilk mutex_lock(&vpci_dev->lock);
9530edc14bSKonrad Rzeszutek Wilk
968a5248feSLaszlo Ersek /*
978a5248feSLaszlo Ersek * Keep multi-function devices together on the virtual PCI bus, except
98*4ba50e7cSJan Beulich * that we want to keep virtual functions at func 0 on their own. They
99*4ba50e7cSJan Beulich * aren't multi-function devices and hence their presence at func 0
100*4ba50e7cSJan Beulich * may cause guests to not scan the other functions.
1018a5248feSLaszlo Ersek */
102*4ba50e7cSJan Beulich if (!dev->is_virtfn || func) {
10330edc14bSKonrad Rzeszutek Wilk for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
1048a5248feSLaszlo Ersek if (list_empty(&vpci_dev->dev_list[slot]))
1058a5248feSLaszlo Ersek continue;
1068a5248feSLaszlo Ersek
10730edc14bSKonrad Rzeszutek Wilk t = list_entry(list_first(&vpci_dev->dev_list[slot]),
10830edc14bSKonrad Rzeszutek Wilk struct pci_dev_entry, list);
109*4ba50e7cSJan Beulich if (t->dev->is_virtfn && !PCI_FUNC(t->dev->devfn))
110*4ba50e7cSJan Beulich continue;
11130edc14bSKonrad Rzeszutek Wilk
11230edc14bSKonrad Rzeszutek Wilk if (match_slot(dev, t->dev)) {
11369049454SBjorn Helgaas dev_info(&dev->dev, "vpci: assign to virtual slot %d func %d\n",
114*4ba50e7cSJan Beulich slot, func);
11530edc14bSKonrad Rzeszutek Wilk list_add_tail(&dev_entry->list,
11630edc14bSKonrad Rzeszutek Wilk &vpci_dev->dev_list[slot]);
11730edc14bSKonrad Rzeszutek Wilk goto unlock;
11830edc14bSKonrad Rzeszutek Wilk }
11930edc14bSKonrad Rzeszutek Wilk }
12030edc14bSKonrad Rzeszutek Wilk }
12130edc14bSKonrad Rzeszutek Wilk
12230edc14bSKonrad Rzeszutek Wilk /* Assign to a new slot on the virtual PCI bus */
12330edc14bSKonrad Rzeszutek Wilk for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
12430edc14bSKonrad Rzeszutek Wilk if (list_empty(&vpci_dev->dev_list[slot])) {
12569049454SBjorn Helgaas dev_info(&dev->dev, "vpci: assign to virtual slot %d\n",
12669049454SBjorn Helgaas slot);
12730edc14bSKonrad Rzeszutek Wilk list_add_tail(&dev_entry->list,
12830edc14bSKonrad Rzeszutek Wilk &vpci_dev->dev_list[slot]);
12930edc14bSKonrad Rzeszutek Wilk goto unlock;
13030edc14bSKonrad Rzeszutek Wilk }
13130edc14bSKonrad Rzeszutek Wilk }
13230edc14bSKonrad Rzeszutek Wilk
13330edc14bSKonrad Rzeszutek Wilk err = -ENOMEM;
13430edc14bSKonrad Rzeszutek Wilk xenbus_dev_fatal(pdev->xdev, err,
13530edc14bSKonrad Rzeszutek Wilk "No more space on root virtual PCI bus");
13630edc14bSKonrad Rzeszutek Wilk
13730edc14bSKonrad Rzeszutek Wilk unlock:
13874d33dedSKonrad Rzeszutek Wilk mutex_unlock(&vpci_dev->lock);
13930edc14bSKonrad Rzeszutek Wilk
14030edc14bSKonrad Rzeszutek Wilk /* Publish this device. */
14130edc14bSKonrad Rzeszutek Wilk if (!err)
14230edc14bSKonrad Rzeszutek Wilk err = publish_cb(pdev, 0, 0, PCI_DEVFN(slot, func), devid);
143cea37f87SDaeseok Youn else
144cea37f87SDaeseok Youn kfree(dev_entry);
14530edc14bSKonrad Rzeszutek Wilk
14630edc14bSKonrad Rzeszutek Wilk out:
14730edc14bSKonrad Rzeszutek Wilk return err;
14830edc14bSKonrad Rzeszutek Wilk }
14930edc14bSKonrad Rzeszutek Wilk
__xen_pcibk_release_pci_dev(struct xen_pcibk_device * pdev,struct pci_dev * dev,bool lock)1502ebdc426SKonrad Rzeszutek Wilk static void __xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
151e8801a74SKonrad Rzeszutek Wilk struct pci_dev *dev, bool lock)
15230edc14bSKonrad Rzeszutek Wilk {
15330edc14bSKonrad Rzeszutek Wilk int slot;
15430edc14bSKonrad Rzeszutek Wilk struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
15530edc14bSKonrad Rzeszutek Wilk struct pci_dev *found_dev = NULL;
15630edc14bSKonrad Rzeszutek Wilk
15774d33dedSKonrad Rzeszutek Wilk mutex_lock(&vpci_dev->lock);
15830edc14bSKonrad Rzeszutek Wilk
15930edc14bSKonrad Rzeszutek Wilk for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
160402c5e15SJan Beulich struct pci_dev_entry *e;
161402c5e15SJan Beulich
162402c5e15SJan Beulich list_for_each_entry(e, &vpci_dev->dev_list[slot], list) {
16330edc14bSKonrad Rzeszutek Wilk if (e->dev == dev) {
16430edc14bSKonrad Rzeszutek Wilk list_del(&e->list);
16530edc14bSKonrad Rzeszutek Wilk found_dev = e->dev;
16630edc14bSKonrad Rzeszutek Wilk kfree(e);
16730edc14bSKonrad Rzeszutek Wilk goto out;
16830edc14bSKonrad Rzeszutek Wilk }
16930edc14bSKonrad Rzeszutek Wilk }
17030edc14bSKonrad Rzeszutek Wilk }
17130edc14bSKonrad Rzeszutek Wilk
17230edc14bSKonrad Rzeszutek Wilk out:
17374d33dedSKonrad Rzeszutek Wilk mutex_unlock(&vpci_dev->lock);
17430edc14bSKonrad Rzeszutek Wilk
175e8801a74SKonrad Rzeszutek Wilk if (found_dev) {
176e8801a74SKonrad Rzeszutek Wilk if (lock)
177e8801a74SKonrad Rzeszutek Wilk device_lock(&found_dev->dev);
17830edc14bSKonrad Rzeszutek Wilk pcistub_put_pci_dev(found_dev);
179e8801a74SKonrad Rzeszutek Wilk if (lock)
180e8801a74SKonrad Rzeszutek Wilk device_unlock(&found_dev->dev);
181e8801a74SKonrad Rzeszutek Wilk }
18230edc14bSKonrad Rzeszutek Wilk }
18330edc14bSKonrad Rzeszutek Wilk
__xen_pcibk_init_devices(struct xen_pcibk_device * pdev)1842ebdc426SKonrad Rzeszutek Wilk static int __xen_pcibk_init_devices(struct xen_pcibk_device *pdev)
18530edc14bSKonrad Rzeszutek Wilk {
18630edc14bSKonrad Rzeszutek Wilk int slot;
18730edc14bSKonrad Rzeszutek Wilk struct vpci_dev_data *vpci_dev;
18830edc14bSKonrad Rzeszutek Wilk
18930edc14bSKonrad Rzeszutek Wilk vpci_dev = kmalloc(sizeof(*vpci_dev), GFP_KERNEL);
19030edc14bSKonrad Rzeszutek Wilk if (!vpci_dev)
19130edc14bSKonrad Rzeszutek Wilk return -ENOMEM;
19230edc14bSKonrad Rzeszutek Wilk
19374d33dedSKonrad Rzeszutek Wilk mutex_init(&vpci_dev->lock);
19430edc14bSKonrad Rzeszutek Wilk
19530edc14bSKonrad Rzeszutek Wilk for (slot = 0; slot < PCI_SLOT_MAX; slot++)
19630edc14bSKonrad Rzeszutek Wilk INIT_LIST_HEAD(&vpci_dev->dev_list[slot]);
19730edc14bSKonrad Rzeszutek Wilk
19830edc14bSKonrad Rzeszutek Wilk pdev->pci_dev_data = vpci_dev;
19930edc14bSKonrad Rzeszutek Wilk
20030edc14bSKonrad Rzeszutek Wilk return 0;
20130edc14bSKonrad Rzeszutek Wilk }
20230edc14bSKonrad Rzeszutek Wilk
__xen_pcibk_publish_pci_roots(struct xen_pcibk_device * pdev,publish_pci_root_cb publish_cb)2032ebdc426SKonrad Rzeszutek Wilk static int __xen_pcibk_publish_pci_roots(struct xen_pcibk_device *pdev,
20430edc14bSKonrad Rzeszutek Wilk publish_pci_root_cb publish_cb)
20530edc14bSKonrad Rzeszutek Wilk {
20630edc14bSKonrad Rzeszutek Wilk /* The Virtual PCI bus has only one root */
20730edc14bSKonrad Rzeszutek Wilk return publish_cb(pdev, 0, 0);
20830edc14bSKonrad Rzeszutek Wilk }
20930edc14bSKonrad Rzeszutek Wilk
__xen_pcibk_release_devices(struct xen_pcibk_device * pdev)2102ebdc426SKonrad Rzeszutek Wilk static void __xen_pcibk_release_devices(struct xen_pcibk_device *pdev)
21130edc14bSKonrad Rzeszutek Wilk {
21230edc14bSKonrad Rzeszutek Wilk int slot;
21330edc14bSKonrad Rzeszutek Wilk struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
21430edc14bSKonrad Rzeszutek Wilk
21530edc14bSKonrad Rzeszutek Wilk for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
21630edc14bSKonrad Rzeszutek Wilk struct pci_dev_entry *e, *tmp;
21730edc14bSKonrad Rzeszutek Wilk list_for_each_entry_safe(e, tmp, &vpci_dev->dev_list[slot],
21830edc14bSKonrad Rzeszutek Wilk list) {
219e8801a74SKonrad Rzeszutek Wilk struct pci_dev *dev = e->dev;
22030edc14bSKonrad Rzeszutek Wilk list_del(&e->list);
221e8801a74SKonrad Rzeszutek Wilk device_lock(&dev->dev);
222e8801a74SKonrad Rzeszutek Wilk pcistub_put_pci_dev(dev);
223e8801a74SKonrad Rzeszutek Wilk device_unlock(&dev->dev);
22430edc14bSKonrad Rzeszutek Wilk kfree(e);
22530edc14bSKonrad Rzeszutek Wilk }
22630edc14bSKonrad Rzeszutek Wilk }
22730edc14bSKonrad Rzeszutek Wilk
22830edc14bSKonrad Rzeszutek Wilk kfree(vpci_dev);
22930edc14bSKonrad Rzeszutek Wilk pdev->pci_dev_data = NULL;
23030edc14bSKonrad Rzeszutek Wilk }
23130edc14bSKonrad Rzeszutek Wilk
__xen_pcibk_get_pcifront_dev(struct pci_dev * pcidev,struct xen_pcibk_device * pdev,unsigned int * domain,unsigned int * bus,unsigned int * devfn)2322ebdc426SKonrad Rzeszutek Wilk static int __xen_pcibk_get_pcifront_dev(struct pci_dev *pcidev,
233a92336a1SKonrad Rzeszutek Wilk struct xen_pcibk_device *pdev,
23430edc14bSKonrad Rzeszutek Wilk unsigned int *domain, unsigned int *bus,
23530edc14bSKonrad Rzeszutek Wilk unsigned int *devfn)
23630edc14bSKonrad Rzeszutek Wilk {
23730edc14bSKonrad Rzeszutek Wilk struct pci_dev_entry *entry;
23830edc14bSKonrad Rzeszutek Wilk struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
23930edc14bSKonrad Rzeszutek Wilk int found = 0, slot;
24030edc14bSKonrad Rzeszutek Wilk
24174d33dedSKonrad Rzeszutek Wilk mutex_lock(&vpci_dev->lock);
24230edc14bSKonrad Rzeszutek Wilk for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
24330edc14bSKonrad Rzeszutek Wilk list_for_each_entry(entry,
24430edc14bSKonrad Rzeszutek Wilk &vpci_dev->dev_list[slot],
24530edc14bSKonrad Rzeszutek Wilk list) {
246a929e124SJan Beulich if (entry->dev == pcidev) {
24730edc14bSKonrad Rzeszutek Wilk found = 1;
24830edc14bSKonrad Rzeszutek Wilk *domain = 0;
24930edc14bSKonrad Rzeszutek Wilk *bus = 0;
25030edc14bSKonrad Rzeszutek Wilk *devfn = PCI_DEVFN(slot,
25130edc14bSKonrad Rzeszutek Wilk PCI_FUNC(pcidev->devfn));
25230edc14bSKonrad Rzeszutek Wilk }
25330edc14bSKonrad Rzeszutek Wilk }
25430edc14bSKonrad Rzeszutek Wilk }
255e1db4cefSDan Carpenter mutex_unlock(&vpci_dev->lock);
25630edc14bSKonrad Rzeszutek Wilk return found;
25730edc14bSKonrad Rzeszutek Wilk }
2582ebdc426SKonrad Rzeszutek Wilk
259402c5e15SJan Beulich const struct xen_pcibk_backend xen_pcibk_vpci_backend = {
2602ebdc426SKonrad Rzeszutek Wilk .name = "vpci",
2612ebdc426SKonrad Rzeszutek Wilk .init = __xen_pcibk_init_devices,
2622ebdc426SKonrad Rzeszutek Wilk .free = __xen_pcibk_release_devices,
2632ebdc426SKonrad Rzeszutek Wilk .find = __xen_pcibk_get_pcifront_dev,
2642ebdc426SKonrad Rzeszutek Wilk .publish = __xen_pcibk_publish_pci_roots,
2652ebdc426SKonrad Rzeszutek Wilk .release = __xen_pcibk_release_pci_dev,
2662ebdc426SKonrad Rzeszutek Wilk .add = __xen_pcibk_add_pci_dev,
2672ebdc426SKonrad Rzeszutek Wilk .get = __xen_pcibk_get_pci_dev,
2682ebdc426SKonrad Rzeszutek Wilk };
269