Loading drivers/soc/qcom/peripheral-loader.c +14 −9 Original line number Original line Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only // 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> #include <linux/module.h> Loading Loading @@ -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, 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; void *region; size_t size = max_addr - min_addr; 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 */ /* Don't reallocate due to fragmentation concerns, just sanity check */ if (priv->region) { if (priv->region) { Loading Loading @@ -820,7 +821,8 @@ static int pil_alloc_region(struct pil_priv *priv, phys_addr_t min_addr, return 0; 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; const struct elf32_phdr *phdr; phys_addr_t min_addr_r, min_addr_n, max_addr_r, max_addr_n, start, end; phys_addr_t min_addr_r, min_addr_n, max_addr_r, max_addr_n, start, end; Loading Loading @@ -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); max_addr_r = ALIGN(max_addr_r, SZ_4K); if (relocatable) { 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 { } else { priv->region_start = min_addr_n; priv->region_start = min_addr_n; priv->region_end = max_addr_n; priv->region_end = max_addr_n; Loading Loading @@ -896,14 +899,15 @@ static int pil_cmp_seg(void *priv, struct list_head *a, struct list_head *b) return ret; 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; struct pil_priv *priv = desc->priv; const struct elf32_phdr *phdr; const struct elf32_phdr *phdr; struct pil_seg *seg; struct pil_seg *seg; int i, ret; int i, ret; ret = pil_setup_region(priv, mdt); ret = pil_setup_region(priv, mdt, mdt_size); if (ret) if (ret) return ret; return ret; Loading Loading @@ -1275,7 +1279,7 @@ int pil_boot(struct pil_desc *desc) goto release_fw; goto release_fw; } } ret = pil_init_mmap(desc, mdt); ret = pil_init_mmap(desc, mdt, fw->size); if (ret) if (ret) goto release_fw; goto release_fw; Loading @@ -1288,7 +1292,8 @@ int pil_boot(struct pil_desc *desc) pil_log("before_init_image", desc); pil_log("before_init_image", desc); if (desc->ops->init_image) 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) { if (ret) { pil_err(desc, "Initializing image failed(rc:%d)\n", ret); pil_err(desc, "Initializing image failed(rc:%d)\n", ret); goto err_boot; goto err_boot; Loading drivers/soc/qcom/peripheral-loader.h +2 −2 Original line number Original line Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* 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 #ifndef __MSM_PERIPHERAL_LOADER_H #define __MSM_PERIPHERAL_LOADER_H #define __MSM_PERIPHERAL_LOADER_H Loading Loading @@ -103,7 +103,7 @@ struct pil_image_info { */ */ struct pil_reset_ops { struct pil_reset_ops { int (*init_image)(struct pil_desc *pil, const u8 *metadata, 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 (*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, int (*verify_blob)(struct pil_desc *pil, phys_addr_t phy_addr, size_t size); size_t size); Loading drivers/soc/qcom/pil-msa.c +7 −4 Original line number Original line Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only // 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 * 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 * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -850,7 +850,8 @@ int pil_mss_debug_reset(struct pil_desc *pil) } } static int pil_msa_auth_modem_mdt(struct pil_desc *pil, const u8 *metadata, 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); struct modem_data *drv = dev_get_drvdata(pil->dev); void *mdata_virt; void *mdata_virt; Loading Loading @@ -934,7 +935,8 @@ static int pil_msa_auth_modem_mdt(struct pil_desc *pil, const u8 *metadata, } } static int pil_msa_mss_reset_mba_load_auth_mdt(struct pil_desc *pil, 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; int ret; Loading @@ -942,7 +944,8 @@ static int pil_msa_mss_reset_mba_load_auth_mdt(struct pil_desc *pil, if (ret) if (ret) return 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, static int pil_msa_mba_verify_blob(struct pil_desc *pil, phys_addr_t phy_addr, Loading drivers/soc/qcom/subsys-pil-tz.c +20 −13 Original line number Original line Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only // 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> #include <linux/kernel.h> Loading Loading @@ -39,6 +39,13 @@ #define desc_to_data(d) container_of(d, struct pil_tz_data, desc) #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) #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 * struct reg_info - regulator info * @reg: regulator handle * @reg: regulator handle Loading Loading @@ -599,16 +606,21 @@ static void pil_remove_proxy_vote(struct pil_desc *pil) } } static int pil_init_image_trusted(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); struct pil_tz_data *d = desc_to_data(pil); u32 scm_ret = 0; u32 scm_ret = 0; void *mdata_buf; void *mdata_buf; dma_addr_t mdata_phys; int ret; int ret; unsigned long attrs = 0; struct device dev = {0}; struct scm_desc desc = {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) if (d->subsys_desc.no_auth) return 0; return 0; Loading @@ -616,15 +628,10 @@ static int pil_init_image_trusted(struct pil_desc *pil, ret = scm_pas_enable_bw(); ret = scm_pas_enable_bw(); if (ret) if (ret) return ret; return ret; arch_setup_dma_ops(&dev, 0, 0, NULL, 0); dev.coherent_dma_mask = mdata_buf = pil->map_fw_mem(mdata_phys, size, map_data); 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); if (!mdata_buf) { 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(); scm_pas_disable_bw(); return -ENOMEM; return -ENOMEM; } } Loading @@ -638,7 +645,7 @@ static int pil_init_image_trusted(struct pil_desc *pil, &desc); &desc); scm_ret = desc.ret[0]; 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(); scm_pas_disable_bw(); if (ret) if (ret) return ret; return ret; Loading Loading
drivers/soc/qcom/peripheral-loader.c +14 −9 Original line number Original line Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only // 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> #include <linux/module.h> Loading Loading @@ -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, 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; void *region; size_t size = max_addr - min_addr; 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 */ /* Don't reallocate due to fragmentation concerns, just sanity check */ if (priv->region) { if (priv->region) { Loading Loading @@ -820,7 +821,8 @@ static int pil_alloc_region(struct pil_priv *priv, phys_addr_t min_addr, return 0; 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; const struct elf32_phdr *phdr; phys_addr_t min_addr_r, min_addr_n, max_addr_r, max_addr_n, start, end; phys_addr_t min_addr_r, min_addr_n, max_addr_r, max_addr_n, start, end; Loading Loading @@ -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); max_addr_r = ALIGN(max_addr_r, SZ_4K); if (relocatable) { 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 { } else { priv->region_start = min_addr_n; priv->region_start = min_addr_n; priv->region_end = max_addr_n; priv->region_end = max_addr_n; Loading Loading @@ -896,14 +899,15 @@ static int pil_cmp_seg(void *priv, struct list_head *a, struct list_head *b) return ret; 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; struct pil_priv *priv = desc->priv; const struct elf32_phdr *phdr; const struct elf32_phdr *phdr; struct pil_seg *seg; struct pil_seg *seg; int i, ret; int i, ret; ret = pil_setup_region(priv, mdt); ret = pil_setup_region(priv, mdt, mdt_size); if (ret) if (ret) return ret; return ret; Loading Loading @@ -1275,7 +1279,7 @@ int pil_boot(struct pil_desc *desc) goto release_fw; goto release_fw; } } ret = pil_init_mmap(desc, mdt); ret = pil_init_mmap(desc, mdt, fw->size); if (ret) if (ret) goto release_fw; goto release_fw; Loading @@ -1288,7 +1292,8 @@ int pil_boot(struct pil_desc *desc) pil_log("before_init_image", desc); pil_log("before_init_image", desc); if (desc->ops->init_image) 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) { if (ret) { pil_err(desc, "Initializing image failed(rc:%d)\n", ret); pil_err(desc, "Initializing image failed(rc:%d)\n", ret); goto err_boot; goto err_boot; Loading
drivers/soc/qcom/peripheral-loader.h +2 −2 Original line number Original line Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* 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 #ifndef __MSM_PERIPHERAL_LOADER_H #define __MSM_PERIPHERAL_LOADER_H #define __MSM_PERIPHERAL_LOADER_H Loading Loading @@ -103,7 +103,7 @@ struct pil_image_info { */ */ struct pil_reset_ops { struct pil_reset_ops { int (*init_image)(struct pil_desc *pil, const u8 *metadata, 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 (*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, int (*verify_blob)(struct pil_desc *pil, phys_addr_t phy_addr, size_t size); size_t size); Loading
drivers/soc/qcom/pil-msa.c +7 −4 Original line number Original line Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only // 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 * 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 * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -850,7 +850,8 @@ int pil_mss_debug_reset(struct pil_desc *pil) } } static int pil_msa_auth_modem_mdt(struct pil_desc *pil, const u8 *metadata, 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); struct modem_data *drv = dev_get_drvdata(pil->dev); void *mdata_virt; void *mdata_virt; Loading Loading @@ -934,7 +935,8 @@ static int pil_msa_auth_modem_mdt(struct pil_desc *pil, const u8 *metadata, } } static int pil_msa_mss_reset_mba_load_auth_mdt(struct pil_desc *pil, 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; int ret; Loading @@ -942,7 +944,8 @@ static int pil_msa_mss_reset_mba_load_auth_mdt(struct pil_desc *pil, if (ret) if (ret) return 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, static int pil_msa_mba_verify_blob(struct pil_desc *pil, phys_addr_t phy_addr, Loading
drivers/soc/qcom/subsys-pil-tz.c +20 −13 Original line number Original line Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only // 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> #include <linux/kernel.h> Loading Loading @@ -39,6 +39,13 @@ #define desc_to_data(d) container_of(d, struct pil_tz_data, desc) #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) #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 * struct reg_info - regulator info * @reg: regulator handle * @reg: regulator handle Loading Loading @@ -599,16 +606,21 @@ static void pil_remove_proxy_vote(struct pil_desc *pil) } } static int pil_init_image_trusted(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); struct pil_tz_data *d = desc_to_data(pil); u32 scm_ret = 0; u32 scm_ret = 0; void *mdata_buf; void *mdata_buf; dma_addr_t mdata_phys; int ret; int ret; unsigned long attrs = 0; struct device dev = {0}; struct scm_desc desc = {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) if (d->subsys_desc.no_auth) return 0; return 0; Loading @@ -616,15 +628,10 @@ static int pil_init_image_trusted(struct pil_desc *pil, ret = scm_pas_enable_bw(); ret = scm_pas_enable_bw(); if (ret) if (ret) return ret; return ret; arch_setup_dma_ops(&dev, 0, 0, NULL, 0); dev.coherent_dma_mask = mdata_buf = pil->map_fw_mem(mdata_phys, size, map_data); 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); if (!mdata_buf) { 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(); scm_pas_disable_bw(); return -ENOMEM; return -ENOMEM; } } Loading @@ -638,7 +645,7 @@ static int pil_init_image_trusted(struct pil_desc *pil, &desc); &desc); scm_ret = desc.ret[0]; 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(); scm_pas_disable_bw(); if (ret) if (ret) return ret; return ret; Loading