diff options
author | Vaibhav Jain <vaibhav@linux.vnet.ibm.com> | 2017-11-22 22:38:57 -0500 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2017-11-23 07:08:34 -0500 |
commit | 12841f87b7a8ceb3d54f171660f72a86941bfcb3 (patch) | |
tree | 224d2308470a53e16aa43fc561c325798cef2de1 | |
parent | 4d6c51b107cc73b15a377224549aa5593f90df89 (diff) |
cxl: Check if vphb exists before iterating over AFU devices
During an eeh a kernel-oops is reported if no vPHB is allocated to the
AFU. This happens as during AFU init, an error in creation of vPHB is
a non-fatal error. Hence afu->phb should always be checked for NULL
before iterating over it for the virtual AFU pci devices.
This patch fixes the kenel-oops by adding a NULL pointer check for
afu->phb before it is dereferenced.
Fixes: 9e8df8a21963 ("cxl: EEH support")
Cc: stable@vger.kernel.org # v4.3+
Signed-off-by: Vaibhav Jain <vaibhav@linux.vnet.ibm.com>
Acked-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
Acked-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r-- | drivers/misc/cxl/pci.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c index bb7fd3f4edab..19969ee86d6f 100644 --- a/drivers/misc/cxl/pci.c +++ b/drivers/misc/cxl/pci.c | |||
@@ -2083,6 +2083,9 @@ static pci_ers_result_t cxl_vphb_error_detected(struct cxl_afu *afu, | |||
2083 | /* There should only be one entry, but go through the list | 2083 | /* There should only be one entry, but go through the list |
2084 | * anyway | 2084 | * anyway |
2085 | */ | 2085 | */ |
2086 | if (afu->phb == NULL) | ||
2087 | return result; | ||
2088 | |||
2086 | list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) { | 2089 | list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) { |
2087 | if (!afu_dev->driver) | 2090 | if (!afu_dev->driver) |
2088 | continue; | 2091 | continue; |
@@ -2124,8 +2127,7 @@ static pci_ers_result_t cxl_pci_error_detected(struct pci_dev *pdev, | |||
2124 | * Tell the AFU drivers; but we don't care what they | 2127 | * Tell the AFU drivers; but we don't care what they |
2125 | * say, we're going away. | 2128 | * say, we're going away. |
2126 | */ | 2129 | */ |
2127 | if (afu->phb != NULL) | 2130 | cxl_vphb_error_detected(afu, state); |
2128 | cxl_vphb_error_detected(afu, state); | ||
2129 | } | 2131 | } |
2130 | return PCI_ERS_RESULT_DISCONNECT; | 2132 | return PCI_ERS_RESULT_DISCONNECT; |
2131 | } | 2133 | } |
@@ -2265,6 +2267,9 @@ static pci_ers_result_t cxl_pci_slot_reset(struct pci_dev *pdev) | |||
2265 | if (cxl_afu_select_best_mode(afu)) | 2267 | if (cxl_afu_select_best_mode(afu)) |
2266 | goto err; | 2268 | goto err; |
2267 | 2269 | ||
2270 | if (afu->phb == NULL) | ||
2271 | continue; | ||
2272 | |||
2268 | list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) { | 2273 | list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) { |
2269 | /* Reset the device context. | 2274 | /* Reset the device context. |
2270 | * TODO: make this less disruptive | 2275 | * TODO: make this less disruptive |
@@ -2327,6 +2332,9 @@ static void cxl_pci_resume(struct pci_dev *pdev) | |||
2327 | for (i = 0; i < adapter->slices; i++) { | 2332 | for (i = 0; i < adapter->slices; i++) { |
2328 | afu = adapter->afu[i]; | 2333 | afu = adapter->afu[i]; |
2329 | 2334 | ||
2335 | if (afu->phb == NULL) | ||
2336 | continue; | ||
2337 | |||
2330 | list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) { | 2338 | list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) { |
2331 | if (afu_dev->driver && afu_dev->driver->err_handler && | 2339 | if (afu_dev->driver && afu_dev->driver->err_handler && |
2332 | afu_dev->driver->err_handler->resume) | 2340 | afu_dev->driver->err_handler->resume) |