2 * PCI Backend - Provides restricted access to the real PCI bus topology
5 * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
8 #include <linux/list.h>
10 #include <linux/mutex.h>
13 struct passthrough_dev_data
{
14 /* Access to dev_list must be protected by lock */
15 struct list_head dev_list
;
19 static struct pci_dev
*__xen_pcibk_get_pci_dev(struct xen_pcibk_device
*pdev
,
24 struct passthrough_dev_data
*dev_data
= pdev
->pci_dev_data
;
25 struct pci_dev_entry
*dev_entry
;
26 struct pci_dev
*dev
= NULL
;
28 mutex_lock(&dev_data
->lock
);
30 list_for_each_entry(dev_entry
, &dev_data
->dev_list
, list
) {
31 if (domain
== (unsigned int)pci_domain_nr(dev_entry
->dev
->bus
)
32 && bus
== (unsigned int)dev_entry
->dev
->bus
->number
33 && devfn
== dev_entry
->dev
->devfn
) {
39 mutex_unlock(&dev_data
->lock
);
44 static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device
*pdev
,
46 int devid
, publish_pci_dev_cb publish_cb
)
48 struct passthrough_dev_data
*dev_data
= pdev
->pci_dev_data
;
49 struct pci_dev_entry
*dev_entry
;
50 unsigned int domain
, bus
, devfn
;
53 dev_entry
= kmalloc(sizeof(*dev_entry
), GFP_KERNEL
);
58 mutex_lock(&dev_data
->lock
);
59 list_add_tail(&dev_entry
->list
, &dev_data
->dev_list
);
60 mutex_unlock(&dev_data
->lock
);
62 /* Publish this device. */
63 domain
= (unsigned int)pci_domain_nr(dev
->bus
);
64 bus
= (unsigned int)dev
->bus
->number
;
66 err
= publish_cb(pdev
, domain
, bus
, devfn
, devid
);
71 static void __xen_pcibk_release_pci_dev(struct xen_pcibk_device
*pdev
,
74 struct passthrough_dev_data
*dev_data
= pdev
->pci_dev_data
;
75 struct pci_dev_entry
*dev_entry
, *t
;
76 struct pci_dev
*found_dev
= NULL
;
78 mutex_lock(&dev_data
->lock
);
80 list_for_each_entry_safe(dev_entry
, t
, &dev_data
->dev_list
, list
) {
81 if (dev_entry
->dev
== dev
) {
82 list_del(&dev_entry
->list
);
83 found_dev
= dev_entry
->dev
;
88 mutex_unlock(&dev_data
->lock
);
91 pcistub_put_pci_dev(found_dev
);
94 static int __xen_pcibk_init_devices(struct xen_pcibk_device
*pdev
)
96 struct passthrough_dev_data
*dev_data
;
98 dev_data
= kmalloc(sizeof(*dev_data
), GFP_KERNEL
);
102 mutex_init(&dev_data
->lock
);
104 INIT_LIST_HEAD(&dev_data
->dev_list
);
106 pdev
->pci_dev_data
= dev_data
;
111 static int __xen_pcibk_publish_pci_roots(struct xen_pcibk_device
*pdev
,
112 publish_pci_root_cb publish_root_cb
)
115 struct passthrough_dev_data
*dev_data
= pdev
->pci_dev_data
;
116 struct pci_dev_entry
*dev_entry
, *e
;
119 unsigned int domain
, bus
;
121 mutex_lock(&dev_data
->lock
);
123 list_for_each_entry(dev_entry
, &dev_data
->dev_list
, list
) {
124 /* Only publish this device as a root if none of its
125 * parent bridges are exported
128 dev
= dev_entry
->dev
->bus
->self
;
129 for (; !found
&& dev
!= NULL
; dev
= dev
->bus
->self
) {
130 list_for_each_entry(e
, &dev_data
->dev_list
, list
) {
138 domain
= (unsigned int)pci_domain_nr(dev_entry
->dev
->bus
);
139 bus
= (unsigned int)dev_entry
->dev
->bus
->number
;
142 err
= publish_root_cb(pdev
, domain
, bus
);
148 mutex_unlock(&dev_data
->lock
);
153 static void __xen_pcibk_release_devices(struct xen_pcibk_device
*pdev
)
155 struct passthrough_dev_data
*dev_data
= pdev
->pci_dev_data
;
156 struct pci_dev_entry
*dev_entry
, *t
;
158 list_for_each_entry_safe(dev_entry
, t
, &dev_data
->dev_list
, list
) {
159 list_del(&dev_entry
->list
);
160 pcistub_put_pci_dev(dev_entry
->dev
);
165 pdev
->pci_dev_data
= NULL
;
168 static int __xen_pcibk_get_pcifront_dev(struct pci_dev
*pcidev
,
169 struct xen_pcibk_device
*pdev
,
170 unsigned int *domain
, unsigned int *bus
,
173 *domain
= pci_domain_nr(pcidev
->bus
);
174 *bus
= pcidev
->bus
->number
;
175 *devfn
= pcidev
->devfn
;
179 const struct xen_pcibk_backend xen_pcibk_passthrough_backend
= {
180 .name
= "passthrough",
181 .init
= __xen_pcibk_init_devices
,
182 .free
= __xen_pcibk_release_devices
,
183 .find
= __xen_pcibk_get_pcifront_dev
,
184 .publish
= __xen_pcibk_publish_pci_roots
,
185 .release
= __xen_pcibk_release_pci_dev
,
186 .add
= __xen_pcibk_add_pci_dev
,
187 .get
= __xen_pcibk_get_pci_dev
,