hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/pci/pcie/aer_inject.c
....@@ -2,18 +2,21 @@
22 /*
33 * PCIe AER software error injection support.
44 *
5
- * Debuging PCIe AER code is quite difficult because it is hard to
5
+ * Debugging PCIe AER code is quite difficult because it is hard to
66 * trigger various real hardware errors. Software based error
77 * injection can fake almost all kinds of errors with the help of a
88 * user space helper tool aer-inject, which can be gotten from:
9
- * http://www.kernel.org/pub/linux/utils/pci/aer-inject/
9
+ * https://www.kernel.org/pub/linux/utils/pci/aer-inject/
1010 *
1111 * Copyright 2009 Intel Corporation.
1212 * Huang Ying <ying.huang@intel.com>
1313 */
1414
15
+#define dev_fmt(fmt) "aer_inject: " fmt
16
+
1517 #include <linux/module.h>
1618 #include <linux/init.h>
19
+#include <linux/interrupt.h>
1720 #include <linux/miscdevice.h>
1821 #include <linux/pci.h>
1922 #include <linux/slab.h>
....@@ -175,14 +178,48 @@
175178 return target;
176179 }
177180
181
+static int aer_inj_read(struct pci_bus *bus, unsigned int devfn, int where,
182
+ int size, u32 *val)
183
+{
184
+ struct pci_ops *ops, *my_ops;
185
+ int rv;
186
+
187
+ ops = __find_pci_bus_ops(bus);
188
+ if (!ops)
189
+ return -1;
190
+
191
+ my_ops = bus->ops;
192
+ bus->ops = ops;
193
+ rv = ops->read(bus, devfn, where, size, val);
194
+ bus->ops = my_ops;
195
+
196
+ return rv;
197
+}
198
+
199
+static int aer_inj_write(struct pci_bus *bus, unsigned int devfn, int where,
200
+ int size, u32 val)
201
+{
202
+ struct pci_ops *ops, *my_ops;
203
+ int rv;
204
+
205
+ ops = __find_pci_bus_ops(bus);
206
+ if (!ops)
207
+ return -1;
208
+
209
+ my_ops = bus->ops;
210
+ bus->ops = ops;
211
+ rv = ops->write(bus, devfn, where, size, val);
212
+ bus->ops = my_ops;
213
+
214
+ return rv;
215
+}
216
+
178217 static int aer_inj_read_config(struct pci_bus *bus, unsigned int devfn,
179218 int where, int size, u32 *val)
180219 {
181220 u32 *sim;
182221 struct aer_error *err;
183222 unsigned long flags;
184
- struct pci_ops *ops;
185
- struct pci_ops *my_ops;
186223 int domain;
187224 int rv;
188225
....@@ -203,18 +240,7 @@
203240 return 0;
204241 }
205242 out:
206
- ops = __find_pci_bus_ops(bus);
207
- /*
208
- * pci_lock must already be held, so we can directly
209
- * manipulate bus->ops. Many config access functions,
210
- * including pci_generic_config_read() require the original
211
- * bus->ops be installed to function, so temporarily put them
212
- * back.
213
- */
214
- my_ops = bus->ops;
215
- bus->ops = ops;
216
- rv = ops->read(bus, devfn, where, size, val);
217
- bus->ops = my_ops;
243
+ rv = aer_inj_read(bus, devfn, where, size, val);
218244 spin_unlock_irqrestore(&inject_lock, flags);
219245 return rv;
220246 }
....@@ -226,8 +252,6 @@
226252 struct aer_error *err;
227253 unsigned long flags;
228254 int rw1cs;
229
- struct pci_ops *ops;
230
- struct pci_ops *my_ops;
231255 int domain;
232256 int rv;
233257
....@@ -251,18 +275,7 @@
251275 return 0;
252276 }
253277 out:
254
- ops = __find_pci_bus_ops(bus);
255
- /*
256
- * pci_lock must already be held, so we can directly
257
- * manipulate bus->ops. Many config access functions,
258
- * including pci_generic_config_write() require the original
259
- * bus->ops be installed to function, so temporarily put them
260
- * back.
261
- */
262
- my_ops = bus->ops;
263
- bus->ops = ops;
264
- rv = ops->write(bus, devfn, where, size, val);
265
- bus->ops = my_ops;
278
+ rv = aer_inj_write(bus, devfn, where, size, val);
266279 spin_unlock_irqrestore(&inject_lock, flags);
267280 return rv;
268281 }
....@@ -303,32 +316,13 @@
303316 return 0;
304317 }
305318
306
-static int find_aer_device_iter(struct device *device, void *data)
307
-{
308
- struct pcie_device **result = data;
309
- struct pcie_device *pcie_dev;
310
-
311
- if (device->bus == &pcie_port_bus_type) {
312
- pcie_dev = to_pcie_device(device);
313
- if (pcie_dev->service & PCIE_PORT_SERVICE_AER) {
314
- *result = pcie_dev;
315
- return 1;
316
- }
317
- }
318
- return 0;
319
-}
320
-
321
-static int find_aer_device(struct pci_dev *dev, struct pcie_device **result)
322
-{
323
- return device_for_each_child(&dev->dev, result, find_aer_device_iter);
324
-}
325
-
326319 static int aer_inject(struct aer_error_inj *einj)
327320 {
328321 struct aer_error *err, *rperr;
329322 struct aer_error *err_alloc = NULL, *rperr_alloc = NULL;
330323 struct pci_dev *dev, *rpdev;
331324 struct pcie_device *edev;
325
+ struct device *device;
332326 unsigned long flags;
333327 unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn);
334328 int pos_cap_err, rp_pos_cap_err;
....@@ -340,14 +334,14 @@
340334 return -ENODEV;
341335 rpdev = pcie_find_root_port(dev);
342336 if (!rpdev) {
343
- pci_err(dev, "aer_inject: Root port not found\n");
337
+ pci_err(dev, "Root port not found\n");
344338 ret = -ENODEV;
345339 goto out_put;
346340 }
347341
348342 pos_cap_err = dev->aer_cap;
349343 if (!pos_cap_err) {
350
- pci_err(dev, "aer_inject: Device doesn't support AER\n");
344
+ pci_err(dev, "Device doesn't support AER\n");
351345 ret = -EPROTONOSUPPORT;
352346 goto out_put;
353347 }
....@@ -358,7 +352,7 @@
358352
359353 rp_pos_cap_err = rpdev->aer_cap;
360354 if (!rp_pos_cap_err) {
361
- pci_err(rpdev, "aer_inject: Root port doesn't support AER\n");
355
+ pci_err(rpdev, "Root port doesn't support AER\n");
362356 ret = -EPROTONOSUPPORT;
363357 goto out_put;
364358 }
....@@ -406,14 +400,14 @@
406400 if (!aer_mask_override && einj->cor_status &&
407401 !(einj->cor_status & ~cor_mask)) {
408402 ret = -EINVAL;
409
- pci_warn(dev, "aer_inject: The correctable error(s) is masked by device\n");
403
+ pci_warn(dev, "The correctable error(s) is masked by device\n");
410404 spin_unlock_irqrestore(&inject_lock, flags);
411405 goto out_put;
412406 }
413407 if (!aer_mask_override && einj->uncor_status &&
414408 !(einj->uncor_status & ~uncor_mask)) {
415409 ret = -EINVAL;
416
- pci_warn(dev, "aer_inject: The uncorrectable error(s) is masked by device\n");
410
+ pci_warn(dev, "The uncorrectable error(s) is masked by device\n");
417411 spin_unlock_irqrestore(&inject_lock, flags);
418412 goto out_put;
419413 }
....@@ -464,19 +458,19 @@
464458 if (ret)
465459 goto out_put;
466460
467
- if (find_aer_device(rpdev, &edev)) {
461
+ device = pcie_port_find_device(rpdev, PCIE_PORT_SERVICE_AER);
462
+ if (device) {
463
+ edev = to_pcie_device(device);
468464 if (!get_service_data(edev)) {
469
- dev_warn(&edev->device,
470
- "aer_inject: AER service is not initialized\n");
465
+ pci_warn(edev->port, "AER service is not initialized\n");
471466 ret = -EPROTONOSUPPORT;
472467 goto out_put;
473468 }
474
- dev_info(&edev->device,
475
- "aer_inject: Injecting errors %08x/%08x into device %s\n",
469
+ pci_info(edev->port, "Injecting errors %08x/%08x into device %s\n",
476470 einj->cor_status, einj->uncor_status, pci_name(dev));
477
- aer_irq(-1, edev);
471
+ ret = irq_inject_interrupt(edev->irq);
478472 } else {
479
- pci_err(rpdev, "aer_inject: AER device not found\n");
473
+ pci_err(rpdev, "AER device not found\n");
480474 ret = -ENODEV;
481475 }
482476 out_put: