diff options
| author | Chris Wilson <chris@chris-wilson.co.uk> | 2017-01-06 10:22:38 -0500 |
|---|---|---|
| committer | Jani Nikula <jani.nikula@intel.com> | 2017-01-12 03:15:44 -0500 |
| commit | e4621b73b6b472fe2b434b4f0f76b8f33ee26a73 (patch) | |
| tree | a3dd884c82ac30a9b658af818282083e5f8c9bc8 | |
| parent | e88893fea17996018b2d68a22e677ea04f3baadf (diff) | |
drm/i915: Fix phys pwrite for struct_mutex-less operation
Since commit fe115628d567 ("drm/i915: Implement pwrite without
struct-mutex") the lowlevel pwrite calls are now called without the
protection of struct_mutex, but pwrite_phys was still asserting that it
held the struct_mutex and later tried to drop and relock it.
Fixes: fe115628d567 ("drm/i915: Implement pwrite without struct-mutex")
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: <drm-intel-fixes@lists.freedesktop.org>
Link: http://patchwork.freedesktop.org/patch/msgid/20170106152240.5793-1-chris@chris-wilson.co.uk
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
(cherry picked from commit 10466d2a59b23aa6d5ecd5310296c8cdb6458dac)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 34 |
1 files changed, 4 insertions, 30 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 3dd7fc662859..4b23a7814713 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -595,47 +595,21 @@ i915_gem_phys_pwrite(struct drm_i915_gem_object *obj, | |||
| 595 | struct drm_i915_gem_pwrite *args, | 595 | struct drm_i915_gem_pwrite *args, |
| 596 | struct drm_file *file) | 596 | struct drm_file *file) |
| 597 | { | 597 | { |
| 598 | struct drm_device *dev = obj->base.dev; | ||
| 599 | void *vaddr = obj->phys_handle->vaddr + args->offset; | 598 | void *vaddr = obj->phys_handle->vaddr + args->offset; |
| 600 | char __user *user_data = u64_to_user_ptr(args->data_ptr); | 599 | char __user *user_data = u64_to_user_ptr(args->data_ptr); |
| 601 | int ret; | ||
| 602 | 600 | ||
| 603 | /* We manually control the domain here and pretend that it | 601 | /* We manually control the domain here and pretend that it |
| 604 | * remains coherent i.e. in the GTT domain, like shmem_pwrite. | 602 | * remains coherent i.e. in the GTT domain, like shmem_pwrite. |
| 605 | */ | 603 | */ |
| 606 | lockdep_assert_held(&obj->base.dev->struct_mutex); | ||
| 607 | ret = i915_gem_object_wait(obj, | ||
| 608 | I915_WAIT_INTERRUPTIBLE | | ||
| 609 | I915_WAIT_LOCKED | | ||
| 610 | I915_WAIT_ALL, | ||
| 611 | MAX_SCHEDULE_TIMEOUT, | ||
| 612 | to_rps_client(file)); | ||
| 613 | if (ret) | ||
| 614 | return ret; | ||
| 615 | |||
| 616 | intel_fb_obj_invalidate(obj, ORIGIN_CPU); | 604 | intel_fb_obj_invalidate(obj, ORIGIN_CPU); |
| 617 | if (__copy_from_user_inatomic_nocache(vaddr, user_data, args->size)) { | 605 | if (copy_from_user(vaddr, user_data, args->size)) |
| 618 | unsigned long unwritten; | 606 | return -EFAULT; |
| 619 | |||
| 620 | /* The physical object once assigned is fixed for the lifetime | ||
| 621 | * of the obj, so we can safely drop the lock and continue | ||
| 622 | * to access vaddr. | ||
| 623 | */ | ||
| 624 | mutex_unlock(&dev->struct_mutex); | ||
| 625 | unwritten = copy_from_user(vaddr, user_data, args->size); | ||
| 626 | mutex_lock(&dev->struct_mutex); | ||
| 627 | if (unwritten) { | ||
| 628 | ret = -EFAULT; | ||
| 629 | goto out; | ||
| 630 | } | ||
| 631 | } | ||
| 632 | 607 | ||
| 633 | drm_clflush_virt_range(vaddr, args->size); | 608 | drm_clflush_virt_range(vaddr, args->size); |
| 634 | i915_gem_chipset_flush(to_i915(dev)); | 609 | i915_gem_chipset_flush(to_i915(obj->base.dev)); |
| 635 | 610 | ||
| 636 | out: | ||
| 637 | intel_fb_obj_flush(obj, false, ORIGIN_CPU); | 611 | intel_fb_obj_flush(obj, false, ORIGIN_CPU); |
| 638 | return ret; | 612 | return 0; |
| 639 | } | 613 | } |
| 640 | 614 | ||
| 641 | void *i915_gem_object_alloc(struct drm_device *dev) | 615 | void *i915_gem_object_alloc(struct drm_device *dev) |
