From: Bryan O'Donoghue <bryan.odonog...@linaro.org>

[ Upstream commit d239380196c4e27a26fa4bea73d2bf994c14ec2d ]

ath10k_pci_dump_memory_reg() will try to access memory of type
ATH10K_MEM_REGION_TYPE_IOREG however, if a hardware restart is in progress
this can crash a system.

Individual ioread32() time has been observed to jump from 15-20 ticks to >
80k ticks followed by a secure-watchdog bite and a system reset.

Work around this corner case by only issuing the read transaction when the
driver state is ATH10K_STATE_ON.

Tested-on: QCA9988 PCI 10.4-3.9.0.2-00044

Fixes: 219cc084c6706 ("ath10k: add memory dump support QCA9984")
Signed-off-by: Bryan O'Donoghue <bryan.odonog...@linaro.org>
Signed-off-by: Kalle Valo <kv...@codeaurora.org>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 drivers/net/wireless/ath/ath10k/pci.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/pci.c 
b/drivers/net/wireless/ath/ath10k/pci.c
index bb44f5a0941b9..4822a65f6f3c2 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -1604,11 +1604,22 @@ static int ath10k_pci_dump_memory_reg(struct ath10k *ar,
 {
        struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
        u32 i;
+       int ret;
+
+       mutex_lock(&ar->conf_mutex);
+       if (ar->state != ATH10K_STATE_ON) {
+               ath10k_warn(ar, "Skipping pci_dump_memory_reg invalid state\n");
+               ret = -EIO;
+               goto done;
+       }
 
        for (i = 0; i < region->len; i += 4)
                *(u32 *)(buf + i) = ioread32(ar_pci->mem + region->start + i);
 
-       return region->len;
+       ret = region->len;
+done:
+       mutex_unlock(&ar->conf_mutex);
+       return ret;
 }
 
 /* if an error happened returns < 0, otherwise the length */
@@ -1704,7 +1715,11 @@ static void ath10k_pci_dump_memory(struct ath10k *ar,
                        count = ath10k_pci_dump_memory_sram(ar, current_region, 
buf);
                        break;
                case ATH10K_MEM_REGION_TYPE_IOREG:
-                       count = ath10k_pci_dump_memory_reg(ar, current_region, 
buf);
+                       ret = ath10k_pci_dump_memory_reg(ar, current_region, 
buf);
+                       if (ret < 0)
+                               break;
+
+                       count = ret;
                        break;
                default:
                        ret = ath10k_pci_dump_memory_generic(ar, 
current_region, buf);
-- 
2.20.1


_______________________________________________
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k

Reply via email to