]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 17 Apr 2018 13:24:30 +0000 (15:24 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 17 Apr 2018 13:24:30 +0000 (15:24 +0200)
added patches:
block-loop-fix-deadlock-after-loop_set_status.patch
getname_kernel-needs-to-make-sure-that-name-iname-in-long-case.patch
rtl8187-fix-null-pointer-dereference-in-priv-conf_mutex.patch
s390-ipl-ensure-loadparm-valid-flag-is-set.patch
s390-qdio-don-t-merge-error-output-buffers.patch
s390-qdio-don-t-retry-eqbs-after-ccq-96.patch

queue-4.4/block-loop-fix-deadlock-after-loop_set_status.patch [new file with mode: 0644]
queue-4.4/getname_kernel-needs-to-make-sure-that-name-iname-in-long-case.patch [new file with mode: 0644]
queue-4.4/rtl8187-fix-null-pointer-dereference-in-priv-conf_mutex.patch [new file with mode: 0644]
queue-4.4/s390-ipl-ensure-loadparm-valid-flag-is-set.patch [new file with mode: 0644]
queue-4.4/s390-qdio-don-t-merge-error-output-buffers.patch [new file with mode: 0644]
queue-4.4/s390-qdio-don-t-retry-eqbs-after-ccq-96.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/block-loop-fix-deadlock-after-loop_set_status.patch b/queue-4.4/block-loop-fix-deadlock-after-loop_set_status.patch
new file mode 100644 (file)
index 0000000..6a4d72d
--- /dev/null
@@ -0,0 +1,132 @@
+From 1e047eaab3bb5564f25b41e9cd3a053009f4e789 Mon Sep 17 00:00:00 2001
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Date: Fri, 6 Apr 2018 10:03:17 +0900
+Subject: block/loop: fix deadlock after loop_set_status
+
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+
+commit 1e047eaab3bb5564f25b41e9cd3a053009f4e789 upstream.
+
+syzbot is reporting deadlocks at __blkdev_get() [1].
+
+----------------------------------------
+[   92.493919] systemd-udevd   D12696   525      1 0x00000000
+[   92.495891] Call Trace:
+[   92.501560]  schedule+0x23/0x80
+[   92.502923]  schedule_preempt_disabled+0x5/0x10
+[   92.504645]  __mutex_lock+0x416/0x9e0
+[   92.510760]  __blkdev_get+0x73/0x4f0
+[   92.512220]  blkdev_get+0x12e/0x390
+[   92.518151]  do_dentry_open+0x1c3/0x2f0
+[   92.519815]  path_openat+0x5d9/0xdc0
+[   92.521437]  do_filp_open+0x7d/0xf0
+[   92.527365]  do_sys_open+0x1b8/0x250
+[   92.528831]  do_syscall_64+0x6e/0x270
+[   92.530341]  entry_SYSCALL_64_after_hwframe+0x42/0xb7
+
+[   92.931922] 1 lock held by systemd-udevd/525:
+[   92.933642]  #0: 00000000a2849e25 (&bdev->bd_mutex){+.+.}, at: __blkdev_get+0x73/0x4f0
+----------------------------------------
+
+The reason of deadlock turned out that wait_event_interruptible() in
+blk_queue_enter() got stuck with bdev->bd_mutex held at __blkdev_put()
+due to q->mq_freeze_depth == 1.
+
+----------------------------------------
+[   92.787172] a.out           S12584   634    633 0x80000002
+[   92.789120] Call Trace:
+[   92.796693]  schedule+0x23/0x80
+[   92.797994]  blk_queue_enter+0x3cb/0x540
+[   92.803272]  generic_make_request+0xf0/0x3d0
+[   92.807970]  submit_bio+0x67/0x130
+[   92.810928]  submit_bh_wbc+0x15e/0x190
+[   92.812461]  __block_write_full_page+0x218/0x460
+[   92.815792]  __writepage+0x11/0x50
+[   92.817209]  write_cache_pages+0x1ae/0x3d0
+[   92.825585]  generic_writepages+0x5a/0x90
+[   92.831865]  do_writepages+0x43/0xd0
+[   92.836972]  __filemap_fdatawrite_range+0xc1/0x100
+[   92.838788]  filemap_write_and_wait+0x24/0x70
+[   92.840491]  __blkdev_put+0x69/0x1e0
+[   92.841949]  blkdev_close+0x16/0x20
+[   92.843418]  __fput+0xda/0x1f0
+[   92.844740]  task_work_run+0x87/0xb0
+[   92.846215]  do_exit+0x2f5/0xba0
+[   92.850528]  do_group_exit+0x34/0xb0
+[   92.852018]  SyS_exit_group+0xb/0x10
+[   92.853449]  do_syscall_64+0x6e/0x270
+[   92.854944]  entry_SYSCALL_64_after_hwframe+0x42/0xb7
+
+[   92.943530] 1 lock held by a.out/634:
+[   92.945105]  #0: 00000000a2849e25 (&bdev->bd_mutex){+.+.}, at: __blkdev_put+0x3c/0x1e0
+----------------------------------------
+
+The reason of q->mq_freeze_depth == 1 turned out that loop_set_status()
+forgot to call blk_mq_unfreeze_queue() at error paths for
+info->lo_encrypt_type != NULL case.
+
+----------------------------------------
+[   37.509497] CPU: 2 PID: 634 Comm: a.out Tainted: G        W        4.16.0+ #457
+[   37.513608] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 05/19/2017
+[   37.518832] RIP: 0010:blk_freeze_queue_start+0x17/0x40
+[   37.521778] RSP: 0018:ffffb0c2013e7c60 EFLAGS: 00010246
+[   37.524078] RAX: 0000000000000000 RBX: ffff8b07b1519798 RCX: 0000000000000000
+[   37.527015] RDX: 0000000000000002 RSI: ffffb0c2013e7cc0 RDI: ffff8b07b1519798
+[   37.529934] RBP: ffffb0c2013e7cc0 R08: 0000000000000008 R09: 47a189966239b898
+[   37.532684] R10: dad78b99b278552f R11: 9332dca72259d5ef R12: ffff8b07acd73678
+[   37.535452] R13: 0000000000004c04 R14: 0000000000000000 R15: ffff8b07b841e940
+[   37.538186] FS:  00007fede33b9740(0000) GS:ffff8b07b8e80000(0000) knlGS:0000000000000000
+[   37.541168] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[   37.543590] CR2: 00000000206fdf18 CR3: 0000000130b30006 CR4: 00000000000606e0
+[   37.546410] Call Trace:
+[   37.547902]  blk_freeze_queue+0x9/0x30
+[   37.549968]  loop_set_status+0x67/0x3c0 [loop]
+[   37.549975]  loop_set_status64+0x3b/0x70 [loop]
+[   37.549986]  lo_ioctl+0x223/0x810 [loop]
+[   37.549995]  blkdev_ioctl+0x572/0x980
+[   37.550003]  block_ioctl+0x34/0x40
+[   37.550006]  do_vfs_ioctl+0xa7/0x6d0
+[   37.550017]  ksys_ioctl+0x6b/0x80
+[   37.573076]  SyS_ioctl+0x5/0x10
+[   37.574831]  do_syscall_64+0x6e/0x270
+[   37.576769]  entry_SYSCALL_64_after_hwframe+0x42/0xb7
+----------------------------------------
+
+[1] https://syzkaller.appspot.com/bug?id=cd662bc3f6022c0979d01a262c318fab2ee9b56f
+
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Reported-by: syzbot <bot+48594378e9851eab70bcd6f99327c7db58c5a28a@syzkaller.appspotmail.com>
+Fixes: ecdd09597a572513 ("block/loop: fix race between I/O and set_status")
+Cc: Ming Lei <tom.leiming@gmail.com>
+Cc: Dmitry Vyukov <dvyukov@google.com>
+Cc: stable <stable@vger.kernel.org>
+Cc: Jens Axboe <axboe@fb.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/loop.c |   12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -1121,11 +1121,15 @@ loop_set_status(struct loop_device *lo,
+       if (info->lo_encrypt_type) {
+               unsigned int type = info->lo_encrypt_type;
+-              if (type >= MAX_LO_CRYPT)
+-                      return -EINVAL;
++              if (type >= MAX_LO_CRYPT) {
++                      err = -EINVAL;
++                      goto exit;
++              }
+               xfer = xfer_funcs[type];
+-              if (xfer == NULL)
+-                      return -EINVAL;
++              if (xfer == NULL) {
++                      err = -EINVAL;
++                      goto exit;
++              }
+       } else
+               xfer = NULL;
diff --git a/queue-4.4/getname_kernel-needs-to-make-sure-that-name-iname-in-long-case.patch b/queue-4.4/getname_kernel-needs-to-make-sure-that-name-iname-in-long-case.patch
new file mode 100644 (file)
index 0000000..48f5d3f
--- /dev/null
@@ -0,0 +1,33 @@
+From 30ce4d1903e1d8a7ccd110860a5eef3c638ed8be Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@zeniv.linux.org.uk>
+Date: Sun, 8 Apr 2018 11:57:10 -0400
+Subject: getname_kernel() needs to make sure that ->name != ->iname in long case
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+commit 30ce4d1903e1d8a7ccd110860a5eef3c638ed8be upstream.
+
+missed it in "kill struct filename.separate" several years ago.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/namei.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/namei.c
++++ b/fs/namei.c
+@@ -219,9 +219,10 @@ getname_kernel(const char * filename)
+       if (len <= EMBEDDED_NAME_MAX) {
+               result->name = (char *)result->iname;
+       } else if (len <= PATH_MAX) {
++              const size_t size = offsetof(struct filename, iname[1]);
+               struct filename *tmp;
+-              tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
++              tmp = kmalloc(size, GFP_KERNEL);
+               if (unlikely(!tmp)) {
+                       __putname(result);
+                       return ERR_PTR(-ENOMEM);
diff --git a/queue-4.4/rtl8187-fix-null-pointer-dereference-in-priv-conf_mutex.patch b/queue-4.4/rtl8187-fix-null-pointer-dereference-in-priv-conf_mutex.patch
new file mode 100644 (file)
index 0000000..39da38d
--- /dev/null
@@ -0,0 +1,74 @@
+From 7972326a26b5bf8dc2adac575c4e03ee7e9d193a Mon Sep 17 00:00:00 2001
+From: Sudhir Sreedharan <ssreedharan@mvista.com>
+Date: Thu, 15 Feb 2018 12:52:45 +0530
+Subject: rtl8187: Fix NULL pointer dereference in priv->conf_mutex
+
+From: Sudhir Sreedharan <ssreedharan@mvista.com>
+
+commit 7972326a26b5bf8dc2adac575c4e03ee7e9d193a upstream.
+
+This can be reproduced by bind/unbind the driver multiple times
+in AM3517 board.
+
+Analysis revealed that rtl8187_start() was invoked before probe
+finishes(ie. before the mutex is initialized).
+
+ INFO: trying to register non-static key.
+ the code is fine but needs lockdep annotation.
+ turning off the locking correctness validator.
+ CPU: 0 PID: 821 Comm: wpa_supplicant Not tainted 4.9.80-dirty #250
+ Hardware name: Generic AM3517 (Flattened Device Tree)
+ [<c010e0d8>] (unwind_backtrace) from [<c010beac>] (show_stack+0x10/0x14)
+ [<c010beac>] (show_stack) from [<c017401c>] (register_lock_class+0x4f4/0x55c)
+ [<c017401c>] (register_lock_class) from [<c0176fe0>] (__lock_acquire+0x74/0x1938)
+ [<c0176fe0>] (__lock_acquire) from [<c0178cfc>] (lock_acquire+0xfc/0x23c)
+ [<c0178cfc>] (lock_acquire) from [<c08aa2f8>] (mutex_lock_nested+0x50/0x3b0)
+ [<c08aa2f8>] (mutex_lock_nested) from [<c05f5bf8>] (rtl8187_start+0x2c/0xd54)
+ [<c05f5bf8>] (rtl8187_start) from [<c082dea0>] (drv_start+0xa8/0x320)
+ [<c082dea0>] (drv_start) from [<c084d1d4>] (ieee80211_do_open+0x2bc/0x8e4)
+ [<c084d1d4>] (ieee80211_do_open) from [<c069be94>] (__dev_open+0xb8/0x120)
+ [<c069be94>] (__dev_open) from [<c069c11c>] (__dev_change_flags+0x88/0x14c)
+ [<c069c11c>] (__dev_change_flags) from [<c069c1f8>] (dev_change_flags+0x18/0x48)
+ [<c069c1f8>] (dev_change_flags) from [<c0710b08>] (devinet_ioctl+0x738/0x840)
+ [<c0710b08>] (devinet_ioctl) from [<c067925c>] (sock_ioctl+0x164/0x2f4)
+ [<c067925c>] (sock_ioctl) from [<c02883f8>] (do_vfs_ioctl+0x8c/0x9d0)
+ [<c02883f8>] (do_vfs_ioctl) from [<c0288da8>] (SyS_ioctl+0x6c/0x7c)
+ [<c0288da8>] (SyS_ioctl) from [<c0107760>] (ret_fast_syscall+0x0/0x1c)
+ Unable to handle kernel NULL pointer dereference at virtual address 00000000
+ pgd = cd1ec000
+ [00000000] *pgd=8d1de831, *pte=00000000, *ppte=00000000
+ Internal error: Oops: 817 [#1] PREEMPT ARM
+ Modules linked in:
+ CPU: 0 PID: 821 Comm: wpa_supplicant Not tainted 4.9.80-dirty #250
+ Hardware name: Generic AM3517 (Flattened Device Tree)
+ task: ce73eec0 task.stack: cd1ea000
+ PC is at mutex_lock_nested+0xe8/0x3b0
+ LR is at mutex_lock_nested+0xd0/0x3b0
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Sudhir Sreedharan <ssreedharan@mvista.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c
++++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c
+@@ -1454,6 +1454,7 @@ static int rtl8187_probe(struct usb_inte
+               goto err_free_dev;
+       }
+       mutex_init(&priv->io_mutex);
++      mutex_init(&priv->conf_mutex);
+       SET_IEEE80211_DEV(dev, &intf->dev);
+       usb_set_intfdata(intf, dev);
+@@ -1627,7 +1628,6 @@ static int rtl8187_probe(struct usb_inte
+               printk(KERN_ERR "rtl8187: Cannot register device\n");
+               goto err_free_dmabuf;
+       }
+-      mutex_init(&priv->conf_mutex);
+       skb_queue_head_init(&priv->b_tx_status.queue);
+       wiphy_info(dev->wiphy, "hwaddr %pM, %s V%d + %s, rfkill mask %d\n",
diff --git a/queue-4.4/s390-ipl-ensure-loadparm-valid-flag-is-set.patch b/queue-4.4/s390-ipl-ensure-loadparm-valid-flag-is-set.patch
new file mode 100644 (file)
index 0000000..e14b7d6
--- /dev/null
@@ -0,0 +1,35 @@
+From 15deb080a6087b73089139569558965750e69d67 Mon Sep 17 00:00:00 2001
+From: Vasily Gorbik <gor@linux.ibm.com>
+Date: Tue, 3 Apr 2018 16:02:15 +0200
+Subject: s390/ipl: ensure loadparm valid flag is set
+
+From: Vasily Gorbik <gor@linux.ibm.com>
+
+commit 15deb080a6087b73089139569558965750e69d67 upstream.
+
+When loadparm is set in reipl parm block, the kernel should also set
+DIAG308_FLAGS_LP_VALID flag.
+
+This fixes loadparm ignoring during z/VM fcp -> ccw reipl and kvm direct
+boot -> ccw reipl.
+
+Cc: <stable@vger.kernel.org>
+Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/s390/kernel/ipl.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/s390/kernel/ipl.c
++++ b/arch/s390/kernel/ipl.c
+@@ -798,6 +798,7 @@ static ssize_t reipl_generic_loadparm_st
+       /* copy and convert to ebcdic */
+       memcpy(ipb->hdr.loadparm, buf, lp_len);
+       ASCEBC(ipb->hdr.loadparm, LOADPARM_LEN);
++      ipb->hdr.flags |= DIAG308_FLAGS_LP_VALID;
+       return len;
+ }
diff --git a/queue-4.4/s390-qdio-don-t-merge-error-output-buffers.patch b/queue-4.4/s390-qdio-don-t-merge-error-output-buffers.patch
new file mode 100644 (file)
index 0000000..5bf8c2e
--- /dev/null
@@ -0,0 +1,93 @@
+From 0cf1e05157b9e5530dcc3ca9fec9bf617fc93375 Mon Sep 17 00:00:00 2001
+From: Julian Wiedmann <jwi@linux.vnet.ibm.com>
+Date: Wed, 7 Mar 2018 14:01:01 +0100
+Subject: s390/qdio: don't merge ERROR output buffers
+
+From: Julian Wiedmann <jwi@linux.vnet.ibm.com>
+
+commit 0cf1e05157b9e5530dcc3ca9fec9bf617fc93375 upstream.
+
+On an Output queue, both EMPTY and PENDING buffer states imply that the
+buffer is ready for completion-processing by the upper-layer drivers.
+
+So for a non-QEBSM Output queue, get_buf_states() merges mixed
+batches of PENDING and EMPTY buffers into one large batch of EMPTY
+buffers. The upper-layer driver (ie. qeth) later distuingishes PENDING
+from EMPTY by inspecting the slsb_state for
+QDIO_OUTBUF_STATE_FLAG_PENDING.
+
+But the merge logic in get_buf_states() contains a bug that causes us to
+erronously also merge ERROR buffers into such a batch of EMPTY buffers
+(ERROR is 0xaf, EMPTY is 0xa1; so ERROR & EMPTY == EMPTY).
+Effectively, most outbound ERROR buffers are currently discarded
+silently and processed as if they had succeeded.
+
+Note that this affects _all_ non-QEBSM device types, not just IQD with CQ.
+
+Fix it by explicitly spelling out the exact conditions for merging.
+
+For extracting the "get initial state" part out of the loop, this relies
+on the fact that get_buf_states() is never called with a count of 0. The
+QEBSM path already strictly requires this, and the two callers with
+variable 'count' make sure of it.
+
+Fixes: 104ea556ee7f ("qdio: support asynchronous delivery of storage blocks")
+Cc: <stable@vger.kernel.org> #v3.2+
+Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com>
+Reviewed-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
+Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/s390/cio/qdio_main.c |   31 ++++++++++++++++++++-----------
+ 1 file changed, 20 insertions(+), 11 deletions(-)
+
+--- a/drivers/s390/cio/qdio_main.c
++++ b/drivers/s390/cio/qdio_main.c
+@@ -205,7 +205,10 @@ again:
+       return 0;
+ }
+-/* returns number of examined buffers and their common state in *state */
++/*
++ * Returns number of examined buffers and their common state in *state.
++ * Requested number of buffers-to-examine must be > 0.
++ */
+ static inline int get_buf_states(struct qdio_q *q, unsigned int bufnr,
+                                unsigned char *state, unsigned int count,
+                                int auto_ack, int merge_pending)
+@@ -216,17 +219,23 @@ static inline int get_buf_states(struct
+       if (is_qebsm(q))
+               return qdio_do_eqbs(q, state, bufnr, count, auto_ack);
+-      for (i = 0; i < count; i++) {
+-              if (!__state) {
+-                      __state = q->slsb.val[bufnr];
+-                      if (merge_pending && __state == SLSB_P_OUTPUT_PENDING)
+-                              __state = SLSB_P_OUTPUT_EMPTY;
+-              } else if (merge_pending) {
+-                      if ((q->slsb.val[bufnr] & __state) != __state)
+-                              break;
+-              } else if (q->slsb.val[bufnr] != __state)
+-                      break;
++      /* get initial state: */
++      __state = q->slsb.val[bufnr];
++      if (merge_pending && __state == SLSB_P_OUTPUT_PENDING)
++              __state = SLSB_P_OUTPUT_EMPTY;
++
++      for (i = 1; i < count; i++) {
+               bufnr = next_buf(bufnr);
++
++              /* merge PENDING into EMPTY: */
++              if (merge_pending &&
++                  q->slsb.val[bufnr] == SLSB_P_OUTPUT_PENDING &&
++                  __state == SLSB_P_OUTPUT_EMPTY)
++                      continue;
++
++              /* stop if next state differs from initial state: */
++              if (q->slsb.val[bufnr] != __state)
++                      break;
+       }
+       *state = __state;
+       return i;
diff --git a/queue-4.4/s390-qdio-don-t-retry-eqbs-after-ccq-96.patch b/queue-4.4/s390-qdio-don-t-retry-eqbs-after-ccq-96.patch
new file mode 100644 (file)
index 0000000..34489c2
--- /dev/null
@@ -0,0 +1,77 @@
+From dae55b6fef58530c13df074bcc182c096609339e Mon Sep 17 00:00:00 2001
+From: Julian Wiedmann <jwi@linux.vnet.ibm.com>
+Date: Mon, 5 Mar 2018 09:39:38 +0100
+Subject: s390/qdio: don't retry EQBS after CCQ 96
+
+From: Julian Wiedmann <jwi@linux.vnet.ibm.com>
+
+commit dae55b6fef58530c13df074bcc182c096609339e upstream.
+
+Immediate retry of EQBS after CCQ 96 means that we potentially misreport
+the state of buffers inspected during the first EQBS call.
+
+This occurs when
+1. the first EQBS finds all inspected buffers still in the initial state
+   set by the driver (ie INPUT EMPTY or OUTPUT PRIMED),
+2. the EQBS terminates early with CCQ 96, and
+3. by the time that the second EQBS comes around, the state of those
+   previously inspected buffers has changed.
+
+If the state reported by the second EQBS is 'driver-owned', all we know
+is that the previous buffers are driver-owned now as well. But we can't
+tell if they all have the same state. So for instance
+- the second EQBS reports OUTPUT EMPTY, but any number of the previous
+  buffers could be OUTPUT ERROR by now,
+- the second EQBS reports OUTPUT ERROR, but any number of the previous
+  buffers could be OUTPUT EMPTY by now.
+
+Effectively, this can result in both over- and underreporting of errors.
+
+If the state reported by the second EQBS is 'HW-owned', that doesn't
+guarantee that the previous buffers have not been switched to
+driver-owned in the mean time. So for instance
+- the second EQBS reports INPUT EMPTY, but any number of the previous
+  buffers could be INPUT PRIMED (or INPUT ERROR) by now.
+
+This would result in failure to process pending work on the queue. If
+it's the final check before yielding initiative, this can cause
+a (temporary) queue stall due to IRQ avoidance.
+
+Fixes: 25f269f17316 ("[S390] qdio: EQBS retry after CCQ 96")
+Cc: <stable@vger.kernel.org> #v3.2+
+Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com>
+Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/s390/cio/qdio_main.c |   11 ++---------
+ 1 file changed, 2 insertions(+), 9 deletions(-)
+
+--- a/drivers/s390/cio/qdio_main.c
++++ b/drivers/s390/cio/qdio_main.c
+@@ -126,7 +126,7 @@ static inline int qdio_check_ccq(struct
+ static int qdio_do_eqbs(struct qdio_q *q, unsigned char *state,
+                       int start, int count, int auto_ack)
+ {
+-      int rc, tmp_count = count, tmp_start = start, nr = q->nr, retried = 0;
++      int rc, tmp_count = count, tmp_start = start, nr = q->nr;
+       unsigned int ccq = 0;
+       qperf_inc(q, eqbs);
+@@ -149,14 +149,7 @@ again:
+               qperf_inc(q, eqbs_partial);
+               DBF_DEV_EVENT(DBF_WARN, q->irq_ptr, "EQBS part:%02x",
+                       tmp_count);
+-              /*
+-               * Retry once, if that fails bail out and process the
+-               * extracted buffers before trying again.
+-               */
+-              if (!retried++)
+-                      goto again;
+-              else
+-                      return count - tmp_count;
++              return count - tmp_count;
+       }
+       DBF_ERROR("%4x EQBS ERROR", SCH_NO(q));
index 3f1e6de3ee76aacf05518c6fe97d728aeef4ca5b..82ea0748656ca3da60410ec43e2c91a1c5fa5c2e 100644 (file)
@@ -6,3 +6,9 @@ perf-intel-pt-fix-error-recovery-from-missing-tip-packet.patch
 perf-intel-pt-fix-timestamp-following-overflow.patch
 radeon-hide-pointless-warning-when-compile-testing.patch
 revert-perf-tests-decompress-kernel-module-before-objdump.patch
+block-loop-fix-deadlock-after-loop_set_status.patch
+s390-qdio-don-t-retry-eqbs-after-ccq-96.patch
+s390-qdio-don-t-merge-error-output-buffers.patch
+s390-ipl-ensure-loadparm-valid-flag-is-set.patch
+getname_kernel-needs-to-make-sure-that-name-iname-in-long-case.patch
+rtl8187-fix-null-pointer-dereference-in-priv-conf_mutex.patch