Re: [bug report] drm/i915/guc: Use GuC submission API version number

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 3/24/2023 02:12, Dan Carpenter wrote:
Hello John Harrison,

The patch 9bbba0667f37: "drm/i915/guc: Use GuC submission API version
number" from Nov 29, 2022, leads to the following Smatch static
checker warning:

	drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c:821 intel_uc_fw_fetch()
	warn: passing zero to 'ERR_PTR'
Doh! Yes. That is a bug. It's an error path that should never be hit - it means a firmware file has been released with a version number that breaks the spec or is simply corrupted data. So it's a low risk bug but it should still be fixed. I'll post a patch...

Thanks,
John.


drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
     709 int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
     710 {
     711         struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
     712         struct drm_i915_private *i915 = gt->i915;
     713         struct intel_uc_fw_file file_ideal;
     714         struct drm_i915_gem_object *obj;
     715         const struct firmware *fw = NULL;
     716         bool old_ver = false;
     717         int err;
     718
     719         GEM_BUG_ON(!gt->wopcm.size);
     720         GEM_BUG_ON(!intel_uc_fw_is_enabled(uc_fw));
     721
     722         err = i915_inject_probe_error(i915, -ENXIO);
     723         if (err)
     724                 goto fail;
     725
     726         __force_fw_fetch_failures(uc_fw, -EINVAL);
     727         __force_fw_fetch_failures(uc_fw, -ESTALE);
     728
     729         err = try_firmware_load(uc_fw, &fw);
     730         memcpy(&file_ideal, &uc_fw->file_wanted, sizeof(file_ideal));
     731
     732         /* Any error is terminal if overriding. Don't bother searching for older versions */
     733         if (err && intel_uc_fw_is_overridden(uc_fw))
     734                 goto fail;
     735
     736         while (err == -ENOENT) {
     737                 old_ver = true;
     738
     739                 __uc_fw_auto_select(i915, uc_fw);
     740                 if (!uc_fw->file_selected.path) {
     741                         /*
     742                          * No more options! But set the path back to something
     743                          * valid just in case it gets dereferenced.
     744                          */
     745                         uc_fw->file_selected.path = file_ideal.path;
     746
     747                         /* Also, preserve the version that was really wanted */
     748                         memcpy(&uc_fw->file_wanted, &file_ideal, sizeof(uc_fw->file_wanted));
     749                         break;
     750                 }
     751
     752                 err = try_firmware_load(uc_fw, &fw);
     753         }
     754
     755         if (err)
     756                 goto fail;
     757
     758         err = check_fw_header(gt, fw, uc_fw);
     759         if (err)
     760                 goto fail;
     761
     762         if (uc_fw->type == INTEL_UC_FW_TYPE_GUC && !guc_check_version_range(uc_fw))
     763                 goto fail;
                         ^^^^^^^^^
Should "err" be set on this path?


     764
     765         if (uc_fw->file_wanted.ver.major && uc_fw->file_selected.ver.major) {
     766                 /* Check the file's major version was as it claimed */
     767                 if (uc_fw->file_selected.ver.major != uc_fw->file_wanted.ver.major) {
     768                         gt_notice(gt, "%s firmware %s: unexpected version: %u.%u != %u.%u\n",
     769                                   intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
     770                                   uc_fw->file_selected.ver.major, uc_fw->file_selected.ver.minor,
     771                                   uc_fw->file_wanted.ver.major, uc_fw->file_wanted.ver.minor);
     772                         if (!intel_uc_fw_is_overridden(uc_fw)) {
     773                                 err = -ENOEXEC;
     774                                 goto fail;
     775                         }
     776                 } else {
     777                         if (uc_fw->file_selected.ver.minor < uc_fw->file_wanted.ver.minor)
     778                                 old_ver = true;
     779                 }
     780         }
     781
     782         if (old_ver && uc_fw->file_selected.ver.major) {
     783                 /* Preserve the version that was really wanted */
     784                 memcpy(&uc_fw->file_wanted, &file_ideal, sizeof(uc_fw->file_wanted));
     785
     786                 gt_notice(gt, "%s firmware %s (%d.%d) is recommended, but only %s (%d.%d) was found\n",
     787                           intel_uc_fw_type_repr(uc_fw->type),
     788                           uc_fw->file_wanted.path,
     789                           uc_fw->file_wanted.ver.major, uc_fw->file_wanted.ver.minor,
     790                           uc_fw->file_selected.path,
     791                           uc_fw->file_selected.ver.major, uc_fw->file_selected.ver.minor);
     792                 gt_info(gt, "Consider updating your linux-firmware pkg or downloading from %s\n",
     793                         INTEL_UC_FIRMWARE_URL);
     794         }
     795
     796         if (HAS_LMEM(i915)) {
     797                 obj = i915_gem_object_create_lmem_from_data(i915, fw->data, fw->size);
     798                 if (!IS_ERR(obj))
     799                         obj->flags |= I915_BO_ALLOC_PM_EARLY;
     800         } else {
     801                 obj = i915_gem_object_create_shmem_from_data(i915, fw->data, fw->size);
     802         }
     803
     804         if (IS_ERR(obj)) {
     805                 err = PTR_ERR(obj);
     806                 goto fail;
     807         }
     808
     809         uc_fw->obj = obj;
     810         uc_fw->size = fw->size;
     811         intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_AVAILABLE);
     812
     813         release_firmware(fw);
     814         return 0;
     815
     816 fail:
     817         intel_uc_fw_change_status(uc_fw, err == -ENOENT ?
     818                                   INTEL_UC_FIRMWARE_MISSING :
     819                                   INTEL_UC_FIRMWARE_ERROR);
     820
--> 821         gt_probe_error(gt, "%s firmware %s: fetch failed %pe\n",
     822                        intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path, ERR_PTR(err));
     823         gt_info(gt, "%s firmware(s) can be downloaded from %s\n",
     824                 intel_uc_fw_type_repr(uc_fw->type), INTEL_UC_FIRMWARE_URL);
     825
     826         release_firmware(fw);                /* OK even if fw is NULL */
     827         return err;
     828 }

regards,
dan carpenter




[Index of Archives]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux