drm/i915/reset: Fix error_state_read ptr + offset use
authorjsg <jsg@openbsd.org>
Wed, 22 Jun 2022 22:55:56 +0000 (22:55 +0000)
committerjsg <jsg@openbsd.org>
Wed, 22 Jun 2022 22:55:56 +0000 (22:55 +0000)
From Alan Previn
f4c5eba87675a07a6c28cdaca7366aeb4258ec78 in linux 5.15.y/5.15.49
c9b576d0c7bf55aeae1a736da7974fa202c4394d in mainline linux

sys/dev/pci/drm/i915/i915_sysfs.c

index 99dbbc5..9e50d6c 100644 (file)
@@ -447,7 +447,14 @@ static ssize_t error_state_read(struct file *filp, struct kobject *kobj,
        struct device *kdev = kobj_to_dev(kobj);
        struct drm_i915_private *i915 = kdev_minor_to_i915(kdev);
        struct i915_gpu_coredump *gpu;
-       ssize_t ret;
+       ssize_t ret = 0;
+
+       /*
+        * FIXME: Concurrent clients triggering resets and reading + clearing
+        * dumps can cause inconsistent sysfs reads when a user calls in with a
+        * non-zero offset to complete a prior partial read but the
+        * gpu_coredump has been cleared or replaced.
+        */
 
        gpu = i915_first_error_state(i915);
        if (IS_ERR(gpu)) {
@@ -459,8 +466,10 @@ static ssize_t error_state_read(struct file *filp, struct kobject *kobj,
                const char *str = "No error state collected\n";
                size_t len = strlen(str);
 
-               ret = min_t(size_t, count, len - off);
-               memcpy(buf, str + off, ret);
+               if (off < len) {
+                       ret = min_t(size_t, count, len - off);
+                       memcpy(buf, str + off, ret);
+               }
        }
 
        return ret;