From patchwork Tue Feb 4 06:26:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bjorn Andersson X-Patchwork-Id: 11364095 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4A63114D5 for ; Tue, 4 Feb 2020 06:26:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2799C2086A for ; Tue, 4 Feb 2020 06:26:58 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="u6GrVEIG" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727240AbgBDG0s (ORCPT ); Tue, 4 Feb 2020 01:26:48 -0500 Received: from mail-pj1-f68.google.com ([209.85.216.68]:50822 "EHLO mail-pj1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726220AbgBDG0s (ORCPT ); Tue, 4 Feb 2020 01:26:48 -0500 Received: by mail-pj1-f68.google.com with SMTP id r67so891553pjb.0 for ; Mon, 03 Feb 2020 22:26:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=9n+iEilQgwgwE8JFMeVrbJ2CZ9pJDHx5XtxEK2zVKro=; b=u6GrVEIG8+UBR2o/8hky44AtgWEJu/hSWHE6UO+Bo2wzW17lOk6Vm0IvB/k2xNmvUk z+5st6uz8ehnPkjJQwZYTB3CSzu+Z3oJQCazJWCes3PuRy4iD4AV0ec+fDyQEfKNCYMt a888D7r3Wu/QCu8D2P7f3eqUHkv/O/KhBV0NqLqYvagFwqgm4FbyLkfCe2yH9Vag2tZ7 BHEQ97bOwhV7Y5B5ELu1XAjMKOmpohF2Th2i5rhVKfYQ5H0cm7rQqq/8yEMcua+LtGfL 8jgWHab7K+n29et5+fhNtUpEEIeFmx0axqq2nNdne7CKNJAUU8t4OtY2gt3oGZZxYW/w XFDg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=9n+iEilQgwgwE8JFMeVrbJ2CZ9pJDHx5XtxEK2zVKro=; b=Jo0C6NTNOxO3jy/7izMIfhL9ODQWd+9Vl5JUnJa1+aaur1dQUOidGI4+UlgV1IA6Qk s+/K1hpo14t91qslhlhXIhDGzUerNbiRWmPbqUXFf4FCBjOTHZHZdVXjJKwlibYmI0ee DlToPaU/hafwAjTZhcf545DJ4N9nscB74YsE18JFFvJ8KBhmkW+iX+wh0wn2P8HJJtDT g/iB6X529+HFlI5RRJv53bMDbkF/qhF2VRjm76dgD+gZTqRjSp5/5aofuc/zpK2Nlkha zBqrjnYRqv/TzcRDIhDkZA/8yxzp83g4rpMqR3Gk3DJdCq3fcXG0l+QgOQ440xXzbK2w hV6w== X-Gm-Message-State: APjAAAXVH8pNq7vYvY/ZOHHJDqLDcZ3C3j9MZmTvBHuzaXUHKNOTry0C QAaLjLaQsE73DBMh6ZZXXEHOrw== X-Google-Smtp-Source: APXvYqzlDyVn6Ye4duFE46q2xndT/Npv5RabzJq8m523NGOTCYL9sgiqsz+ngJOvLV+HIedeJyfA6A== X-Received: by 2002:a17:90a:c78b:: with SMTP id gn11mr4266519pjb.97.1580797606636; Mon, 03 Feb 2020 22:26:46 -0800 (PST) Received: from localhost.localdomain (104-188-17-28.lightspeed.sndgca.sbcglobal.net. [104.188.17.28]) by smtp.gmail.com with ESMTPSA id l69sm6901897pgd.1.2020.02.03.22.26.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Feb 2020 22:26:46 -0800 (PST) From: Bjorn Andersson To: Bjorn Andersson , Ohad Ben-Cohen Cc: linux-arm-msm@vger.kernel.org, linux-remoteproc@vger.kernel.org, linux-kernel@vger.kernel.org, Sibi Sankar , Jeffrey Hugo , stable@vger.kernel.org Subject: [PATCH v3 1/2] remoteproc: qcom_q6v5_mss: Don't reassign mpss region on shutdown Date: Mon, 3 Feb 2020 22:26:40 -0800 Message-Id: <20200204062641.393949-2-bjorn.andersson@linaro.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20200204062641.393949-1-bjorn.andersson@linaro.org> References: <20200204062641.393949-1-bjorn.andersson@linaro.org> MIME-Version: 1.0 Sender: linux-remoteproc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-remoteproc@vger.kernel.org Trying to reclaim mpss memory while the mba is not running causes the system to crash on devices with security fuses blown, so leave it assigned to the remote on shutdown and recover it on a subsequent boot. Fixes: 6c5a9dc2481b ("remoteproc: qcom: Make secure world call for mem ownership switch") Cc: stable@vger.kernel.org Signed-off-by: Bjorn Andersson --- Changes since v2: - The assignment of mpss memory back to Linux is rejected in the coredump case on production devices, so check the return value of q6v5_xfer_mem_ownership() before attempting to memcpy() the data. drivers/remoteproc/qcom_q6v5_mss.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c index 471128a2e723..25c03a26bf88 100644 --- a/drivers/remoteproc/qcom_q6v5_mss.c +++ b/drivers/remoteproc/qcom_q6v5_mss.c @@ -887,11 +887,6 @@ static void q6v5_mba_reclaim(struct q6v5 *qproc) writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); } - ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, - false, qproc->mpss_phys, - qproc->mpss_size); - WARN_ON(ret); - q6v5_reset_assert(qproc); q6v5_clk_disable(qproc->dev, qproc->reset_clks, @@ -981,6 +976,10 @@ static int q6v5_mpss_load(struct q6v5 *qproc) max_addr = ALIGN(phdr->p_paddr + phdr->p_memsz, SZ_4K); } + /* Try to reset ownership back to Linux */ + q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, false, + qproc->mpss_phys, qproc->mpss_size); + mpss_reloc = relocate ? min_addr : qproc->mpss_phys; qproc->mpss_reloc = mpss_reloc; /* Load firmware segments */ @@ -1070,8 +1069,16 @@ static void qcom_q6v5_dump_segment(struct rproc *rproc, void *ptr = rproc_da_to_va(rproc, segment->da, segment->size); /* Unlock mba before copying segments */ - if (!qproc->dump_mba_loaded) + if (!qproc->dump_mba_loaded) { ret = q6v5_mba_load(qproc); + if (!ret) { + /* Try to reset ownership back to Linux */ + ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, + false, + qproc->mpss_phys, + qproc->mpss_size); + } + } if (!ptr || ret) memset(dest, 0xff, segment->size); @@ -1123,10 +1130,6 @@ static int q6v5_start(struct rproc *rproc) return 0; reclaim_mpss: - xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, - false, qproc->mpss_phys, - qproc->mpss_size); - WARN_ON(xfermemop_ret); q6v5_mba_reclaim(qproc); return ret; From patchwork Tue Feb 4 06:26:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bjorn Andersson X-Patchwork-Id: 11364093 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4623F14D5 for ; Tue, 4 Feb 2020 06:26:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 10C422086A for ; Tue, 4 Feb 2020 06:26:53 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="S6Q0CQKR" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727308AbgBDG0u (ORCPT ); Tue, 4 Feb 2020 01:26:50 -0500 Received: from mail-pl1-f196.google.com ([209.85.214.196]:42588 "EHLO mail-pl1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727256AbgBDG0t (ORCPT ); Tue, 4 Feb 2020 01:26:49 -0500 Received: by mail-pl1-f196.google.com with SMTP id e8so4231089plt.9 for ; Mon, 03 Feb 2020 22:26:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=/MsxSmnO7M1aByaqdtSVpeD8wIEt+sQjjgWd9Bkhj/g=; b=S6Q0CQKR3fVspRKvuT2ptfzz6GbxzKVj0PKG68oupJtciOGMUNudcyHDhv7cj30l1j bF93mn58x6pBBjRx0NQkrW9bQk2ldum33amfgyU0R1qyiqAbKSbrXBWa24idtumn83bT 37ZxLM5/m+LGiNh4kJE1LWtKmeopmiuVz6oBbmIw+KfJB8s/KxuKub/0+oQ9tYEe+eBL vYRNTff02LCAZn09D+YsuhEZnGC6zSiBR8GIWlwEk4kBRHMBqcgDn6dRMulbuoyx575Q CAyHaRaQSBbDmkELf+AZPswoP2lk5Xm0DQJmXFLy6IBG6Sfp9ZYcPQ/r0QMINaDnoEzt X/bA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/MsxSmnO7M1aByaqdtSVpeD8wIEt+sQjjgWd9Bkhj/g=; b=TpRaKdzi6pvyglUKOyRh6oSYGG9W3ks49AUoj/F+Qbbpn4SYVLro+9L2vU8GhVF3Zv iizRlXdWO3FnXAqtgGeFo3t3GQQYXyxyJoDJ/Gv7T8HkTM9zM7BzNic/VOZ4M7yKAvJ1 hmXDNEND4ZV6GXLXCoqXXukQIXYO2l7aAR8TCYVbDgJRX+bOJEsptrAfp6b3RrRYdEJO MY9bG9y+/qKy1hbdZ6On4QgFhPDkBdt9sGIsUvtyKZodmVmvbHX3BK+I+Xbfe74v6fpz 6GYddEAR3joJTPdIEBJmvCKr2ZsbP7r2JRq7zlz6XHtB+TEgU/gQyUcNDMUbhsgLG8AI eGlg== X-Gm-Message-State: APjAAAWXcRUOILaywEFFp+gpMwgrdGbTFOF4TmGKHtGFqoeBg01hPi/Z rGtW+rOKa908rb4TR8UFUwG5VQ== X-Google-Smtp-Source: APXvYqxKkro5twpTQ9itRoSve2PlhishCNJxxMdJWRAsjZZmKPt5Q4nhB9pYJ2/ctSPWS2471D1lmA== X-Received: by 2002:a17:90a:8001:: with SMTP id b1mr4211344pjn.39.1580797607810; Mon, 03 Feb 2020 22:26:47 -0800 (PST) Received: from localhost.localdomain (104-188-17-28.lightspeed.sndgca.sbcglobal.net. [104.188.17.28]) by smtp.gmail.com with ESMTPSA id l69sm6901897pgd.1.2020.02.03.22.26.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Feb 2020 22:26:47 -0800 (PST) From: Bjorn Andersson To: Bjorn Andersson , Ohad Ben-Cohen Cc: linux-arm-msm@vger.kernel.org, linux-remoteproc@vger.kernel.org, linux-kernel@vger.kernel.org, Sibi Sankar , Jeffrey Hugo , Luca Weiss Subject: [PATCH v3 2/2] remoteproc: qcom_q6v5_mss: Validate each segment during loading Date: Mon, 3 Feb 2020 22:26:41 -0800 Message-Id: <20200204062641.393949-3-bjorn.andersson@linaro.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20200204062641.393949-1-bjorn.andersson@linaro.org> References: <20200204062641.393949-1-bjorn.andersson@linaro.org> MIME-Version: 1.0 Sender: linux-remoteproc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-remoteproc@vger.kernel.org The code used to sync with the MBA after each segment loaded and this is still what's done downstream. So reduce the delta towards downstream by switching to a model where the content is iteratively validated. Reviewed-by: Jeffrey Hugo Tested-by: Jeffrey Hugo Tested-by: Luca Weiss Signed-off-by: Bjorn Andersson --- Changes since v2: - Picked up Luca's t-b drivers/remoteproc/qcom_q6v5_mss.c | 76 ++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 25 deletions(-) diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c index 25c03a26bf88..5eb154f221a4 100644 --- a/drivers/remoteproc/qcom_q6v5_mss.c +++ b/drivers/remoteproc/qcom_q6v5_mss.c @@ -360,23 +360,29 @@ static void q6v5_pds_disable(struct q6v5 *qproc, struct device **pds, } static int q6v5_xfer_mem_ownership(struct q6v5 *qproc, int *current_perm, - bool remote_owner, phys_addr_t addr, + bool local, bool remote, phys_addr_t addr, size_t size) { - struct qcom_scm_vmperm next; + struct qcom_scm_vmperm next[2]; + int perms = 0; if (!qproc->need_mem_protection) return 0; - if (remote_owner && *current_perm == BIT(QCOM_SCM_VMID_MSS_MSA)) - return 0; - if (!remote_owner && *current_perm == BIT(QCOM_SCM_VMID_HLOS)) - return 0; - next.vmid = remote_owner ? QCOM_SCM_VMID_MSS_MSA : QCOM_SCM_VMID_HLOS; - next.perm = remote_owner ? QCOM_SCM_PERM_RW : QCOM_SCM_PERM_RWX; + if (local) { + next[perms].vmid = QCOM_SCM_VMID_HLOS; + next[perms].perm = QCOM_SCM_PERM_RWX; + perms++; + } + + if (remote) { + next[perms].vmid = QCOM_SCM_VMID_MSS_MSA; + next[perms].perm = QCOM_SCM_PERM_RW; + perms++; + } return qcom_scm_assign_mem(addr, ALIGN(size, SZ_4K), - current_perm, &next, 1); + current_perm, next, perms); } static int q6v5_load(struct rproc *rproc, const struct firmware *fw) @@ -693,7 +699,7 @@ static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw) /* Hypervisor mapping to access metadata by modem */ mdata_perm = BIT(QCOM_SCM_VMID_HLOS); - ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm, true, phys, size); + ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm, false, true, phys, size); if (ret) { dev_err(qproc->dev, "assigning Q6 access to metadata failed: %d\n", ret); @@ -711,7 +717,7 @@ static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw) dev_err(qproc->dev, "MPSS header authentication failed: %d\n", ret); /* Metadata authentication done, remove modem access */ - xferop_ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm, false, phys, size); + xferop_ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm, true, false, phys, size); if (xferop_ret) dev_warn(qproc->dev, "mdt buffer not reclaimed system may become unstable\n"); @@ -798,7 +804,7 @@ static int q6v5_mba_load(struct q6v5 *qproc) } /* Assign MBA image access in DDR to q6 */ - ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true, + ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, false, true, qproc->mba_phys, qproc->mba_size); if (ret) { dev_err(qproc->dev, @@ -832,8 +838,8 @@ static int q6v5_mba_load(struct q6v5 *qproc) q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc); reclaim_mba: - xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, false, - qproc->mba_phys, + xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true, + false, qproc->mba_phys, qproc->mba_size); if (xfermemop_ret) { dev_err(qproc->dev, @@ -900,7 +906,7 @@ static void q6v5_mba_reclaim(struct q6v5 *qproc) /* In case of failure or coredump scenario where reclaiming MBA memory * could not happen reclaim it here. */ - ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, false, + ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true, false, qproc->mba_phys, qproc->mba_size); WARN_ON(ret); @@ -927,6 +933,7 @@ static int q6v5_mpss_load(struct q6v5 *qproc) phys_addr_t boot_addr; phys_addr_t min_addr = PHYS_ADDR_MAX; phys_addr_t max_addr = 0; + u32 code_length; bool relocate = false; char *fw_name; size_t fw_name_len; @@ -977,9 +984,19 @@ static int q6v5_mpss_load(struct q6v5 *qproc) } /* Try to reset ownership back to Linux */ - q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, false, + q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, true, false, qproc->mpss_phys, qproc->mpss_size); + /* Share ownership between Linux and MSS, during segment loading */ + ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, true, true, + qproc->mpss_phys, qproc->mpss_size); + if (ret) { + dev_err(qproc->dev, + "assigning Q6 access to mpss memory failed: %d\n", ret); + ret = -EAGAIN; + goto release_firmware; + } + mpss_reloc = relocate ? min_addr : qproc->mpss_phys; qproc->mpss_reloc = mpss_reloc; /* Load firmware segments */ @@ -1028,10 +1045,24 @@ static int q6v5_mpss_load(struct q6v5 *qproc) phdr->p_memsz - phdr->p_filesz); } size += phdr->p_memsz; + + code_length = readl(qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG); + if (!code_length) { + boot_addr = relocate ? qproc->mpss_phys : min_addr; + writel(boot_addr, qproc->rmb_base + RMB_PMI_CODE_START_REG); + writel(RMB_CMD_LOAD_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG); + } + writel(size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG); + + ret = readl(qproc->rmb_base + RMB_MBA_STATUS_REG); + if (ret < 0) { + dev_err(qproc->dev, "MPSS authentication failed: %d\n", ret); + goto release_firmware; + } } /* Transfer ownership of modem ddr region to q6 */ - ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, true, + ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, false, true, qproc->mpss_phys, qproc->mpss_size); if (ret) { dev_err(qproc->dev, @@ -1040,11 +1071,6 @@ static int q6v5_mpss_load(struct q6v5 *qproc) goto release_firmware; } - boot_addr = relocate ? qproc->mpss_phys : min_addr; - writel(boot_addr, qproc->rmb_base + RMB_PMI_CODE_START_REG); - writel(RMB_CMD_LOAD_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG); - writel(size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG); - ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_AUTH_COMPLETE, 10000); if (ret == -ETIMEDOUT) dev_err(qproc->dev, "MPSS authentication timed out\n"); @@ -1074,7 +1100,7 @@ static void qcom_q6v5_dump_segment(struct rproc *rproc, if (!ret) { /* Try to reset ownership back to Linux */ ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, - false, + true, false, qproc->mpss_phys, qproc->mpss_size); } @@ -1116,8 +1142,8 @@ static int q6v5_start(struct rproc *rproc) goto reclaim_mpss; } - xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, false, - qproc->mba_phys, + xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true, + false, qproc->mba_phys, qproc->mba_size); if (xfermemop_ret) dev_err(qproc->dev,