diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2017-01-06 10:22:38 -0500 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2017-01-06 11:53:44 -0500 |
commit | 10466d2a59b23aa6d5ecd5310296c8cdb6458dac (patch) | |
tree | 04c5dc18dfd38645ec55ebf009d5035d7ca41323 | |
parent | 984ff29f74c0c130b43f0c5b0fe0fbca5de0fddc (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>
-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 f671d052312a..a2b8a74168d7 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -597,47 +597,21 @@ i915_gem_phys_pwrite(struct drm_i915_gem_object *obj, | |||
597 | struct drm_i915_gem_pwrite *args, | 597 | struct drm_i915_gem_pwrite *args, |
598 | struct drm_file *file) | 598 | struct drm_file *file) |
599 | { | 599 | { |
600 | struct drm_device *dev = obj->base.dev; | ||
601 | void *vaddr = obj->phys_handle->vaddr + args->offset; | 600 | void *vaddr = obj->phys_handle->vaddr + args->offset; |
602 | char __user *user_data = u64_to_user_ptr(args->data_ptr); | 601 | char __user *user_data = u64_to_user_ptr(args->data_ptr); |
603 | int ret; | ||
604 | 602 | ||
605 | /* We manually control the domain here and pretend that it | 603 | /* We manually control the domain here and pretend that it |
606 | * remains coherent i.e. in the GTT domain, like shmem_pwrite. | 604 | * remains coherent i.e. in the GTT domain, like shmem_pwrite. |
607 | */ | 605 | */ |
608 | lockdep_assert_held(&obj->base.dev->struct_mutex); | ||
609 | ret = i915_gem_object_wait(obj, | ||
610 | I915_WAIT_INTERRUPTIBLE | | ||
611 | I915_WAIT_LOCKED | | ||
612 | I915_WAIT_ALL, | ||
613 | MAX_SCHEDULE_TIMEOUT, | ||
614 | to_rps_client(file)); | ||
615 | if (ret) | ||
616 | return ret; | ||
617 | |||
618 | intel_fb_obj_invalidate(obj, ORIGIN_CPU); | 606 | intel_fb_obj_invalidate(obj, ORIGIN_CPU); |
619 | if (__copy_from_user_inatomic_nocache(vaddr, user_data, args->size)) { | 607 | if (copy_from_user(vaddr, user_data, args->size)) |
620 | unsigned long unwritten; | 608 | return -EFAULT; |
621 | |||
622 | /* The physical object once assigned is fixed for the lifetime | ||
623 | * of the obj, so we can safely drop the lock and continue | ||
624 | * to access vaddr. | ||
625 | */ | ||
626 | mutex_unlock(&dev->struct_mutex); | ||
627 | unwritten = copy_from_user(vaddr, user_data, args->size); | ||
628 | mutex_lock(&dev->struct_mutex); | ||
629 | if (unwritten) { | ||
630 | ret = -EFAULT; | ||
631 | goto out; | ||
632 | } | ||
633 | } | ||
634 | 609 | ||
635 | drm_clflush_virt_range(vaddr, args->size); | 610 | drm_clflush_virt_range(vaddr, args->size); |
636 | i915_gem_chipset_flush(to_i915(dev)); | 611 | i915_gem_chipset_flush(to_i915(obj->base.dev)); |
637 | 612 | ||
638 | out: | ||
639 | intel_fb_obj_flush(obj, false, ORIGIN_CPU); | 613 | intel_fb_obj_flush(obj, false, ORIGIN_CPU); |
640 | return ret; | 614 | return 0; |
641 | } | 615 | } |
642 | 616 | ||
643 | void *i915_gem_object_alloc(struct drm_i915_private *dev_priv) | 617 | void *i915_gem_object_alloc(struct drm_i915_private *dev_priv) |