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
[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 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
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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.