aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen/xen-pciback/pci_stub.c
diff options
context:
space:
mode:
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2009-10-13 17:22:20 -0400
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2011-07-19 20:58:01 -0400
commit30edc14bf39afde24ef7db2de66c91805db80828 (patch)
tree1cf5b6f28a3ea4159a09bcef9d11be6d427e3558 /drivers/xen/xen-pciback/pci_stub.c
parent56299378726d5f2ba8d3c8cbbd13cb280ba45e4f (diff)
xen/pciback: xen pci backend driver.
This is the host side counterpart to the frontend driver in drivers/pci/xen-pcifront.c. The PV protocol is also implemented by frontend drivers in other OSes too, such as the BSDs. The PV protocol is rather simple. There is page shared with the guest, which has the 'struct xen_pci_sharedinfo' embossed in it. The backend has a thread that is kicked every-time the structure is changed and based on the operation field it performs specific tasks: XEN_PCI_OP_conf_[read|write]: Read/Write 0xCF8/0xCFC filtered data. (conf_space*.c) Based on which field is probed, we either enable/disable the PCI device, change power state, read VPD, etc. The major goal of this call is to provide a Physical IRQ (PIRQ) to the guest. The PIRQ is Xen hypervisor global IRQ value irrespective of the IRQ is tied in to the IO-APIC, or is a vector. For GSI type interrupts, the PIRQ==GSI holds. For MSI/MSI-X the PIRQ value != Linux IRQ number (thought PIRQ==vector). Please note, that with Xen, all interrupts (except those level shared ones) are injected directly to the guest - there is no host interaction. XEN_PCI_OP_[enable|disable]_msi[|x] (pciback_ops.c) Enables/disables the MSI/MSI-X capability of the device. These operations setup the MSI/MSI-X vectors for the guest and pass them to the frontend. When the device is activated, the interrupts are directly injected in the guest without involving the host. XEN_PCI_OP_aer_[detected|resume|mmio|slotreset]: In case of failure, perform the appropriate AER commands on the guest. Right now that is a cop-out - we just kill the guest. Besides implementing those commands, it can also - hide a PCI device from the host. When booting up, the user can specify xen-pciback.hide=(1:0:0)(BDF..) so that host does not try to use the device. The driver was lifted from linux-2.6.18.hg tree and fixed up so that it could compile under v3.0. Per suggestion from Jesse Barnes moved the driver to drivers/xen/xen-pciback. Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Diffstat (limited to 'drivers/xen/xen-pciback/pci_stub.c')
-rw-r--r--drivers/xen/xen-pciback/pci_stub.c1285
1 files changed, 1285 insertions, 0 deletions
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c
new file mode 100644
index 000000000000..0b5a16b81c8c
--- /dev/null
+++ b/drivers/xen/xen-pciback/pci_stub.c
@@ -0,0 +1,1285 @@
1/*
2 * PCI Stub Driver - Grabs devices in backend to be exported later
3 *
4 * Ryan Wilson <hap9@epoch.ncsc.mil>
5 * Chris Bookholt <hap10@epoch.ncsc.mil>
6 */
7#include <linux/module.h>
8#include <linux/init.h>
9#include <linux/rwsem.h>
10#include <linux/list.h>
11#include <linux/spinlock.h>
12#include <linux/kref.h>
13#include <linux/pci.h>
14#include <linux/wait.h>
15#include <linux/sched.h>
16#include <asm/atomic.h>
17#include <xen/events.h>
18#include <asm/xen/pci.h>
19#include <asm/xen/hypervisor.h>
20#include "pciback.h"
21#include "conf_space.h"
22#include "conf_space_quirks.h"
23
24static char *pci_devs_to_hide;
25wait_queue_head_t aer_wait_queue;
26/*Add sem for sync AER handling and pciback remove/reconfigue ops,
27* We want to avoid in middle of AER ops, pciback devices is being removed
28*/
29static DECLARE_RWSEM(pcistub_sem);
30module_param_named(hide, pci_devs_to_hide, charp, 0444);
31
32struct pcistub_device_id {
33 struct list_head slot_list;
34 int domain;
35 unsigned char bus;
36 unsigned int devfn;
37};
38static LIST_HEAD(pcistub_device_ids);
39static DEFINE_SPINLOCK(device_ids_lock);
40
41struct pcistub_device {
42 struct kref kref;
43 struct list_head dev_list;
44 spinlock_t lock;
45
46 struct pci_dev *dev;
47 struct pciback_device *pdev;/* non-NULL if struct pci_dev is in use */
48};
49
50/* Access to pcistub_devices & seized_devices lists and the initialize_devices
51 * flag must be locked with pcistub_devices_lock
52 */
53static DEFINE_SPINLOCK(pcistub_devices_lock);
54static LIST_HEAD(pcistub_devices);
55
56/* wait for device_initcall before initializing our devices
57 * (see pcistub_init_devices_late)
58 */
59static int initialize_devices;
60static LIST_HEAD(seized_devices);
61
62static struct pcistub_device *pcistub_device_alloc(struct pci_dev *dev)
63{
64 struct pcistub_device *psdev;
65
66 dev_dbg(&dev->dev, "pcistub_device_alloc\n");
67
68 psdev = kzalloc(sizeof(*psdev), GFP_ATOMIC);
69 if (!psdev)
70 return NULL;
71
72 psdev->dev = pci_dev_get(dev);
73 if (!psdev->dev) {
74 kfree(psdev);
75 return NULL;
76 }
77
78 kref_init(&psdev->kref);
79 spin_lock_init(&psdev->lock);
80
81 return psdev;
82}
83
84/* Don't call this directly as it's called by pcistub_device_put */
85static void pcistub_device_release(struct kref *kref)
86{
87 struct pcistub_device *psdev;
88
89 psdev = container_of(kref, struct pcistub_device, kref);
90
91 dev_dbg(&psdev->dev->dev, "pcistub_device_release\n");
92
93 /* Clean-up the device */
94 pciback_reset_device(psdev->dev);
95 pciback_config_free_dyn_fields(psdev->dev);
96 pciback_config_free_dev(psdev->dev);
97 kfree(pci_get_drvdata(psdev->dev));
98 pci_set_drvdata(psdev->dev, NULL);
99
100 pci_dev_put(psdev->dev);
101
102 kfree(psdev);
103}
104
105static inline void pcistub_device_get(struct pcistub_device *psdev)
106{
107 kref_get(&psdev->kref);
108}
109
110static inline void pcistub_device_put(struct pcistub_device *psdev)
111{
112 kref_put(&psdev->kref, pcistub_device_release);
113}
114
115static struct pcistub_device *pcistub_device_find(int domain, int bus,
116 int slot, int func)
117{
118 struct pcistub_device *psdev = NULL;
119 unsigned long flags;
120
121 spin_lock_irqsave(&pcistub_devices_lock, flags);
122
123 list_for_each_entry(psdev, &pcistub_devices, dev_list) {
124 if (psdev->dev != NULL
125 && domain == pci_domain_nr(psdev->dev->bus)
126 && bus == psdev->dev->bus->number
127 && PCI_DEVFN(slot, func) == psdev->dev->devfn) {
128 pcistub_device_get(psdev);
129 goto out;
130 }
131 }
132
133 /* didn't find it */
134 psdev = NULL;
135
136out:
137 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
138 return psdev;
139}
140
141static struct pci_dev *pcistub_device_get_pci_dev(struct pciback_device *pdev,
142 struct pcistub_device *psdev)
143{
144 struct pci_dev *pci_dev = NULL;
145 unsigned long flags;
146
147 pcistub_device_get(psdev);
148
149 spin_lock_irqsave(&psdev->lock, flags);
150 if (!psdev->pdev) {
151 psdev->pdev = pdev;
152 pci_dev = psdev->dev;
153 }
154 spin_unlock_irqrestore(&psdev->lock, flags);
155
156 if (!pci_dev)
157 pcistub_device_put(psdev);
158
159 return pci_dev;
160}
161
162struct pci_dev *pcistub_get_pci_dev_by_slot(struct pciback_device *pdev,
163 int domain, int bus,
164 int slot, int func)
165{
166 struct pcistub_device *psdev;
167 struct pci_dev *found_dev = NULL;
168 unsigned long flags;
169
170 spin_lock_irqsave(&pcistub_devices_lock, flags);
171
172 list_for_each_entry(psdev, &pcistub_devices, dev_list) {
173 if (psdev->dev != NULL
174 && domain == pci_domain_nr(psdev->dev->bus)
175 && bus == psdev->dev->bus->number
176 && PCI_DEVFN(slot, func) == psdev->dev->devfn) {
177 found_dev = pcistub_device_get_pci_dev(pdev, psdev);
178 break;
179 }
180 }
181
182 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
183 return found_dev;
184}
185
186struct pci_dev *pcistub_get_pci_dev(struct pciback_device *pdev,
187 struct pci_dev *dev)
188{
189 struct pcistub_device *psdev;
190 struct pci_dev *found_dev = NULL;
191 unsigned long flags;
192
193 spin_lock_irqsave(&pcistub_devices_lock, flags);
194
195 list_for_each_entry(psdev, &pcistub_devices, dev_list) {
196 if (psdev->dev == dev) {
197 found_dev = pcistub_device_get_pci_dev(pdev, psdev);
198 break;
199 }
200 }
201
202 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
203 return found_dev;
204}
205
206void pcistub_put_pci_dev(struct pci_dev *dev)
207{
208 struct pcistub_device *psdev, *found_psdev = NULL;
209 unsigned long flags;
210
211 spin_lock_irqsave(&pcistub_devices_lock, flags);
212
213 list_for_each_entry(psdev, &pcistub_devices, dev_list) {
214 if (psdev->dev == dev) {
215 found_psdev = psdev;
216 break;
217 }
218 }
219
220 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
221
222 /*hold this lock for avoiding breaking link between
223 * pcistub and pciback when AER is in processing
224 */
225 down_write(&pcistub_sem);
226 /* Cleanup our device
227 * (so it's ready for the next domain)
228 */
229 pciback_reset_device(found_psdev->dev);
230 pciback_config_free_dyn_fields(found_psdev->dev);
231 pciback_config_reset_dev(found_psdev->dev);
232
233 spin_lock_irqsave(&found_psdev->lock, flags);
234 found_psdev->pdev = NULL;
235 spin_unlock_irqrestore(&found_psdev->lock, flags);
236
237 pcistub_device_put(found_psdev);
238 up_write(&pcistub_sem);
239}
240
241static int __devinit pcistub_match_one(struct pci_dev *dev,
242 struct pcistub_device_id *pdev_id)
243{
244 /* Match the specified device by domain, bus, slot, func and also if
245 * any of the device's parent bridges match.
246 */
247 for (; dev != NULL; dev = dev->bus->self) {
248 if (pci_domain_nr(dev->bus) == pdev_id->domain
249 && dev->bus->number == pdev_id->bus
250 && dev->devfn == pdev_id->devfn)
251 return 1;
252
253 /* Sometimes topmost bridge links to itself. */
254 if (dev == dev->bus->self)
255 break;
256 }
257
258 return 0;
259}
260
261static int __devinit pcistub_match(struct pci_dev *dev)
262{
263 struct pcistub_device_id *pdev_id;
264 unsigned long flags;
265 int found = 0;
266
267 spin_lock_irqsave(&device_ids_lock, flags);
268 list_for_each_entry(pdev_id, &pcistub_device_ids, slot_list) {
269 if (pcistub_match_one(dev, pdev_id)) {
270 found = 1;
271 break;
272 }
273 }
274 spin_unlock_irqrestore(&device_ids_lock, flags);
275
276 return found;
277}
278
279static int __devinit pcistub_init_device(struct pci_dev *dev)
280{
281 struct pciback_dev_data *dev_data;
282 int err = 0;
283
284 dev_dbg(&dev->dev, "initializing...\n");
285
286 /* The PCI backend is not intended to be a module (or to work with
287 * removable PCI devices (yet). If it were, pciback_config_free()
288 * would need to be called somewhere to free the memory allocated
289 * here and then to call kfree(pci_get_drvdata(psdev->dev)).
290 */
291 dev_data = kzalloc(sizeof(*dev_data), GFP_ATOMIC);
292 if (!dev_data) {
293 err = -ENOMEM;
294 goto out;
295 }
296 pci_set_drvdata(dev, dev_data);
297
298 dev_dbg(&dev->dev, "initializing config\n");
299
300 init_waitqueue_head(&aer_wait_queue);
301 err = pciback_config_init_dev(dev);
302 if (err)
303 goto out;
304
305 /* HACK: Force device (& ACPI) to determine what IRQ it's on - we
306 * must do this here because pcibios_enable_device may specify
307 * the pci device's true irq (and possibly its other resources)
308 * if they differ from what's in the configuration space.
309 * This makes the assumption that the device's resources won't
310 * change after this point (otherwise this code may break!)
311 */
312 dev_dbg(&dev->dev, "enabling device\n");
313 err = pci_enable_device(dev);
314 if (err)
315 goto config_release;
316
317 /* Now disable the device (this also ensures some private device
318 * data is setup before we export)
319 */
320 dev_dbg(&dev->dev, "reset device\n");
321 pciback_reset_device(dev);
322
323 return 0;
324
325config_release:
326 pciback_config_free_dev(dev);
327
328out:
329 pci_set_drvdata(dev, NULL);
330 kfree(dev_data);
331 return err;
332}
333
334/*
335 * Because some initialization still happens on
336 * devices during fs_initcall, we need to defer
337 * full initialization of our devices until
338 * device_initcall.
339 */
340static int __init pcistub_init_devices_late(void)
341{
342 struct pcistub_device *psdev;
343 unsigned long flags;
344 int err = 0;
345
346 pr_debug("pciback: pcistub_init_devices_late\n");
347
348 spin_lock_irqsave(&pcistub_devices_lock, flags);
349
350 while (!list_empty(&seized_devices)) {
351 psdev = container_of(seized_devices.next,
352 struct pcistub_device, dev_list);
353 list_del(&psdev->dev_list);
354
355 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
356
357 err = pcistub_init_device(psdev->dev);
358 if (err) {
359 dev_err(&psdev->dev->dev,
360 "error %d initializing device\n", err);
361 kfree(psdev);
362 psdev = NULL;
363 }
364
365 spin_lock_irqsave(&pcistub_devices_lock, flags);
366
367 if (psdev)
368 list_add_tail(&psdev->dev_list, &pcistub_devices);
369 }
370
371 initialize_devices = 1;
372
373 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
374
375 return 0;
376}
377
378static int __devinit pcistub_seize(struct pci_dev *dev)
379{
380 struct pcistub_device *psdev;
381 unsigned long flags;
382 int err = 0;
383
384 psdev = pcistub_device_alloc(dev);
385 if (!psdev)
386 return -ENOMEM;
387
388 spin_lock_irqsave(&pcistub_devices_lock, flags);
389
390 if (initialize_devices) {
391 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
392
393 /* don't want irqs disabled when calling pcistub_init_device */
394 err = pcistub_init_device(psdev->dev);
395
396 spin_lock_irqsave(&pcistub_devices_lock, flags);
397
398 if (!err)
399 list_add(&psdev->dev_list, &pcistub_devices);
400 } else {
401 dev_dbg(&dev->dev, "deferring initialization\n");
402 list_add(&psdev->dev_list, &seized_devices);
403 }
404
405 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
406
407 if (err)
408 pcistub_device_put(psdev);
409
410 return err;
411}
412
413static int __devinit pcistub_probe(struct pci_dev *dev,
414 const struct pci_device_id *id)
415{
416 int err = 0;
417
418 dev_dbg(&dev->dev, "probing...\n");
419
420 if (pcistub_match(dev)) {
421
422 if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL
423 && dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
424 dev_err(&dev->dev, "can't export pci devices that "
425 "don't have a normal (0) or bridge (1) "
426 "header type!\n");
427 err = -ENODEV;
428 goto out;
429 }
430
431 dev_info(&dev->dev, "seizing device\n");
432 err = pcistub_seize(dev);
433 } else
434 /* Didn't find the device */
435 err = -ENODEV;
436
437out:
438 return err;
439}
440
441static void pcistub_remove(struct pci_dev *dev)
442{
443 struct pcistub_device *psdev, *found_psdev = NULL;
444 unsigned long flags;
445
446 dev_dbg(&dev->dev, "removing\n");
447
448 spin_lock_irqsave(&pcistub_devices_lock, flags);
449
450 pciback_config_quirk_release(dev);
451
452 list_for_each_entry(psdev, &pcistub_devices, dev_list) {
453 if (psdev->dev == dev) {
454 found_psdev = psdev;
455 break;
456 }
457 }
458
459 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
460
461 if (found_psdev) {
462 dev_dbg(&dev->dev, "found device to remove - in use? %p\n",
463 found_psdev->pdev);
464
465 if (found_psdev->pdev) {
466 printk(KERN_WARNING "pciback: ****** removing device "
467 "%s while still in-use! ******\n",
468 pci_name(found_psdev->dev));
469 printk(KERN_WARNING "pciback: ****** driver domain may "
470 "still access this device's i/o resources!\n");
471 printk(KERN_WARNING "pciback: ****** shutdown driver "
472 "domain before binding device\n");
473 printk(KERN_WARNING "pciback: ****** to other drivers "
474 "or domains\n");
475
476 pciback_release_pci_dev(found_psdev->pdev,
477 found_psdev->dev);
478 }
479
480 spin_lock_irqsave(&pcistub_devices_lock, flags);
481 list_del(&found_psdev->dev_list);
482 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
483
484 /* the final put for releasing from the list */
485 pcistub_device_put(found_psdev);
486 }
487}
488
489static const struct pci_device_id pcistub_ids[] = {
490 {
491 .vendor = PCI_ANY_ID,
492 .device = PCI_ANY_ID,
493 .subvendor = PCI_ANY_ID,
494 .subdevice = PCI_ANY_ID,
495 },
496 {0,},
497};
498
499#define PCI_NODENAME_MAX 40
500static void kill_domain_by_device(struct pcistub_device *psdev)
501{
502 struct xenbus_transaction xbt;
503 int err;
504 char nodename[PCI_NODENAME_MAX];
505
506 if (!psdev)
507 dev_err(&psdev->dev->dev,
508 "device is NULL when do AER recovery/kill_domain\n");
509 snprintf(nodename, PCI_NODENAME_MAX, "/local/domain/0/backend/pci/%d/0",
510 psdev->pdev->xdev->otherend_id);
511 nodename[strlen(nodename)] = '\0';
512
513again:
514 err = xenbus_transaction_start(&xbt);
515 if (err) {
516 dev_err(&psdev->dev->dev,
517 "error %d when start xenbus transaction\n", err);
518 return;
519 }
520 /*PV AER handlers will set this flag*/
521 xenbus_printf(xbt, nodename, "aerState" , "aerfail");
522 err = xenbus_transaction_end(xbt, 0);
523 if (err) {
524 if (err == -EAGAIN)
525 goto again;
526 dev_err(&psdev->dev->dev,
527 "error %d when end xenbus transaction\n", err);
528 return;
529 }
530}
531
532/* For each aer recovery step error_detected, mmio_enabled, etc, front_end and
533 * backend need to have cooperation. In pciback, those steps will do similar
534 * jobs: send service request and waiting for front_end response.
535*/
536static pci_ers_result_t common_process(struct pcistub_device *psdev,
537 pci_channel_state_t state, int aer_cmd, pci_ers_result_t result)
538{
539 pci_ers_result_t res = result;
540 struct xen_pcie_aer_op *aer_op;
541 int ret;
542
543 /*with PV AER drivers*/
544 aer_op = &(psdev->pdev->sh_info->aer_op);
545 aer_op->cmd = aer_cmd ;
546 /*useful for error_detected callback*/
547 aer_op->err = state;
548 /*pcifront_end BDF*/
549 ret = pciback_get_pcifront_dev(psdev->dev, psdev->pdev,
550 &aer_op->domain, &aer_op->bus, &aer_op->devfn);
551 if (!ret) {
552 dev_err(&psdev->dev->dev,
553 "pciback: failed to get pcifront device\n");
554 return PCI_ERS_RESULT_NONE;
555 }
556 wmb();
557
558 dev_dbg(&psdev->dev->dev,
559 "pciback: aer_op %x dom %x bus %x devfn %x\n",
560 aer_cmd, aer_op->domain, aer_op->bus, aer_op->devfn);
561 /*local flag to mark there's aer request, pciback callback will use this
562 * flag to judge whether we need to check pci-front give aer service
563 * ack signal
564 */
565 set_bit(_PCIB_op_pending, (unsigned long *)&psdev->pdev->flags);
566
567 /*It is possible that a pcifront conf_read_write ops request invokes
568 * the callback which cause the spurious execution of wake_up.
569 * Yet it is harmless and better than a spinlock here
570 */
571 set_bit(_XEN_PCIB_active,
572 (unsigned long *)&psdev->pdev->sh_info->flags);
573 wmb();
574 notify_remote_via_irq(psdev->pdev->evtchn_irq);
575
576 ret = wait_event_timeout(aer_wait_queue, !(test_bit(_XEN_PCIB_active,
577 (unsigned long *)&psdev->pdev->sh_info->flags)), 300*HZ);
578
579 if (!ret) {
580 if (test_bit(_XEN_PCIB_active,
581 (unsigned long *)&psdev->pdev->sh_info->flags)) {
582 dev_err(&psdev->dev->dev,
583 "pcifront aer process not responding!\n");
584 clear_bit(_XEN_PCIB_active,
585 (unsigned long *)&psdev->pdev->sh_info->flags);
586 aer_op->err = PCI_ERS_RESULT_NONE;
587 return res;
588 }
589 }
590 clear_bit(_PCIB_op_pending, (unsigned long *)&psdev->pdev->flags);
591
592 if (test_bit(_XEN_PCIF_active,
593 (unsigned long *)&psdev->pdev->sh_info->flags)) {
594 dev_dbg(&psdev->dev->dev,
595 "schedule pci_conf service in pciback \n");
596 test_and_schedule_op(psdev->pdev);
597 }
598
599 res = (pci_ers_result_t)aer_op->err;
600 return res;
601}
602
603/*
604* pciback_slot_reset: it will send the slot_reset request to pcifront in case
605* of the device driver could provide this service, and then wait for pcifront
606* ack.
607* @dev: pointer to PCI devices
608* return value is used by aer_core do_recovery policy
609*/
610static pci_ers_result_t pciback_slot_reset(struct pci_dev *dev)
611{
612 struct pcistub_device *psdev;
613 pci_ers_result_t result;
614
615 result = PCI_ERS_RESULT_RECOVERED;
616 dev_dbg(&dev->dev, "pciback_slot_reset(bus:%x,devfn:%x)\n",
617 dev->bus->number, dev->devfn);
618
619 down_write(&pcistub_sem);
620 psdev = pcistub_device_find(pci_domain_nr(dev->bus),
621 dev->bus->number,
622 PCI_SLOT(dev->devfn),
623 PCI_FUNC(dev->devfn));
624
625 if (!psdev || !psdev->pdev) {
626 dev_err(&dev->dev,
627 "pciback device is not found/assigned\n");
628 goto end;
629 }
630
631 if (!psdev->pdev->sh_info) {
632 dev_err(&dev->dev, "pciback device is not connected or owned"
633 " by HVM, kill it\n");
634 kill_domain_by_device(psdev);
635 goto release;
636 }
637
638 if (!test_bit(_XEN_PCIB_AERHANDLER,
639 (unsigned long *)&psdev->pdev->sh_info->flags)) {
640 dev_err(&dev->dev,
641 "guest with no AER driver should have been killed\n");
642 goto release;
643 }
644 result = common_process(psdev, 1, XEN_PCI_OP_aer_slotreset, result);
645
646 if (result == PCI_ERS_RESULT_NONE ||
647 result == PCI_ERS_RESULT_DISCONNECT) {
648 dev_dbg(&dev->dev,
649 "No AER slot_reset service or disconnected!\n");
650 kill_domain_by_device(psdev);
651 }
652release:
653 pcistub_device_put(psdev);
654end:
655 up_write(&pcistub_sem);
656 return result;
657
658}
659
660
661/*pciback_mmio_enabled: it will send the mmio_enabled request to pcifront
662* in case of the device driver could provide this service, and then wait
663* for pcifront ack
664* @dev: pointer to PCI devices
665* return value is used by aer_core do_recovery policy
666*/
667
668static pci_ers_result_t pciback_mmio_enabled(struct pci_dev *dev)
669{
670 struct pcistub_device *psdev;
671 pci_ers_result_t result;
672
673 result = PCI_ERS_RESULT_RECOVERED;
674 dev_dbg(&dev->dev, "pciback_mmio_enabled(bus:%x,devfn:%x)\n",
675 dev->bus->number, dev->devfn);
676
677 down_write(&pcistub_sem);
678 psdev = pcistub_device_find(pci_domain_nr(dev->bus),
679 dev->bus->number,
680 PCI_SLOT(dev->devfn),
681 PCI_FUNC(dev->devfn));
682
683 if (!psdev || !psdev->pdev) {
684 dev_err(&dev->dev,
685 "pciback device is not found/assigned\n");
686 goto end;
687 }
688
689 if (!psdev->pdev->sh_info) {
690 dev_err(&dev->dev, "pciback device is not connected or owned"
691 " by HVM, kill it\n");
692 kill_domain_by_device(psdev);
693 goto release;
694 }
695
696 if (!test_bit(_XEN_PCIB_AERHANDLER,
697 (unsigned long *)&psdev->pdev->sh_info->flags)) {
698 dev_err(&dev->dev,
699 "guest with no AER driver should have been killed\n");
700 goto release;
701 }
702 result = common_process(psdev, 1, XEN_PCI_OP_aer_mmio, result);
703
704 if (result == PCI_ERS_RESULT_NONE ||
705 result == PCI_ERS_RESULT_DISCONNECT) {
706 dev_dbg(&dev->dev,
707 "No AER mmio_enabled service or disconnected!\n");
708 kill_domain_by_device(psdev);
709 }
710release:
711 pcistub_device_put(psdev);
712end:
713 up_write(&pcistub_sem);
714 return result;
715}
716
717/*pciback_error_detected: it will send the error_detected request to pcifront
718* in case of the device driver could provide this service, and then wait
719* for pcifront ack.
720* @dev: pointer to PCI devices
721* @error: the current PCI connection state
722* return value is used by aer_core do_recovery policy
723*/
724
725static pci_ers_result_t pciback_error_detected(struct pci_dev *dev,
726 pci_channel_state_t error)
727{
728 struct pcistub_device *psdev;
729 pci_ers_result_t result;
730
731 result = PCI_ERS_RESULT_CAN_RECOVER;
732 dev_dbg(&dev->dev, "pciback_error_detected(bus:%x,devfn:%x)\n",
733 dev->bus->number, dev->devfn);
734
735 down_write(&pcistub_sem);
736 psdev = pcistub_device_find(pci_domain_nr(dev->bus),
737 dev->bus->number,
738 PCI_SLOT(dev->devfn),
739 PCI_FUNC(dev->devfn));
740
741 if (!psdev || !psdev->pdev) {
742 dev_err(&dev->dev,
743 "pciback device is not found/assigned\n");
744 goto end;
745 }
746
747 if (!psdev->pdev->sh_info) {
748 dev_err(&dev->dev, "pciback device is not connected or owned"
749 " by HVM, kill it\n");
750 kill_domain_by_device(psdev);
751 goto release;
752 }
753
754 /*Guest owns the device yet no aer handler regiested, kill guest*/
755 if (!test_bit(_XEN_PCIB_AERHANDLER,
756 (unsigned long *)&psdev->pdev->sh_info->flags)) {
757 dev_dbg(&dev->dev, "guest may have no aer driver, kill it\n");
758 kill_domain_by_device(psdev);
759 goto release;
760 }
761 result = common_process(psdev, error, XEN_PCI_OP_aer_detected, result);
762
763 if (result == PCI_ERS_RESULT_NONE ||
764 result == PCI_ERS_RESULT_DISCONNECT) {
765 dev_dbg(&dev->dev,
766 "No AER error_detected service or disconnected!\n");
767 kill_domain_by_device(psdev);
768 }
769release:
770 pcistub_device_put(psdev);
771end:
772 up_write(&pcistub_sem);
773 return result;
774}
775
776/*pciback_error_resume: it will send the error_resume request to pcifront
777* in case of the device driver could provide this service, and then wait
778* for pcifront ack.
779* @dev: pointer to PCI devices
780*/
781
782static void pciback_error_resume(struct pci_dev *dev)
783{
784 struct pcistub_device *psdev;
785
786 dev_dbg(&dev->dev, "pciback_error_resume(bus:%x,devfn:%x)\n",
787 dev->bus->number, dev->devfn);
788
789 down_write(&pcistub_sem);
790 psdev = pcistub_device_find(pci_domain_nr(dev->bus),
791 dev->bus->number,
792 PCI_SLOT(dev->devfn),
793 PCI_FUNC(dev->devfn));
794
795 if (!psdev || !psdev->pdev) {
796 dev_err(&dev->dev,
797 "pciback device is not found/assigned\n");
798 goto end;
799 }
800
801 if (!psdev->pdev->sh_info) {
802 dev_err(&dev->dev, "pciback device is not connected or owned"
803 " by HVM, kill it\n");
804 kill_domain_by_device(psdev);
805 goto release;
806 }
807
808 if (!test_bit(_XEN_PCIB_AERHANDLER,
809 (unsigned long *)&psdev->pdev->sh_info->flags)) {
810 dev_err(&dev->dev,
811 "guest with no AER driver should have been killed\n");
812 kill_domain_by_device(psdev);
813 goto release;
814 }
815 common_process(psdev, 1, XEN_PCI_OP_aer_resume,
816 PCI_ERS_RESULT_RECOVERED);
817release:
818 pcistub_device_put(psdev);
819end:
820 up_write(&pcistub_sem);
821 return;
822}
823
824/*add pciback AER handling*/
825static struct pci_error_handlers pciback_error_handler = {
826 .error_detected = pciback_error_detected,
827 .mmio_enabled = pciback_mmio_enabled,
828 .slot_reset = pciback_slot_reset,
829 .resume = pciback_error_resume,
830};
831
832/*
833 * Note: There is no MODULE_DEVICE_TABLE entry here because this isn't
834 * for a normal device. I don't want it to be loaded automatically.
835 */
836
837static struct pci_driver pciback_pci_driver = {
838 .name = "pciback",
839 .id_table = pcistub_ids,
840 .probe = pcistub_probe,
841 .remove = pcistub_remove,
842 .err_handler = &pciback_error_handler,
843};
844
845static inline int str_to_slot(const char *buf, int *domain, int *bus,
846 int *slot, int *func)
847{
848 int err;
849
850 err = sscanf(buf, " %x:%x:%x.%x", domain, bus, slot, func);
851 if (err == 4)
852 return 0;
853 else if (err < 0)
854 return -EINVAL;
855
856 /* try again without domain */
857 *domain = 0;
858 err = sscanf(buf, " %x:%x.%x", bus, slot, func);
859 if (err == 3)
860 return 0;
861
862 return -EINVAL;
863}
864
865static inline int str_to_quirk(const char *buf, int *domain, int *bus, int
866 *slot, int *func, int *reg, int *size, int *mask)
867{
868 int err;
869
870 err =
871 sscanf(buf, " %04x:%02x:%02x.%1x-%08x:%1x:%08x", domain, bus, slot,
872 func, reg, size, mask);
873 if (err == 7)
874 return 0;
875 return -EINVAL;
876}
877
878static int pcistub_device_id_add(int domain, int bus, int slot, int func)
879{
880 struct pcistub_device_id *pci_dev_id;
881 unsigned long flags;
882
883 pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_KERNEL);
884 if (!pci_dev_id)
885 return -ENOMEM;
886
887 pci_dev_id->domain = domain;
888 pci_dev_id->bus = bus;
889 pci_dev_id->devfn = PCI_DEVFN(slot, func);
890
891 pr_debug("pciback: wants to seize %04x:%02x:%02x.%01x\n",
892 domain, bus, slot, func);
893
894 spin_lock_irqsave(&device_ids_lock, flags);
895 list_add_tail(&pci_dev_id->slot_list, &pcistub_device_ids);
896 spin_unlock_irqrestore(&device_ids_lock, flags);
897
898 return 0;
899}
900
901static int pcistub_device_id_remove(int domain, int bus, int slot, int func)
902{
903 struct pcistub_device_id *pci_dev_id, *t;
904 int devfn = PCI_DEVFN(slot, func);
905 int err = -ENOENT;
906 unsigned long flags;
907
908 spin_lock_irqsave(&device_ids_lock, flags);
909 list_for_each_entry_safe(pci_dev_id, t, &pcistub_device_ids,
910 slot_list) {
911 if (pci_dev_id->domain == domain
912 && pci_dev_id->bus == bus && pci_dev_id->devfn == devfn) {
913 /* Don't break; here because it's possible the same
914 * slot could be in the list more than once
915 */
916 list_del(&pci_dev_id->slot_list);
917 kfree(pci_dev_id);
918
919 err = 0;
920
921 pr_debug("pciback: removed %04x:%02x:%02x.%01x from "
922 "seize list\n", domain, bus, slot, func);
923 }
924 }
925 spin_unlock_irqrestore(&device_ids_lock, flags);
926
927 return err;
928}
929
930static int pcistub_reg_add(int domain, int bus, int slot, int func, int reg,
931 int size, int mask)
932{
933 int err = 0;
934 struct pcistub_device *psdev;
935 struct pci_dev *dev;
936 struct config_field *field;
937
938 psdev = pcistub_device_find(domain, bus, slot, func);
939 if (!psdev || !psdev->dev) {
940 err = -ENODEV;
941 goto out;
942 }
943 dev = psdev->dev;
944
945 field = kzalloc(sizeof(*field), GFP_ATOMIC);
946 if (!field) {
947 err = -ENOMEM;
948 goto out;
949 }
950
951 field->offset = reg;
952 field->size = size;
953 field->mask = mask;
954 field->init = NULL;
955 field->reset = NULL;
956 field->release = NULL;
957 field->clean = pciback_config_field_free;
958
959 err = pciback_config_quirks_add_field(dev, field);
960 if (err)
961 kfree(field);
962out:
963 return err;
964}
965
966static ssize_t pcistub_slot_add(struct device_driver *drv, const char *buf,
967 size_t count)
968{
969 int domain, bus, slot, func;
970 int err;
971
972 err = str_to_slot(buf, &domain, &bus, &slot, &func);
973 if (err)
974 goto out;
975
976 err = pcistub_device_id_add(domain, bus, slot, func);
977
978out:
979 if (!err)
980 err = count;
981 return err;
982}
983
984DRIVER_ATTR(new_slot, S_IWUSR, NULL, pcistub_slot_add);
985
986static ssize_t pcistub_slot_remove(struct device_driver *drv, const char *buf,
987 size_t count)
988{
989 int domain, bus, slot, func;
990 int err;
991
992 err = str_to_slot(buf, &domain, &bus, &slot, &func);
993 if (err)
994 goto out;
995
996 err = pcistub_device_id_remove(domain, bus, slot, func);
997
998out:
999 if (!err)
1000 err = count;
1001 return err;
1002}
1003
1004DRIVER_ATTR(remove_slot, S_IWUSR, NULL, pcistub_slot_remove);
1005
1006static ssize_t pcistub_slot_show(struct device_driver *drv, char *buf)
1007{
1008 struct pcistub_device_id *pci_dev_id;
1009 size_t count = 0;
1010 unsigned long flags;
1011
1012 spin_lock_irqsave(&device_ids_lock, flags);
1013 list_for_each_entry(pci_dev_id, &pcistub_device_ids, slot_list) {
1014 if (count >= PAGE_SIZE)
1015 break;
1016
1017 count += scnprintf(buf + count, PAGE_SIZE - count,
1018 "%04x:%02x:%02x.%01x\n",
1019 pci_dev_id->domain, pci_dev_id->bus,
1020 PCI_SLOT(pci_dev_id->devfn),
1021 PCI_FUNC(pci_dev_id->devfn));
1022 }
1023 spin_unlock_irqrestore(&device_ids_lock, flags);
1024
1025 return count;
1026}
1027
1028DRIVER_ATTR(slots, S_IRUSR, pcistub_slot_show, NULL);
1029
1030static ssize_t pcistub_quirk_add(struct device_driver *drv, const char *buf,
1031 size_t count)
1032{
1033 int domain, bus, slot, func, reg, size, mask;
1034 int err;
1035
1036 err = str_to_quirk(buf, &domain, &bus, &slot, &func, &reg, &size,
1037 &mask);
1038 if (err)
1039 goto out;
1040
1041 err = pcistub_reg_add(domain, bus, slot, func, reg, size, mask);
1042
1043out:
1044 if (!err)
1045 err = count;
1046 return err;
1047}
1048
1049static ssize_t pcistub_quirk_show(struct device_driver *drv, char *buf)
1050{
1051 int count = 0;
1052 unsigned long flags;
1053 struct pciback_config_quirk *quirk;
1054 struct pciback_dev_data *dev_data;
1055 const struct config_field *field;
1056 const struct config_field_entry *cfg_entry;
1057
1058 spin_lock_irqsave(&device_ids_lock, flags);
1059 list_for_each_entry(quirk, &pciback_quirks, quirks_list) {
1060 if (count >= PAGE_SIZE)
1061 goto out;
1062
1063 count += scnprintf(buf + count, PAGE_SIZE - count,
1064 "%02x:%02x.%01x\n\t%04x:%04x:%04x:%04x\n",
1065 quirk->pdev->bus->number,
1066 PCI_SLOT(quirk->pdev->devfn),
1067 PCI_FUNC(quirk->pdev->devfn),
1068 quirk->devid.vendor, quirk->devid.device,
1069 quirk->devid.subvendor,
1070 quirk->devid.subdevice);
1071
1072 dev_data = pci_get_drvdata(quirk->pdev);
1073
1074 list_for_each_entry(cfg_entry, &dev_data->config_fields, list) {
1075 field = cfg_entry->field;
1076 if (count >= PAGE_SIZE)
1077 goto out;
1078
1079 count += scnprintf(buf + count, PAGE_SIZE - count,
1080 "\t\t%08x:%01x:%08x\n",
1081 cfg_entry->base_offset +
1082 field->offset, field->size,
1083 field->mask);
1084 }
1085 }
1086
1087out:
1088 spin_unlock_irqrestore(&device_ids_lock, flags);
1089
1090 return count;
1091}
1092
1093DRIVER_ATTR(quirks, S_IRUSR | S_IWUSR, pcistub_quirk_show, pcistub_quirk_add);
1094
1095static ssize_t permissive_add(struct device_driver *drv, const char *buf,
1096 size_t count)
1097{
1098 int domain, bus, slot, func;
1099 int err;
1100 struct pcistub_device *psdev;
1101 struct pciback_dev_data *dev_data;
1102 err = str_to_slot(buf, &domain, &bus, &slot, &func);
1103 if (err)
1104 goto out;
1105 psdev = pcistub_device_find(domain, bus, slot, func);
1106 if (!psdev) {
1107 err = -ENODEV;
1108 goto out;
1109 }
1110 if (!psdev->dev) {
1111 err = -ENODEV;
1112 goto release;
1113 }
1114 dev_data = pci_get_drvdata(psdev->dev);
1115 /* the driver data for a device should never be null at this point */
1116 if (!dev_data) {
1117 err = -ENXIO;
1118 goto release;
1119 }
1120 if (!dev_data->permissive) {
1121 dev_data->permissive = 1;
1122 /* Let user know that what they're doing could be unsafe */
1123 dev_warn(&psdev->dev->dev, "enabling permissive mode "
1124 "configuration space accesses!\n");
1125 dev_warn(&psdev->dev->dev,
1126 "permissive mode is potentially unsafe!\n");
1127 }
1128release:
1129 pcistub_device_put(psdev);
1130out:
1131 if (!err)
1132 err = count;
1133 return err;
1134}
1135
1136static ssize_t permissive_show(struct device_driver *drv, char *buf)
1137{
1138 struct pcistub_device *psdev;
1139 struct pciback_dev_data *dev_data;
1140 size_t count = 0;
1141 unsigned long flags;
1142 spin_lock_irqsave(&pcistub_devices_lock, flags);
1143 list_for_each_entry(psdev, &pcistub_devices, dev_list) {
1144 if (count >= PAGE_SIZE)
1145 break;
1146 if (!psdev->dev)
1147 continue;
1148 dev_data = pci_get_drvdata(psdev->dev);
1149 if (!dev_data || !dev_data->permissive)
1150 continue;
1151 count +=
1152 scnprintf(buf + count, PAGE_SIZE - count, "%s\n",
1153 pci_name(psdev->dev));
1154 }
1155 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
1156 return count;
1157}
1158
1159DRIVER_ATTR(permissive, S_IRUSR | S_IWUSR, permissive_show, permissive_add);
1160
1161static void pcistub_exit(void)
1162{
1163 driver_remove_file(&pciback_pci_driver.driver, &driver_attr_new_slot);
1164 driver_remove_file(&pciback_pci_driver.driver,
1165 &driver_attr_remove_slot);
1166 driver_remove_file(&pciback_pci_driver.driver, &driver_attr_slots);
1167 driver_remove_file(&pciback_pci_driver.driver, &driver_attr_quirks);
1168 driver_remove_file(&pciback_pci_driver.driver, &driver_attr_permissive);
1169
1170 pci_unregister_driver(&pciback_pci_driver);
1171}
1172
1173static int __init pcistub_init(void)
1174{
1175 int pos = 0;
1176 int err = 0;
1177 int domain, bus, slot, func;
1178 int parsed;
1179
1180 if (pci_devs_to_hide && *pci_devs_to_hide) {
1181 do {
1182 parsed = 0;
1183
1184 err = sscanf(pci_devs_to_hide + pos,
1185 " (%x:%x:%x.%x) %n",
1186 &domain, &bus, &slot, &func, &parsed);
1187 if (err != 4) {
1188 domain = 0;
1189 err = sscanf(pci_devs_to_hide + pos,
1190 " (%x:%x.%x) %n",
1191 &bus, &slot, &func, &parsed);
1192 if (err != 3)
1193 goto parse_error;
1194 }
1195
1196 err = pcistub_device_id_add(domain, bus, slot, func);
1197 if (err)
1198 goto out;
1199
1200 /* if parsed<=0, we've reached the end of the string */
1201 pos += parsed;
1202 } while (parsed > 0 && pci_devs_to_hide[pos]);
1203 }
1204
1205 /* If we're the first PCI Device Driver to register, we're the
1206 * first one to get offered PCI devices as they become
1207 * available (and thus we can be the first to grab them)
1208 */
1209 err = pci_register_driver(&pciback_pci_driver);
1210 if (err < 0)
1211 goto out;
1212
1213 err = driver_create_file(&pciback_pci_driver.driver,
1214 &driver_attr_new_slot);
1215 if (!err)
1216 err = driver_create_file(&pciback_pci_driver.driver,
1217 &driver_attr_remove_slot);
1218 if (!err)
1219 err = driver_create_file(&pciback_pci_driver.driver,
1220 &driver_attr_slots);
1221 if (!err)
1222 err = driver_create_file(&pciback_pci_driver.driver,
1223 &driver_attr_quirks);
1224 if (!err)
1225 err = driver_create_file(&pciback_pci_driver.driver,
1226 &driver_attr_permissive);
1227
1228 if (err)
1229 pcistub_exit();
1230
1231out:
1232 return err;
1233
1234parse_error:
1235 printk(KERN_ERR "pciback: Error parsing pci_devs_to_hide at \"%s\"\n",
1236 pci_devs_to_hide + pos);
1237 return -EINVAL;
1238}
1239
1240#ifndef MODULE
1241/*
1242 * fs_initcall happens before device_initcall
1243 * so pciback *should* get called first (b/c we
1244 * want to suck up any device before other drivers
1245 * get a chance by being the first pci device
1246 * driver to register)
1247 */
1248fs_initcall(pcistub_init);
1249#endif
1250
1251static int __init pciback_init(void)
1252{
1253 int err;
1254
1255 if (!xen_initial_domain())
1256 return -ENODEV;
1257
1258 err = pciback_config_init();
1259 if (err)
1260 return err;
1261
1262#ifdef MODULE
1263 err = pcistub_init();
1264 if (err < 0)
1265 return err;
1266#endif
1267
1268 pcistub_init_devices_late();
1269 err = pciback_xenbus_register();
1270 if (err)
1271 pcistub_exit();
1272
1273 return err;
1274}
1275
1276static void __exit pciback_cleanup(void)
1277{
1278 pciback_xenbus_unregister();
1279 pcistub_exit();
1280}
1281
1282module_init(pciback_init);
1283module_exit(pciback_cleanup);
1284
1285MODULE_LICENSE("Dual BSD/GPL");