aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichał Winiarski <[email protected]>2019-08-16 10:54:57 +0000
committerChris Wilson <[email protected]>2019-08-16 16:49:57 +0100
commit1249dc1717381b37266201086d2806559d5715c1 (patch)
treebbd7f0095daedef2ea5e53d437e8b3a2d3eba033
parent3ba09632ce8bd42d1e4b57a6a423dcab937e211b (diff)
drm/i915/uc: Move FW size sanity check back to fetch
While we need to know WOPCM size to do this sanity check, it has more to do with FW than with WOPCM. Let's move the check to fetch phase, it's not like WOPCM is going to grow in the meantime. v2: rebased v3: use __intel_uc_fw_get_upload_size (Daniele) Signed-off-by: Michał Winiarski <[email protected]> Signed-off-by: Michal Wajdeczko <[email protected]> Cc: Daniele Ceraolo Spurio <[email protected]> Cc: Chris Wilson <[email protected]> Cc: Jackie Li <[email protected]> Cc: Joonas Lahtinen <[email protected]> Reviewed-by: Daniele Ceraolo Spurio <[email protected]> Signed-off-by: Chris Wilson <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c11
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h7
-rw-r--r--drivers/gpu/drm/i915/intel_wopcm.c14
3 files changed, 19 insertions, 13 deletions
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index d056e1f4bd6d..f4a34ea579fd 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -265,6 +265,7 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw, struct drm_i915_private *i915)
size_t size;
int err;
+ GEM_BUG_ON(!i915->wopcm.size);
GEM_BUG_ON(!intel_uc_fw_supported(uc_fw));
err = i915_inject_load_error(i915, -ENXIO);
@@ -324,6 +325,16 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw, struct drm_i915_private *i915)
goto fail;
}
+ /* Sanity check whether this fw is not larger than whole WOPCM memory */
+ size = __intel_uc_fw_get_upload_size(uc_fw);
+ if (unlikely(size >= i915->wopcm.size)) {
+ dev_warn(dev, "%s firmware %s: invalid size: %zu > %zu\n",
+ intel_uc_fw_type_repr(uc_fw->type), uc_fw->path,
+ size, (size_t)i915->wopcm.size);
+ err = -E2BIG;
+ goto fail;
+ }
+
/* Get version numbers from the CSS header */
switch (uc_fw->type) {
case INTEL_UC_FW_TYPE_GUC:
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
index ce8e83128a95..6fa50273c2ce 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
@@ -173,6 +173,11 @@ static inline void intel_uc_fw_sanitize(struct intel_uc_fw *uc_fw)
intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_AVAILABLE);
}
+static inline u32 __intel_uc_fw_get_upload_size(struct intel_uc_fw *uc_fw)
+{
+ return sizeof(struct uc_css_header) + uc_fw->ucode_size;
+}
+
/**
* intel_uc_fw_get_upload_size() - Get size of firmware needed to be uploaded.
* @uc_fw: uC firmware.
@@ -186,7 +191,7 @@ static inline u32 intel_uc_fw_get_upload_size(struct intel_uc_fw *uc_fw)
if (!intel_uc_fw_is_available(uc_fw))
return 0;
- return sizeof(struct uc_css_header) + uc_fw->ucode_size;
+ return __intel_uc_fw_get_upload_size(uc_fw);
}
void intel_uc_fw_init_early(struct intel_uc_fw *uc_fw,
diff --git a/drivers/gpu/drm/i915/intel_wopcm.c b/drivers/gpu/drm/i915/intel_wopcm.c
index 2bda24200498..2975e00f57f5 100644
--- a/drivers/gpu/drm/i915/intel_wopcm.c
+++ b/drivers/gpu/drm/i915/intel_wopcm.c
@@ -181,22 +181,12 @@ void intel_wopcm_init(struct intel_wopcm *wopcm)
GEM_BUG_ON(!wopcm->size);
GEM_BUG_ON(wopcm->guc.base);
GEM_BUG_ON(wopcm->guc.size);
+ GEM_BUG_ON(guc_fw_size >= wopcm->size);
+ GEM_BUG_ON(huc_fw_size >= wopcm->size);
if (i915_inject_probe_failure(i915))
return;
- if (guc_fw_size >= wopcm->size) {
- DRM_ERROR("GuC FW (%uKiB) is too big to fit in WOPCM.",
- guc_fw_size / 1024);
- return;
- }
-
- if (huc_fw_size >= wopcm->size) {
- DRM_ERROR("HuC FW (%uKiB) is too big to fit in WOPCM.",
- huc_fw_size / 1024);
- return;
- }
-
guc_wopcm_base = ALIGN(huc_fw_size + WOPCM_RESERVED_SIZE,
GUC_WOPCM_OFFSET_ALIGNMENT);
if ((guc_wopcm_base + ctx_rsvd) >= wopcm->size) {