aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyan Wilson <hap9@epoch.ncsc.mil>2010-08-02 21:31:05 -0400
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2010-10-18 10:49:37 -0400
commit956a9202cd1220397933a07beda9f96b3df1fa24 (patch)
tree49d6ac9b43c16a9363b6ceff81ec62ef81aca0a7
parentb78c9512563780d86a178f11b648bcf73b8d87ec (diff)
xen-pcifront: Xen PCI frontend driver.
This is a port of the 2.6.18 Xen PCI front driver with fixes to make it build under 2.6.34 and later (for the full list of changes: git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen.git historic/xen-pcifront-0.1). It also includes the fixes to make it work properly. [v2: Updated Kconfig, removed crud, added Reviewed-by] [v3: Added 'static', fixed grant table leak, redid Kconfig] [v4: Added one more 'static' and removed comments] Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Reviewed-by: Jan Beulich <JBeulich@novell.com>
-rw-r--r--drivers/pci/Kconfig21
-rw-r--r--drivers/pci/Makefile2
-rw-r--r--drivers/pci/xen-pcifront.c1148
-rw-r--r--include/xen/interface/io/pciif.h112
4 files changed, 1283 insertions, 0 deletions
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 34ef70d562b2..5b1630e4e9e3 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -40,6 +40,27 @@ config PCI_STUB
40 40
41 When in doubt, say N. 41 When in doubt, say N.
42 42
43config XEN_PCIDEV_FRONTEND
44 tristate "Xen PCI Frontend"
45 depends on PCI && X86 && XEN
46 select HOTPLUG
47 select PCI_XEN
48 default y
49 help
50 The PCI device frontend driver allows the kernel to import arbitrary
51 PCI devices from a PCI backend to support PCI driver domains.
52
53config XEN_PCIDEV_FE_DEBUG
54 bool "Xen PCI Frontend debugging"
55 depends on XEN_PCIDEV_FRONTEND && PCI_DEBUG
56 help
57 Say Y here if you want the Xen PCI frontend to produce a bunch of debug
58 messages to the system log. Select this if you are having a
59 problem with Xen PCI frontend support and want to see more of what is
60 going on.
61
62 When in doubt, say N.
63
43config HT_IRQ 64config HT_IRQ
44 bool "Interrupts on hypertransport devices" 65 bool "Interrupts on hypertransport devices"
45 default y 66 default y
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index dc1aa0922868..d5e27050c4e3 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -65,6 +65,8 @@ obj-$(CONFIG_PCI_SYSCALL) += syscall.o
65 65
66obj-$(CONFIG_PCI_STUB) += pci-stub.o 66obj-$(CONFIG_PCI_STUB) += pci-stub.o
67 67
68obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += xen-pcifront.o
69
68ifeq ($(CONFIG_PCI_DEBUG),y) 70ifeq ($(CONFIG_PCI_DEBUG),y)
69EXTRA_CFLAGS += -DDEBUG 71EXTRA_CFLAGS += -DDEBUG
70endif 72endif
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
new file mode 100644
index 000000000000..a87c4985326e
--- /dev/null
+++ b/drivers/pci/xen-pcifront.c
@@ -0,0 +1,1148 @@
1/*
2 * Xen PCI Frontend.
3 *
4 * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
5 */
6#include <linux/module.h>
7#include <linux/init.h>
8#include <linux/mm.h>
9#include <xen/xenbus.h>
10#include <xen/events.h>
11#include <xen/grant_table.h>
12#include <xen/page.h>
13#include <linux/spinlock.h>
14#include <linux/pci.h>
15#include <linux/msi.h>
16#include <xen/xenbus.h>
17#include <xen/interface/io/pciif.h>
18#include <asm/xen/pci.h>
19#include <linux/interrupt.h>
20#include <asm/atomic.h>
21#include <linux/workqueue.h>
22#include <linux/bitops.h>
23#include <linux/time.h>
24
25#define INVALID_GRANT_REF (0)
26#define INVALID_EVTCHN (-1)
27
28struct pci_bus_entry {
29 struct list_head list;
30 struct pci_bus *bus;
31};
32
33#define _PDEVB_op_active (0)
34#define PDEVB_op_active (1 << (_PDEVB_op_active))
35
36struct pcifront_device {
37 struct xenbus_device *xdev;
38 struct list_head root_buses;
39
40 int evtchn;
41 int gnt_ref;
42
43 int irq;
44
45 /* Lock this when doing any operations in sh_info */
46 spinlock_t sh_info_lock;
47 struct xen_pci_sharedinfo *sh_info;
48 struct work_struct op_work;
49 unsigned long flags;
50
51};
52
53struct pcifront_sd {
54 int domain;
55 struct pcifront_device *pdev;
56};
57
58static inline struct pcifront_device *
59pcifront_get_pdev(struct pcifront_sd *sd)
60{
61 return sd->pdev;
62}
63
64static inline void pcifront_init_sd(struct pcifront_sd *sd,
65 unsigned int domain, unsigned int bus,
66 struct pcifront_device *pdev)
67{
68 sd->domain = domain;
69 sd->pdev = pdev;
70}
71
72static DEFINE_SPINLOCK(pcifront_dev_lock);
73static struct pcifront_device *pcifront_dev;
74
75static int verbose_request;
76module_param(verbose_request, int, 0644);
77
78static int errno_to_pcibios_err(int errno)
79{
80 switch (errno) {
81 case XEN_PCI_ERR_success:
82 return PCIBIOS_SUCCESSFUL;
83
84 case XEN_PCI_ERR_dev_not_found:
85 return PCIBIOS_DEVICE_NOT_FOUND;
86
87 case XEN_PCI_ERR_invalid_offset:
88 case XEN_PCI_ERR_op_failed:
89 return PCIBIOS_BAD_REGISTER_NUMBER;
90
91 case XEN_PCI_ERR_not_implemented:
92 return PCIBIOS_FUNC_NOT_SUPPORTED;
93
94 case XEN_PCI_ERR_access_denied:
95 return PCIBIOS_SET_FAILED;
96 }
97 return errno;
98}
99
100static inline void schedule_pcifront_aer_op(struct pcifront_device *pdev)
101{
102 if (test_bit(_XEN_PCIB_active, (unsigned long *)&pdev->sh_info->flags)
103 && !test_and_set_bit(_PDEVB_op_active, &pdev->flags)) {
104 dev_dbg(&pdev->xdev->dev, "schedule aer frontend job\n");
105 schedule_work(&pdev->op_work);
106 }
107}
108
109static int do_pci_op(struct pcifront_device *pdev, struct xen_pci_op *op)
110{
111 int err = 0;
112 struct xen_pci_op *active_op = &pdev->sh_info->op;
113 unsigned long irq_flags;
114 evtchn_port_t port = pdev->evtchn;
115 unsigned irq = pdev->irq;
116 s64 ns, ns_timeout;
117 struct timeval tv;
118
119 spin_lock_irqsave(&pdev->sh_info_lock, irq_flags);
120
121 memcpy(active_op, op, sizeof(struct xen_pci_op));
122
123 /* Go */
124 wmb();
125 set_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags);
126 notify_remote_via_evtchn(port);
127
128 /*
129 * We set a poll timeout of 3 seconds but give up on return after
130 * 2 seconds. It is better to time out too late rather than too early
131 * (in the latter case we end up continually re-executing poll() with a
132 * timeout in the past). 1s difference gives plenty of slack for error.
133 */
134 do_gettimeofday(&tv);
135 ns_timeout = timeval_to_ns(&tv) + 2 * (s64)NSEC_PER_SEC;
136
137 xen_clear_irq_pending(irq);
138
139 while (test_bit(_XEN_PCIF_active,
140 (unsigned long *)&pdev->sh_info->flags)) {
141 xen_poll_irq_timeout(irq, jiffies + 3*HZ);
142 xen_clear_irq_pending(irq);
143 do_gettimeofday(&tv);
144 ns = timeval_to_ns(&tv);
145 if (ns > ns_timeout) {
146 dev_err(&pdev->xdev->dev,
147 "pciback not responding!!!\n");
148 clear_bit(_XEN_PCIF_active,
149 (unsigned long *)&pdev->sh_info->flags);
150 err = XEN_PCI_ERR_dev_not_found;
151 goto out;
152 }
153 }
154
155 /*
156 * We might lose backend service request since we
157 * reuse same evtchn with pci_conf backend response. So re-schedule
158 * aer pcifront service.
159 */
160 if (test_bit(_XEN_PCIB_active,
161 (unsigned long *)&pdev->sh_info->flags)) {
162 dev_err(&pdev->xdev->dev,
163 "schedule aer pcifront service\n");
164 schedule_pcifront_aer_op(pdev);
165 }
166
167 memcpy(op, active_op, sizeof(struct xen_pci_op));
168
169 err = op->err;
170out:
171 spin_unlock_irqrestore(&pdev->sh_info_lock, irq_flags);
172 return err;
173}
174
175/* Access to this function is spinlocked in drivers/pci/access.c */
176static int pcifront_bus_read(struct pci_bus *bus, unsigned int devfn,
177 int where, int size, u32 *val)
178{
179 int err = 0;
180 struct xen_pci_op op = {
181 .cmd = XEN_PCI_OP_conf_read,
182 .domain = pci_domain_nr(bus),
183 .bus = bus->number,
184 .devfn = devfn,
185 .offset = where,
186 .size = size,
187 };
188 struct pcifront_sd *sd = bus->sysdata;
189 struct pcifront_device *pdev = pcifront_get_pdev(sd);
190
191 if (verbose_request)
192 dev_info(&pdev->xdev->dev,
193 "read dev=%04x:%02x:%02x.%01x - offset %x size %d\n",
194 pci_domain_nr(bus), bus->number, PCI_SLOT(devfn),
195 PCI_FUNC(devfn), where, size);
196
197 err = do_pci_op(pdev, &op);
198
199 if (likely(!err)) {
200 if (verbose_request)
201 dev_info(&pdev->xdev->dev, "read got back value %x\n",
202 op.value);
203
204 *val = op.value;
205 } else if (err == -ENODEV) {
206 /* No device here, pretend that it just returned 0 */
207 err = 0;
208 *val = 0;
209 }
210
211 return errno_to_pcibios_err(err);
212}
213
214/* Access to this function is spinlocked in drivers/pci/access.c */
215static int pcifront_bus_write(struct pci_bus *bus, unsigned int devfn,
216 int where, int size, u32 val)
217{
218 struct xen_pci_op op = {
219 .cmd = XEN_PCI_OP_conf_write,
220 .domain = pci_domain_nr(bus),
221 .bus = bus->number,
222 .devfn = devfn,
223 .offset = where,
224 .size = size,
225 .value = val,
226 };
227 struct pcifront_sd *sd = bus->sysdata;
228 struct pcifront_device *pdev = pcifront_get_pdev(sd);
229
230 if (verbose_request)
231 dev_info(&pdev->xdev->dev,
232 "write dev=%04x:%02x:%02x.%01x - "
233 "offset %x size %d val %x\n",
234 pci_domain_nr(bus), bus->number,
235 PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, val);
236
237 return errno_to_pcibios_err(do_pci_op(pdev, &op));
238}
239
240struct pci_ops pcifront_bus_ops = {
241 .read = pcifront_bus_read,
242 .write = pcifront_bus_write,
243};
244
245#ifdef CONFIG_PCI_MSI
246static int pci_frontend_enable_msix(struct pci_dev *dev,
247 int **vector, int nvec)
248{
249 int err;
250 int i;
251 struct xen_pci_op op = {
252 .cmd = XEN_PCI_OP_enable_msix,
253 .domain = pci_domain_nr(dev->bus),
254 .bus = dev->bus->number,
255 .devfn = dev->devfn,
256 .value = nvec,
257 };
258 struct pcifront_sd *sd = dev->bus->sysdata;
259 struct pcifront_device *pdev = pcifront_get_pdev(sd);
260 struct msi_desc *entry;
261
262 if (nvec > SH_INFO_MAX_VEC) {
263 dev_err(&dev->dev, "too much vector for pci frontend: %x."
264 " Increase SH_INFO_MAX_VEC.\n", nvec);
265 return -EINVAL;
266 }
267
268 i = 0;
269 list_for_each_entry(entry, &dev->msi_list, list) {
270 op.msix_entries[i].entry = entry->msi_attrib.entry_nr;
271 /* Vector is useless at this point. */
272 op.msix_entries[i].vector = -1;
273 i++;
274 }
275
276 err = do_pci_op(pdev, &op);
277
278 if (likely(!err)) {
279 if (likely(!op.value)) {
280 /* we get the result */
281 for (i = 0; i < nvec; i++)
282 *(*vector+i) = op.msix_entries[i].vector;
283 return 0;
284 } else {
285 printk(KERN_DEBUG "enable msix get value %x\n",
286 op.value);
287 return op.value;
288 }
289 } else {
290 dev_err(&dev->dev, "enable msix get err %x\n", err);
291 return err;
292 }
293}
294
295static void pci_frontend_disable_msix(struct pci_dev *dev)
296{
297 int err;
298 struct xen_pci_op op = {
299 .cmd = XEN_PCI_OP_disable_msix,
300 .domain = pci_domain_nr(dev->bus),
301 .bus = dev->bus->number,
302 .devfn = dev->devfn,
303 };
304 struct pcifront_sd *sd = dev->bus->sysdata;
305 struct pcifront_device *pdev = pcifront_get_pdev(sd);
306
307 err = do_pci_op(pdev, &op);
308
309 /* What should do for error ? */
310 if (err)
311 dev_err(&dev->dev, "pci_disable_msix get err %x\n", err);
312}
313
314static int pci_frontend_enable_msi(struct pci_dev *dev, int **vector)
315{
316 int err;
317 struct xen_pci_op op = {
318 .cmd = XEN_PCI_OP_enable_msi,
319 .domain = pci_domain_nr(dev->bus),
320 .bus = dev->bus->number,
321 .devfn = dev->devfn,
322 };
323 struct pcifront_sd *sd = dev->bus->sysdata;
324 struct pcifront_device *pdev = pcifront_get_pdev(sd);
325
326 err = do_pci_op(pdev, &op);
327 if (likely(!err)) {
328 *(*vector) = op.value;
329 } else {
330 dev_err(&dev->dev, "pci frontend enable msi failed for dev "
331 "%x:%x\n", op.bus, op.devfn);
332 err = -EINVAL;
333 }
334 return err;
335}
336
337static void pci_frontend_disable_msi(struct pci_dev *dev)
338{
339 int err;
340 struct xen_pci_op op = {
341 .cmd = XEN_PCI_OP_disable_msi,
342 .domain = pci_domain_nr(dev->bus),
343 .bus = dev->bus->number,
344 .devfn = dev->devfn,
345 };
346 struct pcifront_sd *sd = dev->bus->sysdata;
347 struct pcifront_device *pdev = pcifront_get_pdev(sd);
348
349 err = do_pci_op(pdev, &op);
350 if (err == XEN_PCI_ERR_dev_not_found) {
351 /* XXX No response from backend, what shall we do? */
352 printk(KERN_DEBUG "get no response from backend for disable MSI\n");
353 return;
354 }
355 if (err)
356 /* how can pciback notify us fail? */
357 printk(KERN_DEBUG "get fake response frombackend\n");
358}
359
360static struct xen_pci_frontend_ops pci_frontend_ops = {
361 .enable_msi = pci_frontend_enable_msi,
362 .disable_msi = pci_frontend_disable_msi,
363 .enable_msix = pci_frontend_enable_msix,
364 .disable_msix = pci_frontend_disable_msix,
365};
366
367static void pci_frontend_registrar(int enable)
368{
369 if (enable)
370 xen_pci_frontend = &pci_frontend_ops;
371 else
372 xen_pci_frontend = NULL;
373};
374#else
375static inline void pci_frontend_registrar(int enable) { };
376#endif /* CONFIG_PCI_MSI */
377
378/* Claim resources for the PCI frontend as-is, backend won't allow changes */
379static int pcifront_claim_resource(struct pci_dev *dev, void *data)
380{
381 struct pcifront_device *pdev = data;
382 int i;
383 struct resource *r;
384
385 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
386 r = &dev->resource[i];
387
388 if (!r->parent && r->start && r->flags) {
389 dev_info(&pdev->xdev->dev, "claiming resource %s/%d\n",
390 pci_name(dev), i);
391 if (pci_claim_resource(dev, i)) {
392 dev_err(&pdev->xdev->dev, "Could not claim "
393 "resource %s/%d! Device offline. Try "
394 "giving less than 4GB to domain.\n",
395 pci_name(dev), i);
396 }
397 }
398 }
399
400 return 0;
401}
402
403static int __devinit pcifront_scan_bus(struct pcifront_device *pdev,
404 unsigned int domain, unsigned int bus,
405 struct pci_bus *b)
406{
407 struct pci_dev *d;
408 unsigned int devfn;
409
410 /* Scan the bus for functions and add.
411 * We omit handling of PCI bridge attachment because pciback prevents
412 * bridges from being exported.
413 */
414 for (devfn = 0; devfn < 0x100; devfn++) {
415 d = pci_get_slot(b, devfn);
416 if (d) {
417 /* Device is already known. */
418 pci_dev_put(d);
419 continue;
420 }
421
422 d = pci_scan_single_device(b, devfn);
423 if (d)
424 dev_info(&pdev->xdev->dev, "New device on "
425 "%04x:%02x:%02x.%02x found.\n", domain, bus,
426 PCI_SLOT(devfn), PCI_FUNC(devfn));
427 }
428
429 return 0;
430}
431
432static int __devinit pcifront_scan_root(struct pcifront_device *pdev,
433 unsigned int domain, unsigned int bus)
434{
435 struct pci_bus *b;
436 struct pcifront_sd *sd = NULL;
437 struct pci_bus_entry *bus_entry = NULL;
438 int err = 0;
439
440#ifndef CONFIG_PCI_DOMAINS
441 if (domain != 0) {
442 dev_err(&pdev->xdev->dev,
443 "PCI Root in non-zero PCI Domain! domain=%d\n", domain);
444 dev_err(&pdev->xdev->dev,
445 "Please compile with CONFIG_PCI_DOMAINS\n");
446 err = -EINVAL;
447 goto err_out;
448 }
449#endif
450
451 dev_info(&pdev->xdev->dev, "Creating PCI Frontend Bus %04x:%02x\n",
452 domain, bus);
453
454 bus_entry = kmalloc(sizeof(*bus_entry), GFP_KERNEL);
455 sd = kmalloc(sizeof(*sd), GFP_KERNEL);
456 if (!bus_entry || !sd) {
457 err = -ENOMEM;
458 goto err_out;
459 }
460 pcifront_init_sd(sd, domain, bus, pdev);
461
462 b = pci_scan_bus_parented(&pdev->xdev->dev, bus,
463 &pcifront_bus_ops, sd);
464 if (!b) {
465 dev_err(&pdev->xdev->dev,
466 "Error creating PCI Frontend Bus!\n");
467 err = -ENOMEM;
468 goto err_out;
469 }
470
471 bus_entry->bus = b;
472
473 list_add(&bus_entry->list, &pdev->root_buses);
474
475 /* pci_scan_bus_parented skips devices which do not have a have
476 * devfn==0. The pcifront_scan_bus enumerates all devfn. */
477 err = pcifront_scan_bus(pdev, domain, bus, b);
478
479 /* Claim resources before going "live" with our devices */
480 pci_walk_bus(b, pcifront_claim_resource, pdev);
481
482 /* Create SysFS and notify udev of the devices. Aka: "going live" */
483 pci_bus_add_devices(b);
484
485 return err;
486
487err_out:
488 kfree(bus_entry);
489 kfree(sd);
490
491 return err;
492}
493
494static int __devinit pcifront_rescan_root(struct pcifront_device *pdev,
495 unsigned int domain, unsigned int bus)
496{
497 int err;
498 struct pci_bus *b;
499
500#ifndef CONFIG_PCI_DOMAINS
501 if (domain != 0) {
502 dev_err(&pdev->xdev->dev,
503 "PCI Root in non-zero PCI Domain! domain=%d\n", domain);
504 dev_err(&pdev->xdev->dev,
505 "Please compile with CONFIG_PCI_DOMAINS\n");
506 return -EINVAL;
507 }
508#endif
509
510 dev_info(&pdev->xdev->dev, "Rescanning PCI Frontend Bus %04x:%02x\n",
511 domain, bus);
512
513 b = pci_find_bus(domain, bus);
514 if (!b)
515 /* If the bus is unknown, create it. */
516 return pcifront_scan_root(pdev, domain, bus);
517
518 err = pcifront_scan_bus(pdev, domain, bus, b);
519
520 /* Claim resources before going "live" with our devices */
521 pci_walk_bus(b, pcifront_claim_resource, pdev);
522
523 /* Create SysFS and notify udev of the devices. Aka: "going live" */
524 pci_bus_add_devices(b);
525
526 return err;
527}
528
529static void free_root_bus_devs(struct pci_bus *bus)
530{
531 struct pci_dev *dev;
532
533 while (!list_empty(&bus->devices)) {
534 dev = container_of(bus->devices.next, struct pci_dev,
535 bus_list);
536 dev_dbg(&dev->dev, "removing device\n");
537 pci_remove_bus_device(dev);
538 }
539}
540
541static void pcifront_free_roots(struct pcifront_device *pdev)
542{
543 struct pci_bus_entry *bus_entry, *t;
544
545 dev_dbg(&pdev->xdev->dev, "cleaning up root buses\n");
546
547 list_for_each_entry_safe(bus_entry, t, &pdev->root_buses, list) {
548 list_del(&bus_entry->list);
549
550 free_root_bus_devs(bus_entry->bus);
551
552 kfree(bus_entry->bus->sysdata);
553
554 device_unregister(bus_entry->bus->bridge);
555 pci_remove_bus(bus_entry->bus);
556
557 kfree(bus_entry);
558 }
559}
560
561static pci_ers_result_t pcifront_common_process(int cmd,
562 struct pcifront_device *pdev,
563 pci_channel_state_t state)
564{
565 pci_ers_result_t result;
566 struct pci_driver *pdrv;
567 int bus = pdev->sh_info->aer_op.bus;
568 int devfn = pdev->sh_info->aer_op.devfn;
569 struct pci_dev *pcidev;
570 int flag = 0;
571
572 dev_dbg(&pdev->xdev->dev,
573 "pcifront AER process: cmd %x (bus:%x, devfn%x)",
574 cmd, bus, devfn);
575 result = PCI_ERS_RESULT_NONE;
576
577 pcidev = pci_get_bus_and_slot(bus, devfn);
578 if (!pcidev || !pcidev->driver) {
579 dev_err(&pcidev->dev,
580 "device or driver is NULL\n");
581 return result;
582 }
583 pdrv = pcidev->driver;
584
585 if (get_driver(&pdrv->driver)) {
586 if (pdrv->err_handler && pdrv->err_handler->error_detected) {
587 dev_dbg(&pcidev->dev,
588 "trying to call AER service\n");
589 if (pcidev) {
590 flag = 1;
591 switch (cmd) {
592 case XEN_PCI_OP_aer_detected:
593 result = pdrv->err_handler->
594 error_detected(pcidev, state);
595 break;
596 case XEN_PCI_OP_aer_mmio:
597 result = pdrv->err_handler->
598 mmio_enabled(pcidev);
599 break;
600 case XEN_PCI_OP_aer_slotreset:
601 result = pdrv->err_handler->
602 slot_reset(pcidev);
603 break;
604 case XEN_PCI_OP_aer_resume:
605 pdrv->err_handler->resume(pcidev);
606 break;
607 default:
608 dev_err(&pdev->xdev->dev,
609 "bad request in aer recovery "
610 "operation!\n");
611
612 }
613 }
614 }
615 put_driver(&pdrv->driver);
616 }
617 if (!flag)
618 result = PCI_ERS_RESULT_NONE;
619
620 return result;
621}
622
623
624static void pcifront_do_aer(struct work_struct *data)
625{
626 struct pcifront_device *pdev =
627 container_of(data, struct pcifront_device, op_work);
628 int cmd = pdev->sh_info->aer_op.cmd;
629 pci_channel_state_t state =
630 (pci_channel_state_t)pdev->sh_info->aer_op.err;
631
632 /*If a pci_conf op is in progress,
633 we have to wait until it is done before service aer op*/
634 dev_dbg(&pdev->xdev->dev,
635 "pcifront service aer bus %x devfn %x\n",
636 pdev->sh_info->aer_op.bus, pdev->sh_info->aer_op.devfn);
637
638 pdev->sh_info->aer_op.err = pcifront_common_process(cmd, pdev, state);
639
640 /* Post the operation to the guest. */
641 wmb();
642 clear_bit(_XEN_PCIB_active, (unsigned long *)&pdev->sh_info->flags);
643 notify_remote_via_evtchn(pdev->evtchn);
644
645 /*in case of we lost an aer request in four lines time_window*/
646 smp_mb__before_clear_bit();
647 clear_bit(_PDEVB_op_active, &pdev->flags);
648 smp_mb__after_clear_bit();
649
650 schedule_pcifront_aer_op(pdev);
651
652}
653
654static irqreturn_t pcifront_handler_aer(int irq, void *dev)
655{
656 struct pcifront_device *pdev = dev;
657 schedule_pcifront_aer_op(pdev);
658 return IRQ_HANDLED;
659}
660static int pcifront_connect(struct pcifront_device *pdev)
661{
662 int err = 0;
663
664 spin_lock(&pcifront_dev_lock);
665
666 if (!pcifront_dev) {
667 dev_info(&pdev->xdev->dev, "Installing PCI frontend\n");
668 pcifront_dev = pdev;
669 } else {
670 dev_err(&pdev->xdev->dev, "PCI frontend already installed!\n");
671 err = -EEXIST;
672 }
673
674 spin_unlock(&pcifront_dev_lock);
675
676 return err;
677}
678
679static void pcifront_disconnect(struct pcifront_device *pdev)
680{
681 spin_lock(&pcifront_dev_lock);
682
683 if (pdev == pcifront_dev) {
684 dev_info(&pdev->xdev->dev,
685 "Disconnecting PCI Frontend Buses\n");
686 pcifront_dev = NULL;
687 }
688
689 spin_unlock(&pcifront_dev_lock);
690}
691static struct pcifront_device *alloc_pdev(struct xenbus_device *xdev)
692{
693 struct pcifront_device *pdev;
694
695 pdev = kzalloc(sizeof(struct pcifront_device), GFP_KERNEL);
696 if (pdev == NULL)
697 goto out;
698
699 pdev->sh_info =
700 (struct xen_pci_sharedinfo *)__get_free_page(GFP_KERNEL);
701 if (pdev->sh_info == NULL) {
702 kfree(pdev);
703 pdev = NULL;
704 goto out;
705 }
706 pdev->sh_info->flags = 0;
707
708 /*Flag for registering PV AER handler*/
709 set_bit(_XEN_PCIB_AERHANDLER, (void *)&pdev->sh_info->flags);
710
711 dev_set_drvdata(&xdev->dev, pdev);
712 pdev->xdev = xdev;
713
714 INIT_LIST_HEAD(&pdev->root_buses);
715
716 spin_lock_init(&pdev->sh_info_lock);
717
718 pdev->evtchn = INVALID_EVTCHN;
719 pdev->gnt_ref = INVALID_GRANT_REF;
720 pdev->irq = -1;
721
722 INIT_WORK(&pdev->op_work, pcifront_do_aer);
723
724 dev_dbg(&xdev->dev, "Allocated pdev @ 0x%p pdev->sh_info @ 0x%p\n",
725 pdev, pdev->sh_info);
726out:
727 return pdev;
728}
729
730static void free_pdev(struct pcifront_device *pdev)
731{
732 dev_dbg(&pdev->xdev->dev, "freeing pdev @ 0x%p\n", pdev);
733
734 pcifront_free_roots(pdev);
735
736 /*For PCIE_AER error handling job*/
737 flush_scheduled_work();
738
739 if (pdev->irq >= 0)
740 unbind_from_irqhandler(pdev->irq, pdev);
741
742 if (pdev->evtchn != INVALID_EVTCHN)
743 xenbus_free_evtchn(pdev->xdev, pdev->evtchn);
744
745 if (pdev->gnt_ref != INVALID_GRANT_REF)
746 gnttab_end_foreign_access(pdev->gnt_ref, 0 /* r/w page */,
747 (unsigned long)pdev->sh_info);
748 else
749 free_page((unsigned long)pdev->sh_info);
750
751 dev_set_drvdata(&pdev->xdev->dev, NULL);
752
753 kfree(pdev);
754}
755
756static int pcifront_publish_info(struct pcifront_device *pdev)
757{
758 int err = 0;
759 struct xenbus_transaction trans;
760
761 err = xenbus_grant_ring(pdev->xdev, virt_to_mfn(pdev->sh_info));
762 if (err < 0)
763 goto out;
764
765 pdev->gnt_ref = err;
766
767 err = xenbus_alloc_evtchn(pdev->xdev, &pdev->evtchn);
768 if (err)
769 goto out;
770
771 err = bind_evtchn_to_irqhandler(pdev->evtchn, pcifront_handler_aer,
772 0, "pcifront", pdev);
773
774 if (err < 0)
775 return err;
776
777 pdev->irq = err;
778
779do_publish:
780 err = xenbus_transaction_start(&trans);
781 if (err) {
782 xenbus_dev_fatal(pdev->xdev, err,
783 "Error writing configuration for backend "
784 "(start transaction)");
785 goto out;
786 }
787
788 err = xenbus_printf(trans, pdev->xdev->nodename,
789 "pci-op-ref", "%u", pdev->gnt_ref);
790 if (!err)
791 err = xenbus_printf(trans, pdev->xdev->nodename,
792 "event-channel", "%u", pdev->evtchn);
793 if (!err)
794 err = xenbus_printf(trans, pdev->xdev->nodename,
795 "magic", XEN_PCI_MAGIC);
796
797 if (err) {
798 xenbus_transaction_end(trans, 1);
799 xenbus_dev_fatal(pdev->xdev, err,
800 "Error writing configuration for backend");
801 goto out;
802 } else {
803 err = xenbus_transaction_end(trans, 0);
804 if (err == -EAGAIN)
805 goto do_publish;
806 else if (err) {
807 xenbus_dev_fatal(pdev->xdev, err,
808 "Error completing transaction "
809 "for backend");
810 goto out;
811 }
812 }
813
814 xenbus_switch_state(pdev->xdev, XenbusStateInitialised);
815
816 dev_dbg(&pdev->xdev->dev, "publishing successful!\n");
817
818out:
819 return err;
820}
821
822static int __devinit pcifront_try_connect(struct pcifront_device *pdev)
823{
824 int err = -EFAULT;
825 int i, num_roots, len;
826 char str[64];
827 unsigned int domain, bus;
828
829
830 /* Only connect once */
831 if (xenbus_read_driver_state(pdev->xdev->nodename) !=
832 XenbusStateInitialised)
833 goto out;
834
835 err = pcifront_connect(pdev);
836 if (err) {
837 xenbus_dev_fatal(pdev->xdev, err,
838 "Error connecting PCI Frontend");
839 goto out;
840 }
841
842 err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend,
843 "root_num", "%d", &num_roots);
844 if (err == -ENOENT) {
845 xenbus_dev_error(pdev->xdev, err,
846 "No PCI Roots found, trying 0000:00");
847 err = pcifront_scan_root(pdev, 0, 0);
848 num_roots = 0;
849 } else if (err != 1) {
850 if (err == 0)
851 err = -EINVAL;
852 xenbus_dev_fatal(pdev->xdev, err,
853 "Error reading number of PCI roots");
854 goto out;
855 }
856
857 for (i = 0; i < num_roots; i++) {
858 len = snprintf(str, sizeof(str), "root-%d", i);
859 if (unlikely(len >= (sizeof(str) - 1))) {
860 err = -ENOMEM;
861 goto out;
862 }
863
864 err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, str,
865 "%x:%x", &domain, &bus);
866 if (err != 2) {
867 if (err >= 0)
868 err = -EINVAL;
869 xenbus_dev_fatal(pdev->xdev, err,
870 "Error reading PCI root %d", i);
871 goto out;
872 }
873
874 err = pcifront_scan_root(pdev, domain, bus);
875 if (err) {
876 xenbus_dev_fatal(pdev->xdev, err,
877 "Error scanning PCI root %04x:%02x",
878 domain, bus);
879 goto out;
880 }
881 }
882
883 err = xenbus_switch_state(pdev->xdev, XenbusStateConnected);
884
885out:
886 return err;
887}
888
889static int pcifront_try_disconnect(struct pcifront_device *pdev)
890{
891 int err = 0;
892 enum xenbus_state prev_state;
893
894
895 prev_state = xenbus_read_driver_state(pdev->xdev->nodename);
896
897 if (prev_state >= XenbusStateClosing)
898 goto out;
899
900 if (prev_state == XenbusStateConnected) {
901 pcifront_free_roots(pdev);
902 pcifront_disconnect(pdev);
903 }
904
905 err = xenbus_switch_state(pdev->xdev, XenbusStateClosed);
906
907out:
908
909 return err;
910}
911
912static int __devinit pcifront_attach_devices(struct pcifront_device *pdev)
913{
914 int err = -EFAULT;
915 int i, num_roots, len;
916 unsigned int domain, bus;
917 char str[64];
918
919 if (xenbus_read_driver_state(pdev->xdev->nodename) !=
920 XenbusStateReconfiguring)
921 goto out;
922
923 err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend,
924 "root_num", "%d", &num_roots);
925 if (err == -ENOENT) {
926 xenbus_dev_error(pdev->xdev, err,
927 "No PCI Roots found, trying 0000:00");
928 err = pcifront_rescan_root(pdev, 0, 0);
929 num_roots = 0;
930 } else if (err != 1) {
931 if (err == 0)
932 err = -EINVAL;
933 xenbus_dev_fatal(pdev->xdev, err,
934 "Error reading number of PCI roots");
935 goto out;
936 }
937
938 for (i = 0; i < num_roots; i++) {
939 len = snprintf(str, sizeof(str), "root-%d", i);
940 if (unlikely(len >= (sizeof(str) - 1))) {
941 err = -ENOMEM;
942 goto out;
943 }
944
945 err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, str,
946 "%x:%x", &domain, &bus);
947 if (err != 2) {
948 if (err >= 0)
949 err = -EINVAL;
950 xenbus_dev_fatal(pdev->xdev, err,
951 "Error reading PCI root %d", i);
952 goto out;
953 }
954
955 err = pcifront_rescan_root(pdev, domain, bus);
956 if (err) {
957 xenbus_dev_fatal(pdev->xdev, err,
958 "Error scanning PCI root %04x:%02x",
959 domain, bus);
960 goto out;
961 }
962 }
963
964 xenbus_switch_state(pdev->xdev, XenbusStateConnected);
965
966out:
967 return err;
968}
969
970static int pcifront_detach_devices(struct pcifront_device *pdev)
971{
972 int err = 0;
973 int i, num_devs;
974 unsigned int domain, bus, slot, func;
975 struct pci_bus *pci_bus;
976 struct pci_dev *pci_dev;
977 char str[64];
978
979 if (xenbus_read_driver_state(pdev->xdev->nodename) !=
980 XenbusStateConnected)
981 goto out;
982
983 err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, "num_devs", "%d",
984 &num_devs);
985 if (err != 1) {
986 if (err >= 0)
987 err = -EINVAL;
988 xenbus_dev_fatal(pdev->xdev, err,
989 "Error reading number of PCI devices");
990 goto out;
991 }
992
993 /* Find devices being detached and remove them. */
994 for (i = 0; i < num_devs; i++) {
995 int l, state;
996 l = snprintf(str, sizeof(str), "state-%d", i);
997 if (unlikely(l >= (sizeof(str) - 1))) {
998 err = -ENOMEM;
999 goto out;
1000 }
1001 err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, str, "%d",
1002 &state);
1003 if (err != 1)
1004 state = XenbusStateUnknown;
1005
1006 if (state != XenbusStateClosing)
1007 continue;
1008
1009 /* Remove device. */
1010 l = snprintf(str, sizeof(str), "vdev-%d", i);
1011 if (unlikely(l >= (sizeof(str) - 1))) {
1012 err = -ENOMEM;
1013 goto out;
1014 }
1015 err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, str,
1016 "%x:%x:%x.%x", &domain, &bus, &slot, &func);
1017 if (err != 4) {
1018 if (err >= 0)
1019 err = -EINVAL;
1020 xenbus_dev_fatal(pdev->xdev, err,
1021 "Error reading PCI device %d", i);
1022 goto out;
1023 }
1024
1025 pci_bus = pci_find_bus(domain, bus);
1026 if (!pci_bus) {
1027 dev_dbg(&pdev->xdev->dev, "Cannot get bus %04x:%02x\n",
1028 domain, bus);
1029 continue;
1030 }
1031 pci_dev = pci_get_slot(pci_bus, PCI_DEVFN(slot, func));
1032 if (!pci_dev) {
1033 dev_dbg(&pdev->xdev->dev,
1034 "Cannot get PCI device %04x:%02x:%02x.%02x\n",
1035 domain, bus, slot, func);
1036 continue;
1037 }
1038 pci_remove_bus_device(pci_dev);
1039 pci_dev_put(pci_dev);
1040
1041 dev_dbg(&pdev->xdev->dev,
1042 "PCI device %04x:%02x:%02x.%02x removed.\n",
1043 domain, bus, slot, func);
1044 }
1045
1046 err = xenbus_switch_state(pdev->xdev, XenbusStateReconfiguring);
1047
1048out:
1049 return err;
1050}
1051
1052static void __init_refok pcifront_backend_changed(struct xenbus_device *xdev,
1053 enum xenbus_state be_state)
1054{
1055 struct pcifront_device *pdev = dev_get_drvdata(&xdev->dev);
1056
1057 switch (be_state) {
1058 case XenbusStateUnknown:
1059 case XenbusStateInitialising:
1060 case XenbusStateInitWait:
1061 case XenbusStateInitialised:
1062 case XenbusStateClosed:
1063 break;
1064
1065 case XenbusStateConnected:
1066 pcifront_try_connect(pdev);
1067 break;
1068
1069 case XenbusStateClosing:
1070 dev_warn(&xdev->dev, "backend going away!\n");
1071 pcifront_try_disconnect(pdev);
1072 break;
1073
1074 case XenbusStateReconfiguring:
1075 pcifront_detach_devices(pdev);
1076 break;
1077
1078 case XenbusStateReconfigured:
1079 pcifront_attach_devices(pdev);
1080 break;
1081 }
1082}
1083
1084static int pcifront_xenbus_probe(struct xenbus_device *xdev,
1085 const struct xenbus_device_id *id)
1086{
1087 int err = 0;
1088 struct pcifront_device *pdev = alloc_pdev(xdev);
1089
1090 if (pdev == NULL) {
1091 err = -ENOMEM;
1092 xenbus_dev_fatal(xdev, err,
1093 "Error allocating pcifront_device struct");
1094 goto out;
1095 }
1096
1097 err = pcifront_publish_info(pdev);
1098 if (err)
1099 free_pdev(pdev);
1100
1101out:
1102 return err;
1103}
1104
1105static int pcifront_xenbus_remove(struct xenbus_device *xdev)
1106{
1107 struct pcifront_device *pdev = dev_get_drvdata(&xdev->dev);
1108 if (pdev)
1109 free_pdev(pdev);
1110
1111 return 0;
1112}
1113
1114static const struct xenbus_device_id xenpci_ids[] = {
1115 {"pci"},
1116 {""},
1117};
1118
1119static struct xenbus_driver xenbus_pcifront_driver = {
1120 .name = "pcifront",
1121 .owner = THIS_MODULE,
1122 .ids = xenpci_ids,
1123 .probe = pcifront_xenbus_probe,
1124 .remove = pcifront_xenbus_remove,
1125 .otherend_changed = pcifront_backend_changed,
1126};
1127
1128static int __init pcifront_init(void)
1129{
1130 if (!xen_pv_domain() || xen_initial_domain())
1131 return -ENODEV;
1132
1133 pci_frontend_registrar(1 /* enable */);
1134
1135 return xenbus_register_frontend(&xenbus_pcifront_driver);
1136}
1137
1138static void __exit pcifront_cleanup(void)
1139{
1140 xenbus_unregister_driver(&xenbus_pcifront_driver);
1141 pci_frontend_registrar(0 /* disable */);
1142}
1143module_init(pcifront_init);
1144module_exit(pcifront_cleanup);
1145
1146MODULE_DESCRIPTION("Xen PCI passthrough frontend.");
1147MODULE_LICENSE("GPL");
1148MODULE_ALIAS("xen:pci");
diff --git a/include/xen/interface/io/pciif.h b/include/xen/interface/io/pciif.h
new file mode 100644
index 000000000000..d9922ae36eb5
--- /dev/null
+++ b/include/xen/interface/io/pciif.h
@@ -0,0 +1,112 @@
1/*
2 * PCI Backend/Frontend Common Data Structures & Macros
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to
6 * deal in the Software without restriction, including without limitation the
7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 * sell copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 *
22 * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
23 */
24#ifndef __XEN_PCI_COMMON_H__
25#define __XEN_PCI_COMMON_H__
26
27/* Be sure to bump this number if you change this file */
28#define XEN_PCI_MAGIC "7"
29
30/* xen_pci_sharedinfo flags */
31#define _XEN_PCIF_active (0)
32#define XEN_PCIF_active (1<<_XEN_PCIF_active)
33#define _XEN_PCIB_AERHANDLER (1)
34#define XEN_PCIB_AERHANDLER (1<<_XEN_PCIB_AERHANDLER)
35#define _XEN_PCIB_active (2)
36#define XEN_PCIB_active (1<<_XEN_PCIB_active)
37
38/* xen_pci_op commands */
39#define XEN_PCI_OP_conf_read (0)
40#define XEN_PCI_OP_conf_write (1)
41#define XEN_PCI_OP_enable_msi (2)
42#define XEN_PCI_OP_disable_msi (3)
43#define XEN_PCI_OP_enable_msix (4)
44#define XEN_PCI_OP_disable_msix (5)
45#define XEN_PCI_OP_aer_detected (6)
46#define XEN_PCI_OP_aer_resume (7)
47#define XEN_PCI_OP_aer_mmio (8)
48#define XEN_PCI_OP_aer_slotreset (9)
49
50/* xen_pci_op error numbers */
51#define XEN_PCI_ERR_success (0)
52#define XEN_PCI_ERR_dev_not_found (-1)
53#define XEN_PCI_ERR_invalid_offset (-2)
54#define XEN_PCI_ERR_access_denied (-3)
55#define XEN_PCI_ERR_not_implemented (-4)
56/* XEN_PCI_ERR_op_failed - backend failed to complete the operation */
57#define XEN_PCI_ERR_op_failed (-5)
58
59/*
60 * it should be PAGE_SIZE-sizeof(struct xen_pci_op))/sizeof(struct msix_entry))
61 * Should not exceed 128
62 */
63#define SH_INFO_MAX_VEC 128
64
65struct xen_msix_entry {
66 uint16_t vector;
67 uint16_t entry;
68};
69struct xen_pci_op {
70 /* IN: what action to perform: XEN_PCI_OP_* */
71 uint32_t cmd;
72
73 /* OUT: will contain an error number (if any) from errno.h */
74 int32_t err;
75
76 /* IN: which device to touch */
77 uint32_t domain; /* PCI Domain/Segment */
78 uint32_t bus;
79 uint32_t devfn;
80
81 /* IN: which configuration registers to touch */
82 int32_t offset;
83 int32_t size;
84
85 /* IN/OUT: Contains the result after a READ or the value to WRITE */
86 uint32_t value;
87 /* IN: Contains extra infor for this operation */
88 uint32_t info;
89 /*IN: param for msi-x */
90 struct xen_msix_entry msix_entries[SH_INFO_MAX_VEC];
91};
92
93/*used for pcie aer handling*/
94struct xen_pcie_aer_op {
95 /* IN: what action to perform: XEN_PCI_OP_* */
96 uint32_t cmd;
97 /*IN/OUT: return aer_op result or carry error_detected state as input*/
98 int32_t err;
99
100 /* IN: which device to touch */
101 uint32_t domain; /* PCI Domain/Segment*/
102 uint32_t bus;
103 uint32_t devfn;
104};
105struct xen_pci_sharedinfo {
106 /* flags - XEN_PCIF_* */
107 uint32_t flags;
108 struct xen_pci_op op;
109 struct xen_pcie_aer_op aer_op;
110};
111
112#endif /* __XEN_PCI_COMMON_H__ */