]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 18 Apr 2017 18:34:23 +0000 (20:34 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 18 Apr 2017 18:34:23 +0000 (20:34 +0200)
added patches:
alsa-seq-fix-race-during-fifo-resize.patch
alsa-seq-fix-racy-cell-insertions-during-snd_seq_pool_done.patch
c6x-ptrace-remove-useless-ptrace_setregset-implementation.patch
drivers-hv-balloon-don-t-crash-when-memory-is-added-in-non-sorted-order.patch
drm-ttm-drm-vmwgfx-relax-permission-checking-when-opening-surfaces.patch
drm-vmwgfx-avoid-calling-vzalloc-with-a-0-size-in-vmw_get_cap_3d_ioctl.patch
drm-vmwgfx-fix-integer-overflow-in-vmw_surface_define_ioctl.patch
drm-vmwgfx-null-pointer-dereference-in-vmw_surface_define_ioctl.patch
drm-vmwgfx-remove-getparam-error-message.patch
drm-vmwgfx-type-check-lookups-of-fence-objects.patch
metag-ptrace-preserve-previous-registers-for-short-regset-write.patch
metag-ptrace-provide-default-txstatus-for-short-nt_prstatus.patch
metag-ptrace-reject-partial-nt_metag_rpipe-writes.patch
mips-ptrace-preserve-previous-registers-for-short-regset-write.patch
powerpc-boot-fix-zimage-toc-alignment.patch
powerpc-don-t-try-to-fix-up-misaligned-load-with-reservation-instructions.patch
powerpc-mm-add-missing-global-tlb-invalidate-if-cxl-is-active.patch
ptrace-fix-ptrace_listen-race-corrupting-task-state.patch
reset-treeid-to-zero-on-smb2-tree_connect.patch
rtc-s35390a-fix-reading-out-alarm.patch
rtc-s35390a-implement-reset-routine-as-suggested-by-the-reference.patch
rtc-s35390a-improve-irq-handling.patch
rtc-s35390a-make-sure-all-members-in-the-output-are-set.patch
s390-decompressor-fix-initrd-corruption-caused-by-bss-clear.patch
s390-uaccess-get_user-should-zero-on-failure-again.patch
sparc-ptrace-preserve-previous-registers-for-short-regset-write.patch

27 files changed:
queue-3.18/alsa-seq-fix-race-during-fifo-resize.patch [new file with mode: 0644]
queue-3.18/alsa-seq-fix-racy-cell-insertions-during-snd_seq_pool_done.patch [new file with mode: 0644]
queue-3.18/c6x-ptrace-remove-useless-ptrace_setregset-implementation.patch [new file with mode: 0644]
queue-3.18/drivers-hv-balloon-don-t-crash-when-memory-is-added-in-non-sorted-order.patch [new file with mode: 0644]
queue-3.18/drm-ttm-drm-vmwgfx-relax-permission-checking-when-opening-surfaces.patch [new file with mode: 0644]
queue-3.18/drm-vmwgfx-avoid-calling-vzalloc-with-a-0-size-in-vmw_get_cap_3d_ioctl.patch [new file with mode: 0644]
queue-3.18/drm-vmwgfx-fix-integer-overflow-in-vmw_surface_define_ioctl.patch [new file with mode: 0644]
queue-3.18/drm-vmwgfx-null-pointer-dereference-in-vmw_surface_define_ioctl.patch [new file with mode: 0644]
queue-3.18/drm-vmwgfx-remove-getparam-error-message.patch [new file with mode: 0644]
queue-3.18/drm-vmwgfx-type-check-lookups-of-fence-objects.patch [new file with mode: 0644]
queue-3.18/metag-ptrace-preserve-previous-registers-for-short-regset-write.patch [new file with mode: 0644]
queue-3.18/metag-ptrace-provide-default-txstatus-for-short-nt_prstatus.patch [new file with mode: 0644]
queue-3.18/metag-ptrace-reject-partial-nt_metag_rpipe-writes.patch [new file with mode: 0644]
queue-3.18/mips-ptrace-preserve-previous-registers-for-short-regset-write.patch [new file with mode: 0644]
queue-3.18/powerpc-boot-fix-zimage-toc-alignment.patch [new file with mode: 0644]
queue-3.18/powerpc-don-t-try-to-fix-up-misaligned-load-with-reservation-instructions.patch [new file with mode: 0644]
queue-3.18/powerpc-mm-add-missing-global-tlb-invalidate-if-cxl-is-active.patch [new file with mode: 0644]
queue-3.18/ptrace-fix-ptrace_listen-race-corrupting-task-state.patch [new file with mode: 0644]
queue-3.18/reset-treeid-to-zero-on-smb2-tree_connect.patch [new file with mode: 0644]
queue-3.18/rtc-s35390a-fix-reading-out-alarm.patch [new file with mode: 0644]
queue-3.18/rtc-s35390a-implement-reset-routine-as-suggested-by-the-reference.patch [new file with mode: 0644]
queue-3.18/rtc-s35390a-improve-irq-handling.patch [new file with mode: 0644]
queue-3.18/rtc-s35390a-make-sure-all-members-in-the-output-are-set.patch [new file with mode: 0644]
queue-3.18/s390-decompressor-fix-initrd-corruption-caused-by-bss-clear.patch [new file with mode: 0644]
queue-3.18/s390-uaccess-get_user-should-zero-on-failure-again.patch [new file with mode: 0644]
queue-3.18/series
queue-3.18/sparc-ptrace-preserve-previous-registers-for-short-regset-write.patch [new file with mode: 0644]

diff --git a/queue-3.18/alsa-seq-fix-race-during-fifo-resize.patch b/queue-3.18/alsa-seq-fix-race-during-fifo-resize.patch
new file mode 100644 (file)
index 0000000..858b050
--- /dev/null
@@ -0,0 +1,38 @@
+From 2d7d54002e396c180db0c800c1046f0a3c471597 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Fri, 24 Mar 2017 17:07:57 +0100
+Subject: ALSA: seq: Fix race during FIFO resize
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 2d7d54002e396c180db0c800c1046f0a3c471597 upstream.
+
+When a new event is queued while processing to resize the FIFO in
+snd_seq_fifo_clear(), it may lead to a use-after-free, as the old pool
+that is being queued gets removed.  For avoiding this race, we need to
+close the pool to be deleted and sync its usage before actually
+deleting it.
+
+The issue was spotted by syzkaller.
+
+Reported-by: Dmitry Vyukov <dvyukov@google.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/seq/seq_fifo.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/sound/core/seq/seq_fifo.c
++++ b/sound/core/seq/seq_fifo.c
+@@ -262,6 +262,10 @@ int snd_seq_fifo_resize(struct snd_seq_f
+       /* NOTE: overflow flag is not cleared */
+       spin_unlock_irqrestore(&f->lock, flags);
++      /* close the old pool and wait until all users are gone */
++      snd_seq_pool_mark_closing(oldpool);
++      snd_use_lock_sync(&f->use_lock);
++
+       /* release cells in old pool */
+       for (cell = oldhead; cell; cell = next) {
+               next = cell->next;
diff --git a/queue-3.18/alsa-seq-fix-racy-cell-insertions-during-snd_seq_pool_done.patch b/queue-3.18/alsa-seq-fix-racy-cell-insertions-during-snd_seq_pool_done.patch
new file mode 100644 (file)
index 0000000..1876803
--- /dev/null
@@ -0,0 +1,103 @@
+From c520ff3d03f0b5db7146d9beed6373ad5d2a5e0e Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Tue, 21 Mar 2017 13:56:04 +0100
+Subject: ALSA: seq: Fix racy cell insertions during snd_seq_pool_done()
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit c520ff3d03f0b5db7146d9beed6373ad5d2a5e0e upstream.
+
+When snd_seq_pool_done() is called, it marks the closing flag to
+refuse the further cell insertions.  But snd_seq_pool_done() itself
+doesn't clear the cells but just waits until all cells are cleared by
+the caller side.  That is, it's racy, and this leads to the endless
+stall as syzkaller spotted.
+
+This patch addresses the racy by splitting the setup of pool->closing
+flag out of snd_seq_pool_done(), and calling it properly before
+snd_seq_pool_done().
+
+BugLink: http://lkml.kernel.org/r/CACT4Y+aqqy8bZA1fFieifNxR2fAfFQQABcBHj801+u5ePV0URw@mail.gmail.com
+Reported-and-tested-by: Dmitry Vyukov <dvyukov@google.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/seq/seq_clientmgr.c |    1 +
+ sound/core/seq/seq_fifo.c      |    3 +++
+ sound/core/seq/seq_memory.c    |   17 +++++++++++++----
+ sound/core/seq/seq_memory.h    |    1 +
+ 4 files changed, 18 insertions(+), 4 deletions(-)
+
+--- a/sound/core/seq/seq_clientmgr.c
++++ b/sound/core/seq/seq_clientmgr.c
+@@ -1921,6 +1921,7 @@ static int snd_seq_ioctl_set_client_pool
+            info.output_pool != client->pool->size)) {
+               if (snd_seq_write_pool_allocated(client)) {
+                       /* remove all existing cells */
++                      snd_seq_pool_mark_closing(client->pool);
+                       snd_seq_queue_client_leave_cells(client->number);
+                       snd_seq_pool_done(client->pool);
+               }
+--- a/sound/core/seq/seq_fifo.c
++++ b/sound/core/seq/seq_fifo.c
+@@ -70,6 +70,9 @@ void snd_seq_fifo_delete(struct snd_seq_
+               return;
+       *fifo = NULL;
++      if (f->pool)
++              snd_seq_pool_mark_closing(f->pool);
++
+       snd_seq_fifo_clear(f);
+       /* wake up clients if any */
+--- a/sound/core/seq/seq_memory.c
++++ b/sound/core/seq/seq_memory.c
+@@ -414,6 +414,18 @@ int snd_seq_pool_init(struct snd_seq_poo
+       return 0;
+ }
++/* refuse the further insertion to the pool */
++void snd_seq_pool_mark_closing(struct snd_seq_pool *pool)
++{
++      unsigned long flags;
++
++      if (snd_BUG_ON(!pool))
++              return;
++      spin_lock_irqsave(&pool->lock, flags);
++      pool->closing = 1;
++      spin_unlock_irqrestore(&pool->lock, flags);
++}
++
+ /* remove events */
+ int snd_seq_pool_done(struct snd_seq_pool *pool)
+ {
+@@ -425,10 +437,6 @@ int snd_seq_pool_done(struct snd_seq_poo
+               return -EINVAL;
+       /* wait for closing all threads */
+-      spin_lock_irqsave(&pool->lock, flags);
+-      pool->closing = 1;
+-      spin_unlock_irqrestore(&pool->lock, flags);
+-
+       if (waitqueue_active(&pool->output_sleep))
+               wake_up(&pool->output_sleep);
+@@ -491,6 +499,7 @@ int snd_seq_pool_delete(struct snd_seq_p
+       *ppool = NULL;
+       if (pool == NULL)
+               return 0;
++      snd_seq_pool_mark_closing(pool);
+       snd_seq_pool_done(pool);
+       kfree(pool);
+       return 0;
+--- a/sound/core/seq/seq_memory.h
++++ b/sound/core/seq/seq_memory.h
+@@ -84,6 +84,7 @@ static inline int snd_seq_total_cells(st
+ int snd_seq_pool_init(struct snd_seq_pool *pool);
+ /* done pool - free events */
++void snd_seq_pool_mark_closing(struct snd_seq_pool *pool);
+ int snd_seq_pool_done(struct snd_seq_pool *pool);
+ /* create pool */
diff --git a/queue-3.18/c6x-ptrace-remove-useless-ptrace_setregset-implementation.patch b/queue-3.18/c6x-ptrace-remove-useless-ptrace_setregset-implementation.patch
new file mode 100644 (file)
index 0000000..f0ebb08
--- /dev/null
@@ -0,0 +1,82 @@
+From fb411b837b587a32046dc4f369acb93a10b1def8 Mon Sep 17 00:00:00 2001
+From: Dave Martin <Dave.Martin@arm.com>
+Date: Mon, 27 Mar 2017 15:10:53 +0100
+Subject: c6x/ptrace: Remove useless PTRACE_SETREGSET implementation
+
+From: Dave Martin <Dave.Martin@arm.com>
+
+commit fb411b837b587a32046dc4f369acb93a10b1def8 upstream.
+
+gpr_set won't work correctly and can never have been tested, and the
+correct behaviour is not clear due to the endianness-dependent task
+layout.
+
+So, just remove it.  The core code will now return -EOPNOTSUPPORT when
+trying to set NT_PRSTATUS on this architecture until/unless a correct
+implementation is supplied.
+
+Signed-off-by: Dave Martin <Dave.Martin@arm.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/c6x/kernel/ptrace.c |   41 -----------------------------------------
+ 1 file changed, 41 deletions(-)
+
+--- a/arch/c6x/kernel/ptrace.c
++++ b/arch/c6x/kernel/ptrace.c
+@@ -69,46 +69,6 @@ static int gpr_get(struct task_struct *t
+                                  0, sizeof(*regs));
+ }
+-static int gpr_set(struct task_struct *target,
+-                 const struct user_regset *regset,
+-                 unsigned int pos, unsigned int count,
+-                 const void *kbuf, const void __user *ubuf)
+-{
+-      int ret;
+-      struct pt_regs *regs = task_pt_regs(target);
+-
+-      /* Don't copyin TSR or CSR */
+-      ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+-                               &regs,
+-                               0, PT_TSR * sizeof(long));
+-      if (ret)
+-              return ret;
+-
+-      ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+-                                      PT_TSR * sizeof(long),
+-                                      (PT_TSR + 1) * sizeof(long));
+-      if (ret)
+-              return ret;
+-
+-      ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+-                               &regs,
+-                               (PT_TSR + 1) * sizeof(long),
+-                               PT_CSR * sizeof(long));
+-      if (ret)
+-              return ret;
+-
+-      ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+-                                      PT_CSR * sizeof(long),
+-                                      (PT_CSR + 1) * sizeof(long));
+-      if (ret)
+-              return ret;
+-
+-      ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+-                               &regs,
+-                               (PT_CSR + 1) * sizeof(long), -1);
+-      return ret;
+-}
+-
+ enum c6x_regset {
+       REGSET_GPR,
+ };
+@@ -120,7 +80,6 @@ static const struct user_regset c6x_regs
+               .size = sizeof(u32),
+               .align = sizeof(u32),
+               .get = gpr_get,
+-              .set = gpr_set
+       },
+ };
diff --git a/queue-3.18/drivers-hv-balloon-don-t-crash-when-memory-is-added-in-non-sorted-order.patch b/queue-3.18/drivers-hv-balloon-don-t-crash-when-memory-is-added-in-non-sorted-order.patch
new file mode 100644 (file)
index 0000000..47a965b
--- /dev/null
@@ -0,0 +1,46 @@
+From 77c0c9735bc0ba5898e637a3a20d6bcb50e3f67d Mon Sep 17 00:00:00 2001
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+Date: Sat, 30 Apr 2016 19:21:35 -0700
+Subject: Drivers: hv: balloon: don't crash when memory is added in non-sorted order
+
+From: Vitaly Kuznetsov <vkuznets@redhat.com>
+
+commit 77c0c9735bc0ba5898e637a3a20d6bcb50e3f67d upstream.
+
+When we iterate through all HA regions in handle_pg_range() we have an
+assumption that all these regions are sorted in the list and the
+'start_pfn >= has->end_pfn' check is enough to find the proper region.
+Unfortunately it's not the case with WS2016 where host can hot-add regions
+in a different order. We end up modifying the wrong HA region and crashing
+later on pages online. Modify the check to make sure we found the region
+we were searching for while iterating. Fix the same check in pfn_covered()
+as well.
+
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hv/hv_balloon.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/hv/hv_balloon.c
++++ b/drivers/hv/hv_balloon.c
+@@ -673,7 +673,7 @@ static bool pfn_covered(unsigned long st
+                * If the pfn range we are dealing with is not in the current
+                * "hot add block", move on.
+                */
+-              if ((start_pfn >= has->end_pfn))
++              if (start_pfn < has->start_pfn || start_pfn >= has->end_pfn)
+                       continue;
+               /*
+                * If the current hot add-request extends beyond
+@@ -728,7 +728,7 @@ static unsigned long handle_pg_range(uns
+                * If the pfn range we are dealing with is not in the current
+                * "hot add block", move on.
+                */
+-              if ((start_pfn >= has->end_pfn))
++              if (start_pfn < has->start_pfn || start_pfn >= has->end_pfn)
+                       continue;
+               old_covered_state = has->covered_end_pfn;
diff --git a/queue-3.18/drm-ttm-drm-vmwgfx-relax-permission-checking-when-opening-surfaces.patch b/queue-3.18/drm-ttm-drm-vmwgfx-relax-permission-checking-when-opening-surfaces.patch
new file mode 100644 (file)
index 0000000..da7c97a
--- /dev/null
@@ -0,0 +1,172 @@
+From fe25deb7737ce6c0879ccf79c99fa1221d428bf2 Mon Sep 17 00:00:00 2001
+From: Thomas Hellstrom <thellstrom@vmware.com>
+Date: Mon, 27 Mar 2017 11:21:25 +0200
+Subject: drm/ttm, drm/vmwgfx: Relax permission checking when opening surfaces
+
+From: Thomas Hellstrom <thellstrom@vmware.com>
+
+commit fe25deb7737ce6c0879ccf79c99fa1221d428bf2 upstream.
+
+Previously, when a surface was opened using a legacy (non prime) handle,
+it was verified to have been created by a client in the same master realm.
+Relax this so that opening is also allowed recursively if the client
+already has the surface open.
+
+This works around a regression in svga mesa where opening of a shared
+surface is used recursively to obtain surface information.
+
+Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
+Reviewed-by: Sinclair Yeh <syeh@vmware.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/ttm/ttm_object.c         |   10 +++++++---
+ drivers/gpu/drm/vmwgfx/vmwgfx_fence.c    |    6 ++----
+ drivers/gpu/drm/vmwgfx/vmwgfx_resource.c |    4 ++--
+ drivers/gpu/drm/vmwgfx/vmwgfx_surface.c  |   22 +++++++++-------------
+ include/drm/ttm/ttm_object.h             |    5 ++++-
+ 5 files changed, 24 insertions(+), 23 deletions(-)
+
+--- a/drivers/gpu/drm/ttm/ttm_object.c
++++ b/drivers/gpu/drm/ttm/ttm_object.c
+@@ -179,7 +179,7 @@ int ttm_base_object_init(struct ttm_obje
+       if (unlikely(ret != 0))
+               goto out_err0;
+-      ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL);
++      ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL, false);
+       if (unlikely(ret != 0))
+               goto out_err1;
+@@ -318,7 +318,8 @@ EXPORT_SYMBOL(ttm_ref_object_exists);
+ int ttm_ref_object_add(struct ttm_object_file *tfile,
+                      struct ttm_base_object *base,
+-                     enum ttm_ref_type ref_type, bool *existed)
++                     enum ttm_ref_type ref_type, bool *existed,
++                     bool require_existed)
+ {
+       struct drm_open_hash *ht = &tfile->ref_hash[ref_type];
+       struct ttm_ref_object *ref;
+@@ -345,6 +346,9 @@ int ttm_ref_object_add(struct ttm_object
+               }
+               rcu_read_unlock();
++              if (require_existed)
++                      return -EPERM;
++
+               ret = ttm_mem_global_alloc(mem_glob, sizeof(*ref),
+                                          false, false);
+               if (unlikely(ret != 0))
+@@ -635,7 +639,7 @@ int ttm_prime_fd_to_handle(struct ttm_ob
+       prime = (struct ttm_prime_object *) dma_buf->priv;
+       base = &prime->base;
+       *handle = base->hash.key;
+-      ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL);
++      ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL, false);
+       dma_buf_put(dma_buf);
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
+@@ -1144,10 +1144,8 @@ int vmw_fence_event_ioctl(struct drm_dev
+               (void) vmw_fence_obj_reference(fence);
+               if (user_fence_rep != NULL) {
+-                      bool existed;
+-
+-                      ret = ttm_ref_object_add(tfile, base,
+-                                               TTM_REF_USAGE, &existed);
++                      ret = ttm_ref_object_add(vmw_fp->tfile, base,
++                                               TTM_REF_USAGE, NULL, false);
+                       if (unlikely(ret != 0)) {
+                               DRM_ERROR("Failed to reference a fence "
+                                         "object.\n");
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+@@ -588,7 +588,7 @@ static int vmw_user_dmabuf_synccpu_grab(
+               return ret;
+       ret = ttm_ref_object_add(tfile, &user_bo->prime.base,
+-                               TTM_REF_SYNCCPU_WRITE, &existed);
++                               TTM_REF_SYNCCPU_WRITE, &existed, false);
+       if (ret != 0 || existed)
+               ttm_bo_synccpu_write_release(&user_bo->dma.base);
+@@ -764,7 +764,7 @@ int vmw_user_dmabuf_reference(struct ttm
+       *handle = user_bo->prime.base.hash.key;
+       return ttm_ref_object_add(tfile, &user_bo->prime.base,
+-                                TTM_REF_USAGE, NULL);
++                                TTM_REF_USAGE, NULL, false);
+ }
+ /*
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
+@@ -895,17 +895,16 @@ vmw_surface_handle_reference(struct vmw_
+       uint32_t handle;
+       struct ttm_base_object *base;
+       int ret;
++      bool require_exist = false;
+       if (handle_type == DRM_VMW_HANDLE_PRIME) {
+               ret = ttm_prime_fd_to_handle(tfile, u_handle, &handle);
+               if (unlikely(ret != 0))
+                       return ret;
+       } else {
+-              if (unlikely(drm_is_render_client(file_priv))) {
+-                      DRM_ERROR("Render client refused legacy "
+-                                "surface reference.\n");
+-                      return -EACCES;
+-              }
++              if (unlikely(drm_is_render_client(file_priv)))
++                      require_exist = true;
++
+               handle = u_handle;
+       }
+@@ -927,17 +926,14 @@ vmw_surface_handle_reference(struct vmw_
+               /*
+                * Make sure the surface creator has the same
+-               * authenticating master.
++               * authenticating master, or is already registered with us.
+                */
+               if (drm_is_primary_client(file_priv) &&
+-                  user_srf->master != file_priv->master) {
+-                      DRM_ERROR("Trying to reference surface outside of"
+-                                " master domain.\n");
+-                      ret = -EACCES;
+-                      goto out_bad_resource;
+-              }
++                  user_srf->master != file_priv->master)
++                      require_exist = true;
+-              ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL);
++              ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL,
++                                       require_exist);
+               if (unlikely(ret != 0)) {
+                       DRM_ERROR("Could not add a reference to a surface.\n");
+                       goto out_bad_resource;
+--- a/include/drm/ttm/ttm_object.h
++++ b/include/drm/ttm/ttm_object.h
+@@ -229,6 +229,8 @@ extern void ttm_base_object_unref(struct
+  * @ref_type: The type of reference.
+  * @existed: Upon completion, indicates that an identical reference object
+  * already existed, and the refcount was upped on that object instead.
++ * @require_existed: Fail with -EPERM if an identical ref object didn't
++ * already exist.
+  *
+  * Checks that the base object is shareable and adds a ref object to it.
+  *
+@@ -243,7 +245,8 @@ extern void ttm_base_object_unref(struct
+  */
+ extern int ttm_ref_object_add(struct ttm_object_file *tfile,
+                             struct ttm_base_object *base,
+-                            enum ttm_ref_type ref_type, bool *existed);
++                            enum ttm_ref_type ref_type, bool *existed,
++                            bool require_existed);
+ extern bool ttm_ref_object_exists(struct ttm_object_file *tfile,
+                                 struct ttm_base_object *base);
diff --git a/queue-3.18/drm-vmwgfx-avoid-calling-vzalloc-with-a-0-size-in-vmw_get_cap_3d_ioctl.patch b/queue-3.18/drm-vmwgfx-avoid-calling-vzalloc-with-a-0-size-in-vmw_get_cap_3d_ioctl.patch
new file mode 100644 (file)
index 0000000..9bd250d
--- /dev/null
@@ -0,0 +1,34 @@
+From 63774069d9527a1aeaa4aa20e929ef5e8e9ecc38 Mon Sep 17 00:00:00 2001
+From: Murray McAllister <murray.mcallister@insomniasec.com>
+Date: Mon, 27 Mar 2017 11:15:12 +0200
+Subject: drm/vmwgfx: avoid calling vzalloc with a 0 size in vmw_get_cap_3d_ioctl()
+
+From: Murray McAllister <murray.mcallister@insomniasec.com>
+
+commit 63774069d9527a1aeaa4aa20e929ef5e8e9ecc38 upstream.
+
+In vmw_get_cap_3d_ioctl(), a user can supply 0 for a size that is
+used in vzalloc(). This eventually calls dump_stack() (in warn_alloc()),
+which can leak useful addresses to dmesg.
+
+Add check to avoid a size of 0.
+
+Signed-off-by: Murray McAllister <murray.mcallister@insomniasec.com>
+Reviewed-by: Sinclair Yeh <syeh@vmware.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
+@@ -161,7 +161,7 @@ int vmw_get_cap_3d_ioctl(struct drm_devi
+       bool gb_objects = !!(dev_priv->capabilities & SVGA_CAP_GBOBJECTS);
+       struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv);
+-      if (unlikely(arg->pad64 != 0)) {
++      if (unlikely(arg->pad64 != 0 || arg->max_size == 0)) {
+               DRM_ERROR("Illegal GET_3D_CAP argument.\n");
+               return -EINVAL;
+       }
diff --git a/queue-3.18/drm-vmwgfx-fix-integer-overflow-in-vmw_surface_define_ioctl.patch b/queue-3.18/drm-vmwgfx-fix-integer-overflow-in-vmw_surface_define_ioctl.patch
new file mode 100644 (file)
index 0000000..8895e3e
--- /dev/null
@@ -0,0 +1,39 @@
+From e7e11f99564222d82f0ce84bd521e57d78a6b678 Mon Sep 17 00:00:00 2001
+From: Li Qiang <liq3ea@gmail.com>
+Date: Mon, 27 Mar 2017 20:10:53 -0700
+Subject: drm/vmwgfx: fix integer overflow in vmw_surface_define_ioctl()
+
+From: Li Qiang <liq3ea@gmail.com>
+
+commit e7e11f99564222d82f0ce84bd521e57d78a6b678 upstream.
+
+In vmw_surface_define_ioctl(), the 'num_sizes' is the sum of the
+'req->mip_levels' array. This array can be assigned any value from
+the user space. As both the 'num_sizes' and the array is uint32_t,
+it is easy to make 'num_sizes' overflow. The later 'mip_levels' is
+used as the loop count. This can lead an oob write. Add the check of
+'req->mip_levels' to avoid this.
+
+Signed-off-by: Li Qiang <liqiang6-s@360.cn>
+Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_surface.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
+@@ -708,8 +708,11 @@ int vmw_surface_define_ioctl(struct drm_
+                       128;
+       num_sizes = 0;
+-      for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i)
++      for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) {
++              if (req->mip_levels[i] > DRM_VMW_MAX_MIP_LEVELS)
++                      return -EINVAL;
+               num_sizes += req->mip_levels[i];
++      }
+       if (num_sizes > DRM_VMW_MAX_SURFACE_FACES * DRM_VMW_MAX_MIP_LEVELS ||
+           num_sizes == 0)
diff --git a/queue-3.18/drm-vmwgfx-null-pointer-dereference-in-vmw_surface_define_ioctl.patch b/queue-3.18/drm-vmwgfx-null-pointer-dereference-in-vmw_surface_define_ioctl.patch
new file mode 100644 (file)
index 0000000..1312fef
--- /dev/null
@@ -0,0 +1,36 @@
+From 36274ab8c596f1240c606bb514da329add2a1bcd Mon Sep 17 00:00:00 2001
+From: Murray McAllister <murray.mcallister@insomniasec.com>
+Date: Mon, 27 Mar 2017 11:12:53 +0200
+Subject: drm/vmwgfx: NULL pointer dereference in vmw_surface_define_ioctl()
+
+From: Murray McAllister <murray.mcallister@insomniasec.com>
+
+commit 36274ab8c596f1240c606bb514da329add2a1bcd upstream.
+
+Before memory allocations vmw_surface_define_ioctl() checks the
+upper-bounds of a user-supplied size, but does not check if the
+supplied size is 0.
+
+Add check to avoid NULL pointer dereferences.
+
+Signed-off-by: Murray McAllister <murray.mcallister@insomniasec.com>
+Reviewed-by: Sinclair Yeh <syeh@vmware.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_surface.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
+@@ -711,8 +711,8 @@ int vmw_surface_define_ioctl(struct drm_
+       for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i)
+               num_sizes += req->mip_levels[i];
+-      if (num_sizes > DRM_VMW_MAX_SURFACE_FACES *
+-          DRM_VMW_MAX_MIP_LEVELS)
++      if (num_sizes > DRM_VMW_MAX_SURFACE_FACES * DRM_VMW_MAX_MIP_LEVELS ||
++          num_sizes == 0)
+               return -EINVAL;
+       size = vmw_user_surface_size + 128 +
diff --git a/queue-3.18/drm-vmwgfx-remove-getparam-error-message.patch b/queue-3.18/drm-vmwgfx-remove-getparam-error-message.patch
new file mode 100644 (file)
index 0000000..f38bdb9
--- /dev/null
@@ -0,0 +1,33 @@
+From 53e16798b0864464c5444a204e1bb93ae246c429 Mon Sep 17 00:00:00 2001
+From: Thomas Hellstrom <thellstrom@vmware.com>
+Date: Mon, 27 Mar 2017 13:06:05 +0200
+Subject: drm/vmwgfx: Remove getparam error message
+
+From: Thomas Hellstrom <thellstrom@vmware.com>
+
+commit 53e16798b0864464c5444a204e1bb93ae246c429 upstream.
+
+The mesa winsys sometimes uses unimplemented parameter requests to
+check for features. Remove the error message to avoid bloating the
+kernel log.
+
+Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
+Reviewed-by: Brian Paul <brianp@vmware.com>
+Reviewed-by: Sinclair Yeh <syeh@vmware.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c |    2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
+@@ -106,8 +106,6 @@ int vmw_getparam_ioctl(struct drm_device
+               param->value = dev_priv->max_mob_size;
+               break;
+       default:
+-              DRM_ERROR("Illegal vmwgfx get param request: %d\n",
+-                        param->param);
+               return -EINVAL;
+       }
diff --git a/queue-3.18/drm-vmwgfx-type-check-lookups-of-fence-objects.patch b/queue-3.18/drm-vmwgfx-type-check-lookups-of-fence-objects.patch
new file mode 100644 (file)
index 0000000..f08cda4
--- /dev/null
@@ -0,0 +1,157 @@
+From f7652afa8eadb416b23eb57dec6f158529942041 Mon Sep 17 00:00:00 2001
+From: Thomas Hellstrom <thellstrom@vmware.com>
+Date: Mon, 27 Mar 2017 11:09:08 +0200
+Subject: drm/vmwgfx: Type-check lookups of fence objects
+
+From: Thomas Hellstrom <thellstrom@vmware.com>
+
+commit f7652afa8eadb416b23eb57dec6f158529942041 upstream.
+
+A malicious caller could otherwise hand over handles to other objects
+causing all sorts of interesting problems.
+
+Testing done: Ran a Fedora 25 desktop using both Xorg and
+gnome-shell/Wayland.
+
+Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
+Reviewed-by: Sinclair Yeh <syeh@vmware.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_fence.c |   75 ++++++++++++++++++++++------------
+ 1 file changed, 49 insertions(+), 26 deletions(-)
+
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
+@@ -539,7 +539,7 @@ int vmw_fence_create(struct vmw_fence_ma
+                    struct vmw_fence_obj **p_fence)
+ {
+       struct vmw_fence_obj *fence;
+-      int ret;
++      int ret;
+       fence = kzalloc(sizeof(*fence), GFP_KERNEL);
+       if (unlikely(fence == NULL))
+@@ -702,6 +702,41 @@ void vmw_fence_fifo_up(struct vmw_fence_
+ }
++/**
++ * vmw_fence_obj_lookup - Look up a user-space fence object
++ *
++ * @tfile: A struct ttm_object_file identifying the caller.
++ * @handle: A handle identifying the fence object.
++ * @return: A struct vmw_user_fence base ttm object on success or
++ * an error pointer on failure.
++ *
++ * The fence object is looked up and type-checked. The caller needs
++ * to have opened the fence object first, but since that happens on
++ * creation and fence objects aren't shareable, that's not an
++ * issue currently.
++ */
++static struct ttm_base_object *
++vmw_fence_obj_lookup(struct ttm_object_file *tfile, u32 handle)
++{
++      struct ttm_base_object *base = ttm_base_object_lookup(tfile, handle);
++
++      if (!base) {
++              pr_err("Invalid fence object handle 0x%08lx.\n",
++                     (unsigned long)handle);
++              return ERR_PTR(-EINVAL);
++      }
++
++      if (base->refcount_release != vmw_user_fence_base_release) {
++              pr_err("Invalid fence object handle 0x%08lx.\n",
++                     (unsigned long)handle);
++              ttm_base_object_unref(&base);
++              return ERR_PTR(-EINVAL);
++      }
++
++      return base;
++}
++
++
+ int vmw_fence_obj_wait_ioctl(struct drm_device *dev, void *data,
+                            struct drm_file *file_priv)
+ {
+@@ -727,13 +762,9 @@ int vmw_fence_obj_wait_ioctl(struct drm_
+               arg->kernel_cookie = jiffies + wait_timeout;
+       }
+-      base = ttm_base_object_lookup(tfile, arg->handle);
+-      if (unlikely(base == NULL)) {
+-              printk(KERN_ERR "Wait invalid fence object handle "
+-                     "0x%08lx.\n",
+-                     (unsigned long)arg->handle);
+-              return -EINVAL;
+-      }
++      base = vmw_fence_obj_lookup(tfile, arg->handle);
++      if (IS_ERR(base))
++              return PTR_ERR(base);
+       fence = &(container_of(base, struct vmw_user_fence, base)->fence);
+@@ -772,13 +803,9 @@ int vmw_fence_obj_signaled_ioctl(struct
+       struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
+       struct vmw_private *dev_priv = vmw_priv(dev);
+-      base = ttm_base_object_lookup(tfile, arg->handle);
+-      if (unlikely(base == NULL)) {
+-              printk(KERN_ERR "Fence signaled invalid fence object handle "
+-                     "0x%08lx.\n",
+-                     (unsigned long)arg->handle);
+-              return -EINVAL;
+-      }
++      base = vmw_fence_obj_lookup(tfile, arg->handle);
++      if (IS_ERR(base))
++              return PTR_ERR(base);
+       fence = &(container_of(base, struct vmw_user_fence, base)->fence);
+       fman = fman_from_fence(fence);
+@@ -1093,6 +1120,7 @@ int vmw_fence_event_ioctl(struct drm_dev
+               (struct drm_vmw_fence_event_arg *) data;
+       struct vmw_fence_obj *fence = NULL;
+       struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv);
++      struct ttm_object_file *tfile = vmw_fp->tfile;
+       struct drm_vmw_fence_rep __user *user_fence_rep =
+               (struct drm_vmw_fence_rep __user *)(unsigned long)
+               arg->fence_rep;
+@@ -1106,15 +1134,11 @@ int vmw_fence_event_ioctl(struct drm_dev
+        */
+       if (arg->handle) {
+               struct ttm_base_object *base =
+-                      ttm_base_object_lookup_for_ref(dev_priv->tdev,
+-                                                     arg->handle);
++                      vmw_fence_obj_lookup(tfile, arg->handle);
++
++              if (IS_ERR(base))
++                      return PTR_ERR(base);
+-              if (unlikely(base == NULL)) {
+-                      DRM_ERROR("Fence event invalid fence object handle "
+-                                "0x%08lx.\n",
+-                                (unsigned long)arg->handle);
+-                      return -EINVAL;
+-              }
+               fence = &(container_of(base, struct vmw_user_fence,
+                                      base)->fence);
+               (void) vmw_fence_obj_reference(fence);
+@@ -1122,7 +1146,7 @@ int vmw_fence_event_ioctl(struct drm_dev
+               if (user_fence_rep != NULL) {
+                       bool existed;
+-                      ret = ttm_ref_object_add(vmw_fp->tfile, base,
++                      ret = ttm_ref_object_add(tfile, base,
+                                                TTM_REF_USAGE, &existed);
+                       if (unlikely(ret != 0)) {
+                               DRM_ERROR("Failed to reference a fence "
+@@ -1166,8 +1190,7 @@ int vmw_fence_event_ioctl(struct drm_dev
+       return 0;
+ out_no_create:
+       if (user_fence_rep != NULL)
+-              ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile,
+-                                        handle, TTM_REF_USAGE);
++              ttm_ref_object_base_unref(tfile, handle, TTM_REF_USAGE);
+ out_no_ref_obj:
+       vmw_fence_obj_unreference(&fence);
+       return ret;
diff --git a/queue-3.18/metag-ptrace-preserve-previous-registers-for-short-regset-write.patch b/queue-3.18/metag-ptrace-preserve-previous-registers-for-short-regset-write.patch
new file mode 100644 (file)
index 0000000..5fa2558
--- /dev/null
@@ -0,0 +1,32 @@
+From a78ce80d2c9178351b34d78fec805140c29c193e Mon Sep 17 00:00:00 2001
+From: Dave Martin <Dave.Martin@arm.com>
+Date: Mon, 27 Mar 2017 15:10:55 +0100
+Subject: metag/ptrace: Preserve previous registers for short regset write
+
+From: Dave Martin <Dave.Martin@arm.com>
+
+commit a78ce80d2c9178351b34d78fec805140c29c193e upstream.
+
+Ensure that if userspace supplies insufficient data to PTRACE_SETREGSET
+to fill all the registers, the thread's old registers are preserved.
+
+Signed-off-by: Dave Martin <Dave.Martin@arm.com>
+Acked-by: James Hogan <james.hogan@imgtec.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/metag/kernel/ptrace.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/metag/kernel/ptrace.c
++++ b/arch/metag/kernel/ptrace.c
+@@ -303,7 +303,7 @@ static int metag_tls_set(struct task_str
+                       const void *kbuf, const void __user *ubuf)
+ {
+       int ret;
+-      void __user *tls;
++      void __user *tls = target->thread.tls_ptr;
+       ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &tls, 0, -1);
+       if (ret)
diff --git a/queue-3.18/metag-ptrace-provide-default-txstatus-for-short-nt_prstatus.patch b/queue-3.18/metag-ptrace-provide-default-txstatus-for-short-nt_prstatus.patch
new file mode 100644 (file)
index 0000000..010686b
--- /dev/null
@@ -0,0 +1,60 @@
+From 5fe81fe98123ce41265c65e95d34418d30d005d1 Mon Sep 17 00:00:00 2001
+From: Dave Martin <Dave.Martin@arm.com>
+Date: Mon, 27 Mar 2017 15:10:56 +0100
+Subject: metag/ptrace: Provide default TXSTATUS for short NT_PRSTATUS
+
+From: Dave Martin <Dave.Martin@arm.com>
+
+commit 5fe81fe98123ce41265c65e95d34418d30d005d1 upstream.
+
+Ensure that if userspace supplies insufficient data to PTRACE_SETREGSET
+to fill TXSTATUS, a well-defined default value is used, based on the
+task's current value.
+
+Suggested-by: James Hogan <james.hogan@imgtec.com>
+Signed-off-by: Dave Martin <Dave.Martin@arm.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/metag/kernel/ptrace.c |   15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+--- a/arch/metag/kernel/ptrace.c
++++ b/arch/metag/kernel/ptrace.c
+@@ -24,6 +24,16 @@
+  * user_regset definitions.
+  */
++static unsigned long user_txstatus(const struct pt_regs *regs)
++{
++      unsigned long data = (unsigned long)regs->ctx.Flags;
++
++      if (regs->ctx.SaveMask & TBICTX_CBUF_BIT)
++              data |= USER_GP_REGS_STATUS_CATCH_BIT;
++
++      return data;
++}
++
+ int metag_gp_regs_copyout(const struct pt_regs *regs,
+                         unsigned int pos, unsigned int count,
+                         void *kbuf, void __user *ubuf)
+@@ -62,9 +72,7 @@ int metag_gp_regs_copyout(const struct p
+       if (ret)
+               goto out;
+       /* TXSTATUS */
+-      data = (unsigned long)regs->ctx.Flags;
+-      if (regs->ctx.SaveMask & TBICTX_CBUF_BIT)
+-              data |= USER_GP_REGS_STATUS_CATCH_BIT;
++      data = user_txstatus(regs);
+       ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+                                 &data, 4*25, 4*26);
+       if (ret)
+@@ -119,6 +127,7 @@ int metag_gp_regs_copyin(struct pt_regs
+       if (ret)
+               goto out;
+       /* TXSTATUS */
++      data = user_txstatus(regs);
+       ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+                                &data, 4*25, 4*26);
+       if (ret)
diff --git a/queue-3.18/metag-ptrace-reject-partial-nt_metag_rpipe-writes.patch b/queue-3.18/metag-ptrace-reject-partial-nt_metag_rpipe-writes.patch
new file mode 100644 (file)
index 0000000..bfa6cf6
--- /dev/null
@@ -0,0 +1,35 @@
+From 7195ee3120d878259e8d94a5d9f808116f34d5ea Mon Sep 17 00:00:00 2001
+From: Dave Martin <Dave.Martin@arm.com>
+Date: Mon, 27 Mar 2017 15:10:57 +0100
+Subject: metag/ptrace: Reject partial NT_METAG_RPIPE writes
+
+From: Dave Martin <Dave.Martin@arm.com>
+
+commit 7195ee3120d878259e8d94a5d9f808116f34d5ea upstream.
+
+It's not clear what behaviour is sensible when doing partial write of
+NT_METAG_RPIPE, so just don't bother.
+
+This patch assumes that userspace will never rely on a partial SETREGSET
+in this case, since it's not clear what should happen anyway.
+
+Signed-off-by: Dave Martin <Dave.Martin@arm.com>
+Acked-by: James Hogan <james.hogan@imgtec.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/metag/kernel/ptrace.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/metag/kernel/ptrace.c
++++ b/arch/metag/kernel/ptrace.c
+@@ -253,6 +253,8 @@ int metag_rp_state_copyin(struct pt_regs
+       unsigned long long *ptr;
+       int ret, i;
++      if (count < 4*13)
++              return -EINVAL;
+       /* Read the entire pipeline before making any changes */
+       ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+                                &rp, 0, 4*13);
diff --git a/queue-3.18/mips-ptrace-preserve-previous-registers-for-short-regset-write.patch b/queue-3.18/mips-ptrace-preserve-previous-registers-for-short-regset-write.patch
new file mode 100644 (file)
index 0000000..dac11ed
--- /dev/null
@@ -0,0 +1,32 @@
+From d614fd58a2834cfe4efa472c33c8f3ce2338b09b Mon Sep 17 00:00:00 2001
+From: Dave Martin <Dave.Martin@arm.com>
+Date: Mon, 27 Mar 2017 15:10:58 +0100
+Subject: mips/ptrace: Preserve previous registers for short regset write
+
+From: Dave Martin <Dave.Martin@arm.com>
+
+commit d614fd58a2834cfe4efa472c33c8f3ce2338b09b upstream.
+
+Ensure that if userspace supplies insufficient data to PTRACE_SETREGSET
+to fill all the registers, the thread's old registers are preserved.
+
+Signed-off-by: Dave Martin <Dave.Martin@arm.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kernel/ptrace.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/arch/mips/kernel/ptrace.c
++++ b/arch/mips/kernel/ptrace.c
+@@ -444,7 +444,8 @@ static int fpr_set(struct task_struct *t
+                                         &target->thread.fpu,
+                                         0, sizeof(elf_fpregset_t));
+-      for (i = 0; i < NUM_FPU_REGS; i++) {
++      BUILD_BUG_ON(sizeof(fpr_val) != sizeof(elf_fpreg_t));
++      for (i = 0; i < NUM_FPU_REGS && count >= sizeof(elf_fpreg_t); i++) {
+               err = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+                                        &fpr_val, i * sizeof(elf_fpreg_t),
+                                        (i + 1) * sizeof(elf_fpreg_t));
diff --git a/queue-3.18/powerpc-boot-fix-zimage-toc-alignment.patch b/queue-3.18/powerpc-boot-fix-zimage-toc-alignment.patch
new file mode 100644 (file)
index 0000000..1192cde
--- /dev/null
@@ -0,0 +1,33 @@
+From 97ee351b50a49717543533cfb85b4bf9d88c9680 Mon Sep 17 00:00:00 2001
+From: Michael Ellerman <mpe@ellerman.id.au>
+Date: Tue, 7 Mar 2017 16:14:49 +1100
+Subject: powerpc/boot: Fix zImage TOC alignment
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+commit 97ee351b50a49717543533cfb85b4bf9d88c9680 upstream.
+
+Recent toolchains force the TOC to be 256 byte aligned. We need to
+enforce this alignment in the zImage linker script, otherwise pointers
+to our TOC variables (__toc_start) could be incorrect. If the actual
+start of the TOC and __toc_start don't have the same value we crash
+early in the zImage wrapper.
+
+Suggested-by: Alan Modra <amodra@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/boot/zImage.lds.S |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/powerpc/boot/zImage.lds.S
++++ b/arch/powerpc/boot/zImage.lds.S
+@@ -68,6 +68,7 @@ SECTIONS
+   }
+ #ifdef CONFIG_PPC64_BOOT_WRAPPER
++  . = ALIGN(256);
+   .got :
+   {
+     __toc_start = .;
diff --git a/queue-3.18/powerpc-don-t-try-to-fix-up-misaligned-load-with-reservation-instructions.patch b/queue-3.18/powerpc-don-t-try-to-fix-up-misaligned-load-with-reservation-instructions.patch
new file mode 100644 (file)
index 0000000..3f6c8fd
--- /dev/null
@@ -0,0 +1,71 @@
+From 48fe9e9488743eec9b7c1addd3c93f12f2123d54 Mon Sep 17 00:00:00 2001
+From: Paul Mackerras <paulus@ozlabs.org>
+Date: Tue, 4 Apr 2017 14:56:05 +1000
+Subject: powerpc: Don't try to fix up misaligned load-with-reservation instructions
+
+From: Paul Mackerras <paulus@ozlabs.org>
+
+commit 48fe9e9488743eec9b7c1addd3c93f12f2123d54 upstream.
+
+In the past, there was only one load-with-reservation instruction,
+lwarx, and if a program attempted a lwarx on a misaligned address, it
+would take an alignment interrupt and the kernel handler would emulate
+it as though it was lwzx, which was not really correct, but benign since
+it is loading the right amount of data, and the lwarx should be paired
+with a stwcx. to the same address, which would also cause an alignment
+interrupt which would result in a SIGBUS being delivered to the process.
+
+We now have 5 different sizes of load-with-reservation instruction. Of
+those, lharx and ldarx cause an immediate SIGBUS by luck since their
+entries in aligninfo[] overlap instructions which were not fixed up, but
+lqarx overlaps with lhz and will be emulated as such. lbarx can never
+generate an alignment interrupt since it only operates on 1 byte.
+
+To straighten this out and fix the lqarx case, this adds code to detect
+the l[hwdq]arx instructions and return without fixing them up, resulting
+in a SIGBUS being delivered to the process.
+
+Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/align.c |   27 +++++++++++++++++++--------
+ 1 file changed, 19 insertions(+), 8 deletions(-)
+
+--- a/arch/powerpc/kernel/align.c
++++ b/arch/powerpc/kernel/align.c
+@@ -808,14 +808,25 @@ int fix_alignment(struct pt_regs *regs)
+       nb = aligninfo[instr].len;
+       flags = aligninfo[instr].flags;
+-      /* ldbrx/stdbrx overlap lfs/stfs in the DSISR unfortunately */
+-      if (IS_XFORM(instruction) && ((instruction >> 1) & 0x3ff) == 532) {
+-              nb = 8;
+-              flags = LD+SW;
+-      } else if (IS_XFORM(instruction) &&
+-                 ((instruction >> 1) & 0x3ff) == 660) {
+-              nb = 8;
+-              flags = ST+SW;
++      /*
++       * Handle some cases which give overlaps in the DSISR values.
++       */
++      if (IS_XFORM(instruction)) {
++              switch (get_xop(instruction)) {
++              case 532:       /* ldbrx */
++                      nb = 8;
++                      flags = LD+SW;
++                      break;
++              case 660:       /* stdbrx */
++                      nb = 8;
++                      flags = ST+SW;
++                      break;
++              case 20:        /* lwarx */
++              case 84:        /* ldarx */
++              case 116:       /* lharx */
++              case 276:       /* lqarx */
++                      return 0;       /* not emulated ever */
++              }
+       }
+       /* Byteswap little endian loads and stores */
diff --git a/queue-3.18/powerpc-mm-add-missing-global-tlb-invalidate-if-cxl-is-active.patch b/queue-3.18/powerpc-mm-add-missing-global-tlb-invalidate-if-cxl-is-active.patch
new file mode 100644 (file)
index 0000000..20b6452
--- /dev/null
@@ -0,0 +1,52 @@
+From 88b1bf7268f56887ca88eb09c6fb0f4fc970121a Mon Sep 17 00:00:00 2001
+From: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
+Date: Wed, 29 Mar 2017 19:19:42 +0200
+Subject: powerpc/mm: Add missing global TLB invalidate if cxl is active
+
+From: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
+
+commit 88b1bf7268f56887ca88eb09c6fb0f4fc970121a upstream.
+
+Commit 4c6d9acce1f4 ("powerpc/mm: Add hooks for cxl") converted local
+TLB invalidates to global if the cxl driver is active. This is necessary
+because the CAPP snoops invalidations to forward them to the PSL on the
+cxl adapter. However one path was forgotten. native_flush_hash_range()
+still does local TLB invalidates, as found out the hard way recently.
+
+This patch fixes it by following the same logic as previously: if the
+cxl driver is active, the local TLB invalidates are 'upgraded' to
+global.
+
+Fixes: 4c6d9acce1f4 ("powerpc/mm: Add hooks for cxl")
+Signed-off-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
+Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/mm/hash_native_64.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/arch/powerpc/mm/hash_native_64.c
++++ b/arch/powerpc/mm/hash_native_64.c
+@@ -633,6 +633,10 @@ static void native_flush_hash_range(unsi
+       unsigned long psize = batch->psize;
+       int ssize = batch->ssize;
+       int i;
++      unsigned int use_local;
++
++      use_local = local && mmu_has_feature(MMU_FTR_TLBIEL) &&
++              mmu_psize_defs[psize].tlbiel && !cxl_ctx_in_use();
+       local_irq_save(flags);
+@@ -659,8 +663,7 @@ static void native_flush_hash_range(unsi
+               } pte_iterate_hashed_end();
+       }
+-      if (mmu_has_feature(MMU_FTR_TLBIEL) &&
+-          mmu_psize_defs[psize].tlbiel && local) {
++      if (use_local) {
+               asm volatile("ptesync":::"memory");
+               for (i = 0; i < number; i++) {
+                       vpn = batch->vpn[i];
diff --git a/queue-3.18/ptrace-fix-ptrace_listen-race-corrupting-task-state.patch b/queue-3.18/ptrace-fix-ptrace_listen-race-corrupting-task-state.patch
new file mode 100644 (file)
index 0000000..00d8746
--- /dev/null
@@ -0,0 +1,61 @@
+From 5402e97af667e35e54177af8f6575518bf251d51 Mon Sep 17 00:00:00 2001
+From: "bsegall@google.com" <bsegall@google.com>
+Date: Fri, 7 Apr 2017 16:04:51 -0700
+Subject: ptrace: fix PTRACE_LISTEN race corrupting task->state
+
+From: bsegall@google.com <bsegall@google.com>
+
+commit 5402e97af667e35e54177af8f6575518bf251d51 upstream.
+
+In PT_SEIZED + LISTEN mode STOP/CONT signals cause a wakeup against
+__TASK_TRACED.  If this races with the ptrace_unfreeze_traced at the end
+of a PTRACE_LISTEN, this can wake the task /after/ the check against
+__TASK_TRACED, but before the reset of state to TASK_TRACED.  This
+causes it to instead clobber TASK_WAKING, allowing a subsequent wakeup
+against TRACED while the task is still on the rq wake_list, corrupting
+it.
+
+Oleg said:
+ "The kernel can crash or this can lead to other hard-to-debug problems.
+  In short, "task->state = TASK_TRACED" in ptrace_unfreeze_traced()
+  assumes that nobody else can wake it up, but PTRACE_LISTEN breaks the
+  contract. Obviusly it is very wrong to manipulate task->state if this
+  task is already running, or WAKING, or it sleeps again"
+
+[akpm@linux-foundation.org: coding-style fixes]
+Fixes: 9899d11f ("ptrace: ensure arch_ptrace/ptrace_request can never race with SIGKILL")
+Link: http://lkml.kernel.org/r/xm26y3vfhmkp.fsf_-_@bsegall-linux.mtv.corp.google.com
+Signed-off-by: Ben Segall <bsegall@google.com>
+Acked-by: Oleg Nesterov <oleg@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/ptrace.c |   14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+--- a/kernel/ptrace.c
++++ b/kernel/ptrace.c
+@@ -144,11 +144,17 @@ static void ptrace_unfreeze_traced(struc
+       WARN_ON(!task->ptrace || task->parent != current);
++      /*
++       * PTRACE_LISTEN can allow ptrace_trap_notify to wake us up remotely.
++       * Recheck state under the lock to close this race.
++       */
+       spin_lock_irq(&task->sighand->siglock);
+-      if (__fatal_signal_pending(task))
+-              wake_up_state(task, __TASK_TRACED);
+-      else
+-              task->state = TASK_TRACED;
++      if (task->state == __TASK_TRACED) {
++              if (__fatal_signal_pending(task))
++                      wake_up_state(task, __TASK_TRACED);
++              else
++                      task->state = TASK_TRACED;
++      }
+       spin_unlock_irq(&task->sighand->siglock);
+ }
diff --git a/queue-3.18/reset-treeid-to-zero-on-smb2-tree_connect.patch b/queue-3.18/reset-treeid-to-zero-on-smb2-tree_connect.patch
new file mode 100644 (file)
index 0000000..a5be084
--- /dev/null
@@ -0,0 +1,38 @@
+From 806a28efe9b78ffae5e2757e1ee924b8e50c08ab Mon Sep 17 00:00:00 2001
+From: Jan-Marek Glogowski <glogow@fbihome.de>
+Date: Mon, 20 Feb 2017 12:25:58 +0100
+Subject: Reset TreeId to zero on SMB2 TREE_CONNECT
+
+From: Jan-Marek Glogowski <glogow@fbihome.de>
+
+commit 806a28efe9b78ffae5e2757e1ee924b8e50c08ab upstream.
+
+Currently the cifs module breaks the CIFS specs on reconnect as
+described in http://msdn.microsoft.com/en-us/library/cc246529.aspx:
+
+"TreeId (4 bytes): Uniquely identifies the tree connect for the
+command. This MUST be 0 for the SMB2 TREE_CONNECT Request."
+
+Signed-off-by: Jan-Marek Glogowski <glogow@fbihome.de>
+Reviewed-by: Aurelien Aptel <aaptel@suse.com>
+Tested-by: Aurelien Aptel <aaptel@suse.com>
+Signed-off-by: Steve French <smfrench@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/smb2pdu.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -868,6 +868,10 @@ SMB2_tcon(const unsigned int xid, struct
+               return -EINVAL;
+       }
++      /* SMB2 TREE_CONNECT request must be called with TreeId == 0 */
++      if (tcon)
++              tcon->tid = 0;
++
+       rc = small_smb2_init(SMB2_TREE_CONNECT, tcon, (void **) &req);
+       if (rc) {
+               kfree(unc_path);
diff --git a/queue-3.18/rtc-s35390a-fix-reading-out-alarm.patch b/queue-3.18/rtc-s35390a-fix-reading-out-alarm.patch
new file mode 100644 (file)
index 0000000..dfb76a5
--- /dev/null
@@ -0,0 +1,98 @@
+From f87e904ddd8f0ef120e46045b0addeb1cc88354e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <uwe@kleine-koenig.org>
+Date: Sat, 2 Jul 2016 17:28:08 +0200
+Subject: rtc: s35390a: fix reading out alarm
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <uwe@kleine-koenig.org>
+
+commit f87e904ddd8f0ef120e46045b0addeb1cc88354e upstream.
+
+There are several issues fixed in this patch:
+
+ - When alarm isn't enabled, set .enabled to zero instead of returning
+   -EINVAL.
+ - Ignore how IRQ1 is configured when determining if IRQ2 is on.
+ - The three alarm registers have an enable flag which must be
+   evaluated.
+ - The chip always triggers when the seconds register gets 0.
+
+Note that the rtc framework however doesn't handle the result correctly
+because it doesn't check wday being initialized and so interprets an
+alarm being set for 10:00 AM in three days as 10:00 AM tomorrow (or
+today if that's not over yet).
+
+Signed-off-by: Uwe Kleine-König <uwe@kleine-koenig.org>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/rtc/rtc-s35390a.c |   40 +++++++++++++++++++++++++++++++---------
+ 1 file changed, 31 insertions(+), 9 deletions(-)
+
+--- a/drivers/rtc/rtc-s35390a.c
++++ b/drivers/rtc/rtc-s35390a.c
+@@ -242,6 +242,8 @@ static int s35390a_set_alarm(struct i2c_
+       if (alm->time.tm_wday != -1)
+               buf[S35390A_ALRM_BYTE_WDAY] = bin2bcd(alm->time.tm_wday) | 0x80;
++      else
++              buf[S35390A_ALRM_BYTE_WDAY] = 0;
+       buf[S35390A_ALRM_BYTE_HOURS] = s35390a_hr2reg(s35390a,
+                       alm->time.tm_hour) | 0x80;
+@@ -269,23 +271,43 @@ static int s35390a_read_alarm(struct i2c
+       if (err < 0)
+               return err;
+-      if (bitrev8(sts) != S35390A_INT2_MODE_ALARM)
+-              return -EINVAL;
++      if ((bitrev8(sts) & S35390A_INT2_MODE_MASK) != S35390A_INT2_MODE_ALARM) {
++              /*
++               * When the alarm isn't enabled, the register to configure
++               * the alarm time isn't accessible.
++               */
++              alm->enabled = 0;
++              return 0;
++      } else {
++              alm->enabled = 1;
++      }
+       err = s35390a_get_reg(s35390a, S35390A_CMD_INT2_REG1, buf, sizeof(buf));
+       if (err < 0)
+               return err;
+       /* This chip returns the bits of each byte in reverse order */
+-      for (i = 0; i < 3; ++i) {
++      for (i = 0; i < 3; ++i)
+               buf[i] = bitrev8(buf[i]);
+-              buf[i] &= ~0x80;
+-      }
+-      alm->time.tm_wday = bcd2bin(buf[S35390A_ALRM_BYTE_WDAY]);
+-      alm->time.tm_hour = s35390a_reg2hr(s35390a,
+-                                              buf[S35390A_ALRM_BYTE_HOURS]);
+-      alm->time.tm_min = bcd2bin(buf[S35390A_ALRM_BYTE_MINS]);
++      /*
++       * B0 of the three matching registers is an enable flag. Iff it is set
++       * the configured value is used for matching.
++       */
++      if (buf[S35390A_ALRM_BYTE_WDAY] & 0x80)
++              alm->time.tm_wday =
++                      bcd2bin(buf[S35390A_ALRM_BYTE_WDAY] & ~0x80);
++
++      if (buf[S35390A_ALRM_BYTE_HOURS] & 0x80)
++              alm->time.tm_hour =
++                      s35390a_reg2hr(s35390a,
++                                     buf[S35390A_ALRM_BYTE_HOURS] & ~0x80);
++
++      if (buf[S35390A_ALRM_BYTE_MINS] & 0x80)
++              alm->time.tm_min = bcd2bin(buf[S35390A_ALRM_BYTE_MINS] & ~0x80);
++
++      /* alarm triggers always at s=0 */
++      alm->time.tm_sec = 0;
+       dev_dbg(&client->dev, "%s: alm is mins=%d, hours=%d, wday=%d\n",
+                       __func__, alm->time.tm_min, alm->time.tm_hour,
diff --git a/queue-3.18/rtc-s35390a-implement-reset-routine-as-suggested-by-the-reference.patch b/queue-3.18/rtc-s35390a-implement-reset-routine-as-suggested-by-the-reference.patch
new file mode 100644 (file)
index 0000000..c2822f1
--- /dev/null
@@ -0,0 +1,133 @@
+From 8e6583f1b5d1f5f129b873f1428b7e414263d847 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <uwe@kleine-koenig.org>
+Date: Sat, 2 Jul 2016 17:28:09 +0200
+Subject: rtc: s35390a: implement reset routine as suggested by the reference
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <uwe@kleine-koenig.org>
+
+commit 8e6583f1b5d1f5f129b873f1428b7e414263d847 upstream.
+
+There were two deviations from the reference manual: you have to wait
+half a second when POC is active and you might have to repeat
+initialization when POC or BLD are still set after the sequence.
+
+Note however that as POC and BLD are cleared by read the driver might
+not be able to detect that a reset is necessary. I don't have a good
+idea how to fix this.
+
+Additionally report the value read from STATUS1 to the caller. This
+prepares the next patch.
+
+Signed-off-by: Uwe Kleine-König <uwe@kleine-koenig.org>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/rtc/rtc-s35390a.c |   69 ++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 57 insertions(+), 12 deletions(-)
+
+--- a/drivers/rtc/rtc-s35390a.c
++++ b/drivers/rtc/rtc-s35390a.c
+@@ -15,6 +15,7 @@
+ #include <linux/bitrev.h>
+ #include <linux/bcd.h>
+ #include <linux/slab.h>
++#include <linux/delay.h>
+ #define S35390A_CMD_STATUS1   0
+ #define S35390A_CMD_STATUS2   1
+@@ -94,19 +95,63 @@ static int s35390a_get_reg(struct s35390
+       return 0;
+ }
+-static int s35390a_reset(struct s35390a *s35390a)
+-{
+-      char buf[1];
+-
+-      if (s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf)) < 0)
+-              return -EIO;
++/*
++ * Returns <0 on error, 0 if rtc is setup fine and 1 if the chip was reset.
++ * To keep the information if an irq is pending, pass the value read from
++ * STATUS1 to the caller.
++ */
++static int s35390a_reset(struct s35390a *s35390a, char *status1)
++{
++      char buf;
++      int ret;
++      unsigned initcount = 0;
++
++      ret = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, status1, 1);
++      if (ret < 0)
++              return ret;
+-      if (!(buf[0] & (S35390A_FLAG_POC | S35390A_FLAG_BLD)))
++      if (*status1 & S35390A_FLAG_POC)
++              /*
++               * Do not communicate for 0.5 seconds since the power-on
++               * detection circuit is in operation.
++               */
++              msleep(500);
++      else if (!(*status1 & S35390A_FLAG_BLD))
++              /*
++               * If both POC and BLD are unset everything is fine.
++               */
+               return 0;
+-      buf[0] |= (S35390A_FLAG_RESET | S35390A_FLAG_24H);
+-      buf[0] &= 0xf0;
+-      return s35390a_set_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf));
++      /*
++       * At least one of POC and BLD are set, so reinitialise chip. Keeping
++       * this information in the hardware to know later that the time isn't
++       * valid is unfortunately not possible because POC and BLD are cleared
++       * on read. So the reset is best done now.
++       *
++       * The 24H bit is kept over reset, so set it already here.
++       */
++initialize:
++      *status1 = S35390A_FLAG_24H;
++      buf = S35390A_FLAG_RESET | S35390A_FLAG_24H;
++      ret = s35390a_set_reg(s35390a, S35390A_CMD_STATUS1, &buf, 1);
++
++      if (ret < 0)
++              return ret;
++
++      ret = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, &buf, 1);
++      if (ret < 0)
++              return ret;
++
++      if (buf & (S35390A_FLAG_POC | S35390A_FLAG_BLD)) {
++              /* Try up to five times to reset the chip */
++              if (initcount < 5) {
++                      ++initcount;
++                      goto initialize;
++              } else
++                      return -EIO;
++      }
++
++      return 1;
+ }
+ static int s35390a_disable_test_mode(struct s35390a *s35390a)
+@@ -367,7 +412,7 @@ static int s35390a_probe(struct i2c_clie
+       unsigned int i;
+       struct s35390a *s35390a;
+       struct rtc_time tm;
+-      char buf[1];
++      char buf[1], status1;
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+               err = -ENODEV;
+@@ -396,7 +441,7 @@ static int s35390a_probe(struct i2c_clie
+               }
+       }
+-      err = s35390a_reset(s35390a);
++      err = s35390a_reset(s35390a, &status1);
+       if (err < 0) {
+               dev_err(&client->dev, "error resetting chip\n");
+               goto exit_dummy;
diff --git a/queue-3.18/rtc-s35390a-improve-irq-handling.patch b/queue-3.18/rtc-s35390a-improve-irq-handling.patch
new file mode 100644 (file)
index 0000000..feb479a
--- /dev/null
@@ -0,0 +1,127 @@
+From 3bd32722c827d00eafe8e6d5b83e9f3148ea7c7e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <uwe@kleine-koenig.org>
+Date: Sat, 2 Jul 2016 17:28:10 +0200
+Subject: rtc: s35390a: improve irq handling
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <uwe@kleine-koenig.org>
+
+commit 3bd32722c827d00eafe8e6d5b83e9f3148ea7c7e upstream.
+
+On some QNAP NAS devices the rtc can wake the machine. Several people
+noticed that once the machine was woken this way it fails to shut down.
+That's because the driver fails to acknowledge the interrupt and so it
+keeps active and restarts the machine immediatly after shutdown. See
+https://bugs.debian.org/794266 for a bug report.
+
+Doing this correctly requires to interpret the INT2 flag of the first read
+of the STATUS1 register because this bit is cleared by read.
+
+Note this is not maximally robust though because a pending irq isn't
+detected when the STATUS1 register was already read (and so INT2 is not
+set) but the irq was not disabled. But that is a hardware imposed problem
+that cannot easily be fixed by software.
+
+Signed-off-by: Uwe Kleine-König <uwe@kleine-koenig.org>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/rtc/rtc-s35390a.c |   48 +++++++++++++++++++++++++++++-----------------
+ 1 file changed, 31 insertions(+), 17 deletions(-)
+
+--- a/drivers/rtc/rtc-s35390a.c
++++ b/drivers/rtc/rtc-s35390a.c
+@@ -35,10 +35,14 @@
+ #define S35390A_ALRM_BYTE_HOURS       1
+ #define S35390A_ALRM_BYTE_MINS        2
++/* flags for STATUS1 */
+ #define S35390A_FLAG_POC      0x01
+ #define S35390A_FLAG_BLD      0x02
++#define S35390A_FLAG_INT2     0x04
+ #define S35390A_FLAG_24H      0x40
+ #define S35390A_FLAG_RESET    0x80
++
++/* flag for STATUS2 */
+ #define S35390A_FLAG_TEST     0x01
+ #define S35390A_INT2_MODE_MASK                0xF0
+@@ -408,11 +412,11 @@ static struct i2c_driver s35390a_driver;
+ static int s35390a_probe(struct i2c_client *client,
+                        const struct i2c_device_id *id)
+ {
+-      int err;
++      int err, err_reset;
+       unsigned int i;
+       struct s35390a *s35390a;
+       struct rtc_time tm;
+-      char buf[1], status1;
++      char buf, status1;
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+               err = -ENODEV;
+@@ -441,29 +445,35 @@ static int s35390a_probe(struct i2c_clie
+               }
+       }
+-      err = s35390a_reset(s35390a, &status1);
+-      if (err < 0) {
++      err_reset = s35390a_reset(s35390a, &status1);
++      if (err_reset < 0) {
++              err = err_reset;
+               dev_err(&client->dev, "error resetting chip\n");
+               goto exit_dummy;
+       }
+-      err = s35390a_disable_test_mode(s35390a);
+-      if (err < 0) {
+-              dev_err(&client->dev, "error disabling test mode\n");
+-              goto exit_dummy;
+-      }
+-
+-      err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf));
+-      if (err < 0) {
+-              dev_err(&client->dev, "error checking 12/24 hour mode\n");
+-              goto exit_dummy;
+-      }
+-      if (buf[0] & S35390A_FLAG_24H)
++      if (status1 & S35390A_FLAG_24H)
+               s35390a->twentyfourhour = 1;
+       else
+               s35390a->twentyfourhour = 0;
+-      if (s35390a_get_datetime(client, &tm) < 0)
++      if (status1 & S35390A_FLAG_INT2) {
++              /* disable alarm (and maybe test mode) */
++              buf = 0;
++              err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &buf, 1);
++              if (err < 0) {
++                      dev_err(&client->dev, "error disabling alarm");
++                      goto exit_dummy;
++              }
++      } else {
++              err = s35390a_disable_test_mode(s35390a);
++              if (err < 0) {
++                      dev_err(&client->dev, "error disabling test mode\n");
++                      goto exit_dummy;
++              }
++      }
++
++      if (err_reset > 0 || s35390a_get_datetime(client, &tm) < 0)
+               dev_warn(&client->dev, "clock needs to be set\n");
+       device_set_wakeup_capable(&client->dev, 1);
+@@ -476,6 +486,10 @@ static int s35390a_probe(struct i2c_clie
+               err = PTR_ERR(s35390a->rtc);
+               goto exit_dummy;
+       }
++
++      if (status1 & S35390A_FLAG_INT2)
++              rtc_update_irq(s35390a->rtc, 1, RTC_AF);
++
+       return 0;
+ exit_dummy:
diff --git a/queue-3.18/rtc-s35390a-make-sure-all-members-in-the-output-are-set.patch b/queue-3.18/rtc-s35390a-make-sure-all-members-in-the-output-are-set.patch
new file mode 100644 (file)
index 0000000..edc348a
--- /dev/null
@@ -0,0 +1,54 @@
+From fdd4bc9313e59a1757cfc8ac5836cff55ec03eeb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <uwe@kleine-koenig.org>
+Date: Mon, 3 Apr 2017 23:32:38 +0200
+Subject: rtc: s35390a: make sure all members in the output are set
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <uwe@kleine-koenig.org>
+
+commit fdd4bc9313e59a1757cfc8ac5836cff55ec03eeb in 4.4-stable.
+
+The rtc core calls the .read_alarm with all fields initialized to 0. As
+the s35390a driver doesn't touch some fields the returned date is
+interpreted as a date in January 1900. So make sure all fields are set
+to -1; some of them are then overwritten with the right data depending
+on the hardware state.
+
+In mainline this is done by commit d68778b80dd7 ("rtc: initialize output
+parameter for read alarm to "uninitialized"") in the core. This is
+considered to dangerous for stable as it might have side effects for
+other rtc drivers that might for example rely on alarm->time.tm_sec
+being initialized to 0.
+
+Signed-off-by: Uwe Kleine-König <uwe@kleine-koenig.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/rtc/rtc-s35390a.c |   14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/drivers/rtc/rtc-s35390a.c
++++ b/drivers/rtc/rtc-s35390a.c
+@@ -267,6 +267,20 @@ static int s35390a_read_alarm(struct i2c
+       char buf[3], sts;
+       int i, err;
++      /*
++       * initialize all members to -1 to signal the core that they are not
++       * defined by the hardware.
++       */
++      alm->time.tm_sec = -1;
++      alm->time.tm_min = -1;
++      alm->time.tm_hour = -1;
++      alm->time.tm_mday = -1;
++      alm->time.tm_mon = -1;
++      alm->time.tm_year = -1;
++      alm->time.tm_wday = -1;
++      alm->time.tm_yday = -1;
++      alm->time.tm_isdst = -1;
++
+       err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts));
+       if (err < 0)
+               return err;
diff --git a/queue-3.18/s390-decompressor-fix-initrd-corruption-caused-by-bss-clear.patch b/queue-3.18/s390-decompressor-fix-initrd-corruption-caused-by-bss-clear.patch
new file mode 100644 (file)
index 0000000..f7bee9e
--- /dev/null
@@ -0,0 +1,85 @@
+From d82c0d12c92705ef468683c9b7a8298dd61ed191 Mon Sep 17 00:00:00 2001
+From: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
+Date: Mon, 13 Mar 2017 12:14:58 -0300
+Subject: s390/decompressor: fix initrd corruption caused by bss clear
+
+From: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
+
+commit d82c0d12c92705ef468683c9b7a8298dd61ed191 upstream.
+
+Reorder the operations in decompress_kernel() to ensure initrd is moved
+to a safe location before the bss section is zeroed.
+
+During decompression bss can overlap with the initrd and this can
+corrupt the initrd contents depending on the size of the compressed
+kernel (which affects where the initrd is placed by the bootloader) and
+the size of the bss section of the decompressor.
+
+Also use the correct initrd size when checking for overlaps with
+parmblock.
+
+Fixes: 06c0dd72aea3 ([S390] fix boot failures with compressed kernels)
+Reviewed-by: Joy Latten <joy.latten@canonical.com>
+Reviewed-by: Vineetha HariPai <vineetha.hari.pai@canonical.com>
+Signed-off-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
+Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/s390/boot/compressed/misc.c |   35 +++++++++++++++++++----------------
+ 1 file changed, 19 insertions(+), 16 deletions(-)
+
+--- a/arch/s390/boot/compressed/misc.c
++++ b/arch/s390/boot/compressed/misc.c
+@@ -142,31 +142,34 @@ static void check_ipl_parmblock(void *st
+ unsigned long decompress_kernel(void)
+ {
+-      unsigned long output_addr;
+-      unsigned char *output;
++      void *output, *kernel_end;
+-      output_addr = ((unsigned long) &_end + HEAP_SIZE + 4095UL) & -4096UL;
+-      check_ipl_parmblock((void *) 0, output_addr + SZ__bss_start);
+-      memset(&_bss, 0, &_ebss - &_bss);
+-      free_mem_ptr = (unsigned long)&_end;
+-      free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
+-      output = (unsigned char *) output_addr;
++      output = (void *) ALIGN((unsigned long) &_end + HEAP_SIZE, PAGE_SIZE);
++      kernel_end = output + SZ__bss_start;
++      check_ipl_parmblock((void *) 0, (unsigned long) kernel_end);
+ #ifdef CONFIG_BLK_DEV_INITRD
+       /*
+        * Move the initrd right behind the end of the decompressed
+-       * kernel image.
++       * kernel image. This also prevents initrd corruption caused by
++       * bss clearing since kernel_end will always be located behind the
++       * current bss section..
+        */
+-      if (INITRD_START && INITRD_SIZE &&
+-          INITRD_START < (unsigned long) output + SZ__bss_start) {
+-              check_ipl_parmblock(output + SZ__bss_start,
+-                                  INITRD_START + INITRD_SIZE);
+-              memmove(output + SZ__bss_start,
+-                      (void *) INITRD_START, INITRD_SIZE);
+-              INITRD_START = (unsigned long) output + SZ__bss_start;
++      if (INITRD_START && INITRD_SIZE && kernel_end > (void *) INITRD_START) {
++              check_ipl_parmblock(kernel_end, INITRD_SIZE);
++              memmove(kernel_end, (void *) INITRD_START, INITRD_SIZE);
++              INITRD_START = (unsigned long) kernel_end;
+       }
+ #endif
++      /*
++       * Clear bss section. free_mem_ptr and free_mem_end_ptr need to be
++       * initialized afterwards since they reside in bss.
++       */
++      memset(&_bss, 0, &_ebss - &_bss);
++      free_mem_ptr = (unsigned long) &_end;
++      free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
++
+       puts("Uncompressing Linux... ");
+       decompress(input_data, input_len, NULL, NULL, output, NULL, error);
+       puts("Ok, booting the kernel.\n");
diff --git a/queue-3.18/s390-uaccess-get_user-should-zero-on-failure-again.patch b/queue-3.18/s390-uaccess-get_user-should-zero-on-failure-again.patch
new file mode 100644 (file)
index 0000000..b99a196
--- /dev/null
@@ -0,0 +1,44 @@
+From d09c5373e8e4eaaa09233552cbf75dc4c4f21203 Mon Sep 17 00:00:00 2001
+From: Heiko Carstens <heiko.carstens@de.ibm.com>
+Date: Mon, 27 Mar 2017 09:48:04 +0200
+Subject: s390/uaccess: get_user() should zero on failure (again)
+
+From: Heiko Carstens <heiko.carstens@de.ibm.com>
+
+commit d09c5373e8e4eaaa09233552cbf75dc4c4f21203 upstream.
+
+Commit fd2d2b191fe7 ("s390: get_user() should zero on failure")
+intended to fix s390's get_user() implementation which did not zero
+the target operand if the read from user space faulted. Unfortunately
+the patch has no effect: the corresponding inline assembly specifies
+that the operand is only written to ("=") and the previous value is
+discarded.
+
+Therefore the compiler is free to and actually does omit the zero
+initialization.
+
+To fix this simply change the contraint modifier to "+", so the
+compiler cannot omit the initialization anymore.
+
+Fixes: c9ca78415ac1 ("s390/uaccess: provide inline variants of get_user/put_user")
+Fixes: fd2d2b191fe7 ("s390: get_user() should zero on failure")
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/s390/include/asm/uaccess.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/s390/include/asm/uaccess.h
++++ b/arch/s390/include/asm/uaccess.h
+@@ -148,7 +148,7 @@ unsigned long __must_check __copy_to_use
+               "       jg      2b\n"                           \
+               ".popsection\n"                                 \
+               EX_TABLE(0b,3b) EX_TABLE(1b,3b)                 \
+-              : "=d" (__rc), "=Q" (*(to))                     \
++              : "=d" (__rc), "+Q" (*(to))                     \
+               : "d" (size), "Q" (*(from)),                    \
+                 "d" (__reg0), "K" (-EFAULT)                   \
+               : "cc");                                        \
index 88dd3e349baee29d023e7355303b1d2facb02353..ac4fe785b8c27ee4f38b3cc88518fe7d681190bb 100644 (file)
@@ -14,3 +14,29 @@ char-drop-bogus-dependency-of-devport-on-m68k.patch
 char-lack-of-bool-string-made-config_devport-always-on.patch
 revert-arm-8457-1-psci-smp-is-built-only-for-smp.patch
 kvm-fix-page-struct-leak-in-handle_vmon.patch
+drm-vmwgfx-type-check-lookups-of-fence-objects.patch
+drm-vmwgfx-null-pointer-dereference-in-vmw_surface_define_ioctl.patch
+drm-vmwgfx-avoid-calling-vzalloc-with-a-0-size-in-vmw_get_cap_3d_ioctl.patch
+drm-ttm-drm-vmwgfx-relax-permission-checking-when-opening-surfaces.patch
+drm-vmwgfx-remove-getparam-error-message.patch
+drm-vmwgfx-fix-integer-overflow-in-vmw_surface_define_ioctl.patch
+c6x-ptrace-remove-useless-ptrace_setregset-implementation.patch
+mips-ptrace-preserve-previous-registers-for-short-regset-write.patch
+sparc-ptrace-preserve-previous-registers-for-short-regset-write.patch
+metag-ptrace-preserve-previous-registers-for-short-regset-write.patch
+metag-ptrace-provide-default-txstatus-for-short-nt_prstatus.patch
+metag-ptrace-reject-partial-nt_metag_rpipe-writes.patch
+s390-decompressor-fix-initrd-corruption-caused-by-bss-clear.patch
+s390-uaccess-get_user-should-zero-on-failure-again.patch
+reset-treeid-to-zero-on-smb2-tree_connect.patch
+ptrace-fix-ptrace_listen-race-corrupting-task-state.patch
+drivers-hv-balloon-don-t-crash-when-memory-is-added-in-non-sorted-order.patch
+rtc-s35390a-fix-reading-out-alarm.patch
+rtc-s35390a-make-sure-all-members-in-the-output-are-set.patch
+rtc-s35390a-implement-reset-routine-as-suggested-by-the-reference.patch
+rtc-s35390a-improve-irq-handling.patch
+alsa-seq-fix-racy-cell-insertions-during-snd_seq_pool_done.patch
+alsa-seq-fix-race-during-fifo-resize.patch
+powerpc-mm-add-missing-global-tlb-invalidate-if-cxl-is-active.patch
+powerpc-don-t-try-to-fix-up-misaligned-load-with-reservation-instructions.patch
+powerpc-boot-fix-zimage-toc-alignment.patch
diff --git a/queue-3.18/sparc-ptrace-preserve-previous-registers-for-short-regset-write.patch b/queue-3.18/sparc-ptrace-preserve-previous-registers-for-short-regset-write.patch
new file mode 100644 (file)
index 0000000..4f34b0f
--- /dev/null
@@ -0,0 +1,32 @@
+From d3805c546b275c8cc7d40f759d029ae92c7175f2 Mon Sep 17 00:00:00 2001
+From: Dave Martin <Dave.Martin@arm.com>
+Date: Mon, 27 Mar 2017 15:10:59 +0100
+Subject: sparc/ptrace: Preserve previous registers for short regset write
+
+From: Dave Martin <Dave.Martin@arm.com>
+
+commit d3805c546b275c8cc7d40f759d029ae92c7175f2 upstream.
+
+Ensure that if userspace supplies insufficient data to PTRACE_SETREGSET
+to fill all the registers, the thread's old registers are preserved.
+
+Signed-off-by: Dave Martin <Dave.Martin@arm.com>
+Acked-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/sparc/kernel/ptrace_64.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/sparc/kernel/ptrace_64.c
++++ b/arch/sparc/kernel/ptrace_64.c
+@@ -311,7 +311,7 @@ static int genregs64_set(struct task_str
+       }
+       if (!ret) {
+-              unsigned long y;
++              unsigned long y = regs->y;
+               ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+                                        &y,