Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes
[pandora-kernel.git] / drivers / pci / pcie / aer / aer_inject.c
1 /*
2  * PCIe AER software error injection support.
3  *
4  * Debuging PCIe AER code is quite difficult because it is hard to
5  * trigger various real hardware errors. Software based error
6  * injection can fake almost all kinds of errors with the help of a
7  * user space helper tool aer-inject, which can be gotten from:
8  *   http://www.kernel.org/pub/linux/utils/pci/aer-inject/
9  *
10  * Copyright 2009 Intel Corporation.
11  *     Huang Ying <ying.huang@intel.com>
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; version 2
16  * of the License.
17  *
18  */
19
20 #include <linux/module.h>
21 #include <linux/init.h>
22 #include <linux/miscdevice.h>
23 #include <linux/pci.h>
24 #include <linux/slab.h>
25 #include <linux/fs.h>
26 #include <linux/uaccess.h>
27 #include <linux/stddef.h>
28 #include "aerdrv.h"
29
30 struct aer_error_inj {
31         u8 bus;
32         u8 dev;
33         u8 fn;
34         u32 uncor_status;
35         u32 cor_status;
36         u32 header_log0;
37         u32 header_log1;
38         u32 header_log2;
39         u32 header_log3;
40         u16 domain;
41 };
42
43 struct aer_error {
44         struct list_head list;
45         u16 domain;
46         unsigned int bus;
47         unsigned int devfn;
48         int pos_cap_err;
49
50         u32 uncor_status;
51         u32 cor_status;
52         u32 header_log0;
53         u32 header_log1;
54         u32 header_log2;
55         u32 header_log3;
56         u32 root_status;
57         u32 source_id;
58 };
59
60 struct pci_bus_ops {
61         struct list_head list;
62         struct pci_bus *bus;
63         struct pci_ops *ops;
64 };
65
66 static LIST_HEAD(einjected);
67
68 static LIST_HEAD(pci_bus_ops_list);
69
70 /* Protect einjected and pci_bus_ops_list */
71 static DEFINE_SPINLOCK(inject_lock);
72
73 static void aer_error_init(struct aer_error *err, u16 domain,
74                            unsigned int bus, unsigned int devfn,
75                            int pos_cap_err)
76 {
77         INIT_LIST_HEAD(&err->list);
78         err->domain = domain;
79         err->bus = bus;
80         err->devfn = devfn;
81         err->pos_cap_err = pos_cap_err;
82 }
83
84 /* inject_lock must be held before calling */
85 static struct aer_error *__find_aer_error(u16 domain, unsigned int bus,
86                                           unsigned int devfn)
87 {
88         struct aer_error *err;
89
90         list_for_each_entry(err, &einjected, list) {
91                 if (domain == err->domain &&
92                     bus == err->bus &&
93                     devfn == err->devfn)
94                         return err;
95         }
96         return NULL;
97 }
98
99 /* inject_lock must be held before calling */
100 static struct aer_error *__find_aer_error_by_dev(struct pci_dev *dev)
101 {
102         int domain = pci_domain_nr(dev->bus);
103         if (domain < 0)
104                 return NULL;
105         return __find_aer_error((u16)domain, dev->bus->number, dev->devfn);
106 }
107
108 /* inject_lock must be held before calling */
109 static struct pci_ops *__find_pci_bus_ops(struct pci_bus *bus)
110 {
111         struct pci_bus_ops *bus_ops;
112
113         list_for_each_entry(bus_ops, &pci_bus_ops_list, list) {
114                 if (bus_ops->bus == bus)
115                         return bus_ops->ops;
116         }
117         return NULL;
118 }
119
120 static struct pci_bus_ops *pci_bus_ops_pop(void)
121 {
122         unsigned long flags;
123         struct pci_bus_ops *bus_ops = NULL;
124
125         spin_lock_irqsave(&inject_lock, flags);
126         if (list_empty(&pci_bus_ops_list))
127                 bus_ops = NULL;
128         else {
129                 struct list_head *lh = pci_bus_ops_list.next;
130                 list_del(lh);
131                 bus_ops = list_entry(lh, struct pci_bus_ops, list);
132         }
133         spin_unlock_irqrestore(&inject_lock, flags);
134         return bus_ops;
135 }
136
137 static u32 *find_pci_config_dword(struct aer_error *err, int where,
138                                   int *prw1cs)
139 {
140         int rw1cs = 0;
141         u32 *target = NULL;
142
143         if (err->pos_cap_err == -1)
144                 return NULL;
145
146         switch (where - err->pos_cap_err) {
147         case PCI_ERR_UNCOR_STATUS:
148                 target = &err->uncor_status;
149                 rw1cs = 1;
150                 break;
151         case PCI_ERR_COR_STATUS:
152                 target = &err->cor_status;
153                 rw1cs = 1;
154                 break;
155         case PCI_ERR_HEADER_LOG:
156                 target = &err->header_log0;
157                 break;
158         case PCI_ERR_HEADER_LOG+4:
159                 target = &err->header_log1;
160                 break;
161         case PCI_ERR_HEADER_LOG+8:
162                 target = &err->header_log2;
163                 break;
164         case PCI_ERR_HEADER_LOG+12:
165                 target = &err->header_log3;
166                 break;
167         case PCI_ERR_ROOT_STATUS:
168                 target = &err->root_status;
169                 rw1cs = 1;
170                 break;
171         case PCI_ERR_ROOT_ERR_SRC:
172                 target = &err->source_id;
173                 break;
174         }
175         if (prw1cs)
176                 *prw1cs = rw1cs;
177         return target;
178 }
179
180 static int pci_read_aer(struct pci_bus *bus, unsigned int devfn, int where,
181                         int size, u32 *val)
182 {
183         u32 *sim;
184         struct aer_error *err;
185         unsigned long flags;
186         struct pci_ops *ops;
187         int domain;
188
189         spin_lock_irqsave(&inject_lock, flags);
190         if (size != sizeof(u32))
191                 goto out;
192         domain = pci_domain_nr(bus);
193         if (domain < 0)
194                 goto out;
195         err = __find_aer_error((u16)domain, bus->number, devfn);
196         if (!err)
197                 goto out;
198
199         sim = find_pci_config_dword(err, where, NULL);
200         if (sim) {
201                 *val = *sim;
202                 spin_unlock_irqrestore(&inject_lock, flags);
203                 return 0;
204         }
205 out:
206         ops = __find_pci_bus_ops(bus);
207         spin_unlock_irqrestore(&inject_lock, flags);
208         return ops->read(bus, devfn, where, size, val);
209 }
210
211 int pci_write_aer(struct pci_bus *bus, unsigned int devfn, int where, int size,
212                   u32 val)
213 {
214         u32 *sim;
215         struct aer_error *err;
216         unsigned long flags;
217         int rw1cs;
218         struct pci_ops *ops;
219         int domain;
220
221         spin_lock_irqsave(&inject_lock, flags);
222         if (size != sizeof(u32))
223                 goto out;
224         domain = pci_domain_nr(bus);
225         if (domain < 0)
226                 goto out;
227         err = __find_aer_error((u16)domain, bus->number, devfn);
228         if (!err)
229                 goto out;
230
231         sim = find_pci_config_dword(err, where, &rw1cs);
232         if (sim) {
233                 if (rw1cs)
234                         *sim ^= val;
235                 else
236                         *sim = val;
237                 spin_unlock_irqrestore(&inject_lock, flags);
238                 return 0;
239         }
240 out:
241         ops = __find_pci_bus_ops(bus);
242         spin_unlock_irqrestore(&inject_lock, flags);
243         return ops->write(bus, devfn, where, size, val);
244 }
245
246 static struct pci_ops pci_ops_aer = {
247         .read = pci_read_aer,
248         .write = pci_write_aer,
249 };
250
251 static void pci_bus_ops_init(struct pci_bus_ops *bus_ops,
252                              struct pci_bus *bus,
253                              struct pci_ops *ops)
254 {
255         INIT_LIST_HEAD(&bus_ops->list);
256         bus_ops->bus = bus;
257         bus_ops->ops = ops;
258 }
259
260 static int pci_bus_set_aer_ops(struct pci_bus *bus)
261 {
262         struct pci_ops *ops;
263         struct pci_bus_ops *bus_ops;
264         unsigned long flags;
265
266         bus_ops = kmalloc(sizeof(*bus_ops), GFP_KERNEL);
267         if (!bus_ops)
268                 return -ENOMEM;
269         ops = pci_bus_set_ops(bus, &pci_ops_aer);
270         spin_lock_irqsave(&inject_lock, flags);
271         if (ops == &pci_ops_aer)
272                 goto out;
273         pci_bus_ops_init(bus_ops, bus, ops);
274         list_add(&bus_ops->list, &pci_bus_ops_list);
275         bus_ops = NULL;
276 out:
277         spin_unlock_irqrestore(&inject_lock, flags);
278         kfree(bus_ops);
279         return 0;
280 }
281
282 static struct pci_dev *pcie_find_root_port(struct pci_dev *dev)
283 {
284         while (1) {
285                 if (!pci_is_pcie(dev))
286                         break;
287                 if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
288                         return dev;
289                 if (!dev->bus->self)
290                         break;
291                 dev = dev->bus->self;
292         }
293         return NULL;
294 }
295
296 static int find_aer_device_iter(struct device *device, void *data)
297 {
298         struct pcie_device **result = data;
299         struct pcie_device *pcie_dev;
300
301         if (device->bus == &pcie_port_bus_type) {
302                 pcie_dev = to_pcie_device(device);
303                 if (pcie_dev->service & PCIE_PORT_SERVICE_AER) {
304                         *result = pcie_dev;
305                         return 1;
306                 }
307         }
308         return 0;
309 }
310
311 static int find_aer_device(struct pci_dev *dev, struct pcie_device **result)
312 {
313         return device_for_each_child(&dev->dev, result, find_aer_device_iter);
314 }
315
316 static int aer_inject(struct aer_error_inj *einj)
317 {
318         struct aer_error *err, *rperr;
319         struct aer_error *err_alloc = NULL, *rperr_alloc = NULL;
320         struct pci_dev *dev, *rpdev;
321         struct pcie_device *edev;
322         unsigned long flags;
323         unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn);
324         int pos_cap_err, rp_pos_cap_err;
325         u32 sever, cor_mask, uncor_mask;
326         int ret = 0;
327
328         dev = pci_get_domain_bus_and_slot((int)einj->domain, einj->bus, devfn);
329         if (!dev)
330                 return -ENODEV;
331         rpdev = pcie_find_root_port(dev);
332         if (!rpdev) {
333                 ret = -ENOTTY;
334                 goto out_put;
335         }
336
337         pos_cap_err = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
338         if (!pos_cap_err) {
339                 ret = -ENOTTY;
340                 goto out_put;
341         }
342         pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever);
343         pci_read_config_dword(dev, pos_cap_err + PCI_ERR_COR_MASK, &cor_mask);
344         pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_MASK,
345                               &uncor_mask);
346
347         rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR);
348         if (!rp_pos_cap_err) {
349                 ret = -ENOTTY;
350                 goto out_put;
351         }
352
353         err_alloc =  kzalloc(sizeof(struct aer_error), GFP_KERNEL);
354         if (!err_alloc) {
355                 ret = -ENOMEM;
356                 goto out_put;
357         }
358         rperr_alloc =  kzalloc(sizeof(struct aer_error), GFP_KERNEL);
359         if (!rperr_alloc) {
360                 ret = -ENOMEM;
361                 goto out_put;
362         }
363
364         spin_lock_irqsave(&inject_lock, flags);
365
366         err = __find_aer_error_by_dev(dev);
367         if (!err) {
368                 err = err_alloc;
369                 err_alloc = NULL;
370                 aer_error_init(err, einj->domain, einj->bus, devfn,
371                                pos_cap_err);
372                 list_add(&err->list, &einjected);
373         }
374         err->uncor_status |= einj->uncor_status;
375         err->cor_status |= einj->cor_status;
376         err->header_log0 = einj->header_log0;
377         err->header_log1 = einj->header_log1;
378         err->header_log2 = einj->header_log2;
379         err->header_log3 = einj->header_log3;
380
381         if (einj->cor_status && !(einj->cor_status & ~cor_mask)) {
382                 ret = -EINVAL;
383                 printk(KERN_WARNING "The correctable error(s) is masked "
384                                 "by device\n");
385                 spin_unlock_irqrestore(&inject_lock, flags);
386                 goto out_put;
387         }
388         if (einj->uncor_status && !(einj->uncor_status & ~uncor_mask)) {
389                 ret = -EINVAL;
390                 printk(KERN_WARNING "The uncorrectable error(s) is masked "
391                                 "by device\n");
392                 spin_unlock_irqrestore(&inject_lock, flags);
393                 goto out_put;
394         }
395
396         rperr = __find_aer_error_by_dev(rpdev);
397         if (!rperr) {
398                 rperr = rperr_alloc;
399                 rperr_alloc = NULL;
400                 aer_error_init(rperr, pci_domain_nr(rpdev->bus),
401                                rpdev->bus->number, rpdev->devfn,
402                                rp_pos_cap_err);
403                 list_add(&rperr->list, &einjected);
404         }
405         if (einj->cor_status) {
406                 if (rperr->root_status & PCI_ERR_ROOT_COR_RCV)
407                         rperr->root_status |= PCI_ERR_ROOT_MULTI_COR_RCV;
408                 else
409                         rperr->root_status |= PCI_ERR_ROOT_COR_RCV;
410                 rperr->source_id &= 0xffff0000;
411                 rperr->source_id |= (einj->bus << 8) | devfn;
412         }
413         if (einj->uncor_status) {
414                 if (rperr->root_status & PCI_ERR_ROOT_UNCOR_RCV)
415                         rperr->root_status |= PCI_ERR_ROOT_MULTI_UNCOR_RCV;
416                 if (sever & einj->uncor_status) {
417                         rperr->root_status |= PCI_ERR_ROOT_FATAL_RCV;
418                         if (!(rperr->root_status & PCI_ERR_ROOT_UNCOR_RCV))
419                                 rperr->root_status |= PCI_ERR_ROOT_FIRST_FATAL;
420                 } else
421                         rperr->root_status |= PCI_ERR_ROOT_NONFATAL_RCV;
422                 rperr->root_status |= PCI_ERR_ROOT_UNCOR_RCV;
423                 rperr->source_id &= 0x0000ffff;
424                 rperr->source_id |= ((einj->bus << 8) | devfn) << 16;
425         }
426         spin_unlock_irqrestore(&inject_lock, flags);
427
428         ret = pci_bus_set_aer_ops(dev->bus);
429         if (ret)
430                 goto out_put;
431         ret = pci_bus_set_aer_ops(rpdev->bus);
432         if (ret)
433                 goto out_put;
434
435         if (find_aer_device(rpdev, &edev)) {
436                 if (!get_service_data(edev)) {
437                         printk(KERN_WARNING "AER service is not initialized\n");
438                         ret = -EINVAL;
439                         goto out_put;
440                 }
441                 aer_irq(-1, edev);
442         }
443         else
444                 ret = -EINVAL;
445 out_put:
446         kfree(err_alloc);
447         kfree(rperr_alloc);
448         pci_dev_put(dev);
449         return ret;
450 }
451
452 static ssize_t aer_inject_write(struct file *filp, const char __user *ubuf,
453                                 size_t usize, loff_t *off)
454 {
455         struct aer_error_inj einj;
456         int ret;
457
458         if (!capable(CAP_SYS_ADMIN))
459                 return -EPERM;
460         if (usize < offsetof(struct aer_error_inj, domain) ||
461             usize > sizeof(einj))
462                 return -EINVAL;
463
464         memset(&einj, 0, sizeof(einj));
465         if (copy_from_user(&einj, ubuf, usize))
466                 return -EFAULT;
467
468         ret = aer_inject(&einj);
469         return ret ? ret : usize;
470 }
471
472 static const struct file_operations aer_inject_fops = {
473         .write = aer_inject_write,
474         .owner = THIS_MODULE,
475 };
476
477 static struct miscdevice aer_inject_device = {
478         .minor = MISC_DYNAMIC_MINOR,
479         .name = "aer_inject",
480         .fops = &aer_inject_fops,
481 };
482
483 static int __init aer_inject_init(void)
484 {
485         return misc_register(&aer_inject_device);
486 }
487
488 static void __exit aer_inject_exit(void)
489 {
490         struct aer_error *err, *err_next;
491         unsigned long flags;
492         struct pci_bus_ops *bus_ops;
493
494         misc_deregister(&aer_inject_device);
495
496         while ((bus_ops = pci_bus_ops_pop())) {
497                 pci_bus_set_ops(bus_ops->bus, bus_ops->ops);
498                 kfree(bus_ops);
499         }
500
501         spin_lock_irqsave(&inject_lock, flags);
502         list_for_each_entry_safe(err, err_next, &einjected, list) {
503                 list_del(&err->list);
504                 kfree(err);
505         }
506         spin_unlock_irqrestore(&inject_lock, flags);
507 }
508
509 module_init(aer_inject_init);
510 module_exit(aer_inject_exit);
511
512 MODULE_DESCRIPTION("PCIe AER software error injector");
513 MODULE_LICENSE("GPL");