soc: qcom: pil: Reuse carveout region for mdt header

Currently we allocate a new dma region for our image headers to pass
into TZ for image verification. Instead reuse the previously allocated
region for the main firmware body to store the image header to avoid
having to allocate more memory than needed.

Change-Id: I1e50df2b417d9823c4e75f28134a3f9e078463aa
Signed-off-by: Kyle Yan <kyan@codeaurora.org>
Signed-off-by: Archana Sriram <apsrir@codeaurora.org>
This commit is contained in:
Kyle Yan 2017-12-01 17:05:59 -08:00 committed by Archana Sriram
parent 46ce72b895
commit dc880ca423
4 changed files with 43 additions and 28 deletions

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2010-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2010-2021, The Linux Foundation. All rights reserved.
*/
#include <linux/module.h>
@ -776,11 +776,12 @@ static int pil_init_entry_addr(struct pil_priv *priv, const struct pil_mdt *mdt)
}
static int pil_alloc_region(struct pil_priv *priv, phys_addr_t min_addr,
phys_addr_t max_addr, size_t align)
phys_addr_t max_addr, size_t align,
size_t mdt_size)
{
void *region;
size_t size = max_addr - min_addr;
size_t aligned_size;
size_t aligned_size = max(size, mdt_size);
/* Don't reallocate due to fragmentation concerns, just sanity check */
if (priv->region) {
@ -820,7 +821,8 @@ static int pil_alloc_region(struct pil_priv *priv, phys_addr_t min_addr,
return 0;
}
static int pil_setup_region(struct pil_priv *priv, const struct pil_mdt *mdt)
static int pil_setup_region(struct pil_priv *priv, const struct pil_mdt *mdt,
size_t mdt_size)
{
const struct elf32_phdr *phdr;
phys_addr_t min_addr_r, min_addr_n, max_addr_r, max_addr_n, start, end;
@ -865,7 +867,8 @@ static int pil_setup_region(struct pil_priv *priv, const struct pil_mdt *mdt)
max_addr_r = ALIGN(max_addr_r, SZ_4K);
if (relocatable) {
ret = pil_alloc_region(priv, min_addr_r, max_addr_r, align);
ret = pil_alloc_region(priv, min_addr_r, max_addr_r, align,
mdt_size);
} else {
priv->region_start = min_addr_n;
priv->region_end = max_addr_n;
@ -896,14 +899,15 @@ static int pil_cmp_seg(void *priv, struct list_head *a, struct list_head *b)
return ret;
}
static int pil_init_mmap(struct pil_desc *desc, const struct pil_mdt *mdt)
static int pil_init_mmap(struct pil_desc *desc, const struct pil_mdt *mdt,
size_t mdt_size)
{
struct pil_priv *priv = desc->priv;
const struct elf32_phdr *phdr;
struct pil_seg *seg;
int i, ret;
ret = pil_setup_region(priv, mdt);
ret = pil_setup_region(priv, mdt, mdt_size);
if (ret)
return ret;
@ -1275,7 +1279,7 @@ int pil_boot(struct pil_desc *desc)
goto release_fw;
}
ret = pil_init_mmap(desc, mdt);
ret = pil_init_mmap(desc, mdt, fw->size);
if (ret)
goto release_fw;
@ -1288,7 +1292,8 @@ int pil_boot(struct pil_desc *desc)
pil_log("before_init_image", desc);
if (desc->ops->init_image)
ret = desc->ops->init_image(desc, fw->data, fw->size);
ret = desc->ops->init_image(desc, fw->data, fw->size,
priv->region_start, priv->region);
if (ret) {
pil_err(desc, "Initializing image failed(rc:%d)\n", ret);
goto err_boot;

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2010-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2010-2019,2021, The Linux Foundation. All rights reserved.
*/
#ifndef __MSM_PERIPHERAL_LOADER_H
#define __MSM_PERIPHERAL_LOADER_H
@ -103,7 +103,7 @@ struct pil_image_info {
*/
struct pil_reset_ops {
int (*init_image)(struct pil_desc *pil, const u8 *metadata,
size_t size);
size_t size, phys_addr_t mdata_phys, void *region);
int (*mem_setup)(struct pil_desc *pil, phys_addr_t addr, size_t size);
int (*verify_blob)(struct pil_desc *pil, phys_addr_t phy_addr,
size_t size);

View File

@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -850,7 +850,8 @@ err_restart:
}
static int pil_msa_auth_modem_mdt(struct pil_desc *pil, const u8 *metadata,
size_t size)
size_t size, phys_addr_t region_start,
void *region)
{
struct modem_data *drv = dev_get_drvdata(pil->dev);
void *mdata_virt;
@ -934,7 +935,8 @@ fail:
}
static int pil_msa_mss_reset_mba_load_auth_mdt(struct pil_desc *pil,
const u8 *metadata, size_t size)
const u8 *metadata, size_t size,
phys_addr_t region_start, void *region)
{
int ret;
@ -942,7 +944,8 @@ static int pil_msa_mss_reset_mba_load_auth_mdt(struct pil_desc *pil,
if (ret)
return ret;
return pil_msa_auth_modem_mdt(pil, metadata, size);
return pil_msa_auth_modem_mdt(pil, metadata, size, region_start,
region);
}
static int pil_msa_mba_verify_blob(struct pil_desc *pil, phys_addr_t phy_addr,

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
*/
#include <linux/kernel.h>
@ -39,6 +39,13 @@
#define desc_to_data(d) container_of(d, struct pil_tz_data, desc)
#define subsys_to_data(d) container_of(d, struct pil_tz_data, subsys_desc)
struct pil_map_fw_info {
void *region;
unsigned long attrs;
phys_addr_t base_addr;
struct device *dev;
};
/**
* struct reg_info - regulator info
* @reg: regulator handle
@ -599,16 +606,21 @@ static void pil_remove_proxy_vote(struct pil_desc *pil)
}
static int pil_init_image_trusted(struct pil_desc *pil,
const u8 *metadata, size_t size)
const u8 *metadata, size_t size, phys_addr_t mdata_phys,
void *region)
{
struct pil_tz_data *d = desc_to_data(pil);
u32 scm_ret = 0;
void *mdata_buf;
dma_addr_t mdata_phys;
int ret;
unsigned long attrs = 0;
struct device dev = {0};
struct scm_desc desc = {0};
struct pil_map_fw_info map_fw_info = {
.attrs = pil->attrs,
.region = region,
.base_addr = mdata_phys,
.dev = pil->dev,
};
void *map_data = pil->map_data ? pil->map_data : &map_fw_info;
if (d->subsys_desc.no_auth)
return 0;
@ -616,15 +628,10 @@ static int pil_init_image_trusted(struct pil_desc *pil,
ret = scm_pas_enable_bw();
if (ret)
return ret;
arch_setup_dma_ops(&dev, 0, 0, NULL, 0);
dev.coherent_dma_mask =
DMA_BIT_MASK(sizeof(dma_addr_t) * 8);
attrs |= DMA_ATTR_STRONGLY_ORDERED;
mdata_buf = dma_alloc_attrs(&dev, size, &mdata_phys, GFP_KERNEL,
attrs);
mdata_buf = pil->map_fw_mem(mdata_phys, size, map_data);
if (!mdata_buf) {
pr_err("scm-pas: Allocation for metadata failed.\n");
dev_err(pil->dev, "Failed to map memory for metadata.\n");
scm_pas_disable_bw();
return -ENOMEM;
}
@ -638,7 +645,7 @@ static int pil_init_image_trusted(struct pil_desc *pil,
&desc);
scm_ret = desc.ret[0];
dma_free_attrs(&dev, size, mdata_buf, mdata_phys, attrs);
pil->unmap_fw_mem(mdata_buf, size, map_data);
scm_pas_disable_bw();
if (ret)
return ret;