]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.6-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 22 Jun 2016 05:22:55 +0000 (22:22 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 22 Jun 2016 05:22:55 +0000 (22:22 -0700)
added patches:
drm-core-do-not-preserve-framebuffer-on-rmfb-v4.patch
gpio-zynq-fix-the-error-path.patch
gpio-zynq-initialize-clock-even-without-config_pm.patch

queue-4.6/drm-core-do-not-preserve-framebuffer-on-rmfb-v4.patch [new file with mode: 0644]
queue-4.6/gpio-zynq-fix-the-error-path.patch [new file with mode: 0644]
queue-4.6/gpio-zynq-initialize-clock-even-without-config_pm.patch [new file with mode: 0644]
queue-4.6/series

diff --git a/queue-4.6/drm-core-do-not-preserve-framebuffer-on-rmfb-v4.patch b/queue-4.6/drm-core-do-not-preserve-framebuffer-on-rmfb-v4.patch
new file mode 100644 (file)
index 0000000..692df79
--- /dev/null
@@ -0,0 +1,143 @@
+From f2d580b9a8149735cbc4b59c4a8df60173658140 Mon Sep 17 00:00:00 2001
+From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+Date: Wed, 4 May 2016 14:38:26 +0200
+Subject: drm/core: Do not preserve framebuffer on rmfb, v4.
+
+From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+
+commit f2d580b9a8149735cbc4b59c4a8df60173658140 upstream.
+
+It turns out that preserving framebuffers after the rmfb call breaks
+vmwgfx userspace. This was originally introduced because it was thought
+nobody relied on the behavior, but unfortunately it seems there are
+exceptions.
+
+drm_framebuffer_remove may fail with -EINTR now, so a straight revert
+is impossible. There is no way to remove the framebuffer from the lists
+and active planes without introducing a race because of the different
+locking requirements. Instead call drm_framebuffer_remove from a
+workqueue, which is unaffected by signals.
+
+Changes since v1:
+- Add comment.
+Changes since v2:
+- Add fastpath for refcount = 1. (danvet)
+Changes since v3:
+- Rebased.
+- Restore lastclose framebuffer removal too.
+
+Fixes: 13803132818c ("drm/core: Preserve the framebuffer after removing it.")
+Testcase: kms_rmfb_basic
+References: https://lists.freedesktop.org/archives/dri-devel/2016-March/102876.html
+Cc: Thomas Hellstrom <thellstrom@vmware.com>
+Cc: David Herrmann <dh.herrmann@gmail.com>
+Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Tested-by: Thomas Hellstrom <thellstrom@vmware.com> #v3
+Tested-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Link: http://patchwork.freedesktop.org/patch/msgid/6c63ca37-0e7e-ac7f-a6d2-c7822e3d611f@linux.intel.com
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/drm_crtc.c |   60 +++++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 55 insertions(+), 5 deletions(-)
+
+--- a/drivers/gpu/drm/drm_crtc.c
++++ b/drivers/gpu/drm/drm_crtc.c
+@@ -3434,6 +3434,24 @@ int drm_mode_addfb2(struct drm_device *d
+       return 0;
+ }
++struct drm_mode_rmfb_work {
++      struct work_struct work;
++      struct list_head fbs;
++};
++
++static void drm_mode_rmfb_work_fn(struct work_struct *w)
++{
++      struct drm_mode_rmfb_work *arg = container_of(w, typeof(*arg), work);
++
++      while (!list_empty(&arg->fbs)) {
++              struct drm_framebuffer *fb =
++                      list_first_entry(&arg->fbs, typeof(*fb), filp_head);
++
++              list_del_init(&fb->filp_head);
++              drm_framebuffer_remove(fb);
++      }
++}
++
+ /**
+  * drm_mode_rmfb - remove an FB from the configuration
+  * @dev: drm device for the ioctl
+@@ -3474,7 +3492,25 @@ int drm_mode_rmfb(struct drm_device *dev
+       mutex_unlock(&dev->mode_config.fb_lock);
+       mutex_unlock(&file_priv->fbs_lock);
+-      drm_framebuffer_unreference(fb);
++      /*
++       * we now own the reference that was stored in the fbs list
++       *
++       * drm_framebuffer_remove may fail with -EINTR on pending signals,
++       * so run this in a separate stack as there's no way to correctly
++       * handle this after the fb is already removed from the lookup table.
++       */
++      if (atomic_read(&fb->refcount.refcount) > 1) {
++              struct drm_mode_rmfb_work arg;
++
++              INIT_WORK_ONSTACK(&arg.work, drm_mode_rmfb_work_fn);
++              INIT_LIST_HEAD(&arg.fbs);
++              list_add_tail(&fb->filp_head, &arg.fbs);
++
++              schedule_work(&arg.work);
++              flush_work(&arg.work);
++              destroy_work_on_stack(&arg.work);
++      } else
++              drm_framebuffer_unreference(fb);
+       return 0;
+@@ -3627,7 +3663,6 @@ out_err1:
+       return ret;
+ }
+-
+ /**
+  * drm_fb_release - remove and free the FBs on this file
+  * @priv: drm file for the ioctl
+@@ -3642,6 +3677,9 @@ out_err1:
+ void drm_fb_release(struct drm_file *priv)
+ {
+       struct drm_framebuffer *fb, *tfb;
++      struct drm_mode_rmfb_work arg;
++
++      INIT_LIST_HEAD(&arg.fbs);
+       /*
+        * When the file gets released that means no one else can access the fb
+@@ -3654,10 +3692,22 @@ void drm_fb_release(struct drm_file *pri
+        * at it any more.
+        */
+       list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
+-              list_del_init(&fb->filp_head);
++              if (atomic_read(&fb->refcount.refcount) > 1) {
++                      list_move_tail(&fb->filp_head, &arg.fbs);
++              } else {
++                      list_del_init(&fb->filp_head);
+-              /* This drops the fpriv->fbs reference. */
+-              drm_framebuffer_unreference(fb);
++                      /* This drops the fpriv->fbs reference. */
++                      drm_framebuffer_unreference(fb);
++              }
++      }
++
++      if (!list_empty(&arg.fbs)) {
++              INIT_WORK_ONSTACK(&arg.work, drm_mode_rmfb_work_fn);
++
++              schedule_work(&arg.work);
++              flush_work(&arg.work);
++              destroy_work_on_stack(&arg.work);
+       }
+ }
diff --git a/queue-4.6/gpio-zynq-fix-the-error-path.patch b/queue-4.6/gpio-zynq-fix-the-error-path.patch
new file mode 100644 (file)
index 0000000..5b9ca64
--- /dev/null
@@ -0,0 +1,42 @@
+From 615d23f80efc60f8c5146223f305d19207c742e4 Mon Sep 17 00:00:00 2001
+From: Shubhrajyoti Datta <shubhrajyoti.datta@xilinx.com>
+Date: Mon, 4 Apr 2016 23:44:06 +0530
+Subject: gpio: zynq: Fix the error path
+
+From: Shubhrajyoti Datta <shubhrajyoti.datta@xilinx.com>
+
+commit 615d23f80efc60f8c5146223f305d19207c742e4 upstream.
+
+pm_runtime_disable is called only in remove it is missed
+out in the error path.
+Fix the same.
+
+Signed-off-by: Shubhrajyoti Datta <shubhraj@xilinx.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Cc: Helmut Grohne <h.grohne@intenta.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpio/gpio-zynq.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpio/gpio-zynq.c
++++ b/drivers/gpio/gpio-zynq.c
+@@ -713,7 +713,7 @@ static int zynq_gpio_probe(struct platfo
+       pm_runtime_enable(&pdev->dev);
+       ret = pm_runtime_get_sync(&pdev->dev);
+       if (ret < 0)
+-              return ret;
++              goto err_pm_dis;
+       /* report a bug if gpio chip registration fails */
+       ret = gpiochip_add_data(chip, gpio);
+@@ -745,6 +745,8 @@ err_rm_gpiochip:
+       gpiochip_remove(chip);
+ err_pm_put:
+       pm_runtime_put(&pdev->dev);
++err_pm_dis:
++      pm_runtime_disable(&pdev->dev);
+       return ret;
+ }
diff --git a/queue-4.6/gpio-zynq-initialize-clock-even-without-config_pm.patch b/queue-4.6/gpio-zynq-initialize-clock-even-without-config_pm.patch
new file mode 100644 (file)
index 0000000..65796ff
--- /dev/null
@@ -0,0 +1,51 @@
+From 0f84f29ff30bdb1bca23017b118b4ea3999cac32 Mon Sep 17 00:00:00 2001
+From: Helmut Grohne <h.grohne@intenta.de>
+Date: Fri, 3 Jun 2016 14:15:32 +0200
+Subject: gpio: zynq: initialize clock even without CONFIG_PM
+
+From: Helmut Grohne <h.grohne@intenta.de>
+
+commit 0f84f29ff30bdb1bca23017b118b4ea3999cac32 upstream.
+
+When the PM initialization was moved in the commit referenced below, the
+code enabling the clock was removed from the probe function. On
+CONFIG_PM=y kernels, this is not a problem as the pm resume hook enables
+the clock, but when power management is disabled, all those pm_*
+functions are noops and the clock is never enabled resulting in a
+dysfunctional gpio controller.
+
+Put the clock initialization back to support CONFIG_PM=n.
+
+Signed-off-by: Helmut Grohne <h.grohne@intenta.de>
+Fixes: 3773c195d387 ("gpio: zynq: Do PM initialization earlier to support gpio hogs")
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpio/gpio-zynq.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/gpio/gpio-zynq.c
++++ b/drivers/gpio/gpio-zynq.c
+@@ -709,7 +709,13 @@ static int zynq_gpio_probe(struct platfo
+               dev_err(&pdev->dev, "input clock not found.\n");
+               return PTR_ERR(gpio->clk);
+       }
++      ret = clk_prepare_enable(gpio->clk);
++      if (ret) {
++              dev_err(&pdev->dev, "Unable to enable clock.\n");
++              return ret;
++      }
++      pm_runtime_set_active(&pdev->dev);
+       pm_runtime_enable(&pdev->dev);
+       ret = pm_runtime_get_sync(&pdev->dev);
+       if (ret < 0)
+@@ -747,6 +753,7 @@ err_pm_put:
+       pm_runtime_put(&pdev->dev);
+ err_pm_dis:
+       pm_runtime_disable(&pdev->dev);
++      clk_disable_unprepare(gpio->clk);
+       return ret;
+ }
index ff0c26fb18a76def1c05d996781ccf5f535e664f..a497f00ad2eaea9f3cb297db24e9d24df5fd42ae 100644 (file)
@@ -65,3 +65,6 @@ sparc64-reduce-tlb-flushes-during-hugepte-changes.patch
 sparc64-take-ctx_alloc_lock-properly-in-hugetlb_setup.patch
 sparc-harden-signal-return-frame-checks.patch
 sparc64-fix-return-from-trap-window-fill-crashes.patch
+gpio-zynq-fix-the-error-path.patch
+gpio-zynq-initialize-clock-even-without-config_pm.patch
+drm-core-do-not-preserve-framebuffer-on-rmfb-v4.patch