drm/i915/uc: Move FW size sanity check back to fetch
authorMichał Winiarski <michal.winiarski@intel.com>
Fri, 16 Aug 2019 10:54:57 +0000 (10:54 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Fri, 16 Aug 2019 15:49:57 +0000 (16:49 +0100)
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 <michal.winiarski@intel.com>
Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Jackie Li <yaodong.li@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Reviewed-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20190816105501.31020-2-michal.wajdeczko@intel.com
drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
drivers/gpu/drm/i915/intel_wopcm.c

index d056e1f4bd6d44c67b7f400a13c2fc879f68a7dc..f4a34ea579fdf22ef54f50ca37994f779a4d93b2 100644 (file)
@@ -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:
index ce8e83128a95b7758afdd595917a89a55a01a929..6fa50273c2ce8baea1554aacbdbc486f4b809f97 100644 (file)
@@ -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,
index 2bda2420049831720795a1868e4fbbc466ba109a..2975e00f57f586ba1f7fce5e0ad2bfd04b910f7a 100644 (file)
@@ -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) {