From: Greg Kroah-Hartman Date: Tue, 18 Apr 2017 18:34:23 +0000 (+0200) Subject: 3.18-stable patches X-Git-Tag: v4.4.63~22 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9566b7022154e4c2c1d10da92fd5ced7406b6687;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches 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 --- 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 index 00000000000..858b0502bec --- /dev/null +++ b/queue-3.18/alsa-seq-fix-race-during-fifo-resize.patch @@ -0,0 +1,38 @@ +From 2d7d54002e396c180db0c800c1046f0a3c471597 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Fri, 24 Mar 2017 17:07:57 +0100 +Subject: ALSA: seq: Fix race during FIFO resize + +From: Takashi Iwai + +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 +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..18768035da3 --- /dev/null +++ b/queue-3.18/alsa-seq-fix-racy-cell-insertions-during-snd_seq_pool_done.patch @@ -0,0 +1,103 @@ +From c520ff3d03f0b5db7146d9beed6373ad5d2a5e0e Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 21 Mar 2017 13:56:04 +0100 +Subject: ALSA: seq: Fix racy cell insertions during snd_seq_pool_done() + +From: Takashi Iwai + +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 +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..f0ebb0872a2 --- /dev/null +++ b/queue-3.18/c6x-ptrace-remove-useless-ptrace_setregset-implementation.patch @@ -0,0 +1,82 @@ +From fb411b837b587a32046dc4f369acb93a10b1def8 Mon Sep 17 00:00:00 2001 +From: Dave Martin +Date: Mon, 27 Mar 2017 15:10:53 +0100 +Subject: c6x/ptrace: Remove useless PTRACE_SETREGSET implementation + +From: Dave Martin + +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 +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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, +- ®s, +- 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, +- ®s, +- (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, +- ®s, +- (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 index 00000000000..47a965b116a --- /dev/null +++ b/queue-3.18/drivers-hv-balloon-don-t-crash-when-memory-is-added-in-non-sorted-order.patch @@ -0,0 +1,46 @@ +From 77c0c9735bc0ba5898e637a3a20d6bcb50e3f67d Mon Sep 17 00:00:00 2001 +From: Vitaly Kuznetsov +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 + +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 +Signed-off-by: K. Y. Srinivasan +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..da7c97a4985 --- /dev/null +++ b/queue-3.18/drm-ttm-drm-vmwgfx-relax-permission-checking-when-opening-surfaces.patch @@ -0,0 +1,172 @@ +From fe25deb7737ce6c0879ccf79c99fa1221d428bf2 Mon Sep 17 00:00:00 2001 +From: Thomas Hellstrom +Date: Mon, 27 Mar 2017 11:21:25 +0200 +Subject: drm/ttm, drm/vmwgfx: Relax permission checking when opening surfaces + +From: Thomas Hellstrom + +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 +Reviewed-by: Sinclair Yeh +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..9bd250d337b --- /dev/null +++ b/queue-3.18/drm-vmwgfx-avoid-calling-vzalloc-with-a-0-size-in-vmw_get_cap_3d_ioctl.patch @@ -0,0 +1,34 @@ +From 63774069d9527a1aeaa4aa20e929ef5e8e9ecc38 Mon Sep 17 00:00:00 2001 +From: Murray McAllister +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 + +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 +Reviewed-by: Sinclair Yeh +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..8895e3ee6fa --- /dev/null +++ b/queue-3.18/drm-vmwgfx-fix-integer-overflow-in-vmw_surface_define_ioctl.patch @@ -0,0 +1,39 @@ +From e7e11f99564222d82f0ce84bd521e57d78a6b678 Mon Sep 17 00:00:00 2001 +From: Li Qiang +Date: Mon, 27 Mar 2017 20:10:53 -0700 +Subject: drm/vmwgfx: fix integer overflow in vmw_surface_define_ioctl() + +From: Li Qiang + +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 +Reviewed-by: Thomas Hellstrom +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..1312fefbb52 --- /dev/null +++ b/queue-3.18/drm-vmwgfx-null-pointer-dereference-in-vmw_surface_define_ioctl.patch @@ -0,0 +1,36 @@ +From 36274ab8c596f1240c606bb514da329add2a1bcd Mon Sep 17 00:00:00 2001 +From: Murray McAllister +Date: Mon, 27 Mar 2017 11:12:53 +0200 +Subject: drm/vmwgfx: NULL pointer dereference in vmw_surface_define_ioctl() + +From: Murray McAllister + +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 +Reviewed-by: Sinclair Yeh +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..f38bdb9860a --- /dev/null +++ b/queue-3.18/drm-vmwgfx-remove-getparam-error-message.patch @@ -0,0 +1,33 @@ +From 53e16798b0864464c5444a204e1bb93ae246c429 Mon Sep 17 00:00:00 2001 +From: Thomas Hellstrom +Date: Mon, 27 Mar 2017 13:06:05 +0200 +Subject: drm/vmwgfx: Remove getparam error message + +From: Thomas Hellstrom + +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 +Reviewed-by: Brian Paul +Reviewed-by: Sinclair Yeh +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..f08cda47cef --- /dev/null +++ b/queue-3.18/drm-vmwgfx-type-check-lookups-of-fence-objects.patch @@ -0,0 +1,157 @@ +From f7652afa8eadb416b23eb57dec6f158529942041 Mon Sep 17 00:00:00 2001 +From: Thomas Hellstrom +Date: Mon, 27 Mar 2017 11:09:08 +0200 +Subject: drm/vmwgfx: Type-check lookups of fence objects + +From: Thomas Hellstrom + +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 +Reviewed-by: Sinclair Yeh +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..5fa2558a73b --- /dev/null +++ b/queue-3.18/metag-ptrace-preserve-previous-registers-for-short-regset-write.patch @@ -0,0 +1,32 @@ +From a78ce80d2c9178351b34d78fec805140c29c193e Mon Sep 17 00:00:00 2001 +From: Dave Martin +Date: Mon, 27 Mar 2017 15:10:55 +0100 +Subject: metag/ptrace: Preserve previous registers for short regset write + +From: Dave Martin + +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 +Acked-by: James Hogan +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..010686b3eee --- /dev/null +++ b/queue-3.18/metag-ptrace-provide-default-txstatus-for-short-nt_prstatus.patch @@ -0,0 +1,60 @@ +From 5fe81fe98123ce41265c65e95d34418d30d005d1 Mon Sep 17 00:00:00 2001 +From: Dave Martin +Date: Mon, 27 Mar 2017 15:10:56 +0100 +Subject: metag/ptrace: Provide default TXSTATUS for short NT_PRSTATUS + +From: Dave Martin + +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 +Signed-off-by: Dave Martin +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..bfa6cf6ebc2 --- /dev/null +++ b/queue-3.18/metag-ptrace-reject-partial-nt_metag_rpipe-writes.patch @@ -0,0 +1,35 @@ +From 7195ee3120d878259e8d94a5d9f808116f34d5ea Mon Sep 17 00:00:00 2001 +From: Dave Martin +Date: Mon, 27 Mar 2017 15:10:57 +0100 +Subject: metag/ptrace: Reject partial NT_METAG_RPIPE writes + +From: Dave Martin + +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 +Acked-by: James Hogan +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..dac11ed098b --- /dev/null +++ b/queue-3.18/mips-ptrace-preserve-previous-registers-for-short-regset-write.patch @@ -0,0 +1,32 @@ +From d614fd58a2834cfe4efa472c33c8f3ce2338b09b Mon Sep 17 00:00:00 2001 +From: Dave Martin +Date: Mon, 27 Mar 2017 15:10:58 +0100 +Subject: mips/ptrace: Preserve previous registers for short regset write + +From: Dave Martin + +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 +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..1192cde9f63 --- /dev/null +++ b/queue-3.18/powerpc-boot-fix-zimage-toc-alignment.patch @@ -0,0 +1,33 @@ +From 97ee351b50a49717543533cfb85b4bf9d88c9680 Mon Sep 17 00:00:00 2001 +From: Michael Ellerman +Date: Tue, 7 Mar 2017 16:14:49 +1100 +Subject: powerpc/boot: Fix zImage TOC alignment + +From: Michael Ellerman + +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 +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..3f6c8fd9ac5 --- /dev/null +++ b/queue-3.18/powerpc-don-t-try-to-fix-up-misaligned-load-with-reservation-instructions.patch @@ -0,0 +1,71 @@ +From 48fe9e9488743eec9b7c1addd3c93f12f2123d54 Mon Sep 17 00:00:00 2001 +From: Paul Mackerras +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 + +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 +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..20b6452711f --- /dev/null +++ b/queue-3.18/powerpc-mm-add-missing-global-tlb-invalidate-if-cxl-is-active.patch @@ -0,0 +1,52 @@ +From 88b1bf7268f56887ca88eb09c6fb0f4fc970121a Mon Sep 17 00:00:00 2001 +From: Frederic Barrat +Date: Wed, 29 Mar 2017 19:19:42 +0200 +Subject: powerpc/mm: Add missing global TLB invalidate if cxl is active + +From: Frederic Barrat + +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 +Reviewed-by: Aneesh Kumar K.V +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..00d87460b73 --- /dev/null +++ b/queue-3.18/ptrace-fix-ptrace_listen-race-corrupting-task-state.patch @@ -0,0 +1,61 @@ +From 5402e97af667e35e54177af8f6575518bf251d51 Mon Sep 17 00:00:00 2001 +From: "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 + +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 +Acked-by: Oleg Nesterov +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..a5be084c320 --- /dev/null +++ b/queue-3.18/reset-treeid-to-zero-on-smb2-tree_connect.patch @@ -0,0 +1,38 @@ +From 806a28efe9b78ffae5e2757e1ee924b8e50c08ab Mon Sep 17 00:00:00 2001 +From: Jan-Marek Glogowski +Date: Mon, 20 Feb 2017 12:25:58 +0100 +Subject: Reset TreeId to zero on SMB2 TREE_CONNECT + +From: Jan-Marek Glogowski + +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 +Reviewed-by: Aurelien Aptel +Tested-by: Aurelien Aptel +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..dfb76a5779c --- /dev/null +++ b/queue-3.18/rtc-s35390a-fix-reading-out-alarm.patch @@ -0,0 +1,98 @@ +From f87e904ddd8f0ef120e46045b0addeb1cc88354e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +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 + +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 +Signed-off-by: Alexandre Belloni +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..c2822f14117 --- /dev/null +++ b/queue-3.18/rtc-s35390a-implement-reset-routine-as-suggested-by-the-reference.patch @@ -0,0 +1,133 @@ +From 8e6583f1b5d1f5f129b873f1428b7e414263d847 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +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 + +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 +Signed-off-by: Alexandre Belloni +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + #include + #include ++#include + + #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 index 00000000000..feb479a0797 --- /dev/null +++ b/queue-3.18/rtc-s35390a-improve-irq-handling.patch @@ -0,0 +1,127 @@ +From 3bd32722c827d00eafe8e6d5b83e9f3148ea7c7e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +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 + +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 +Signed-off-by: Alexandre Belloni +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..edc348a4c53 --- /dev/null +++ b/queue-3.18/rtc-s35390a-make-sure-all-members-in-the-output-are-set.patch @@ -0,0 +1,54 @@ +From fdd4bc9313e59a1757cfc8ac5836cff55ec03eeb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +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 + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..f7bee9e5076 --- /dev/null +++ b/queue-3.18/s390-decompressor-fix-initrd-corruption-caused-by-bss-clear.patch @@ -0,0 +1,85 @@ +From d82c0d12c92705ef468683c9b7a8298dd61ed191 Mon Sep 17 00:00:00 2001 +From: Marcelo Henrique Cerri +Date: Mon, 13 Mar 2017 12:14:58 -0300 +Subject: s390/decompressor: fix initrd corruption caused by bss clear + +From: Marcelo Henrique Cerri + +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 +Reviewed-by: Vineetha HariPai +Signed-off-by: Marcelo Henrique Cerri +Signed-off-by: Heiko Carstens +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..b99a196c444 --- /dev/null +++ b/queue-3.18/s390-uaccess-get_user-should-zero-on-failure-again.patch @@ -0,0 +1,44 @@ +From d09c5373e8e4eaaa09233552cbf75dc4c4f21203 Mon Sep 17 00:00:00 2001 +From: Heiko Carstens +Date: Mon, 27 Mar 2017 09:48:04 +0200 +Subject: s390/uaccess: get_user() should zero on failure (again) + +From: Heiko Carstens + +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 +Signed-off-by: Heiko Carstens +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman + +--- + 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"); \ diff --git a/queue-3.18/series b/queue-3.18/series index 88dd3e349ba..ac4fe785b8c 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -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 index 00000000000..4f34b0f283a --- /dev/null +++ b/queue-3.18/sparc-ptrace-preserve-previous-registers-for-short-regset-write.patch @@ -0,0 +1,32 @@ +From d3805c546b275c8cc7d40f759d029ae92c7175f2 Mon Sep 17 00:00:00 2001 +From: Dave Martin +Date: Mon, 27 Mar 2017 15:10:59 +0100 +Subject: sparc/ptrace: Preserve previous registers for short regset write + +From: Dave Martin + +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 +Acked-by: David S. Miller +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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,