lkml.org 
[lkml]   [2020]   [Feb]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.5 471/542] ath10k: pci: Only dump ATH10K_MEM_REGION_TYPE_IOREG when safe
    Date
    From: Bryan O'Donoghue <bryan.odonoghue@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.odonoghue@linaro.org>
    Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
    Signed-off-by: Sasha Levin <sashal@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
    \
     
     \ /
      Last update: 2020-02-14 17:00    [W:2.595 / U:2.376 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site