intel / gvt-linux

Other
512 stars 94 forks source link

Fixes issues #212 and #77 #215

Open smsilva98 opened 2 years ago

smsilva98 commented 2 years ago

When request_firmware runs its prints an error message "Direct firmware load for i915/gvt/vid_0x8086_did_0x5917_rid_0x07.golden_hw_state failed with error -2" into the logs, as mentioned in issue #77 this is not a real error message and should be removed. firmware_request_nowarn is the proper system call to use. It runs the exact same code as request_firmware except passes an extra bit to the internally called _request_firmware to disable the branch of code that prints the error message. I posted and discussed some of the functioning of the internal code of request_firmware in issue #212

smsilva98 commented 2 years ago

Information to help verify the commit

Error message raised Direct firmware load for i915/gvt/vid_0x8086_did_0x5917_rid_0x07.golden_hw_state failed with error -2

Link to the documentation for firmware_request_nowarn https://docs.kernel.org/driver-api/firmware/request_firmware.html#firmware-request-nowarn

Implementation for request_firmware

int request_firmware(const struct firmware **firmware_p, const char *name, struct device *device)
{
    int ret;

    /* Need to pin this module until return */
    __module_get(THIS_MODULE);
    ret = _request_firmware(firmware_p, name, device, NULL, 0, 0,
                FW_OPT_UEVENT);
    module_put(THIS_MODULE);
    return ret;
}

Implementation for firmware_request_nowarn

int firmware_request_nowarn(const struct firmware **firmware, const char *name, struct device *device)
{
    int ret;

    /* Need to pin this module until return */
    __module_get(THIS_MODULE);
    ret = _request_firmware(firmware, name, device, NULL, 0, 0,
                FW_OPT_UEVENT | FW_OPT_NO_WARN);
    module_put(THIS_MODULE);
    return ret;
}

The only difference between these two functions is firmware_request_nowarn adds FW_OPT_NOWARN to the opt_flags bitstring passed into _request_firmware. This disables the branch of code that prints the error message with no other side effects. The branch that prints the error message is towards the bottom of the code.

Implementation for _request_firmware

static int _request_firmware(const struct firmware **firmware_p, const char *name,
          struct device *device, void *buf, size_t size,
          size_t offset, u32 opt_flags)
{
    struct firmware *fw = NULL;
    struct cred *kern_cred = NULL;
    const struct cred *old_cred;
    bool nondirect = false;
    int ret;

    if (!firmware_p)
        return -EINVAL;

    if (!name || name[0] == '\0') {
        ret = -EINVAL;
        goto out;
    }

    ret = _request_firmware_prepare(&fw, name, device, buf, size,
                    offset, opt_flags);
    if (ret <= 0) /* error or already assigned */
        goto out;

    /*
     * We are about to try to access the firmware file. Because we may have been
     * called by a driver when serving an unrelated request from userland, we use
     * the kernel credentials to read the file.
     */
    kern_cred = prepare_kernel_cred(NULL);
    if (!kern_cred) {
        ret = -ENOMEM;
        goto out;
    }
    old_cred = override_creds(kern_cred);

    ret = fw_get_filesystem_firmware(device, fw->priv, "", NULL);

    /* Only full reads can support decompression, platform, and sysfs. */
    if (!(opt_flags & FW_OPT_PARTIAL))
        nondirect = true;

#ifdef CONFIG_FW_LOADER_COMPRESS_ZSTD
    if (ret == -ENOENT && nondirect)
        ret = fw_get_filesystem_firmware(device, fw->priv, ".zst",
                         fw_decompress_zstd);
#endif
#ifdef CONFIG_FW_LOADER_COMPRESS_XZ
    if (ret == -ENOENT && nondirect)
        ret = fw_get_filesystem_firmware(device, fw->priv, ".xz",
                         fw_decompress_xz);
#endif
    if (ret == -ENOENT && nondirect)
        ret = firmware_fallback_platform(fw->priv);

    if (ret) {
        if (!(opt_flags & FW_OPT_NO_WARN))
            dev_warn(device,
                 "Direct firmware load for %s failed with error %d\n",
                 name, ret);
        if (nondirect)
            ret = firmware_fallback_sysfs(fw, name, device,
                              opt_flags, ret);
    } else
        ret = assign_fw(fw, device);

    revert_creds(old_cred);
    put_cred(kern_cred);

 out:
    if (ret < 0) {
        fw_abort_batch_reqs(fw);
        release_firmware(fw);
        fw = NULL;
    }

    *firmware_p = fw;
    return ret;
}
smsilva98 commented 2 years ago

@TerrenceXu I'm not sure who I should reach out to, but can I get someone to take a look at this pull request? Thank you!