]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 27 Sep 2013 22:17:37 +0000 (15:17 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 27 Sep 2013 22:17:37 +0000 (15:17 -0700)
added patches:
drm-ast-fix-the-ast-open-key-function.patch
drm-fix-drm_ioctl_mode_getfb-handle-leak.patch
drm-i915-fix-gpu-hang-vs.-flip-stall-deadlocks.patch
drm-i915-fix-wait_for_pending_flips-vs-gpu-hang-deadlock.patch
drm-nv50-disp-prevent-false-output-detection-on-the-original-nv50.patch
drm-radeon-fix-endian-bugs-in-hw-i2c-atom-routines.patch
drm-radeon-fix-lcd-record-parsing.patch
drm-ttm-fix-the-tt_populated-check-in-ttm_tt_destroy.patch

queue-3.10/drm-ast-fix-the-ast-open-key-function.patch [new file with mode: 0644]
queue-3.10/drm-fix-drm_ioctl_mode_getfb-handle-leak.patch [new file with mode: 0644]
queue-3.10/drm-i915-fix-gpu-hang-vs.-flip-stall-deadlocks.patch [new file with mode: 0644]
queue-3.10/drm-i915-fix-wait_for_pending_flips-vs-gpu-hang-deadlock.patch [new file with mode: 0644]
queue-3.10/drm-nv50-disp-prevent-false-output-detection-on-the-original-nv50.patch [new file with mode: 0644]
queue-3.10/drm-radeon-fix-endian-bugs-in-hw-i2c-atom-routines.patch [new file with mode: 0644]
queue-3.10/drm-radeon-fix-lcd-record-parsing.patch [new file with mode: 0644]
queue-3.10/drm-ttm-fix-the-tt_populated-check-in-ttm_tt_destroy.patch [new file with mode: 0644]
queue-3.10/series

diff --git a/queue-3.10/drm-ast-fix-the-ast-open-key-function.patch b/queue-3.10/drm-ast-fix-the-ast-open-key-function.patch
new file mode 100644 (file)
index 0000000..c6eed88
--- /dev/null
@@ -0,0 +1,31 @@
+From 2e8378136f28bea960cec643d3fa5d843c9049ec Mon Sep 17 00:00:00 2001
+From: Dave Airlie <airlied@redhat.com>
+Date: Thu, 12 Sep 2013 15:31:04 +1000
+Subject: drm/ast: fix the ast open key function
+
+From: Dave Airlie <airlied@redhat.com>
+
+commit 2e8378136f28bea960cec643d3fa5d843c9049ec upstream.
+
+When porting from UMS I mistyped this from the wrong place, AST noticed
+and pointed it out, so we should fix it to be like the X.org driver.
+
+Reported-by: Y.C. Chen <yc_chen@aspeedtech.com>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/ast/ast_drv.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/ast/ast_drv.h
++++ b/drivers/gpu/drm/ast/ast_drv.h
+@@ -177,7 +177,7 @@ uint8_t ast_get_index_reg_mask(struct as
+ static inline void ast_open_key(struct ast_private *ast)
+ {
+-      ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xA1, 0xFF, 0x04);
++      ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x80, 0xA8);
+ }
+ #define AST_VIDMEM_SIZE_8M    0x00800000
diff --git a/queue-3.10/drm-fix-drm_ioctl_mode_getfb-handle-leak.patch b/queue-3.10/drm-fix-drm_ioctl_mode_getfb-handle-leak.patch
new file mode 100644 (file)
index 0000000..b73b32b
--- /dev/null
@@ -0,0 +1,75 @@
+From 101b96f32956ee99bf1468afaf572b88cda9f88b Mon Sep 17 00:00:00 2001
+From: David Herrmann <dh.herrmann@gmail.com>
+Date: Mon, 26 Aug 2013 15:16:49 +0200
+Subject: drm: fix DRM_IOCTL_MODE_GETFB handle-leak
+
+From: David Herrmann <dh.herrmann@gmail.com>
+
+commit 101b96f32956ee99bf1468afaf572b88cda9f88b upstream.
+
+DRM_IOCTL_MODE_GETFB is used to retrieve information about a given
+framebuffer ID. It is a read-only helper and was thus declassified for
+unprivileged access in:
+
+  commit a14b1b42477c5ef089fcda88cbaae50d979eb8f9
+  Author: Mandeep Singh Baines <mandeep.baines@gmail.com>
+  Date:   Fri Jan 20 12:11:16 2012 -0800
+
+      drm: remove master fd restriction on mode setting getters
+
+However, alongside width, height and stride information,
+DRM_IOCTL_MODE_GETFB also passes back a handle to the underlying buffer of
+the framebuffer. This handle allows users to mmap() it and read or write
+into it. Obviously, this should be restricted to DRM-Master.
+
+With the current setup, *any* process with access to /dev/dri/card0 (which
+means any process with access to hardware-accelerated rendering) can
+access the current screen framebuffer and modify it ad libitum.
+
+For backwards-compatibility reasons we want to keep the
+DRM_IOCTL_MODE_GETFB call unprivileged. Besides, it provides quite useful
+information regarding screen setup. So we simply test whether the caller
+is the current DRM-Master and if not, we return 0 as handle, which is
+always invalid. A following DRM_IOCTL_GEM_CLOSE on this handle will fail
+with EINVAL, but we accept this. Users shouldn't test for errors during
+GEM_CLOSE, anyway. And it is still better as a failing MODE_GETFB call.
+
+v2: add capable(CAP_SYS_ADMIN) check for compatibility with i-g-t
+
+Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
+Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/drm_crtc.c |   18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/drm_crtc.c
++++ b/drivers/gpu/drm/drm_crtc.c
+@@ -2501,10 +2501,22 @@ int drm_mode_getfb(struct drm_device *de
+       r->depth = fb->depth;
+       r->bpp = fb->bits_per_pixel;
+       r->pitch = fb->pitches[0];
+-      if (fb->funcs->create_handle)
+-              ret = fb->funcs->create_handle(fb, file_priv, &r->handle);
+-      else
++      if (fb->funcs->create_handle) {
++              if (file_priv->is_master || capable(CAP_SYS_ADMIN)) {
++                      ret = fb->funcs->create_handle(fb, file_priv,
++                                                     &r->handle);
++              } else {
++                      /* GET_FB() is an unprivileged ioctl so we must not
++                       * return a buffer-handle to non-master processes! For
++                       * backwards-compatibility reasons, we cannot make
++                       * GET_FB() privileged, so just return an invalid handle
++                       * for non-masters. */
++                      r->handle = 0;
++                      ret = 0;
++              }
++      } else {
+               ret = -ENODEV;
++      }
+       drm_framebuffer_unreference(fb);
diff --git a/queue-3.10/drm-i915-fix-gpu-hang-vs.-flip-stall-deadlocks.patch b/queue-3.10/drm-i915-fix-gpu-hang-vs.-flip-stall-deadlocks.patch
new file mode 100644 (file)
index 0000000..cae9509
--- /dev/null
@@ -0,0 +1,122 @@
+From 122f46badaafbe651f05c2c0f24cadee692f761b Mon Sep 17 00:00:00 2001
+From: Daniel Vetter <daniel.vetter@ffwll.ch>
+Date: Wed, 4 Sep 2013 17:36:14 +0200
+Subject: drm/i915: fix gpu hang vs. flip stall deadlocks
+
+From: Daniel Vetter <daniel.vetter@ffwll.ch>
+
+commit 122f46badaafbe651f05c2c0f24cadee692f761b upstream.
+
+Since we've started to clean up pending flips when the gpu hangs in
+
+commit 96a02917a0131e52efefde49c2784c0421d6c439
+Author: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Date:   Mon Feb 18 19:08:49 2013 +0200
+
+    drm/i915: Finish page flips and update primary planes after a GPU reset
+
+the gpu reset work now also grabs modeset locks. But since work items
+on our private work queue are not allowed to do that due to the
+flush_workqueue from the pageflip code this results in a neat
+deadlock:
+
+INFO: task kms_flip:14676 blocked for more than 120 seconds.
+"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+kms_flip        D ffff88019283a5c0     0 14676  13344 0x00000004
+ ffff88018e62dbf8 0000000000000046 ffff88013bdb12e0 ffff88018e62dfd8
+ ffff88018e62dfd8 00000000001d3b00 ffff88019283a5c0 ffff88018ec21000
+ ffff88018f693f00 ffff88018eece000 ffff88018e62dd60 ffff88018eece898
+Call Trace:
+ [<ffffffff8138ee7b>] schedule+0x60/0x62
+ [<ffffffffa046c0dd>] intel_crtc_wait_for_pending_flips+0xb2/0x114 [i915]
+ [<ffffffff81050ff4>] ? finish_wait+0x60/0x60
+ [<ffffffffa0478041>] intel_crtc_set_config+0x7f3/0x81e [i915]
+ [<ffffffffa031780a>] drm_mode_set_config_internal+0x4f/0xc6 [drm]
+ [<ffffffffa0319cf3>] drm_mode_setcrtc+0x44d/0x4f9 [drm]
+ [<ffffffff810e44da>] ? might_fault+0x38/0x86
+ [<ffffffffa030d51f>] drm_ioctl+0x2f9/0x447 [drm]
+ [<ffffffff8107a722>] ? trace_hardirqs_off+0xd/0xf
+ [<ffffffffa03198a6>] ? drm_mode_setplane+0x343/0x343 [drm]
+ [<ffffffff8112222f>] ? mntput_no_expire+0x3e/0x13d
+ [<ffffffff81117f33>] vfs_ioctl+0x18/0x34
+ [<ffffffff81118776>] do_vfs_ioctl+0x396/0x454
+ [<ffffffff81396b37>] ? sysret_check+0x1b/0x56
+ [<ffffffff81118886>] SyS_ioctl+0x52/0x7d
+ [<ffffffff81396b12>] system_call_fastpath+0x16/0x1b
+2 locks held by kms_flip/14676:
+ #0:  (&dev->mode_config.mutex){+.+.+.}, at: [<ffffffffa0316545>] drm_modeset_lock_all+0x22/0x59 [drm]
+ #1:  (&crtc->mutex){+.+.+.}, at: [<ffffffffa031656b>] drm_modeset_lock_all+0x48/0x59 [drm]
+INFO: task kworker/u8:4:175 blocked for more than 120 seconds.
+"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+kworker/u8:4    D ffff88018de9a5c0     0   175      2 0x00000000
+Workqueue: i915 i915_error_work_func [i915]
+ ffff88018e37dc30 0000000000000046 ffff8801938ab8a0 ffff88018e37dfd8
+ ffff88018e37dfd8 00000000001d3b00 ffff88018de9a5c0 ffff88018ec21018
+ 0000000000000246 ffff88018e37dca0 000000005a865a86 ffff88018de9a5c0
+Call Trace:
+ [<ffffffff8138ee7b>] schedule+0x60/0x62
+ [<ffffffff8138f23d>] schedule_preempt_disabled+0x9/0xb
+ [<ffffffff8138d0cd>] mutex_lock_nested+0x205/0x3b1
+ [<ffffffffa0477094>] ? intel_display_handle_reset+0x7e/0xbd [i915]
+ [<ffffffffa0477094>] ? intel_display_handle_reset+0x7e/0xbd [i915]
+ [<ffffffffa0477094>] intel_display_handle_reset+0x7e/0xbd [i915]
+ [<ffffffffa044e0a2>] i915_error_work_func+0x128/0x147 [i915]
+ [<ffffffff8104a89a>] process_one_work+0x1d4/0x35a
+ [<ffffffff8104a821>] ? process_one_work+0x15b/0x35a
+ [<ffffffff8104b4a5>] worker_thread+0x144/0x1f0
+ [<ffffffff8104b361>] ? rescuer_thread+0x275/0x275
+ [<ffffffff8105076d>] kthread+0xac/0xb4
+ [<ffffffff81059d30>] ? finish_task_switch+0x3b/0xc0
+ [<ffffffff810506c1>] ? __kthread_parkme+0x60/0x60
+ [<ffffffff81396a6c>] ret_from_fork+0x7c/0xb0
+ [<ffffffff810506c1>] ? __kthread_parkme+0x60/0x60
+3 locks held by kworker/u8:4/175:
+ #0:  (i915){.+.+.+}, at: [<ffffffff8104a821>] process_one_work+0x15b/0x35a
+ #1:  ((&dev_priv->gpu_error.work)){+.+.+.}, at: [<ffffffff8104a821>] process_one_work+0x15b/0x35a
+ #2:  (&crtc->mutex){+.+.+.}, at: [<ffffffffa0477094>] intel_display_handle_reset+0x7e/0xbd [i915]
+
+This blew up while running kms_flip/flip-vs-panning-vs-hang-interruptible
+on one of my older machines.
+
+Unfortunately (despite the proper lockdep annotations for
+flush_workqueue) lockdep still doesn't detect this correctly, so we
+need to rely on chance to discover these bugs.
+
+Apply the usual bugfix and schedule the reset work on the system
+workqueue to keep our own driver workqueue free of any modeset lock
+grabbing.
+
+Note that this is not a terribly serious regression since before the
+offending commit we'd simply have stalled userspace forever due to
+failing to abort all outstanding pageflips.
+
+v2: Add a comment as requested by Chris.
+
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Cc: Chris Wilson <chris@chris-wilson.co.uk>
+Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/i915_irq.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/i915/i915_irq.c
++++ b/drivers/gpu/drm/i915/i915_irq.c
+@@ -1727,7 +1727,13 @@ void i915_handle_error(struct drm_device
+                       wake_up_all(&ring->irq_queue);
+       }
+-      queue_work(dev_priv->wq, &dev_priv->gpu_error.work);
++      /*
++       * Our reset work can grab modeset locks (since it needs to reset the
++       * state of outstanding pagelips). Hence it must not be run on our own
++       * dev-priv->wq work queue for otherwise the flush_work in the pageflip
++       * code will deadlock.
++       */
++      schedule_work(&dev_priv->gpu_error.work);
+ }
+ static void __always_unused i915_pageflip_stall_check(struct drm_device *dev, int pipe)
diff --git a/queue-3.10/drm-i915-fix-wait_for_pending_flips-vs-gpu-hang-deadlock.patch b/queue-3.10/drm-i915-fix-wait_for_pending_flips-vs-gpu-hang-deadlock.patch
new file mode 100644 (file)
index 0000000..ae607a0
--- /dev/null
@@ -0,0 +1,196 @@
+From 17e1df07df0fbc77696a1e1b6ccf9f2e5af70e40 Mon Sep 17 00:00:00 2001
+From: Daniel Vetter <daniel.vetter@ffwll.ch>
+Date: Sun, 8 Sep 2013 21:57:13 +0200
+Subject: drm/i915: fix wait_for_pending_flips vs gpu hang deadlock
+
+From: Daniel Vetter <daniel.vetter@ffwll.ch>
+
+commit 17e1df07df0fbc77696a1e1b6ccf9f2e5af70e40 upstream.
+
+My g33 here seems to be shockingly good at hitting them all. This time
+around kms_flip/flip-vs-panning-vs-hang blows up:
+
+intel_crtc_wait_for_pending_flips correctly checks for gpu hangs and
+if a gpu hang is pending aborts the wait for outstanding flips so that
+the setcrtc call will succeed and release the crtc mutex. And the gpu
+hang handler needs that lock in intel_display_handle_reset to be able
+to complete outstanding flips.
+
+The problem is that we can race in two ways:
+- Waiters on the dev_priv->pending_flip_queue aren't woken up after
+  we've the reset as pending, but before we actually start the reset
+  work. This means that the waiter doesn't notice the pending reset
+  and hence will keep on hogging the locks.
+
+  Like with dev->struct_mutex and the ring->irq_queue wait queues we
+  there need to wake up everyone that potentially holds a lock which
+  the reset handler needs.
+
+- intel_display_handle_reset was called _after_ we've already
+  signalled the completion of the reset work. Which means a waiter
+  could sneak in, grab the lock and never release it (since the
+  pageflips won't ever get released).
+
+  Similar to resetting the gem state all the reset work must complete
+  before we update the reset counter. Contrary to the gem reset we
+  don't need to have a second explicit wake up call since that will
+  have happened already when completing the pageflips. We also don't
+  have any issues that the completion happens while the reset state is
+  still pending - wait_for_pending_flips is only there to ensure we
+  display the right frame. After a gpu hang&reset events such
+  guarantees are out the window anyway. This is in contrast to the gem
+  code where too-early wake-up would result in unnecessary restarting
+  of ioctls.
+
+Also, since we've gotten these various deadlocks and ordering
+constraints wrong so often throw copious amounts of comments at the
+code.
+
+This deadlock regression has been introduced in the commit which added
+the pageflip reset logic to the gpu hang work:
+
+commit 96a02917a0131e52efefde49c2784c0421d6c439
+Author: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Date:   Mon Feb 18 19:08:49 2013 +0200
+
+    drm/i915: Finish page flips and update primary planes after a GPU reset
+
+v2:
+- Add comments to explain how the wake_up serves as memory barriers
+  for the atomic_t reset counter.
+- Improve the comments a bit as suggested by Chris Wilson.
+- Extract the wake_up calls before/after the reset into a little
+  i915_error_wake_up and unconditionally wake up the
+  pending_flip_queue waiters, again as suggested by Chris Wilson.
+
+v3: Throw copious amounts of comments at i915_error_wake_up as
+suggested by Chris Wilson.
+
+Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Cc: Chris Wilson <chris@chris-wilson.co.uk>
+Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/i915_irq.c |   68 +++++++++++++++++++++++++++++++---------
+ 1 file changed, 54 insertions(+), 14 deletions(-)
+
+--- a/drivers/gpu/drm/i915/i915_irq.c
++++ b/drivers/gpu/drm/i915/i915_irq.c
+@@ -1009,6 +1009,34 @@ done:
+       return ret;
+ }
++static void i915_error_wake_up(struct drm_i915_private *dev_priv,
++                             bool reset_completed)
++{
++      struct intel_ring_buffer *ring;
++      int i;
++
++      /*
++       * Notify all waiters for GPU completion events that reset state has
++       * been changed, and that they need to restart their wait after
++       * checking for potential errors (and bail out to drop locks if there is
++       * a gpu reset pending so that i915_error_work_func can acquire them).
++       */
++
++      /* Wake up __wait_seqno, potentially holding dev->struct_mutex. */
++      for_each_ring(ring, dev_priv, i)
++              wake_up_all(&ring->irq_queue);
++
++      /* Wake up intel_crtc_wait_for_pending_flips, holding crtc->mutex. */
++      wake_up_all(&dev_priv->pending_flip_queue);
++
++      /*
++       * Signal tasks blocked in i915_gem_wait_for_error that the pending
++       * reset state is cleared.
++       */
++      if (reset_completed)
++              wake_up_all(&dev_priv->gpu_error.reset_queue);
++}
++
+ /**
+  * i915_error_work_func - do process context error handling work
+  * @work: work struct
+@@ -1023,11 +1051,10 @@ static void i915_error_work_func(struct
+       drm_i915_private_t *dev_priv = container_of(error, drm_i915_private_t,
+                                                   gpu_error);
+       struct drm_device *dev = dev_priv->dev;
+-      struct intel_ring_buffer *ring;
+       char *error_event[] = { "ERROR=1", NULL };
+       char *reset_event[] = { "RESET=1", NULL };
+       char *reset_done_event[] = { "ERROR=0", NULL };
+-      int i, ret;
++      int ret;
+       kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, error_event);
+@@ -1046,8 +1073,16 @@ static void i915_error_work_func(struct
+               kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE,
+                                  reset_event);
++              /*
++               * All state reset _must_ be completed before we update the
++               * reset counter, for otherwise waiters might miss the reset
++               * pending state and not properly drop locks, resulting in
++               * deadlocks with the reset work.
++               */
+               ret = i915_reset(dev);
++              intel_display_handle_reset(dev);
++
+               if (ret == 0) {
+                       /*
+                        * After all the gem state is reset, increment the reset
+@@ -1068,12 +1103,11 @@ static void i915_error_work_func(struct
+                       atomic_set(&error->reset_counter, I915_WEDGED);
+               }
+-              for_each_ring(ring, dev_priv, i)
+-                      wake_up_all(&ring->irq_queue);
+-
+-              intel_display_handle_reset(dev);
+-
+-              wake_up_all(&dev_priv->gpu_error.reset_queue);
++              /*
++               * Note: The wake_up also serves as a memory barrier so that
++               * waiters see the update value of the reset counter atomic_t.
++               */
++              i915_error_wake_up(dev_priv, true);
+       }
+ }
+@@ -1709,8 +1743,6 @@ static void i915_report_and_clear_eir(st
+ void i915_handle_error(struct drm_device *dev, bool wedged)
+ {
+       struct drm_i915_private *dev_priv = dev->dev_private;
+-      struct intel_ring_buffer *ring;
+-      int i;
+       i915_capture_error_state(dev);
+       i915_report_and_clear_eir(dev);
+@@ -1720,11 +1752,19 @@ void i915_handle_error(struct drm_device
+                               &dev_priv->gpu_error.reset_counter);
+               /*
+-               * Wakeup waiting processes so that the reset work item
+-               * doesn't deadlock trying to grab various locks.
++               * Wakeup waiting processes so that the reset work function
++               * i915_error_work_func doesn't deadlock trying to grab various
++               * locks. By bumping the reset counter first, the woken
++               * processes will see a reset in progress and back off,
++               * releasing their locks and then wait for the reset completion.
++               * We must do this for _all_ gpu waiters that might hold locks
++               * that the reset work needs to acquire.
++               *
++               * Note: The wake_up serves as the required memory barrier to
++               * ensure that the waiters see the updated value of the reset
++               * counter atomic_t.
+                */
+-              for_each_ring(ring, dev_priv, i)
+-                      wake_up_all(&ring->irq_queue);
++              i915_error_wake_up(dev_priv, false);
+       }
+       /*
diff --git a/queue-3.10/drm-nv50-disp-prevent-false-output-detection-on-the-original-nv50.patch b/queue-3.10/drm-nv50-disp-prevent-false-output-detection-on-the-original-nv50.patch
new file mode 100644 (file)
index 0000000..3c32ae7
--- /dev/null
@@ -0,0 +1,58 @@
+From 5087f51da805f53cba7366f70d596e7bde2a5486 Mon Sep 17 00:00:00 2001
+From: Emil Velikov <emil.l.velikov@gmail.com>
+Date: Fri, 23 Aug 2013 18:43:42 +0100
+Subject: drm/nv50/disp: prevent false output detection on the original nv50
+
+From: Emil Velikov <emil.l.velikov@gmail.com>
+
+commit 5087f51da805f53cba7366f70d596e7bde2a5486 upstream.
+
+Commit ea9197cc323839ef3d5280c0453b2c622caa6bc7 effectively enabled the
+use of an improved DAC detection code, but introduced a regression on
+the original nv50 chipset, causing a ghost monitor to be detected.
+
+v2 (Ben Skeggs): the offending line was likely a thinko, removed it for
+all chipsets (tested nv50 and nve6 to cover entire range) and added
+some additional debugging.
+
+Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=67382
+Tested-by: Martin Peres <martin.peres@labri.fr>
+Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c |   15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+--- a/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c
++++ b/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c
+@@ -49,18 +49,23 @@ int
+ nv50_dac_sense(struct nv50_disp_priv *priv, int or, u32 loadval)
+ {
+       const u32 doff = (or * 0x800);
+-      int load = -EINVAL;
++
+       nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80150000);
+       nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000);
++
+       nv_wr32(priv, 0x61a00c + doff, 0x00100000 | loadval);
+       mdelay(9);
+       udelay(500);
+-      nv_wr32(priv, 0x61a00c + doff, 0x80000000);
+-      load = (nv_rd32(priv, 0x61a00c + doff) & 0x38000000) >> 27;
+-      nv_wr32(priv, 0x61a00c + doff, 0x00000000);
++      loadval = nv_mask(priv, 0x61a00c + doff, 0xffffffff, 0x00000000);
++
+       nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80550000);
+       nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000);
+-      return load;
++
++      nv_debug(priv, "DAC%d sense: 0x%08x\n", or, loadval);
++      if (!(loadval & 0x80000000))
++              return -ETIMEDOUT;
++
++      return (loadval & 0x38000000) >> 27;
+ }
+ int
diff --git a/queue-3.10/drm-radeon-fix-endian-bugs-in-hw-i2c-atom-routines.patch b/queue-3.10/drm-radeon-fix-endian-bugs-in-hw-i2c-atom-routines.patch
new file mode 100644 (file)
index 0000000..b658479
--- /dev/null
@@ -0,0 +1,70 @@
+From 4543eda52113d1e2cc0e9bf416f79597e6ef1ec7 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Wed, 7 Aug 2013 19:34:53 -0400
+Subject: drm/radeon: fix endian bugs in hw i2c atom routines
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 4543eda52113d1e2cc0e9bf416f79597e6ef1ec7 upstream.
+
+Need to swap the data fetched over i2c properly.  This
+is the same fix as the endian fix for aux channel
+transactions.
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/atombios_dp.c  |    6 +++---
+ drivers/gpu/drm/radeon/atombios_i2c.c |    4 +++-
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/atombios_dp.c
++++ b/drivers/gpu/drm/radeon/atombios_dp.c
+@@ -50,7 +50,7 @@ static char *pre_emph_names[] = {
+  * or from atom. Note that atom operates on
+  * dw units.
+  */
+-static void radeon_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le)
++void radeon_atom_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le)
+ {
+ #ifdef __BIG_ENDIAN
+       u8 src_tmp[20], dst_tmp[20]; /* used for byteswapping */
+@@ -100,7 +100,7 @@ static int radeon_process_aux_ch(struct
+       base = (unsigned char *)(rdev->mode_info.atom_context->scratch + 1);
+-      radeon_copy_swap(base, send, send_bytes, true);
++      radeon_atom_copy_swap(base, send, send_bytes, true);
+       args.v1.lpAuxRequest = cpu_to_le16((u16)(0 + 4));
+       args.v1.lpDataOut = cpu_to_le16((u16)(16 + 4));
+@@ -137,7 +137,7 @@ static int radeon_process_aux_ch(struct
+               recv_bytes = recv_size;
+       if (recv && recv_size)
+-              radeon_copy_swap(recv, base + 16, recv_bytes, false);
++              radeon_atom_copy_swap(recv, base + 16, recv_bytes, false);
+       return recv_bytes;
+ }
+--- a/drivers/gpu/drm/radeon/atombios_i2c.c
++++ b/drivers/gpu/drm/radeon/atombios_i2c.c
+@@ -27,6 +27,8 @@
+ #include "radeon.h"
+ #include "atom.h"
++extern void radeon_atom_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le);
++
+ #define TARGET_HW_I2C_CLOCK 50
+ /* these are a limitation of ProcessI2cChannelTransaction not the hw */
+@@ -77,7 +79,7 @@ static int radeon_process_i2c_ch(struct
+       }
+       if (!(flags & HW_I2C_WRITE))
+-              memcpy(buf, base, num);
++              radeon_atom_copy_swap(buf, base, num, false);
+       return 0;
+ }
diff --git a/queue-3.10/drm-radeon-fix-lcd-record-parsing.patch b/queue-3.10/drm-radeon-fix-lcd-record-parsing.patch
new file mode 100644 (file)
index 0000000..ff1f9c1
--- /dev/null
@@ -0,0 +1,34 @@
+From 95663948ba22a4be8b99acd67fbf83e86ddffba4 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Tue, 20 Aug 2013 14:59:01 -0400
+Subject: drm/radeon: fix LCD record parsing
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 95663948ba22a4be8b99acd67fbf83e86ddffba4 upstream.
+
+If the LCD table contains an EDID record, properly account
+for the edid size when walking through the records.
+
+This should fix error messages about unknown LCD records.
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon_atombios.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/radeon/radeon_atombios.c
++++ b/drivers/gpu/drm/radeon/radeon_atombios.c
+@@ -1651,7 +1651,9 @@ struct radeon_encoder_atom_dig *radeon_a
+                                                               kfree(edid);
+                                               }
+                                       }
+-                                      record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD);
++                                      record += fake_edid_record->ucFakeEDIDLength ?
++                                              fake_edid_record->ucFakeEDIDLength + 2 :
++                                              sizeof(ATOM_FAKE_EDID_PATCH_RECORD);
+                                       break;
+                               case LCD_PANEL_RESOLUTION_RECORD_TYPE:
+                                       panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;
diff --git a/queue-3.10/drm-ttm-fix-the-tt_populated-check-in-ttm_tt_destroy.patch b/queue-3.10/drm-ttm-fix-the-tt_populated-check-in-ttm_tt_destroy.patch
new file mode 100644 (file)
index 0000000..2d50b77
--- /dev/null
@@ -0,0 +1,43 @@
+From 182b17c8dc4e83aab000ce86587b6810e515da87 Mon Sep 17 00:00:00 2001
+From: Ben Skeggs <bskeggs@redhat.com>
+Date: Tue, 17 Sep 2013 14:21:15 +1000
+Subject: drm/ttm: fix the tt_populated check in ttm_tt_destroy()
+
+From: Ben Skeggs <bskeggs@redhat.com>
+
+commit 182b17c8dc4e83aab000ce86587b6810e515da87 upstream.
+
+After a vmalloc failure in ttm_dma_tt_alloc_page_directory(),
+ttm_dma_tt_init() will call ttm_tt_destroy() to cleanup, and end up
+inside the driver's unpopulate() hook when populate() has never yet
+been called.
+
+On nouveau, the first issue to be hit because of this is that
+dma_address[] may be a NULL pointer.  After working around this,
+ttm_pool_unpopulate() may potentially hit the same issue with
+the pages[] array.
+
+It seems to make more sense to avoid calling unpopulate on already
+unpopulated TTMs than to add checks to all the implementations.
+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
+Cc: Jerome Glisse <jglisse@redhat.com>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/ttm/ttm_tt.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/ttm/ttm_tt.c
++++ b/drivers/gpu/drm/ttm/ttm_tt.c
+@@ -170,7 +170,7 @@ void ttm_tt_destroy(struct ttm_tt *ttm)
+               ttm_tt_unbind(ttm);
+       }
+-      if (likely(ttm->pages != NULL)) {
++      if (ttm->state == tt_unbound) {
+               ttm->bdev->driver->ttm_tt_unpopulate(ttm);
+       }
index febc7554fa6e3fec476224fd09d598a28f8cf529..e86a2ecaf7948d2416393885fb82cd5b5f12eec5 100644 (file)
@@ -16,3 +16,11 @@ hid-steelseries-validate-output-report-details.patch
 hid-lenovo-tpkbd-validate-output-report-details.patch
 hid-logitech-dj-validate-output-report-details.patch
 usb-gadget-fix-a-bug-and-a-warn_on-in-dummy-hcd.patch
+drm-i915-fix-gpu-hang-vs.-flip-stall-deadlocks.patch
+drm-i915-fix-wait_for_pending_flips-vs-gpu-hang-deadlock.patch
+drm-fix-drm_ioctl_mode_getfb-handle-leak.patch
+drm-ast-fix-the-ast-open-key-function.patch
+drm-ttm-fix-the-tt_populated-check-in-ttm_tt_destroy.patch
+drm-nv50-disp-prevent-false-output-detection-on-the-original-nv50.patch
+drm-radeon-fix-lcd-record-parsing.patch
+drm-radeon-fix-endian-bugs-in-hw-i2c-atom-routines.patch