lkml.org 
[lkml]   [2020]   [Jun]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 028/314] remoteproc: qcom_q6v5_mss: map/unmap mpss segments before/after use
    Date
    From: Sibi Sankar <sibis@codeaurora.org>

    [ Upstream commit be050a3429f46ecf13eb2b80f299479f8bb823fb ]

    The application processor accessing the mpss region when the Q6 modem is
    running will lead to an XPU violation. Fix this by un-mapping the mpss
    segments post copy during mpss authentication and coredumps.

    Tested-by: Evan Green <evgreen@chromium.org>
    Signed-off-by: Sibi Sankar <sibis@codeaurora.org>
    Link: https://lore.kernel.org/r/20200415071619.6052-1-sibis@codeaurora.org
    Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/remoteproc/qcom_q6v5_mss.c | 31 +++++++++++++++++++-----------
    1 file changed, 20 insertions(+), 11 deletions(-)

    diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c
    index 6ba065d5c4d95..d84e9f306086b 100644
    --- a/drivers/remoteproc/qcom_q6v5_mss.c
    +++ b/drivers/remoteproc/qcom_q6v5_mss.c
    @@ -1005,7 +1005,13 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
    goto release_firmware;
    }

    - ptr = qproc->mpss_region + offset;
    + ptr = ioremap_wc(qproc->mpss_phys + offset, phdr->p_memsz);
    + if (!ptr) {
    + dev_err(qproc->dev,
    + "unable to map memory region: %pa+%zx-%x\n",
    + &qproc->mpss_phys, offset, phdr->p_memsz);
    + goto release_firmware;
    + }

    if (phdr->p_filesz && phdr->p_offset < fw->size) {
    /* Firmware is large enough to be non-split */
    @@ -1014,6 +1020,7 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
    "failed to load segment %d from truncated file %s\n",
    i, fw_name);
    ret = -EINVAL;
    + iounmap(ptr);
    goto release_firmware;
    }

    @@ -1024,6 +1031,7 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
    ret = request_firmware(&seg_fw, fw_name, qproc->dev);
    if (ret) {
    dev_err(qproc->dev, "failed to load %s\n", fw_name);
    + iounmap(ptr);
    goto release_firmware;
    }

    @@ -1036,6 +1044,7 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
    memset(ptr + phdr->p_filesz, 0,
    phdr->p_memsz - phdr->p_filesz);
    }
    + iounmap(ptr);
    size += phdr->p_memsz;
    }

    @@ -1075,7 +1084,8 @@ static void qcom_q6v5_dump_segment(struct rproc *rproc,
    int ret = 0;
    struct q6v5 *qproc = rproc->priv;
    unsigned long mask = BIT((unsigned long)segment->priv);
    - void *ptr = rproc_da_to_va(rproc, segment->da, segment->size);
    + int offset = segment->da - qproc->mpss_reloc;
    + void *ptr = NULL;

    /* Unlock mba before copying segments */
    if (!qproc->dump_mba_loaded) {
    @@ -1089,10 +1099,15 @@ static void qcom_q6v5_dump_segment(struct rproc *rproc,
    }
    }

    - if (!ptr || ret)
    - memset(dest, 0xff, segment->size);
    - else
    + if (!ret)
    + ptr = ioremap_wc(qproc->mpss_phys + offset, segment->size);
    +
    + if (ptr) {
    memcpy(dest, ptr, segment->size);
    + iounmap(ptr);
    + } else {
    + memset(dest, 0xff, segment->size);
    + }

    qproc->dump_segment_mask |= mask;

    @@ -1393,12 +1408,6 @@ static int q6v5_alloc_memory_region(struct q6v5 *qproc)

    qproc->mpss_phys = qproc->mpss_reloc = r.start;
    qproc->mpss_size = resource_size(&r);
    - qproc->mpss_region = devm_ioremap_wc(qproc->dev, qproc->mpss_phys, qproc->mpss_size);
    - if (!qproc->mpss_region) {
    - dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n",
    - &r.start, qproc->mpss_size);
    - return -EBUSY;
    - }

    return 0;
    }
    --
    2.25.1


    \
     
     \ /
      Last update: 2020-06-23 23:20    [W:2.363 / U:0.160 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site