diff options
author | Lucas De Marchi <lucas.demarchi@intel.com> | 2019-06-07 02:12:25 -0700 |
---|---|---|
committer | Lucas De Marchi <lucas.demarchi@intel.com> | 2019-06-17 12:32:29 -0700 |
commit | 46fcbe4b5e40d5f0862b44cd1c7d9adbbe59f511 (patch) | |
tree | aaeef66d9d130a92d6924ef7e02e72e92cadb9e3 /drivers/gpu/drm/i915 | |
parent | 0bba84975b3780db115d396f86518cc8d67fc0ae (diff) | |
download | linux-46fcbe4b5e40d5f0862b44cd1c7d9adbbe59f511.tar.bz2 |
drm/i915/dmc: extract function to parse css header
Let's start splitting the parse function, making all of them return the
number of bytes parsed - different versions of the firmware header may
require different sizes for the structures.
v2: rework remaining bytes calculation on new protection for amount of
bytes read
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
Reviewed-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190607091230.1489-5-lucas.demarchi@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r-- | drivers/gpu/drm/i915/intel_csr.c | 66 |
1 files changed, 41 insertions, 25 deletions
diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index 0bcda68fe44c..3cf2f2bc6b5c 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c @@ -332,36 +332,22 @@ static u32 find_dmc_fw_offset(const struct intel_fw_info *fw_info, return dmc_offset; } -static u32 *parse_csr_fw(struct drm_i915_private *dev_priv, - const struct firmware *fw) +/* Return number of bytes parsed or 0 on error */ +static u32 parse_csr_fw_css(struct intel_csr *csr, + struct intel_css_header *css_header, + size_t rem_size) { - struct intel_css_header *css_header; - struct intel_package_header *package_header; - struct intel_dmc_header *dmc_header; - struct intel_csr *csr = &dev_priv->csr; - const struct stepping_info *si = intel_get_stepping_info(dev_priv); - u32 dmc_offset, num_entries, max_entries, readcount = 0, nbytes; - u32 i; - u32 *dmc_payload; - size_t fsize; - - if (!fw) - return NULL; - - fsize = sizeof(struct intel_css_header) + - sizeof(struct intel_package_header) + - sizeof(struct intel_dmc_header); - if (fsize > fw->size) - goto error_truncated; + if (rem_size < sizeof(struct intel_css_header)) { + DRM_ERROR("Truncated DMC firmware, refusing.\n"); + return 0; + } - /* Extract CSS Header information*/ - css_header = (struct intel_css_header *)fw->data; if (sizeof(struct intel_css_header) != (css_header->header_len * 4)) { DRM_ERROR("DMC firmware has wrong CSS header length " "(%u bytes)\n", (css_header->header_len * 4)); - return NULL; + return 0; } if (csr->required_version && @@ -372,12 +358,42 @@ static u32 *parse_csr_fw(struct drm_i915_private *dev_priv, CSR_VERSION_MINOR(css_header->version), CSR_VERSION_MAJOR(csr->required_version), CSR_VERSION_MINOR(csr->required_version)); - return NULL; + return 0; } csr->version = css_header->version; - readcount += sizeof(struct intel_css_header); + return sizeof(struct intel_css_header); +} + +static u32 *parse_csr_fw(struct drm_i915_private *dev_priv, + const struct firmware *fw) +{ + struct intel_css_header *css_header; + struct intel_package_header *package_header; + struct intel_dmc_header *dmc_header; + struct intel_csr *csr = &dev_priv->csr; + const struct stepping_info *si = intel_get_stepping_info(dev_priv); + u32 dmc_offset, num_entries, max_entries, readcount = 0, nbytes; + u32 i, r; + u32 *dmc_payload; + size_t fsize; + + if (!fw) + return NULL; + + /* Extract CSS Header information */ + css_header = (struct intel_css_header *)fw->data; + r = parse_csr_fw_css(csr, css_header, fw->size); + if (!r) + return NULL; + + readcount += r; + fsize = readcount + + sizeof(struct intel_package_header) + + sizeof(struct intel_dmc_header); + if (fsize > fw->size) + goto error_truncated; /* Extract Package Header information*/ package_header = (struct intel_package_header *) |