From: Bjorn Andersson <bjorn.andersson@linaro.org>
To: Jordan Crouse <jcrouse@codeaurora.org>
Cc: freedreno@lists.freedesktop.org,
linux-arm-msm <linux-arm-msm@vger.kernel.org>,
ML dri-devel <dri-devel@lists.freedesktop.org>
Subject: Re: [PATCH 11/12] drm/msm: Add a quick and dirty PIL loader
Date: Mon, 5 Dec 2016 11:57:43 -0800 [thread overview]
Message-ID: <20161205195743.GM9322@tuxbot> (raw)
In-Reply-To: <1480361317-9937-12-git-send-email-jcrouse@codeaurora.org>
On Mon 28 Nov 11:28 PST 2016, Jordan Crouse wrote:
> In order to switch the GPU out of secure mode on most systems we
> need to load a zap shader into memory and get it authenticated
> and into the secure world. All the bits and pieces to do
> the load are scattered throughout the kernel, but we need to
> bring everything together.
>
> Add a semi-custom loader that will read a MDT file and get
> it loaded and authenticated through SCM.
>
I've been trying to figure out a reasonable way to provide a
scm/pas/mdt-loader, but haven't come up with anything sane yet. Perhaps
it's better to provide helpers for the scm case and open code the MDT
loading in the non-scm driver. I think this is an okay approach for now.
But it's not a "PIL loader", that's just a side effect of reusing parts
of the existing PIL load in the Qualcomm tree. I would suggest just
making the subject "Add ZAP MDT loader".
Some minor comments below.
> Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
> ---
> drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 166 ++++++++++++++++++++++++++++++++++
> 1 file changed, 166 insertions(+)
>
> diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> index 3824bc4..eefe197 100644
> --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> @@ -11,12 +11,178 @@
> *
> */
>
> +#include <linux/elf.h>
> +#include <linux/types.h>
> +#include <linux/cpumask.h>
> +#include <linux/qcom_scm.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/of_reserved_mem.h>
> #include "msm_gem.h"
> #include "a5xx_gpu.h"
>
> extern bool hang_debug;
> static void a5xx_dump(struct msm_gpu *gpu);
>
> +static inline bool _check_segment(const struct elf32_phdr *phdr)
> +{
> + return ((phdr->p_type == PT_LOAD) &&
> + ((phdr->p_flags & (7 << 24)) != (2 << 24)) &&
> + phdr->p_memsz);
> +}
> +
> +static int __pil_tz_load_image(struct platform_device *pdev,
Rather than throwing more underscores at it I would have named this
"zap_load_segments".
> + const struct firmware *mdt, const char *fwname,
> + void *fwptr, size_t fw_size, unsigned long fw_min_addr)
> +{
> + char str[64] = { 0 };
Name this filename or similar and no need to initialize it.
> + const struct elf32_hdr *ehdr = (struct elf32_hdr *) mdt->data;
> + const struct elf32_phdr *phdrs = (struct elf32_phdr *) (ehdr + 1);
> + const struct firmware *fw;
> + int i, ret = 0;
> +
> + for (i = 0; i < ehdr->e_phnum; i++) {
> + const struct elf32_phdr *phdr = &phdrs[i];
> + size_t offset;
> +
> + /* Make sure the segment is loadable */
> + if (!_check_segment(phdr))
> + continue; > +
> + /* Get the offset of the segment within the region */
> + offset = (phdr->p_paddr - fw_min_addr);
> +
> + /* Request the file containing the segment */
> + snprintf(str, sizeof(str) - 1, "%s.b%02d", fwname, i);
snprintf(, size, ) writes at most size bytes and includes null
termination, so drop the "- 1".
> +
> + ret = request_firmware(&fw, str, &pdev->dev);
> + if (ret) {
> + dev_err(&pdev->dev, "Failed to load segment %s\n", str);
> + break;
> + }
> +
> + if (offset + fw->size > fw_size) {
> + dev_err(&pdev->dev, "Segment %s is too big\n", str);
> + ret = -EINVAL;
> + release_firmware(fw);
> + break;
> + }
> +
> + /* Copy the segment into place */
> + memcpy(fwptr + offset, fw->data, fw->size);
Just to be on the safe side, please add:
if (phdr->p_memsz > phdr->p_filesz)
memset(fwptr + fw->size, 0, phdr->p_memsz - phdr->p_filesz);
> + release_firmware(fw);
> + }
> +
> + return ret;
> +}
> +
> +static int _pil_tz_load_image(struct platform_device *pdev)
zap_load_mdt() ?
> +{
> + char str[64] = { 0 };
> + const char *fwname;
> + const struct elf32_hdr *ehdr;
> + const struct elf32_phdr *phdrs;
> + const struct firmware *mdt;
> + phys_addr_t fw_min_addr, fw_max_addr;
> + dma_addr_t fw_phys;
> + size_t fw_size;
> + u32 pas_id;
> + void *ptr;
> + int i, ret;
> +
> + if (pdev == NULL)
> + return -ENODEV;
This should not happen.
> +
> + if (!qcom_scm_is_available()) {
> + dev_err(&pdev->dev, "SCM is not available\n");
> + return -EINVAL;
We generally return -EPROBE_DEFER here.
> + }
> +
> + ret = of_reserved_mem_device_init(&pdev->dev);
> +
Please drop the extra newline.
> + if (ret) {
> + dev_err(&pdev->dev, "Unable to set up the reserved memory\n");
> + return ret;
> + }
> +
> + /* Get the firmware and PAS id from the device node */
> + if (of_property_read_string(pdev->dev.of_node, "qcom,firmware",
> + &fwname)) {
> + dev_err(&pdev->dev, "Could not read a firmware name\n");
> + return -EINVAL;
> + }
> +
> + if (of_property_read_u32(pdev->dev.of_node, "qcom,pas-id", &pas_id)) {
This is constant, so define it in the driver.
> + dev_err(&pdev->dev, "Could not read the pas ID\n");
> + return -EINVAL;
> + }
> +
> + snprintf(str, sizeof(str) - 1, "%s.mdt", fwname);
As above, re "- 1", name of str and initialization.
> +
> + /* Request the MDT file for the firmware */
> + ret = request_firmware(&mdt, str, &pdev->dev);
> + if (ret) {
> + dev_err(&pdev->dev, "Unable to load %s\n", str);
> + return ret;
> + }
> +
> + ehdr = (struct elf32_hdr *) mdt->data;
> + phdrs = (struct elf32_phdr *) (ehdr + 1);
> +
> + /* Get the extents of the firmware image */
> +
> + fw_min_addr = (phys_addr_t) ULLONG_MAX;
> + fw_max_addr = 0;
> +
> + for (i = 0; i < ehdr->e_phnum; i++) {
> + const struct elf32_phdr *phdr = &phdrs[i];
> +
> + if (!_check_segment(phdr))
> + continue;
> +
> + fw_min_addr = min_t(phys_addr_t, fw_min_addr, phdr->p_paddr);
> + fw_max_addr = max_t(phys_addr_t, fw_max_addr,
> + PAGE_ALIGN(phdr->p_paddr + phdr->p_memsz));
> + }
> +
> + if (fw_min_addr == (phys_addr_t) ULLONG_MAX && fw_max_addr == 0)
> + goto out;
> +
> + fw_size = (size_t) (fw_max_addr - fw_min_addr);
> +
> + /* Verify the MDT header */
> + ret = qcom_scm_pas_init_image(pas_id, mdt->data, mdt->size);
> + if (ret) {
> + dev_err(&pdev->dev, "Invalid firmware metadata\n");
> + goto out;
> + }
> +
> + /* allocate some memory */
> + ptr = dma_alloc_coherent(&pdev->dev, fw_size, &fw_phys, GFP_KERNEL);
> + if (ptr == NULL)
> + goto out;
> +
> + /* Set up the newly allocated memory region */
> + ret = qcom_scm_pas_mem_setup(pas_id, fw_phys, fw_size);
> + if (ret) {
> + dev_err(&pdev->dev, "Unable to set up firmware memory\n");
> + goto out;
> + }
> +
> + ret = __pil_tz_load_image(pdev, mdt, fwname, ptr, fw_size, fw_min_addr);
> + if (!ret) {
Please don't mix style like this, goto out on error.
> + ret = qcom_scm_pas_auth_and_reset(pas_id);
> + if (ret)
> + dev_err(&pdev->dev, "Unable to authorize the image\n");
> + }
> +
> +out:
> + if (ret && ptr)
> + dma_free_coherent(&pdev->dev, fw_size, ptr, fw_phys);
> +
> + release_firmware(mdt);
> + return ret;
> +}
> +
Regards,
Bjorn
next prev parent reply other threads:[~2016-12-05 19:57 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-11-28 19:28 [PATCH 00/12] Adreno A5XX support Jordan Crouse
2016-11-28 19:28 ` [PATCH 01/12] drm/msm: gpu: Cut down the list of "generic" registers to the ones we use Jordan Crouse
2016-11-28 19:28 ` [PATCH 03/12] drm/msm: gpu Add new gpu register read/write functions Jordan Crouse
2016-11-28 19:28 ` [PATCH 04/12] drm/msm: Add adreno_gpu_write64() Jordan Crouse
[not found] ` <1480361317-9937-1-git-send-email-jcrouse-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2016-11-28 19:28 ` [PATCH 02/12] drm/msm: gpu: Return error on hw_init failure Jordan Crouse
2016-11-28 19:28 ` [PATCH 05/12] drm/msm: gpu: Add OUT_TYPE4 and OUT_TYPE7 Jordan Crouse
2016-11-28 19:28 ` [PATCH 06/12] drm/msm: Remove 'src_clk' from adreno configuration Jordan Crouse
2016-11-28 19:28 ` [PATCH 07/12] drm/msm: Disable interrupts during init Jordan Crouse
2016-11-28 19:28 ` [PATCH 08/12] drm/msm: gpu: Add A5XX target support Jordan Crouse
2016-11-28 19:28 ` [PATCH 09/12] drm/msm: gpu: Add support for the GPMU Jordan Crouse
2016-11-28 19:28 ` [PATCH 10/12] firmware: qcom_scm: Add qcom_scm_gpu_zap_resume() Jordan Crouse
2017-01-13 17:12 ` Andy Gross
[not found] ` <20170113171241.GH5710-3KkwrOJo9xYlRp7syxWybdHuzzzSOjJt@public.gmane.org>
2017-01-13 17:22 ` Jordan Crouse
[not found] ` <20170113172244.GA28592-9PYrDHPZ2Orvke4nUoYGnHL1okKdlPRT@public.gmane.org>
2017-01-13 17:45 ` Andy Gross
2017-01-13 23:24 ` [Freedreno] " Jordan Crouse
[not found] ` <20170113232438.GA24139-9PYrDHPZ2Orvke4nUoYGnHL1okKdlPRT@public.gmane.org>
2017-01-15 3:49 ` Andy Gross
2017-01-15 5:20 ` [Freedreno] " Andy Gross
2017-01-16 15:13 ` Stanimir Varbanov
2017-01-17 17:04 ` Jordan Crouse
[not found] ` <20170117170459.GA29647-9PYrDHPZ2Orvke4nUoYGnHL1okKdlPRT@public.gmane.org>
2017-01-17 19:31 ` Andy Gross
[not found] ` <1480361317-9937-11-git-send-email-jcrouse-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2017-01-17 5:56 ` [PATCH] firmware: qcom_scm: Add set remote state API Andy Gross
[not found] ` <1484632578-4539-1-git-send-email-andy.gross-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2017-01-18 16:51 ` Jordan Crouse
2017-01-18 17:37 ` Stanimir Varbanov
2017-01-24 9:54 ` Stanimir Varbanov
2017-01-24 16:11 ` Andy Gross
2016-11-28 19:28 ` [PATCH 11/12] drm/msm: Add a quick and dirty PIL loader Jordan Crouse
2016-12-05 19:57 ` Bjorn Andersson [this message]
2016-12-06 17:49 ` Jordan Crouse
2016-11-28 19:28 ` [PATCH 12/12] drm/msm: gpu: Use the zap shader on 5XX if we can Jordan Crouse
2016-12-05 19:57 ` Bjorn Andersson
2016-12-05 20:10 ` Bjorn Andersson
2016-12-06 15:35 ` Jordan Crouse
2016-12-06 16:37 ` [Freedreno] " Rob Clark
[not found] ` <20161206153501.GA25541-9PYrDHPZ2Orvke4nUoYGnHL1okKdlPRT@public.gmane.org>
2016-12-06 17:18 ` Bjorn Andersson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20161205195743.GM9322@tuxbot \
--to=bjorn.andersson@linaro.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=freedreno@lists.freedesktop.org \
--cc=jcrouse@codeaurora.org \
--cc=linux-arm-msm@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).