]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.2-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 12 Jul 2019 12:18:54 +0000 (14:18 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 12 Jul 2019 12:18:54 +0000 (14:18 +0200)
added patches:
staging-bcm2835-camera-ensure-all-buffers-are-returned-on-disable.patch
staging-bcm2835-camera-handle-empty-eos-buffers-whilst-streaming.patch
staging-bcm2835-camera-remove-check-of-the-number-of-buffers-supplied.patch
staging-bcm2835-camera-replace-spinlock-protecting-context_map-with-mutex.patch
staging-fsl-dpaa2-ethsw-fix-memory-leak-of-switchdev_work.patch
staging-rtl8712-reduce-stack-usage-again.patch
staging-vchiq-make-wait-events-interruptible.patch
staging-vchiq-revert-switch-to-wait_for_completion_killable.patch
staging-vchiq_2835_arm-revert-quit-using-custom-down_interruptible.patch

queue-5.2/series
queue-5.2/staging-bcm2835-camera-ensure-all-buffers-are-returned-on-disable.patch [new file with mode: 0644]
queue-5.2/staging-bcm2835-camera-handle-empty-eos-buffers-whilst-streaming.patch [new file with mode: 0644]
queue-5.2/staging-bcm2835-camera-remove-check-of-the-number-of-buffers-supplied.patch [new file with mode: 0644]
queue-5.2/staging-bcm2835-camera-replace-spinlock-protecting-context_map-with-mutex.patch [new file with mode: 0644]
queue-5.2/staging-fsl-dpaa2-ethsw-fix-memory-leak-of-switchdev_work.patch [new file with mode: 0644]
queue-5.2/staging-rtl8712-reduce-stack-usage-again.patch [new file with mode: 0644]
queue-5.2/staging-vchiq-make-wait-events-interruptible.patch [new file with mode: 0644]
queue-5.2/staging-vchiq-revert-switch-to-wait_for_completion_killable.patch [new file with mode: 0644]
queue-5.2/staging-vchiq_2835_arm-revert-quit-using-custom-down_interruptible.patch [new file with mode: 0644]

index 836028d833d911526718283a813cf2de1fe61032..8c6bd6fda849f0029d3cef169a0f54153a0d6011 100644 (file)
@@ -50,3 +50,12 @@ coresight-tmc-etf-do-not-call-smp_processor_id-from-preemptible.patch
 carl9170-fix-misuse-of-device-driver-api.patch
 revert-x86-build-move-_etext-to-actual-end-of-.text.patch
 vmci-fix-integer-overflow-in-vmci-handle-arrays.patch
+staging-vchiq_2835_arm-revert-quit-using-custom-down_interruptible.patch
+staging-vchiq-make-wait-events-interruptible.patch
+staging-vchiq-revert-switch-to-wait_for_completion_killable.patch
+staging-fsl-dpaa2-ethsw-fix-memory-leak-of-switchdev_work.patch
+staging-bcm2835-camera-replace-spinlock-protecting-context_map-with-mutex.patch
+staging-bcm2835-camera-ensure-all-buffers-are-returned-on-disable.patch
+staging-bcm2835-camera-remove-check-of-the-number-of-buffers-supplied.patch
+staging-bcm2835-camera-handle-empty-eos-buffers-whilst-streaming.patch
+staging-rtl8712-reduce-stack-usage-again.patch
diff --git a/queue-5.2/staging-bcm2835-camera-ensure-all-buffers-are-returned-on-disable.patch b/queue-5.2/staging-bcm2835-camera-ensure-all-buffers-are-returned-on-disable.patch
new file mode 100644 (file)
index 0000000..5f58820
--- /dev/null
@@ -0,0 +1,103 @@
+From 70ec64ccdaac5d8f634338e33b016c1c99831499 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.org>
+Date: Sat, 29 Jun 2019 14:13:29 +0200
+Subject: staging: bcm2835-camera: Ensure all buffers are returned on disable
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.org>
+
+commit 70ec64ccdaac5d8f634338e33b016c1c99831499 upstream.
+
+With the recent change to match MMAL and V4L2 buffers there
+is a need to wait for all MMAL buffers to be returned during
+stop_streaming.
+
+Fixes: 938416707071 ("staging: bcm2835-camera: Remove V4L2/MMAL buffer remapping")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
+Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
+Acked-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Acked-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c |   22 +++++++---
+ drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c     |    4 +
+ drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h     |    3 +
+ 3 files changed, 23 insertions(+), 6 deletions(-)
+
+--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
++++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+@@ -576,6 +576,7 @@ static void stop_streaming(struct vb2_qu
+       int ret;
+       unsigned long timeout;
+       struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vq);
++      struct vchiq_mmal_port *port = dev->capture.port;
+       v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p\n",
+                __func__, dev);
+@@ -599,12 +600,6 @@ static void stop_streaming(struct vb2_qu
+                                     &dev->capture.frame_count,
+                                     sizeof(dev->capture.frame_count));
+-      /* wait for last frame to complete */
+-      timeout = wait_for_completion_timeout(&dev->capture.frame_cmplt, HZ);
+-      if (timeout == 0)
+-              v4l2_err(&dev->v4l2_dev,
+-                       "timed out waiting for frame completion\n");
+-
+       v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
+                "disabling connection\n");
+@@ -619,6 +614,21 @@ static void stop_streaming(struct vb2_qu
+                        ret);
+       }
++      /* wait for all buffers to be returned */
++      while (atomic_read(&port->buffers_with_vpu)) {
++              v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
++                       "%s: Waiting for buffers to be returned - %d outstanding\n",
++                       __func__, atomic_read(&port->buffers_with_vpu));
++              timeout = wait_for_completion_timeout(&dev->capture.frame_cmplt,
++                                                    HZ);
++              if (timeout == 0) {
++                      v4l2_err(&dev->v4l2_dev, "%s: Timeout waiting for buffers to be returned - %d outstanding\n",
++                               __func__,
++                               atomic_read(&port->buffers_with_vpu));
++                      break;
++              }
++      }
++
+       if (disable_camera(dev) < 0)
+               v4l2_err(&dev->v4l2_dev, "Failed to disable camera\n");
+ }
+--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c
++++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c
+@@ -240,6 +240,8 @@ static void buffer_work_cb(struct work_s
+       struct mmal_msg_context *msg_context =
+               container_of(work, struct mmal_msg_context, u.bulk.work);
++      atomic_dec(&msg_context->u.bulk.port->buffers_with_vpu);
++
+       msg_context->u.bulk.port->buffer_cb(msg_context->u.bulk.instance,
+                                           msg_context->u.bulk.port,
+                                           msg_context->u.bulk.status,
+@@ -380,6 +382,8 @@ buffer_from_host(struct vchiq_mmal_insta
+       /* initialise work structure ready to schedule callback */
+       INIT_WORK(&msg_context->u.bulk.work, buffer_work_cb);
++      atomic_inc(&port->buffers_with_vpu);
++
+       /* prep the buffer from host message */
+       memset(&m, 0xbc, sizeof(m));    /* just to make debug clearer */
+--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h
++++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h
+@@ -71,6 +71,9 @@ struct vchiq_mmal_port {
+       struct list_head buffers;
+       /* lock to serialise adding and removing buffers from list */
+       spinlock_t slock;
++
++      /* Count of buffers the VPU has yet to return */
++      atomic_t buffers_with_vpu;
+       /* callback on buffer completion */
+       vchiq_mmal_buffer_cb buffer_cb;
+       /* callback context */
diff --git a/queue-5.2/staging-bcm2835-camera-handle-empty-eos-buffers-whilst-streaming.patch b/queue-5.2/staging-bcm2835-camera-handle-empty-eos-buffers-whilst-streaming.patch
new file mode 100644 (file)
index 0000000..a53856e
--- /dev/null
@@ -0,0 +1,91 @@
+From a26be06d6d96c10a9ab005e99d93fbb5d3babd98 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.org>
+Date: Sat, 29 Jun 2019 14:48:23 +0200
+Subject: staging: bcm2835-camera: Handle empty EOS buffers whilst streaming
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.org>
+
+commit a26be06d6d96c10a9ab005e99d93fbb5d3babd98 upstream.
+
+The change to mapping V4L2 to MMAL buffers 1:1 didn't handle
+the condition we get with raw pixel buffers (eg YUV and RGB)
+direct from the camera's stills port. That sends the pixel buffer
+and then an empty buffer with the EOS flag set. The EOS buffer
+wasn't handled and returned an error up the stack.
+
+Handle the condition correctly by returning it to the component
+if streaming, or returning with an error if stopping streaming.
+
+Fixes: 938416707071 ("staging: bcm2835-camera: Remove V4L2/MMAL buffer remapping")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
+Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
+Acked-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Acked-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c |   21 +++++-----
+ drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c     |    5 +-
+ 2 files changed, 15 insertions(+), 11 deletions(-)
+
+--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
++++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+@@ -336,16 +336,13 @@ static void buffer_cb(struct vchiq_mmal_
+               return;
+       } else if (length == 0) {
+               /* stream ended */
+-              if (buf) {
+-                      /* this should only ever happen if the port is
+-                       * disabled and there are buffers still queued
++              if (dev->capture.frame_count) {
++                      /* empty buffer whilst capturing - expected to be an
++                       * EOS, so grab another frame
+                        */
+-                      vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+-                      pr_debug("Empty buffer");
+-              } else if (dev->capture.frame_count) {
+-                      /* grab another frame */
+                       if (is_capturing(dev)) {
+-                              pr_debug("Grab another frame");
++                              v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
++                                       "Grab another frame");
+                               vchiq_mmal_port_parameter_set(
+                                       instance,
+                                       dev->capture.camera_port,
+@@ -353,8 +350,14 @@ static void buffer_cb(struct vchiq_mmal_
+                                       &dev->capture.frame_count,
+                                       sizeof(dev->capture.frame_count));
+                       }
++                      if (vchiq_mmal_submit_buffer(instance, port, buf))
++                              v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
++                                       "Failed to return EOS buffer");
+               } else {
+-                      /* signal frame completion */
++                      /* stopping streaming.
++                       * return buffer, and signal frame completion
++                       */
++                      vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+                       complete(&dev->capture.frame_cmplt);
+               }
+       } else {
+--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c
++++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c
+@@ -290,8 +290,6 @@ static int bulk_receive(struct vchiq_mma
+       /* store length */
+       msg_context->u.bulk.buffer_used = rd_len;
+-      msg_context->u.bulk.mmal_flags =
+-          msg->u.buffer_from_host.buffer_header.flags;
+       msg_context->u.bulk.dts = msg->u.buffer_from_host.buffer_header.dts;
+       msg_context->u.bulk.pts = msg->u.buffer_from_host.buffer_header.pts;
+@@ -452,6 +450,9 @@ static void buffer_to_host_cb(struct vch
+               return;
+       }
++      msg_context->u.bulk.mmal_flags =
++                              msg->u.buffer_from_host.buffer_header.flags;
++
+       if (msg->h.status != MMAL_MSG_STATUS_SUCCESS) {
+               /* message reception had an error */
+               pr_warn("error %d in reply\n", msg->h.status);
diff --git a/queue-5.2/staging-bcm2835-camera-remove-check-of-the-number-of-buffers-supplied.patch b/queue-5.2/staging-bcm2835-camera-remove-check-of-the-number-of-buffers-supplied.patch
new file mode 100644 (file)
index 0000000..8608f4a
--- /dev/null
@@ -0,0 +1,47 @@
+From bb8e97006d701ae725a177f8f322e5a75fa761b7 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.org>
+Date: Sat, 29 Jun 2019 14:13:30 +0200
+Subject: staging: bcm2835-camera: Remove check of the number of buffers supplied
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.org>
+
+commit bb8e97006d701ae725a177f8f322e5a75fa761b7 upstream.
+
+Before commit "staging: bcm2835-camera: Remove V4L2/MMAL buffer remapping"
+there was a need to ensure that there were sufficient buffers supplied from
+the user to cover those being sent to the VPU (always 1).
+
+Now the buffers are linked 1:1 between MMAL and V4L2,
+therefore there is no need for that check, and indeed it is wrong
+as there is no need to submit all the buffers before starting streaming.
+
+Fixes: 938416707071 ("staging: bcm2835-camera: Remove V4L2/MMAL buffer remapping")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
+Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
+Acked-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Acked-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c |   10 ----------
+ 1 file changed, 10 deletions(-)
+
+--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c
++++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c
+@@ -1328,16 +1328,6 @@ static int port_enable(struct vchiq_mmal
+       if (port->enabled)
+               return 0;
+-      /* ensure there are enough buffers queued to cover the buffer headers */
+-      if (port->buffer_cb) {
+-              hdr_count = 0;
+-              list_for_each(buf_head, &port->buffers) {
+-                      hdr_count++;
+-              }
+-              if (hdr_count < port->current_buffer.num)
+-                      return -ENOSPC;
+-      }
+-
+       ret = port_action_port(instance, port,
+                              MMAL_MSG_PORT_ACTION_TYPE_ENABLE);
+       if (ret)
diff --git a/queue-5.2/staging-bcm2835-camera-replace-spinlock-protecting-context_map-with-mutex.patch b/queue-5.2/staging-bcm2835-camera-replace-spinlock-protecting-context_map-with-mutex.patch
new file mode 100644 (file)
index 0000000..7e3731e
--- /dev/null
@@ -0,0 +1,75 @@
+From 8dedab2903f152aa3cee9ae3d57c828dea0d356e Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.org>
+Date: Sat, 29 Jun 2019 14:13:17 +0200
+Subject: staging: bcm2835-camera: Replace spinlock protecting context_map with mutex
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.org>
+
+commit 8dedab2903f152aa3cee9ae3d57c828dea0d356e upstream.
+
+The commit "staging: bcm2835-camera: Replace open-coded idr with a struct idr."
+replaced an internal implementation of an idr with the standard functions
+and a spinlock. idr_alloc(GFP_KERNEL) can sleep whilst calling kmem_cache_alloc
+to allocate the new node, but this is not valid whilst in an atomic context
+due to the spinlock.
+
+There is no need for this to be a spinlock as a standard mutex is
+sufficient.
+
+Fixes: 950fd867c635 ("staging: bcm2835-camera: Replace open-coded idr with a struct idr.")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
+Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
+Acked-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Acked-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c |   13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c
++++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c
+@@ -161,7 +161,8 @@ struct vchiq_mmal_instance {
+       void *bulk_scratch;
+       struct idr context_map;
+-      spinlock_t context_map_lock;
++      /* protect accesses to context_map */
++      struct mutex context_map_lock;
+       /* component to use next */
+       int component_idx;
+@@ -184,10 +185,10 @@ get_msg_context(struct vchiq_mmal_instan
+        * that when we service the VCHI reply, we can look up what
+        * message is being replied to.
+        */
+-      spin_lock(&instance->context_map_lock);
++      mutex_lock(&instance->context_map_lock);
+       handle = idr_alloc(&instance->context_map, msg_context,
+                          0, 0, GFP_KERNEL);
+-      spin_unlock(&instance->context_map_lock);
++      mutex_unlock(&instance->context_map_lock);
+       if (handle < 0) {
+               kfree(msg_context);
+@@ -211,9 +212,9 @@ release_msg_context(struct mmal_msg_cont
+ {
+       struct vchiq_mmal_instance *instance = msg_context->instance;
+-      spin_lock(&instance->context_map_lock);
++      mutex_lock(&instance->context_map_lock);
+       idr_remove(&instance->context_map, msg_context->handle);
+-      spin_unlock(&instance->context_map_lock);
++      mutex_unlock(&instance->context_map_lock);
+       kfree(msg_context);
+ }
+@@ -1849,7 +1850,7 @@ int vchiq_mmal_init(struct vchiq_mmal_in
+       instance->bulk_scratch = vmalloc(PAGE_SIZE);
+-      spin_lock_init(&instance->context_map_lock);
++      mutex_init(&instance->context_map_lock);
+       idr_init_base(&instance->context_map, 1);
+       params.callback_param = instance;
diff --git a/queue-5.2/staging-fsl-dpaa2-ethsw-fix-memory-leak-of-switchdev_work.patch b/queue-5.2/staging-fsl-dpaa2-ethsw-fix-memory-leak-of-switchdev_work.patch
new file mode 100644 (file)
index 0000000..38a96e3
--- /dev/null
@@ -0,0 +1,32 @@
+From 5555ebbbac822b4fa28db2be15aaf98b3c21af26 Mon Sep 17 00:00:00 2001
+From: Colin Ian King <colin.king@canonical.com>
+Date: Sat, 8 Jun 2019 12:50:31 +0100
+Subject: staging: fsl-dpaa2/ethsw: fix memory leak of switchdev_work
+
+From: Colin Ian King <colin.king@canonical.com>
+
+commit 5555ebbbac822b4fa28db2be15aaf98b3c21af26 upstream.
+
+In the default event case switchdev_work is being leaked because
+nothing is queued for work. Fix this by kfree'ing switchdev_work
+before returning NOTIFY_DONE.
+
+Addresses-Coverity: ("Resource leak")
+Fixes: 44baaa43d7cc ("staging: fsl-dpaa2/ethsw: Add Freescale DPAA2 Ethernet Switch driver")
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/fsl-dpaa2/ethsw/ethsw.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
++++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+@@ -1086,6 +1086,7 @@ static int port_switchdev_event(struct n
+               dev_hold(dev);
+               break;
+       default:
++              kfree(switchdev_work);
+               return NOTIFY_DONE;
+       }
diff --git a/queue-5.2/staging-rtl8712-reduce-stack-usage-again.patch b/queue-5.2/staging-rtl8712-reduce-stack-usage-again.patch
new file mode 100644 (file)
index 0000000..4c3a2aa
--- /dev/null
@@ -0,0 +1,205 @@
+From fbd6b25009ac76b2034168cd21d5e01f8c2d83d1 Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Fri, 28 Jun 2019 14:37:48 +0200
+Subject: staging: rtl8712: reduce stack usage, again
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+commit fbd6b25009ac76b2034168cd21d5e01f8c2d83d1 upstream.
+
+An earlier patch I sent reduced the stack usage enough to get
+below the warning limit, and I could show this was safe, but with
+GCC_PLUGIN_STRUCTLEAK_BYREF_ALL, it gets worse again because large stack
+variables in the same function no longer overlap:
+
+drivers/staging/rtl8712/rtl871x_ioctl_linux.c: In function 'translate_scan.isra.2':
+drivers/staging/rtl8712/rtl871x_ioctl_linux.c:322:1: error: the frame size of 1200 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]
+
+Split out the largest two blocks in the affected function into two
+separate functions and mark those noinline_for_stack.
+
+Fixes: 8c5af16f7953 ("staging: rtl8712: reduce stack usage")
+Fixes: 81a56f6dcd20 ("gcc-plugins: structleak: Generalize to all variable types")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/rtl8712/rtl871x_ioctl_linux.c |  159 ++++++++++++++------------
+ 1 file changed, 89 insertions(+), 70 deletions(-)
+
+--- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
++++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
+@@ -124,10 +124,91 @@ static inline void handle_group_key(stru
+       }
+ }
+-static noinline_for_stack char *translate_scan(struct _adapter *padapter,
+-                                 struct iw_request_info *info,
+-                                 struct wlan_network *pnetwork,
+-                                 char *start, char *stop)
++static noinline_for_stack char *translate_scan_wpa(struct iw_request_info *info,
++                                                 struct wlan_network *pnetwork,
++                                                 struct iw_event *iwe,
++                                                 char *start, char *stop)
++{
++      /* parsing WPA/WPA2 IE */
++      u8 buf[MAX_WPA_IE_LEN];
++      u8 wpa_ie[255], rsn_ie[255];
++      u16 wpa_len = 0, rsn_len = 0;
++      int n, i;
++
++      r8712_get_sec_ie(pnetwork->network.IEs,
++                       pnetwork->network.IELength, rsn_ie, &rsn_len,
++                       wpa_ie, &wpa_len);
++      if (wpa_len > 0) {
++              memset(buf, 0, MAX_WPA_IE_LEN);
++              n = sprintf(buf, "wpa_ie=");
++              for (i = 0; i < wpa_len; i++) {
++                      n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
++                                              "%02x", wpa_ie[i]);
++                      if (n >= MAX_WPA_IE_LEN)
++                              break;
++              }
++              memset(iwe, 0, sizeof(*iwe));
++              iwe->cmd = IWEVCUSTOM;
++              iwe->u.data.length = (u16)strlen(buf);
++              start = iwe_stream_add_point(info, start, stop,
++                      iwe, buf);
++              memset(iwe, 0, sizeof(*iwe));
++              iwe->cmd = IWEVGENIE;
++              iwe->u.data.length = (u16)wpa_len;
++              start = iwe_stream_add_point(info, start, stop,
++                      iwe, wpa_ie);
++      }
++      if (rsn_len > 0) {
++              memset(buf, 0, MAX_WPA_IE_LEN);
++              n = sprintf(buf, "rsn_ie=");
++              for (i = 0; i < rsn_len; i++) {
++                      n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
++                                              "%02x", rsn_ie[i]);
++                      if (n >= MAX_WPA_IE_LEN)
++                              break;
++              }
++              memset(iwe, 0, sizeof(*iwe));
++              iwe->cmd = IWEVCUSTOM;
++              iwe->u.data.length = strlen(buf);
++              start = iwe_stream_add_point(info, start, stop,
++                      iwe, buf);
++              memset(iwe, 0, sizeof(*iwe));
++              iwe->cmd = IWEVGENIE;
++              iwe->u.data.length = rsn_len;
++              start = iwe_stream_add_point(info, start, stop, iwe,
++                      rsn_ie);
++      }
++
++      return start;
++}
++
++static noinline_for_stack char *translate_scan_wps(struct iw_request_info *info,
++                                                 struct wlan_network *pnetwork,
++                                                 struct iw_event *iwe,
++                                                 char *start, char *stop)
++{
++      /* parsing WPS IE */
++      u8 wps_ie[512];
++      uint wps_ielen;
++
++      if (r8712_get_wps_ie(pnetwork->network.IEs,
++          pnetwork->network.IELength,
++          wps_ie, &wps_ielen)) {
++              if (wps_ielen > 2) {
++                      iwe->cmd = IWEVGENIE;
++                      iwe->u.data.length = (u16)wps_ielen;
++                      start = iwe_stream_add_point(info, start, stop,
++                              iwe, wps_ie);
++              }
++      }
++
++      return start;
++}
++
++static char *translate_scan(struct _adapter *padapter,
++                          struct iw_request_info *info,
++                          struct wlan_network *pnetwork,
++                          char *start, char *stop)
+ {
+       struct iw_event iwe;
+       struct ieee80211_ht_cap *pht_capie;
+@@ -240,73 +321,11 @@ static noinline_for_stack char *translat
+       /* Check if we added any event */
+       if ((current_val - start) > iwe_stream_lcp_len(info))
+               start = current_val;
+-      /* parsing WPA/WPA2 IE */
+-      {
+-              u8 buf[MAX_WPA_IE_LEN];
+-              u8 wpa_ie[255], rsn_ie[255];
+-              u16 wpa_len = 0, rsn_len = 0;
+-              int n;
+-
+-              r8712_get_sec_ie(pnetwork->network.IEs,
+-                               pnetwork->network.IELength, rsn_ie, &rsn_len,
+-                               wpa_ie, &wpa_len);
+-              if (wpa_len > 0) {
+-                      memset(buf, 0, MAX_WPA_IE_LEN);
+-                      n = sprintf(buf, "wpa_ie=");
+-                      for (i = 0; i < wpa_len; i++) {
+-                              n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
+-                                                      "%02x", wpa_ie[i]);
+-                              if (n >= MAX_WPA_IE_LEN)
+-                                      break;
+-                      }
+-                      memset(&iwe, 0, sizeof(iwe));
+-                      iwe.cmd = IWEVCUSTOM;
+-                      iwe.u.data.length = (u16)strlen(buf);
+-                      start = iwe_stream_add_point(info, start, stop,
+-                              &iwe, buf);
+-                      memset(&iwe, 0, sizeof(iwe));
+-                      iwe.cmd = IWEVGENIE;
+-                      iwe.u.data.length = (u16)wpa_len;
+-                      start = iwe_stream_add_point(info, start, stop,
+-                              &iwe, wpa_ie);
+-              }
+-              if (rsn_len > 0) {
+-                      memset(buf, 0, MAX_WPA_IE_LEN);
+-                      n = sprintf(buf, "rsn_ie=");
+-                      for (i = 0; i < rsn_len; i++) {
+-                              n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
+-                                                      "%02x", rsn_ie[i]);
+-                              if (n >= MAX_WPA_IE_LEN)
+-                                      break;
+-                      }
+-                      memset(&iwe, 0, sizeof(iwe));
+-                      iwe.cmd = IWEVCUSTOM;
+-                      iwe.u.data.length = strlen(buf);
+-                      start = iwe_stream_add_point(info, start, stop,
+-                              &iwe, buf);
+-                      memset(&iwe, 0, sizeof(iwe));
+-                      iwe.cmd = IWEVGENIE;
+-                      iwe.u.data.length = rsn_len;
+-                      start = iwe_stream_add_point(info, start, stop, &iwe,
+-                              rsn_ie);
+-              }
+-      }
+-      { /* parsing WPS IE */
+-              u8 wps_ie[512];
+-              uint wps_ielen;
+-
+-              if (r8712_get_wps_ie(pnetwork->network.IEs,
+-                  pnetwork->network.IELength,
+-                  wps_ie, &wps_ielen)) {
+-                      if (wps_ielen > 2) {
+-                              iwe.cmd = IWEVGENIE;
+-                              iwe.u.data.length = (u16)wps_ielen;
+-                              start = iwe_stream_add_point(info, start, stop,
+-                                      &iwe, wps_ie);
+-                      }
+-              }
+-      }
++      start = translate_scan_wpa(info, pnetwork, &iwe, start, stop);
++
++      start = translate_scan_wps(info, pnetwork, &iwe, start, stop);
++
+       /* Add quality statistics */
+       iwe.cmd = IWEVQUAL;
+       rssi = r8712_signal_scale_mapping(pnetwork->network.Rssi);
diff --git a/queue-5.2/staging-vchiq-make-wait-events-interruptible.patch b/queue-5.2/staging-vchiq-make-wait-events-interruptible.patch
new file mode 100644 (file)
index 0000000..e64c783
--- /dev/null
@@ -0,0 +1,49 @@
+From 77cf3f5dcf35c8f547f075213dbc15146d44cc76 Mon Sep 17 00:00:00 2001
+From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Date: Thu, 9 May 2019 16:31:35 +0200
+Subject: staging: vchiq: make wait events interruptible
+
+From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+
+commit 77cf3f5dcf35c8f547f075213dbc15146d44cc76 upstream.
+
+The killable version of wait_event() is meant to be used on situations
+where it should not fail at all costs, but still have the convenience of
+being able to kill it if really necessary. Wait events in VCHIQ doesn't
+fit this criteria, as it's mainly used as an interface to V4L2 and ALSA
+devices.
+
+Fixes: 852b2876a8a8 ("staging: vchiq: rework remove_event handling")
+Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Acked-by: Stefan Wahren <stefan.wahren@i2se.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c |   10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
+@@ -395,13 +395,21 @@ remote_event_create(wait_queue_head_t *w
+       init_waitqueue_head(wq);
+ }
++/*
++ * All the event waiting routines in VCHIQ used a custom semaphore
++ * implementation that filtered most signals. This achieved a behaviour similar
++ * to the "killable" family of functions. While cleaning up this code all the
++ * routines where switched to the "interruptible" family of functions, as the
++ * former was deemed unjustified and the use "killable" set all VCHIQ's
++ * threads in D state.
++ */
+ static inline int
+ remote_event_wait(wait_queue_head_t *wq, struct remote_event *event)
+ {
+       if (!event->fired) {
+               event->armed = 1;
+               dsb(sy);
+-              if (wait_event_killable(*wq, event->fired)) {
++              if (wait_event_interruptible(*wq, event->fired)) {
+                       event->armed = 0;
+                       return 0;
+               }
diff --git a/queue-5.2/staging-vchiq-revert-switch-to-wait_for_completion_killable.patch b/queue-5.2/staging-vchiq-revert-switch-to-wait_for_completion_killable.patch
new file mode 100644 (file)
index 0000000..afdb277
--- /dev/null
@@ -0,0 +1,241 @@
+From 086efbabdc04563268372aaef4d66039d85ee76c Mon Sep 17 00:00:00 2001
+From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Date: Thu, 9 May 2019 16:31:34 +0200
+Subject: staging: vchiq: revert "switch to wait_for_completion_killable"
+
+From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+
+commit 086efbabdc04563268372aaef4d66039d85ee76c upstream.
+
+The killable version of wait_for_completion() is meant to be used on
+situations where it should not fail at all costs, but still have the
+convenience of being able to kill it if really necessary. VCHIQ doesn't
+fit this criteria, as it's mainly used as an interface to V4L2 and ALSA
+devices.
+
+Fixes: a772f116702e ("staging: vchiq: switch to wait_for_completion_killable")
+Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Acked-by: Stefan Wahren <stefan.wahren@i2se.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c  |   21 +++++-----
+ drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c |   21 +++++-----
+ drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c |    6 +-
+ 3 files changed, 25 insertions(+), 23 deletions(-)
+
+--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+@@ -532,7 +532,8 @@ add_completion(VCHIQ_INSTANCE_T instance
+               vchiq_log_trace(vchiq_arm_log_level,
+                       "%s - completion queue full", __func__);
+               DEBUG_COUNT(COMPLETION_QUEUE_FULL_COUNT);
+-              if (wait_for_completion_killable(&instance->remove_event)) {
++              if (wait_for_completion_interruptible(
++                                      &instance->remove_event)) {
+                       vchiq_log_info(vchiq_arm_log_level,
+                               "service_callback interrupted");
+                       return VCHIQ_RETRY;
+@@ -643,7 +644,7 @@ service_callback(VCHIQ_REASON_T reason,
+                       }
+                       DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+-                      if (wait_for_completion_killable(
++                      if (wait_for_completion_interruptible(
+                                               &user_service->remove_event)
+                               != 0) {
+                               vchiq_log_info(vchiq_arm_log_level,
+@@ -978,7 +979,7 @@ vchiq_ioctl(struct file *file, unsigned
+                  has been closed until the client library calls the
+                  CLOSE_DELIVERED ioctl, signalling close_event. */
+               if (user_service->close_pending &&
+-                      wait_for_completion_killable(
++                      wait_for_completion_interruptible(
+                               &user_service->close_event))
+                       status = VCHIQ_RETRY;
+               break;
+@@ -1154,7 +1155,7 @@ vchiq_ioctl(struct file *file, unsigned
+                       DEBUG_TRACE(AWAIT_COMPLETION_LINE);
+                       mutex_unlock(&instance->completion_mutex);
+-                      rc = wait_for_completion_killable(
++                      rc = wait_for_completion_interruptible(
+                                               &instance->insert_event);
+                       mutex_lock(&instance->completion_mutex);
+                       if (rc != 0) {
+@@ -1324,7 +1325,7 @@ vchiq_ioctl(struct file *file, unsigned
+                       do {
+                               spin_unlock(&msg_queue_spinlock);
+                               DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
+-                              if (wait_for_completion_killable(
++                              if (wait_for_completion_interruptible(
+                                       &user_service->insert_event)) {
+                                       vchiq_log_info(vchiq_arm_log_level,
+                                               "DEQUEUE_MESSAGE interrupted");
+@@ -2328,7 +2329,7 @@ vchiq_keepalive_thread_func(void *v)
+       while (1) {
+               long rc = 0, uc = 0;
+-              if (wait_for_completion_killable(&arm_state->ka_evt)
++              if (wait_for_completion_interruptible(&arm_state->ka_evt)
+                               != 0) {
+                       vchiq_log_error(vchiq_susp_log_level,
+                               "%s interrupted", __func__);
+@@ -2579,7 +2580,7 @@ block_resume(struct vchiq_arm_state *arm
+               write_unlock_bh(&arm_state->susp_res_lock);
+               vchiq_log_info(vchiq_susp_log_level, "%s wait for previously "
+                       "blocked clients", __func__);
+-              if (wait_for_completion_killable_timeout(
++              if (wait_for_completion_interruptible_timeout(
+                               &arm_state->blocked_blocker, timeout_val)
+                                       <= 0) {
+                       vchiq_log_error(vchiq_susp_log_level, "%s wait for "
+@@ -2605,7 +2606,7 @@ block_resume(struct vchiq_arm_state *arm
+               write_unlock_bh(&arm_state->susp_res_lock);
+               vchiq_log_info(vchiq_susp_log_level, "%s wait for resume",
+                       __func__);
+-              if (wait_for_completion_killable_timeout(
++              if (wait_for_completion_interruptible_timeout(
+                               &arm_state->vc_resume_complete, timeout_val)
+                                       <= 0) {
+                       vchiq_log_error(vchiq_susp_log_level, "%s wait for "
+@@ -2812,7 +2813,7 @@ vchiq_arm_force_suspend(struct vchiq_sta
+       do {
+               write_unlock_bh(&arm_state->susp_res_lock);
+-              rc = wait_for_completion_killable_timeout(
++              rc = wait_for_completion_interruptible_timeout(
+                               &arm_state->vc_suspend_complete,
+                               msecs_to_jiffies(FORCE_SUSPEND_TIMEOUT_MS));
+@@ -2908,7 +2909,7 @@ vchiq_arm_allow_resume(struct vchiq_stat
+       write_unlock_bh(&arm_state->susp_res_lock);
+       if (resume) {
+-              if (wait_for_completion_killable(
++              if (wait_for_completion_interruptible(
+                       &arm_state->vc_resume_complete) < 0) {
+                       vchiq_log_error(vchiq_susp_log_level,
+                               "%s interrupted", __func__);
+--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
+@@ -568,7 +568,7 @@ reserve_space(struct vchiq_state *state,
+                       remote_event_signal(&state->remote->trigger);
+                       if (!is_blocking ||
+-                              (wait_for_completion_killable(
++                              (wait_for_completion_interruptible(
+                               &state->slot_available_event)))
+                               return NULL; /* No space available */
+               }
+@@ -838,7 +838,7 @@ queue_message(struct vchiq_state *state,
+                       spin_unlock(&quota_spinlock);
+                       mutex_unlock(&state->slot_mutex);
+-                      if (wait_for_completion_killable(
++                      if (wait_for_completion_interruptible(
+                                               &state->data_quota_event))
+                               return VCHIQ_RETRY;
+@@ -869,7 +869,7 @@ queue_message(struct vchiq_state *state,
+                               service_quota->slot_use_count);
+                       VCHIQ_SERVICE_STATS_INC(service, quota_stalls);
+                       mutex_unlock(&state->slot_mutex);
+-                      if (wait_for_completion_killable(
++                      if (wait_for_completion_interruptible(
+                                               &service_quota->quota_event))
+                               return VCHIQ_RETRY;
+                       if (service->closing)
+@@ -1718,7 +1718,8 @@ parse_rx_slots(struct vchiq_state *state
+                                       &service->bulk_rx : &service->bulk_tx;
+                               DEBUG_TRACE(PARSE_LINE);
+-                              if (mutex_lock_killable(&service->bulk_mutex)) {
++                              if (mutex_lock_killable(
++                                      &service->bulk_mutex) != 0) {
+                                       DEBUG_TRACE(PARSE_LINE);
+                                       goto bail_not_ready;
+                               }
+@@ -2436,7 +2437,7 @@ vchiq_open_service_internal(struct vchiq
+                              QMFLAGS_IS_BLOCKING);
+       if (status == VCHIQ_SUCCESS) {
+               /* Wait for the ACK/NAK */
+-              if (wait_for_completion_killable(&service->remove_event)) {
++              if (wait_for_completion_interruptible(&service->remove_event)) {
+                       status = VCHIQ_RETRY;
+                       vchiq_release_service_internal(service);
+               } else if ((service->srvstate != VCHIQ_SRVSTATE_OPEN) &&
+@@ -2803,7 +2804,7 @@ vchiq_connect_internal(struct vchiq_stat
+       }
+       if (state->conn_state == VCHIQ_CONNSTATE_CONNECTING) {
+-              if (wait_for_completion_killable(&state->connect))
++              if (wait_for_completion_interruptible(&state->connect))
+                       return VCHIQ_RETRY;
+               vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTED);
+@@ -2902,7 +2903,7 @@ vchiq_close_service(VCHIQ_SERVICE_HANDLE
+       }
+       while (1) {
+-              if (wait_for_completion_killable(&service->remove_event)) {
++              if (wait_for_completion_interruptible(&service->remove_event)) {
+                       status = VCHIQ_RETRY;
+                       break;
+               }
+@@ -2963,7 +2964,7 @@ vchiq_remove_service(VCHIQ_SERVICE_HANDL
+               request_poll(service->state, service, VCHIQ_POLL_REMOVE);
+       }
+       while (1) {
+-              if (wait_for_completion_killable(&service->remove_event)) {
++              if (wait_for_completion_interruptible(&service->remove_event)) {
+                       status = VCHIQ_RETRY;
+                       break;
+               }
+@@ -3046,7 +3047,7 @@ VCHIQ_STATUS_T vchiq_bulk_transfer(VCHIQ
+               VCHIQ_SERVICE_STATS_INC(service, bulk_stalls);
+               do {
+                       mutex_unlock(&service->bulk_mutex);
+-                      if (wait_for_completion_killable(
++                      if (wait_for_completion_interruptible(
+                                               &service->bulk_remove_event)) {
+                               status = VCHIQ_RETRY;
+                               goto error_exit;
+@@ -3123,7 +3124,7 @@ waiting:
+       if (bulk_waiter) {
+               bulk_waiter->bulk = bulk;
+-              if (wait_for_completion_killable(&bulk_waiter->event))
++              if (wait_for_completion_interruptible(&bulk_waiter->event))
+                       status = VCHIQ_RETRY;
+               else if (bulk_waiter->actual == VCHIQ_BULK_ACTUAL_ABORTED)
+                       status = VCHIQ_ERROR;
+--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c
++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c
+@@ -50,7 +50,7 @@ void vchiu_queue_push(struct vchiu_queue
+               return;
+       while (queue->write == queue->read + queue->size) {
+-              if (wait_for_completion_killable(&queue->pop))
++              if (wait_for_completion_interruptible(&queue->pop))
+                       flush_signals(current);
+       }
+@@ -63,7 +63,7 @@ void vchiu_queue_push(struct vchiu_queue
+ struct vchiq_header *vchiu_queue_peek(struct vchiu_queue *queue)
+ {
+       while (queue->write == queue->read) {
+-              if (wait_for_completion_killable(&queue->push))
++              if (wait_for_completion_interruptible(&queue->push))
+                       flush_signals(current);
+       }
+@@ -77,7 +77,7 @@ struct vchiq_header *vchiu_queue_pop(str
+       struct vchiq_header *header;
+       while (queue->write == queue->read) {
+-              if (wait_for_completion_killable(&queue->push))
++              if (wait_for_completion_interruptible(&queue->push))
+                       flush_signals(current);
+       }
diff --git a/queue-5.2/staging-vchiq_2835_arm-revert-quit-using-custom-down_interruptible.patch b/queue-5.2/staging-vchiq_2835_arm-revert-quit-using-custom-down_interruptible.patch
new file mode 100644 (file)
index 0000000..a8e14f5
--- /dev/null
@@ -0,0 +1,34 @@
+From 061ca1401f96c254e7f179bf97a1fc5c7f47e1e1 Mon Sep 17 00:00:00 2001
+From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Date: Thu, 9 May 2019 16:31:33 +0200
+Subject: staging: vchiq_2835_arm: revert "quit using custom down_interruptible()"
+
+From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+
+commit 061ca1401f96c254e7f179bf97a1fc5c7f47e1e1 upstream.
+
+The killable version of down() is meant to be used on situations where
+it should not fail at all costs, but still have the convenience of being
+able to kill it if really necessary. VCHIQ doesn't fit this criteria, as
+it's mainly used as an interface to V4L2 and ALSA devices.
+
+Fixes: ff5979ad8636 ("staging: vchiq_2835_arm: quit using custom down_interruptible()")
+Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Acked-by: Stefan Wahren <stefan.wahren@i2se.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
+@@ -523,7 +523,7 @@ create_pagelist(char __user *buf, size_t
+               (g_cache_line_size - 1)))) {
+               char *fragments;
+-              if (down_killable(&g_free_fragments_sema)) {
++              if (down_interruptible(&g_free_fragments_sema) != 0) {
+                       cleanup_pagelistinfo(pagelistinfo);
+                       return NULL;
+               }