~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/s390/pci/pci_event.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  *  Copyright IBM Corp. 2012
  4  *
  5  *  Author(s):
  6  *    Jan Glauber <jang@linux.vnet.ibm.com>
  7  */
  8 
  9 #define KMSG_COMPONENT "zpci"
 10 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 11 
 12 #include <linux/kernel.h>
 13 #include <linux/pci.h>
 14 #include <asm/pci_debug.h>
 15 #include <asm/pci_dma.h>
 16 #include <asm/sclp.h>
 17 
 18 #include "pci_bus.h"
 19 
 20 /* Content Code Description for PCI Function Error */
 21 struct zpci_ccdf_err {
 22         u32 reserved1;
 23         u32 fh;                         /* function handle */
 24         u32 fid;                        /* function id */
 25         u32 ett         :  4;           /* expected table type */
 26         u32 mvn         : 12;           /* MSI vector number */
 27         u32 dmaas       :  8;           /* DMA address space */
 28         u32             :  6;
 29         u32 q           :  1;           /* event qualifier */
 30         u32 rw          :  1;           /* read/write */
 31         u64 faddr;                      /* failing address */
 32         u32 reserved3;
 33         u16 reserved4;
 34         u16 pec;                        /* PCI event code */
 35 } __packed;
 36 
 37 /* Content Code Description for PCI Function Availability */
 38 struct zpci_ccdf_avail {
 39         u32 reserved1;
 40         u32 fh;                         /* function handle */
 41         u32 fid;                        /* function id */
 42         u32 reserved2;
 43         u32 reserved3;
 44         u32 reserved4;
 45         u32 reserved5;
 46         u16 reserved6;
 47         u16 pec;                        /* PCI event code */
 48 } __packed;
 49 
 50 static inline bool ers_result_indicates_abort(pci_ers_result_t ers_res)
 51 {
 52         switch (ers_res) {
 53         case PCI_ERS_RESULT_CAN_RECOVER:
 54         case PCI_ERS_RESULT_RECOVERED:
 55         case PCI_ERS_RESULT_NEED_RESET:
 56                 return false;
 57         default:
 58                 return true;
 59         }
 60 }
 61 
 62 static bool is_passed_through(struct pci_dev *pdev)
 63 {
 64         struct zpci_dev *zdev = to_zpci(pdev);
 65         bool ret;
 66 
 67         mutex_lock(&zdev->kzdev_lock);
 68         ret = !!zdev->kzdev;
 69         mutex_unlock(&zdev->kzdev_lock);
 70 
 71         return ret;
 72 }
 73 
 74 static bool is_driver_supported(struct pci_driver *driver)
 75 {
 76         if (!driver || !driver->err_handler)
 77                 return false;
 78         if (!driver->err_handler->error_detected)
 79                 return false;
 80         if (!driver->err_handler->slot_reset)
 81                 return false;
 82         if (!driver->err_handler->resume)
 83                 return false;
 84         return true;
 85 }
 86 
 87 static pci_ers_result_t zpci_event_notify_error_detected(struct pci_dev *pdev,
 88                                                          struct pci_driver *driver)
 89 {
 90         pci_ers_result_t ers_res = PCI_ERS_RESULT_DISCONNECT;
 91 
 92         ers_res = driver->err_handler->error_detected(pdev,  pdev->error_state);
 93         if (ers_result_indicates_abort(ers_res))
 94                 pr_info("%s: Automatic recovery failed after initial reporting\n", pci_name(pdev));
 95         else if (ers_res == PCI_ERS_RESULT_NEED_RESET)
 96                 pr_debug("%s: Driver needs reset to recover\n", pci_name(pdev));
 97 
 98         return ers_res;
 99 }
100 
101 static pci_ers_result_t zpci_event_do_error_state_clear(struct pci_dev *pdev,
102                                                         struct pci_driver *driver)
103 {
104         pci_ers_result_t ers_res = PCI_ERS_RESULT_DISCONNECT;
105         struct zpci_dev *zdev = to_zpci(pdev);
106         int rc;
107 
108         pr_info("%s: Unblocking device access for examination\n", pci_name(pdev));
109         rc = zpci_reset_load_store_blocked(zdev);
110         if (rc) {
111                 pr_err("%s: Unblocking device access failed\n", pci_name(pdev));
112                 /* Let's try a full reset instead */
113                 return PCI_ERS_RESULT_NEED_RESET;
114         }
115 
116         if (driver->err_handler->mmio_enabled) {
117                 ers_res = driver->err_handler->mmio_enabled(pdev);
118                 if (ers_result_indicates_abort(ers_res)) {
119                         pr_info("%s: Automatic recovery failed after MMIO re-enable\n",
120                                 pci_name(pdev));
121                         return ers_res;
122                 } else if (ers_res == PCI_ERS_RESULT_NEED_RESET) {
123                         pr_debug("%s: Driver needs reset to recover\n", pci_name(pdev));
124                         return ers_res;
125                 }
126         }
127 
128         pr_debug("%s: Unblocking DMA\n", pci_name(pdev));
129         rc = zpci_clear_error_state(zdev);
130         if (!rc) {
131                 pdev->error_state = pci_channel_io_normal;
132         } else {
133                 pr_err("%s: Unblocking DMA failed\n", pci_name(pdev));
134                 /* Let's try a full reset instead */
135                 return PCI_ERS_RESULT_NEED_RESET;
136         }
137 
138         return ers_res;
139 }
140 
141 static pci_ers_result_t zpci_event_do_reset(struct pci_dev *pdev,
142                                             struct pci_driver *driver)
143 {
144         pci_ers_result_t ers_res = PCI_ERS_RESULT_DISCONNECT;
145 
146         pr_info("%s: Initiating reset\n", pci_name(pdev));
147         if (zpci_hot_reset_device(to_zpci(pdev))) {
148                 pr_err("%s: The reset request failed\n", pci_name(pdev));
149                 return ers_res;
150         }
151         pdev->error_state = pci_channel_io_normal;
152         ers_res = driver->err_handler->slot_reset(pdev);
153         if (ers_result_indicates_abort(ers_res)) {
154                 pr_info("%s: Automatic recovery failed after slot reset\n", pci_name(pdev));
155                 return ers_res;
156         }
157 
158         return ers_res;
159 }
160 
161 /* zpci_event_attempt_error_recovery - Try to recover the given PCI function
162  * @pdev: PCI function to recover currently in the error state
163  *
164  * We follow the scheme outlined in Documentation/PCI/pci-error-recovery.rst.
165  * With the simplification that recovery always happens per function
166  * and the platform determines which functions are affected for
167  * multi-function devices.
168  */
169 static pci_ers_result_t zpci_event_attempt_error_recovery(struct pci_dev *pdev)
170 {
171         pci_ers_result_t ers_res = PCI_ERS_RESULT_DISCONNECT;
172         struct pci_driver *driver;
173 
174         /*
175          * Ensure that the PCI function is not removed concurrently, no driver
176          * is unbound or probed and that userspace can't access its
177          * configuration space while we perform recovery.
178          */
179         pci_dev_lock(pdev);
180         if (pdev->error_state == pci_channel_io_perm_failure) {
181                 ers_res = PCI_ERS_RESULT_DISCONNECT;
182                 goto out_unlock;
183         }
184         pdev->error_state = pci_channel_io_frozen;
185 
186         if (is_passed_through(pdev)) {
187                 pr_info("%s: Cannot be recovered in the host because it is a pass-through device\n",
188                         pci_name(pdev));
189                 goto out_unlock;
190         }
191 
192         driver = to_pci_driver(pdev->dev.driver);
193         if (!is_driver_supported(driver)) {
194                 if (!driver)
195                         pr_info("%s: Cannot be recovered because no driver is bound to the device\n",
196                                 pci_name(pdev));
197                 else
198                         pr_info("%s: The %s driver bound to the device does not support error recovery\n",
199                                 pci_name(pdev),
200                                 driver->name);
201                 goto out_unlock;
202         }
203 
204         ers_res = zpci_event_notify_error_detected(pdev, driver);
205         if (ers_result_indicates_abort(ers_res))
206                 goto out_unlock;
207 
208         if (ers_res == PCI_ERS_RESULT_CAN_RECOVER) {
209                 ers_res = zpci_event_do_error_state_clear(pdev, driver);
210                 if (ers_result_indicates_abort(ers_res))
211                         goto out_unlock;
212         }
213 
214         if (ers_res == PCI_ERS_RESULT_NEED_RESET)
215                 ers_res = zpci_event_do_reset(pdev, driver);
216 
217         if (ers_res != PCI_ERS_RESULT_RECOVERED) {
218                 pr_err("%s: Automatic recovery failed; operator intervention is required\n",
219                        pci_name(pdev));
220                 goto out_unlock;
221         }
222 
223         pr_info("%s: The device is ready to resume operations\n", pci_name(pdev));
224         if (driver->err_handler->resume)
225                 driver->err_handler->resume(pdev);
226 out_unlock:
227         pci_dev_unlock(pdev);
228 
229         return ers_res;
230 }
231 
232 /* zpci_event_io_failure - Report PCI channel failure state to driver
233  * @pdev: PCI function for which to report
234  * @es: PCI channel failure state to report
235  */
236 static void zpci_event_io_failure(struct pci_dev *pdev, pci_channel_state_t es)
237 {
238         struct pci_driver *driver;
239 
240         pci_dev_lock(pdev);
241         pdev->error_state = es;
242         /**
243          * While vfio-pci's error_detected callback notifies user-space QEMU
244          * reacts to this by freezing the guest. In an s390 environment PCI
245          * errors are rarely fatal so this is overkill. Instead in the future
246          * we will inject the error event and let the guest recover the device
247          * itself.
248          */
249         if (is_passed_through(pdev))
250                 goto out;
251         driver = to_pci_driver(pdev->dev.driver);
252         if (driver && driver->err_handler && driver->err_handler->error_detected)
253                 driver->err_handler->error_detected(pdev, pdev->error_state);
254 out:
255         pci_dev_unlock(pdev);
256 }
257 
258 static void __zpci_event_error(struct zpci_ccdf_err *ccdf)
259 {
260         struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
261         struct pci_dev *pdev = NULL;
262         pci_ers_result_t ers_res;
263 
264         zpci_dbg(3, "err fid:%x, fh:%x, pec:%x\n",
265                  ccdf->fid, ccdf->fh, ccdf->pec);
266         zpci_err("error CCDF:\n");
267         zpci_err_hex(ccdf, sizeof(*ccdf));
268 
269         if (zdev) {
270                 mutex_lock(&zdev->state_lock);
271                 zpci_update_fh(zdev, ccdf->fh);
272                 if (zdev->zbus->bus)
273                         pdev = pci_get_slot(zdev->zbus->bus, zdev->devfn);
274         }
275 
276         pr_err("%s: Event 0x%x reports an error for PCI function 0x%x\n",
277                pdev ? pci_name(pdev) : "n/a", ccdf->pec, ccdf->fid);
278 
279         if (!pdev)
280                 goto no_pdev;
281 
282         switch (ccdf->pec) {
283         case 0x003a: /* Service Action or Error Recovery Successful */
284                 ers_res = zpci_event_attempt_error_recovery(pdev);
285                 if (ers_res != PCI_ERS_RESULT_RECOVERED)
286                         zpci_event_io_failure(pdev, pci_channel_io_perm_failure);
287                 break;
288         default:
289                 /*
290                  * Mark as frozen not permanently failed because the device
291                  * could be subsequently recovered by the platform.
292                  */
293                 zpci_event_io_failure(pdev, pci_channel_io_frozen);
294                 break;
295         }
296         pci_dev_put(pdev);
297 no_pdev:
298         if (zdev)
299                 mutex_unlock(&zdev->state_lock);
300         zpci_zdev_put(zdev);
301 }
302 
303 void zpci_event_error(void *data)
304 {
305         if (zpci_is_enabled())
306                 __zpci_event_error(data);
307 }
308 
309 static void zpci_event_hard_deconfigured(struct zpci_dev *zdev, u32 fh)
310 {
311         zpci_update_fh(zdev, fh);
312         /* Give the driver a hint that the function is
313          * already unusable.
314          */
315         zpci_bus_remove_device(zdev, true);
316         /* Even though the device is already gone we still
317          * need to free zPCI resources as part of the disable.
318          */
319         if (zdev_enabled(zdev))
320                 zpci_disable_device(zdev);
321         zdev->state = ZPCI_FN_STATE_STANDBY;
322 }
323 
324 static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
325 {
326         struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
327         bool existing_zdev = !!zdev;
328         enum zpci_state state;
329 
330         zpci_dbg(3, "avl fid:%x, fh:%x, pec:%x\n",
331                  ccdf->fid, ccdf->fh, ccdf->pec);
332 
333         if (existing_zdev)
334                 mutex_lock(&zdev->state_lock);
335 
336         switch (ccdf->pec) {
337         case 0x0301: /* Reserved|Standby -> Configured */
338                 if (!zdev) {
339                         zdev = zpci_create_device(ccdf->fid, ccdf->fh, ZPCI_FN_STATE_CONFIGURED);
340                         if (IS_ERR(zdev))
341                                 break;
342                 } else {
343                         /* the configuration request may be stale */
344                         if (zdev->state != ZPCI_FN_STATE_STANDBY)
345                                 break;
346                         zdev->state = ZPCI_FN_STATE_CONFIGURED;
347                 }
348                 zpci_scan_configured_device(zdev, ccdf->fh);
349                 break;
350         case 0x0302: /* Reserved -> Standby */
351                 if (!zdev)
352                         zpci_create_device(ccdf->fid, ccdf->fh, ZPCI_FN_STATE_STANDBY);
353                 else
354                         zpci_update_fh(zdev, ccdf->fh);
355                 break;
356         case 0x0303: /* Deconfiguration requested */
357                 if (zdev) {
358                         /* The event may have been queued before we configured
359                          * the device.
360                          */
361                         if (zdev->state != ZPCI_FN_STATE_CONFIGURED)
362                                 break;
363                         zpci_update_fh(zdev, ccdf->fh);
364                         zpci_deconfigure_device(zdev);
365                 }
366                 break;
367         case 0x0304: /* Configured -> Standby|Reserved */
368                 if (zdev) {
369                         /* The event may have been queued before we configured
370                          * the device.:
371                          */
372                         if (zdev->state == ZPCI_FN_STATE_CONFIGURED)
373                                 zpci_event_hard_deconfigured(zdev, ccdf->fh);
374                         /* The 0x0304 event may immediately reserve the device */
375                         if (!clp_get_state(zdev->fid, &state) &&
376                             state == ZPCI_FN_STATE_RESERVED) {
377                                 zpci_device_reserved(zdev);
378                         }
379                 }
380                 break;
381         case 0x0306: /* 0x308 or 0x302 for multiple devices */
382                 zpci_remove_reserved_devices();
383                 clp_scan_pci_devices();
384                 break;
385         case 0x0308: /* Standby -> Reserved */
386                 if (!zdev)
387                         break;
388                 zpci_device_reserved(zdev);
389                 break;
390         default:
391                 break;
392         }
393         if (existing_zdev) {
394                 mutex_unlock(&zdev->state_lock);
395                 zpci_zdev_put(zdev);
396         }
397 }
398 
399 void zpci_event_availability(void *data)
400 {
401         if (zpci_is_enabled())
402                 __zpci_event_availability(data);
403 }
404 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php