]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 9 Sep 2016 16:06:56 +0000 (18:06 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 9 Sep 2016 16:06:56 +0000 (18:06 +0200)
added patches:
asoc-atmel_ssc_dai-don-t-unconditionally-reset-ssc-on-stream-startup.patch
drm-msm-fix-use-of-copy_from_user-while-holding-spinlock.patch
drm-radeon-fix-radeon_move_blit-on-32bit-systems.patch
drm-reject-page_flip-for-driver_modeset.patch
timekeeping-avoid-taking-lock-in-nmi-path-with-config_debug_timekeeping.patch
timekeeping-cap-array-access-in-timekeeping_debug.patch
xfs-fix-superblock-inprogress-check.patch

queue-4.4/asoc-atmel_ssc_dai-don-t-unconditionally-reset-ssc-on-stream-startup.patch [new file with mode: 0644]
queue-4.4/drm-msm-fix-use-of-copy_from_user-while-holding-spinlock.patch [new file with mode: 0644]
queue-4.4/drm-radeon-fix-radeon_move_blit-on-32bit-systems.patch [new file with mode: 0644]
queue-4.4/drm-reject-page_flip-for-driver_modeset.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/timekeeping-avoid-taking-lock-in-nmi-path-with-config_debug_timekeeping.patch [new file with mode: 0644]
queue-4.4/timekeeping-cap-array-access-in-timekeeping_debug.patch [new file with mode: 0644]
queue-4.4/xfs-fix-superblock-inprogress-check.patch [new file with mode: 0644]

diff --git a/queue-4.4/asoc-atmel_ssc_dai-don-t-unconditionally-reset-ssc-on-stream-startup.patch b/queue-4.4/asoc-atmel_ssc_dai-don-t-unconditionally-reset-ssc-on-stream-startup.patch
new file mode 100644 (file)
index 0000000..57a26fa
--- /dev/null
@@ -0,0 +1,38 @@
+From 3e103a65514c2947e53f3171b21255fbde8b60c6 Mon Sep 17 00:00:00 2001
+From: Christoph Huber <c.huber@bct-electronic.com>
+Date: Mon, 15 Aug 2016 18:59:25 +0200
+Subject: ASoC: atmel_ssc_dai: Don't unconditionally reset SSC on stream startup
+
+From: Christoph Huber <c.huber@bct-electronic.com>
+
+commit 3e103a65514c2947e53f3171b21255fbde8b60c6 upstream.
+
+commit cbaadf0f90d6 ("ASoC: atmel_ssc_dai: refactor the startup and
+shutdown") refactored code such that the SSC is reset on every
+startup; this breaks duplex audio (e.g. first start audio playback,
+then start record, causing the playback to stop/hang)
+
+Fixes: cbaadf0f90d6 (ASoC: atmel_ssc_dai: refactor the startup and shutdown)
+Signed-off-by: Christoph Huber <c.huber@bct-electronic.com>
+Signed-off-by: Peter Meerwald-Stadler <p.meerwald@bct-electronic.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/soc/atmel/atmel_ssc_dai.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/sound/soc/atmel/atmel_ssc_dai.c
++++ b/sound/soc/atmel/atmel_ssc_dai.c
+@@ -298,8 +298,9 @@ static int atmel_ssc_startup(struct snd_
+       clk_enable(ssc_p->ssc->clk);
+       ssc_p->mck_rate = clk_get_rate(ssc_p->ssc->clk);
+-      /* Reset the SSC to keep it at a clean status */
+-      ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
++      /* Reset the SSC unless initialized to keep it in a clean state */
++      if (!ssc_p->initialized)
++              ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+               dir = 0;
diff --git a/queue-4.4/drm-msm-fix-use-of-copy_from_user-while-holding-spinlock.patch b/queue-4.4/drm-msm-fix-use-of-copy_from_user-while-holding-spinlock.patch
new file mode 100644 (file)
index 0000000..dc398eb
--- /dev/null
@@ -0,0 +1,79 @@
+From 89f82cbb0d5c0ab768c8d02914188aa2211cd2e3 Mon Sep 17 00:00:00 2001
+From: Rob Clark <robdclark@gmail.com>
+Date: Mon, 22 Aug 2016 15:15:23 -0400
+Subject: drm/msm: fix use of copy_from_user() while holding spinlock
+
+From: Rob Clark <robdclark@gmail.com>
+
+commit 89f82cbb0d5c0ab768c8d02914188aa2211cd2e3 upstream.
+
+Use instead __copy_from_user_inatomic() and fallback to slow-path where
+we drop and re-aquire the lock in case of fault.
+
+Reported-by: Vaishali Thakkar <vaishali.thakkar@oracle.com>
+Signed-off-by: Rob Clark <robdclark@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/msm/msm_gem_submit.c |   27 ++++++++++++++++++++++-----
+ 1 file changed, 22 insertions(+), 5 deletions(-)
+
+--- a/drivers/gpu/drm/msm/msm_gem_submit.c
++++ b/drivers/gpu/drm/msm/msm_gem_submit.c
+@@ -55,6 +55,14 @@ static struct msm_gem_submit *submit_cre
+       return submit;
+ }
++static inline unsigned long __must_check
++copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
++{
++      if (access_ok(VERIFY_READ, from, n))
++              return __copy_from_user_inatomic(to, from, n);
++      return -EFAULT;
++}
++
+ static int submit_lookup_objects(struct msm_gem_submit *submit,
+               struct drm_msm_gem_submit *args, struct drm_file *file)
+ {
+@@ -62,6 +70,7 @@ static int submit_lookup_objects(struct
+       int ret = 0;
+       spin_lock(&file->table_lock);
++      pagefault_disable();
+       for (i = 0; i < args->nr_bos; i++) {
+               struct drm_msm_gem_submit_bo submit_bo;
+@@ -70,10 +79,15 @@ static int submit_lookup_objects(struct
+               void __user *userptr =
+                       to_user_ptr(args->bos + (i * sizeof(submit_bo)));
+-              ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo));
+-              if (ret) {
+-                      ret = -EFAULT;
+-                      goto out_unlock;
++              ret = copy_from_user_inatomic(&submit_bo, userptr, sizeof(submit_bo));
++              if (unlikely(ret)) {
++                      pagefault_enable();
++                      spin_unlock(&file->table_lock);
++                      ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo));
++                      if (ret)
++                              goto out;
++                      spin_lock(&file->table_lock);
++                      pagefault_disable();
+               }
+               if (submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) {
+@@ -113,9 +127,12 @@ static int submit_lookup_objects(struct
+       }
+ out_unlock:
+-      submit->nr_bos = i;
++      pagefault_enable();
+       spin_unlock(&file->table_lock);
++out:
++      submit->nr_bos = i;
++
+       return ret;
+ }
diff --git a/queue-4.4/drm-radeon-fix-radeon_move_blit-on-32bit-systems.patch b/queue-4.4/drm-radeon-fix-radeon_move_blit-on-32bit-systems.patch
new file mode 100644 (file)
index 0000000..8be29b9
--- /dev/null
@@ -0,0 +1,36 @@
+From 13f479b9df4e2bbf2d16e7e1b02f3f55f70e2455 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Wed, 17 Aug 2016 09:46:42 +0200
+Subject: drm/radeon: fix radeon_move_blit on 32bit systems
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Christian König <christian.koenig@amd.com>
+
+commit 13f479b9df4e2bbf2d16e7e1b02f3f55f70e2455 upstream.
+
+This bug seems to be present for a very long time.
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon_ttm.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/radeon_ttm.c
++++ b/drivers/gpu/drm/radeon/radeon_ttm.c
+@@ -263,8 +263,8 @@ static int radeon_move_blit(struct ttm_b
+       rdev = radeon_get_rdev(bo->bdev);
+       ridx = radeon_copy_ring_index(rdev);
+-      old_start = old_mem->start << PAGE_SHIFT;
+-      new_start = new_mem->start << PAGE_SHIFT;
++      old_start = (u64)old_mem->start << PAGE_SHIFT;
++      new_start = (u64)new_mem->start << PAGE_SHIFT;
+       switch (old_mem->mem_type) {
+       case TTM_PL_VRAM:
diff --git a/queue-4.4/drm-reject-page_flip-for-driver_modeset.patch b/queue-4.4/drm-reject-page_flip-for-driver_modeset.patch
new file mode 100644 (file)
index 0000000..4cb9405
--- /dev/null
@@ -0,0 +1,37 @@
+From 6f00975c619064a18c23fd3aced325ae165a73b9 Mon Sep 17 00:00:00 2001
+From: Daniel Vetter <daniel.vetter@ffwll.ch>
+Date: Sat, 20 Aug 2016 12:22:11 +0200
+Subject: drm: Reject page_flip for !DRIVER_MODESET
+
+From: Daniel Vetter <daniel.vetter@ffwll.ch>
+
+commit 6f00975c619064a18c23fd3aced325ae165a73b9 upstream.
+
+Somehow this one slipped through, which means drivers without modeset
+support can be oopsed (since those also don't call
+drm_mode_config_init, which means the crtc lookup will chase an
+uninitalized idr).
+
+Reported-by: Alexander Potapenko <glider@google.com>
+Cc: Alexander Potapenko <glider@google.com>
+Signed-off-by: Daniel Vetter <daniel.vetter@intel.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 |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/gpu/drm/drm_crtc.c
++++ b/drivers/gpu/drm/drm_crtc.c
+@@ -5231,6 +5231,9 @@ int drm_mode_page_flip_ioctl(struct drm_
+       unsigned long flags;
+       int ret = -EINVAL;
++      if (!drm_core_check_feature(dev, DRIVER_MODESET))
++              return -EINVAL;
++
+       if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS ||
+           page_flip->reserved != 0)
+               return -EINVAL;
index 62c8c2b8d0c13644bc9adfc5d706350737ab0d55..758f7808c85242b9c936f0e1e9c066aec21ce13e 100644 (file)
@@ -158,3 +158,10 @@ nvme-call-pci_disable_device-on-the-error-path.patch
 powerpc-tm-avoid-slb-faults-in-treclaim-trecheckpoint-when-ri-0.patch
 rds-fix-an-infoleak-in-rds_inc_info_copy.patch
 s390-sclp_ctl-fix-potential-information-leak-with-dev-sclp.patch
+drm-radeon-fix-radeon_move_blit-on-32bit-systems.patch
+drm-reject-page_flip-for-driver_modeset.patch
+drm-msm-fix-use-of-copy_from_user-while-holding-spinlock.patch
+asoc-atmel_ssc_dai-don-t-unconditionally-reset-ssc-on-stream-startup.patch
+xfs-fix-superblock-inprogress-check.patch
+timekeeping-cap-array-access-in-timekeeping_debug.patch
+timekeeping-avoid-taking-lock-in-nmi-path-with-config_debug_timekeeping.patch
diff --git a/queue-4.4/timekeeping-avoid-taking-lock-in-nmi-path-with-config_debug_timekeeping.patch b/queue-4.4/timekeeping-avoid-taking-lock-in-nmi-path-with-config_debug_timekeeping.patch
new file mode 100644 (file)
index 0000000..3b89838
--- /dev/null
@@ -0,0 +1,45 @@
+From 27727df240c7cc84f2ba6047c6f18d5addfd25ef Mon Sep 17 00:00:00 2001
+From: John Stultz <john.stultz@linaro.org>
+Date: Tue, 23 Aug 2016 16:08:21 -0700
+Subject: timekeeping: Avoid taking lock in NMI path with CONFIG_DEBUG_TIMEKEEPING
+
+From: John Stultz <john.stultz@linaro.org>
+
+commit 27727df240c7cc84f2ba6047c6f18d5addfd25ef upstream.
+
+When I added some extra sanity checking in timekeeping_get_ns() under
+CONFIG_DEBUG_TIMEKEEPING, I missed that the NMI safe __ktime_get_fast_ns()
+method was using timekeeping_get_ns().
+
+Thus the locking added to the debug checks broke the NMI-safety of
+__ktime_get_fast_ns().
+
+This patch open-codes the timekeeping_get_ns() logic for
+__ktime_get_fast_ns(), so can avoid any deadlocks in NMI.
+
+Fixes: 4ca22c2648f9 "timekeeping: Add warnings when overflows or underflows are observed"
+Reported-by: Steven Rostedt <rostedt@goodmis.org>
+Reported-by: Peter Zijlstra <peterz@infradead.org>
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Link: http://lkml.kernel.org/r/1471993702-29148-2-git-send-email-john.stultz@linaro.org
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/time/timekeeping.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/kernel/time/timekeeping.c
++++ b/kernel/time/timekeeping.c
+@@ -383,7 +383,10 @@ static __always_inline u64 __ktime_get_f
+       do {
+               seq = raw_read_seqcount_latch(&tkf->seq);
+               tkr = tkf->base + (seq & 0x01);
+-              now = ktime_to_ns(tkr->base) + timekeeping_get_ns(tkr);
++              now = ktime_to_ns(tkr->base);
++
++              now += clocksource_delta(tkr->read(tkr->clock),
++                                       tkr->cycle_last, tkr->mask);
+       } while (read_seqcount_retry(&tkf->seq, seq));
+       return now;
diff --git a/queue-4.4/timekeeping-cap-array-access-in-timekeeping_debug.patch b/queue-4.4/timekeeping-cap-array-access-in-timekeeping_debug.patch
new file mode 100644 (file)
index 0000000..9faefd8
--- /dev/null
@@ -0,0 +1,83 @@
+From a4f8f6667f099036c88f231dcad4cf233652c824 Mon Sep 17 00:00:00 2001
+From: John Stultz <john.stultz@linaro.org>
+Date: Tue, 23 Aug 2016 16:08:22 -0700
+Subject: timekeeping: Cap array access in timekeeping_debug
+
+From: John Stultz <john.stultz@linaro.org>
+
+commit a4f8f6667f099036c88f231dcad4cf233652c824 upstream.
+
+It was reported that hibernation could fail on the 2nd attempt, where the
+system hangs at hibernate() -> syscore_resume() -> i8237A_resume() ->
+claim_dma_lock(), because the lock has already been taken.
+
+However there is actually no other process would like to grab this lock on
+that problematic platform.
+
+Further investigation showed that the problem is triggered by setting
+/sys/power/pm_trace to 1 before the 1st hibernation.
+
+Since once pm_trace is enabled, the rtc becomes unmeaningful after suspend,
+and meanwhile some BIOSes would like to adjust the 'invalid' RTC (e.g, smaller
+than 1970) to the release date of that motherboard during POST stage, thus
+after resumed, it may seem that the system had a significant long sleep time
+which is a completely meaningless value.
+
+Then in timekeeping_resume -> tk_debug_account_sleep_time, if the bit31 of the
+sleep time happened to be set to 1, fls() returns 32 and we add 1 to
+sleep_time_bin[32], which causes an out of bounds array access and therefor
+memory being overwritten.
+
+As depicted by System.map:
+0xffffffff81c9d080 b sleep_time_bin
+0xffffffff81c9d100 B dma_spin_lock
+the dma_spin_lock.val is set to 1, which caused this problem.
+
+This patch adds a sanity check in tk_debug_account_sleep_time()
+to ensure we don't index past the sleep_time_bin array.
+
+[jstultz: Problem diagnosed and original patch by Chen Yu, I've solved the
+ issue slightly differently, but borrowed his excelent explanation of the
+ issue here.]
+
+Fixes: 5c83545f24ab "power: Add option to log time spent in suspend"
+Reported-by: Janek Kozicki <cosurgi@gmail.com>
+Reported-by: Chen Yu <yu.c.chen@intel.com>
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Cc: linux-pm@vger.kernel.org
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Xunlei Pang <xpang@redhat.com>
+Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
+Cc: Zhang Rui <rui.zhang@intel.com>
+Link: http://lkml.kernel.org/r/1471993702-29148-3-git-send-email-john.stultz@linaro.org
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/time/timekeeping_debug.c |    9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/kernel/time/timekeeping_debug.c
++++ b/kernel/time/timekeeping_debug.c
+@@ -23,7 +23,9 @@
+ #include "timekeeping_internal.h"
+-static unsigned int sleep_time_bin[32] = {0};
++#define NUM_BINS 32
++
++static unsigned int sleep_time_bin[NUM_BINS] = {0};
+ static int tk_debug_show_sleep_time(struct seq_file *s, void *data)
+ {
+@@ -69,6 +71,9 @@ late_initcall(tk_debug_sleep_time_init);
+ void tk_debug_account_sleep_time(struct timespec64 *t)
+ {
+-      sleep_time_bin[fls(t->tv_sec)]++;
++      /* Cap bin index so we don't overflow the array */
++      int bin = min(fls(t->tv_sec), NUM_BINS-1);
++
++      sleep_time_bin[bin]++;
+ }
diff --git a/queue-4.4/xfs-fix-superblock-inprogress-check.patch b/queue-4.4/xfs-fix-superblock-inprogress-check.patch
new file mode 100644 (file)
index 0000000..f40f882
--- /dev/null
@@ -0,0 +1,42 @@
+From f3d7ebdeb2c297bd26272384e955033493ca291c Mon Sep 17 00:00:00 2001
+From: Dave Chinner <dchinner@redhat.com>
+Date: Fri, 26 Aug 2016 16:01:30 +1000
+Subject: xfs: fix superblock inprogress check
+
+From: Dave Chinner <dchinner@redhat.com>
+
+commit f3d7ebdeb2c297bd26272384e955033493ca291c upstream.
+
+From inspection, the superblock sb_inprogress check is done in the
+verifier and triggered only for the primary superblock via a
+"bp->b_bn == XFS_SB_DADDR" check.
+
+Unfortunately, the primary superblock is an uncached buffer, and
+hence it is configured by xfs_buf_read_uncached() with:
+
+       bp->b_bn = XFS_BUF_DADDR_NULL;  /* always null for uncached buffers */
+
+And so this check never triggers. Fix it.
+
+Signed-off-by: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Dave Chinner <david@fromorbit.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/xfs/libxfs/xfs_sb.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/xfs/libxfs/xfs_sb.c
++++ b/fs/xfs/libxfs/xfs_sb.c
+@@ -581,7 +581,8 @@ xfs_sb_verify(
+        * Only check the in progress field for the primary superblock as
+        * mkfs.xfs doesn't clear it from secondary superblocks.
+        */
+-      return xfs_mount_validate_sb(mp, &sb, bp->b_bn == XFS_SB_DADDR,
++      return xfs_mount_validate_sb(mp, &sb,
++                                   bp->b_maps[0].bm_bn == XFS_SB_DADDR,
+                                    check_version);
+ }