From patchwork Sat Jun 22 01:21:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bjorn Andersson X-Patchwork-Id: 167457 Delivered-To: patch@linaro.org Received: by 2002:a92:4782:0:0:0:0:0 with SMTP id e2csp1413709ilk; Fri, 21 Jun 2019 18:21:57 -0700 (PDT) X-Google-Smtp-Source: APXvYqzOEflwREXNe65MjtgOb88UVLhHXOcNE2aC4kdU0+8mc1o7yf6fH7w2wkQxflfbSsgxzFdG X-Received: by 2002:a17:90a:bb8b:: with SMTP id v11mr10119302pjr.64.1561166517206; Fri, 21 Jun 2019 18:21:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1561166517; cv=none; d=google.com; s=arc-20160816; b=zRLVCTuas0QYDnXM57jIJMn/pDrOGLIKh5P6Ykaq/KyS1FRaYRJKCLUnJU7tUf4xJ8 uEXwdAXnLkp+gCtZuF0I0ua2robPpOX9j29IdE8gmCtIeMfBXQaOxTKdurFfig420lDO aalKNrIwC6fVpuyfGRgLm6zpxa8OqiIujaPv1AMcVDPJb6KQPYXrfzH5h2tpHK+qzbln ql6tx+ctYffRIPgbhGh0wRhexp42SahqOiKIcoI/nsOJJnwKIS7FqToJQtDV3GHCgED6 wklStNO6gOBqITvaNLbTdnpWL+Z7cC6GUAqF4QS0hzwFduFzhgmSSWrAMXHA5+Z6xY2o nARg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=xB3/B19tVpEhHq+TPm5inc50jGFG4GCSdB1a/UsXLnI=; b=CadMq0DN/vZ3wUsjYzpQnFYflK8Gi7MYbDdwLRKaQlk7XItQu6NLY3gwt6NZj1tGFC C5UPvQryw10sLuoCWG0lFmFeiRISqSn/ym304Cp6opKnjxHu9rBxe8YFZRx0GVKP6yd8 wnnDl8ObyBG7YSXRQdTakjVFDkdLOrxZP6iI3qrBRIyWhlh1tNpPyMcoUvuyvKB6uHDY QsR/IuX2ae51jtv+CyDlf2ZNm0BDBPljcHCAEojEVFjpP/gKv5EZorLfW/PkxeyHvyqu HeKqjZZFgiRHjJapQrhB/89hQ/tV+WOxmBMXTgis4lgSep8ZDhIV/4aSvgvfi0vSNa6x J9EQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=y1vM3AN3; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u2si4424484pjb.25.2019.06.21.18.21.53; Fri, 21 Jun 2019 18:21:57 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=y1vM3AN3; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726369AbfFVBVw (ORCPT + 15 others); Fri, 21 Jun 2019 21:21:52 -0400 Received: from mail-pl1-f195.google.com ([209.85.214.195]:33184 "EHLO mail-pl1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726353AbfFVBVw (ORCPT ); Fri, 21 Jun 2019 21:21:52 -0400 Received: by mail-pl1-f195.google.com with SMTP id c14so3803779plo.0 for ; Fri, 21 Jun 2019 18:21:52 -0700 (PDT) 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; bh=xB3/B19tVpEhHq+TPm5inc50jGFG4GCSdB1a/UsXLnI=; b=y1vM3AN3hBQFD56/ckzb22hrbIz1MCP4Q2Qv87zLSEE9a8xmpjkku/M8bmoQ3jI6SP ON2z/6j2VqZwNpmySH6WlIrWwBa/eWzLIGjTmvKdeMwE3qfkY7oSQOz18vITQDT7YWyW pCCnb1E0eb+CwDSEBlldmvmbz9yN4lLkRJsqvViHNAPwgWsv9HaoKmrWO53GsbK6FqJQ U92poDpZ7q3su0eVq5SmcbLtfsMxOjKllEUUuwxQNMK3K6i8pp7V0HFM+fxTAH51ZX0d d4cXPF/t04wRsKxSy7Re7UU4OollmpN9mkeDYbLHwXSOPNm7KToYVus8Sg6NgnrzBvgY +PSQ== 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; bh=xB3/B19tVpEhHq+TPm5inc50jGFG4GCSdB1a/UsXLnI=; b=fxdD4SXQR/EJDcVui8jpHRAmCLs4N0O8XHHfKOwSKgJPXRDYeXMpzKSW7s1k62LR4w E54htSXmwqxVkcmX84a4ZjZl5Ah+dd/vOLUN4RKzHfQ9dFer5ISPQetQf0vU8qFX03EH KCQysrJHqqM0AIcFc6w14UB5gYD0rg1PNt29UZk+5mXjIK0vp6zZtlbOVt5YqxzlI6AZ NaPrOYmMVYHYeV/alGzYVwwiopj9HScb9vVWi2g4+3ZD4HO0UQsPlvFazktbRLN1p08a o+AMWzS3reSotRW4q3isOgByepPr9cXyhh0YcRpb11cRiUo66toMcgX2G/kwWHCllzqp c5lQ== X-Gm-Message-State: APjAAAUIe7pCphX1SJI/Dv2F126kkgEnz8R7sa0/U5RURoS46vJXDFO2 N32QixVxfntyFUdAezAKK/mISg== X-Received: by 2002:a17:902:934a:: with SMTP id g10mr125264057plp.18.1561166511405; Fri, 21 Jun 2019 18:21:51 -0700 (PDT) Received: from localhost.localdomain (104-188-17-28.lightspeed.sndgca.sbcglobal.net. [104.188.17.28]) by smtp.gmail.com with ESMTPSA id u5sm3539148pgp.19.2019.06.21.18.21.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 21 Jun 2019 18:21:50 -0700 (PDT) From: Bjorn Andersson To: Andy Gross , Ohad Ben-Cohen , Bjorn Andersson , Sibi Sankar Cc: linux-arm-msm@vger.kernel.org, linux-remoteproc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/2] soc: qcom: mdt_loader: Support loading non-split images Date: Fri, 21 Jun 2019 18:21:45 -0700 Message-Id: <20190622012146.19719-2-bjorn.andersson@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20190622012146.19719-1-bjorn.andersson@linaro.org> References: <20190622012146.19719-1-bjorn.andersson@linaro.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org In some software releases the firmware images are not split up with each loadable segment in it's own file. Check the size of the loaded firmware to see if it still contains each segment to be loaded, before falling back to the split-out segments. Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/mdt_loader.c | 88 ++++++++++++++++++++++++++++- include/linux/soc/qcom/mdt_loader.h | 2 + 2 files changed, 87 insertions(+), 3 deletions(-) -- 2.18.0 Acked-by: Andy Gross diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c index 9ca7d9484de0..24cd193dec55 100644 --- a/drivers/soc/qcom/mdt_loader.c +++ b/drivers/soc/qcom/mdt_loader.c @@ -66,6 +66,66 @@ ssize_t qcom_mdt_get_size(const struct firmware *fw) } EXPORT_SYMBOL_GPL(qcom_mdt_get_size); +/** + * qcom_mdt_read_metadata() - read header and metadata from mdt or mbn + * @fw: firmware of mdt header or mbn + * @data_len: length of the read metadata blob + * + * The mechanism that performs the authentication of the loading firmware + * expects an ELF header directly followed by the segment of hashes, with no + * padding inbetween. This function allocates a chunk of memory for this pair + * and copy the two pieces into the buffer. + * + * In the case of split firmware the hash is found directly following the ELF + * header, rather than at p_offset described by the second program header. + * + * The caller is responsible to free (kfree()) the returned pointer. + * + * Return: pointer to data, or ERR_PTR() + */ +void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len) +{ + const struct elf32_phdr *phdrs; + const struct elf32_hdr *ehdr; + size_t hash_offset; + size_t hash_size; + size_t ehdr_size; + void *data; + + ehdr = (struct elf32_hdr *)fw->data; + phdrs = (struct elf32_phdr *)(ehdr + 1); + + if (ehdr->e_phnum < 2) + return ERR_PTR(-EINVAL); + + if (phdrs[0].p_type == PT_LOAD || phdrs[1].p_type == PT_LOAD) + return ERR_PTR(-EINVAL); + + if ((phdrs[1].p_flags & QCOM_MDT_TYPE_MASK) != QCOM_MDT_TYPE_HASH) + return ERR_PTR(-EINVAL); + + ehdr_size = phdrs[0].p_filesz; + hash_size = phdrs[1].p_filesz; + + data = kmalloc(ehdr_size + hash_size, GFP_KERNEL); + if (!data) + return ERR_PTR(-ENOMEM); + + /* Is the header and hash already packed */ + if (ehdr_size + hash_size == fw->size) + hash_offset = phdrs[0].p_filesz; + else + hash_offset = phdrs[1].p_offset; + + memcpy(data, fw->data, ehdr_size); + memcpy(data + ehdr_size, fw->data + hash_offset, hash_size); + + *data_len = ehdr_size + hash_size; + + return data; +} +EXPORT_SYMBOL_GPL(qcom_mdt_read_metadata); + static int __qcom_mdt_load(struct device *dev, const struct firmware *fw, const char *firmware, int pas_id, void *mem_region, phys_addr_t mem_phys, size_t mem_size, @@ -78,12 +138,14 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw, phys_addr_t mem_reloc; phys_addr_t min_addr = PHYS_ADDR_MAX; phys_addr_t max_addr = 0; + size_t metadata_len; size_t fw_name_len; ssize_t offset; + void *metadata; char *fw_name; bool relocate = false; void *ptr; - int ret; + int ret = 0; int i; if (!fw || !mem_region || !mem_phys || !mem_size) @@ -101,7 +163,15 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw, return -ENOMEM; if (pas_init) { - ret = qcom_scm_pas_init_image(pas_id, fw->data, fw->size); + metadata = qcom_mdt_read_metadata(fw, &metadata_len); + if (IS_ERR(metadata)) { + ret = PTR_ERR(metadata); + goto out; + } + + ret = qcom_scm_pas_init_image(pas_id, metadata, metadata_len); + + kfree(metadata); if (ret) { dev_err(dev, "invalid firmware metadata\n"); goto out; @@ -162,7 +232,19 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw, ptr = mem_region + offset; - if (phdr->p_filesz) { + if (phdr->p_filesz && phdr->p_offset < fw->size) { + /* Firmware is large enough to be non-split */ + if (phdr->p_offset + phdr->p_filesz > fw->size) { + dev_err(dev, + "failed to load segment %d from truncated file %s\n", + i, firmware); + ret = -EINVAL; + break; + } + + memcpy(ptr, fw->data + phdr->p_offset, phdr->p_filesz); + } else if (phdr->p_filesz) { + /* Firmware not large enough, load split-out segments */ sprintf(fw_name + fw_name_len - 3, "b%02d", i); ret = request_firmware_into_buf(&seg_fw, fw_name, dev, ptr, phdr->p_filesz); diff --git a/include/linux/soc/qcom/mdt_loader.h b/include/linux/soc/qcom/mdt_loader.h index 944b06aefb0f..e600baec6825 100644 --- a/include/linux/soc/qcom/mdt_loader.h +++ b/include/linux/soc/qcom/mdt_loader.h @@ -21,4 +21,6 @@ int qcom_mdt_load_no_init(struct device *dev, const struct firmware *fw, const char *fw_name, int pas_id, void *mem_region, phys_addr_t mem_phys, size_t mem_size, phys_addr_t *reloc_base); +void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len); + #endif From patchwork Sat Jun 22 01:21:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bjorn Andersson X-Patchwork-Id: 167458 Delivered-To: patch@linaro.org Received: by 2002:a92:4782:0:0:0:0:0 with SMTP id e2csp1413726ilk; Fri, 21 Jun 2019 18:21:58 -0700 (PDT) X-Google-Smtp-Source: APXvYqy7aUbS6p1xyqf+MmZPy9CXNe3xetYOQJjIufB1RYkoCrZ+Pg1RNUZhWLjvCRE5erp+IG9q X-Received: by 2002:a17:90a:a00d:: with SMTP id q13mr10156558pjp.80.1561166518338; Fri, 21 Jun 2019 18:21:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1561166518; cv=none; d=google.com; s=arc-20160816; b=zVjdoao9Mq7VR8DhUEPXf+PhJf14wHOuJH5TF3OkZ4m0tpwNLOkIuyagoYz87ZZfLc OHkPZ8EPUJgR/AekRdr39x0hrWCSqxqceDWDlwlr3wOoo8WH7RRbvYttmzfYUncs2KlJ TQZWTV03fdMClJujMAX8X/0oh6X9Hd1/onEoh9AADvAEf0+Acm91uP6L+hQDgkfZwGYC eydnthFh9na8Ey9+ApB+prGvkr10CBVz952ovG/hM0Eed4S1p7UfS2rzADJLeyiDy//H OSAphBCCL7z4YAH6EV+QfUODMSRXd5HciHsnDAhK5QCo2GKQc4Y021MrKfgz2bJS+26N wKFA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=UJEwQtJkIZfbBqvjIvCvA/yth1IBpQ7oqB1C3jxXe0M=; b=bEFPuz7dx4zb86KMUAhPFtJWUwBiXW0v2NoR2Ult0azy95xJddogY4jp3/dFvFrPP4 gWogjcTZW3zTDfGomECUqB1coSCWXe3KI1zOKNncvAYLb0i8lk0bFJpQWfDMq6UhNNZj BK5yrcKzI79GA5El4PpAuBZxgug9k6a0zfkWJXXWv4WWZ4eD6vLNzqcc+mI6sEYPJc4c qQptj6oB0g7BUW+6GANC7G9KhxTURYO5mC7qQPWmP9zvPDoiPjFskindUyHEon+1scoP Blj010uybCn2m7sXqySZHPcYiWgaUJD5XRrRbVPpHoDXlps+tKl81sFAn7s6COZWxlk7 UwcQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=sXkNatyX; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u2si4424484pjb.25.2019.06.21.18.21.58; Fri, 21 Jun 2019 18:21:58 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=sXkNatyX; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726374AbfFVBV4 (ORCPT + 15 others); Fri, 21 Jun 2019 21:21:56 -0400 Received: from mail-pl1-f193.google.com ([209.85.214.193]:36968 "EHLO mail-pl1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726382AbfFVBVx (ORCPT ); Fri, 21 Jun 2019 21:21:53 -0400 Received: by mail-pl1-f193.google.com with SMTP id bh12so3794229plb.4 for ; Fri, 21 Jun 2019 18:21:52 -0700 (PDT) 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; bh=UJEwQtJkIZfbBqvjIvCvA/yth1IBpQ7oqB1C3jxXe0M=; b=sXkNatyXtejwKy/sxoDXafLPyHSFvYsKIjYJrXbWVlnfp2fH60dwJAkkJtmcS/crTQ MId3NLomd4gUBfZ69/4VhTphnIUWc/+aH/CcEN62M55cZCnb+bBrwsRRjyyCtheBOplL zGI4m+CPFoWQPYmu3abSRLMlX3ECAWBvaVR0dlZZja4riuJVY9A9CL2tX8o7olfMUqPE ZNRd1tmZ6kPcRdTypp2+HXQ+/AJrxcvzze2t5JWH0yRzHBVvv62LkaIAF1zYZ2yDqRz8 xbkLUMPF+x7QtAxVnl5V6bsd3Y3x76LRsINkTv77aHWuQaE/htUngHdeDzOF5vsmDoqP c7FQ== 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; bh=UJEwQtJkIZfbBqvjIvCvA/yth1IBpQ7oqB1C3jxXe0M=; b=faTAh30HZYi6Jy0D5eUDPLSIzNgrG7yGEK1c6ZW6q1qbf13gglHSgdQ1cZqOe5MCzx RJukH+i32rRdjFULgRABV2FlnybaQw0/von2hyjU5zPyB08ikc98pnZq0+Ll5USGXpKl IbIqIgIN+3TdrcObg3XViHC0/MJ1UMPnKrvWsviEY0EijKksng9aX8GjAIxryf4t1ABJ QZiuO/Yy5l8SCS8Trb0XmlvF6DJ4muZcXwatZnwUvZlsstPppb+XWgUAvmBkQM2qOE59 P6AxESR+5+qJbZCEZOxKss2pG09XeUWbyJ2qlN/x1GMoMO/7NFp0j/L/4z2gwNYB3c4e JCzQ== X-Gm-Message-State: APjAAAXgELf3NDw9bfDZkEYTdZ/V7SWTkNZW7iu4RCMS5ETiGCek3X9E pngZQ6TBEfXQmwiYI6ZVxUnD4g== X-Received: by 2002:a17:902:aa83:: with SMTP id d3mr110047275plr.74.1561166512481; Fri, 21 Jun 2019 18:21:52 -0700 (PDT) Received: from localhost.localdomain (104-188-17-28.lightspeed.sndgca.sbcglobal.net. [104.188.17.28]) by smtp.gmail.com with ESMTPSA id u5sm3539148pgp.19.2019.06.21.18.21.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 21 Jun 2019 18:21:51 -0700 (PDT) From: Bjorn Andersson To: Andy Gross , Ohad Ben-Cohen , Bjorn Andersson , Sibi Sankar Cc: linux-arm-msm@vger.kernel.org, linux-remoteproc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/2] remoteproc: qcom: q6v5-mss: Support loading non-split images Date: Fri, 21 Jun 2019 18:21:46 -0700 Message-Id: <20190622012146.19719-3-bjorn.andersson@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20190622012146.19719-1-bjorn.andersson@linaro.org> References: <20190622012146.19719-1-bjorn.andersson@linaro.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org In some software releases the firmware images are not split up with each loadable segment in it's own file. Check the size of the loaded firmware to see if it still contains each segment to be loaded, before falling back to the split-out segments. Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_q6v5_mss.c | 33 ++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) -- 2.18.0 diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c index 981581bcdd56..8fcf9d28dd73 100644 --- a/drivers/remoteproc/qcom_q6v5_mss.c +++ b/drivers/remoteproc/qcom_q6v5_mss.c @@ -659,23 +659,29 @@ static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw) { unsigned long dma_attrs = DMA_ATTR_FORCE_CONTIGUOUS; dma_addr_t phys; + void *metadata; int mdata_perm; int xferop_ret; + size_t size; void *ptr; int ret; - ptr = dma_alloc_attrs(qproc->dev, fw->size, &phys, GFP_KERNEL, dma_attrs); + metadata = qcom_mdt_read_metadata(fw, &size); + if (IS_ERR(metadata)) + return PTR_ERR(metadata); + + ptr = dma_alloc_attrs(qproc->dev, size, &phys, GFP_KERNEL, dma_attrs); if (!ptr) { + kfree(metadata); dev_err(qproc->dev, "failed to allocate mdt buffer\n"); return -ENOMEM; } - memcpy(ptr, fw->data, fw->size); + memcpy(ptr, metadata, size); /* Hypervisor mapping to access metadata by modem */ mdata_perm = BIT(QCOM_SCM_VMID_HLOS); - ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm, - true, phys, fw->size); + ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm, true, phys, size); if (ret) { dev_err(qproc->dev, "assigning Q6 access to metadata failed: %d\n", ret); @@ -693,14 +699,14 @@ 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, fw->size); + xferop_ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm, false, phys, size); if (xferop_ret) dev_warn(qproc->dev, "mdt buffer not reclaimed system may become unstable\n"); free_dma_attrs: - dma_free_attrs(qproc->dev, fw->size, ptr, phys, dma_attrs); + dma_free_attrs(qproc->dev, size, ptr, phys, dma_attrs); + kfree(metadata); return ret < 0 ? ret : 0; } @@ -981,7 +987,18 @@ static int q6v5_mpss_load(struct q6v5 *qproc) ptr = qproc->mpss_region + offset; - if (phdr->p_filesz) { + if (phdr->p_filesz && phdr->p_offset < fw->size) { + /* Firmware is large enough to be non-split */ + if (phdr->p_offset + phdr->p_filesz > fw->size) { + dev_err(qproc->dev, + "failed to load segment %d from truncated file %s\n", + i, fw_name); + ret = -EINVAL; + goto release_firmware; + } + + memcpy(ptr, fw->data + phdr->p_offset, phdr->p_filesz); + } else if (phdr->p_filesz) { /* Replace "xxx.xxx" with "xxx.bxx" */ sprintf(fw_name + fw_name_len - 3, "b%02d", i); ret = request_firmware(&seg_fw, fw_name, qproc->dev);