From: Greg Kroah-Hartman Date: Fri, 12 Jul 2019 12:18:54 +0000 (+0200) Subject: 5.2-stable patches X-Git-Tag: v5.2.1~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d6cd6604fea6fbb7f778d0a41afe4b6e6d0b872b;p=thirdparty%2Fkernel%2Fstable-queue.git 5.2-stable patches 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 --- diff --git a/queue-5.2/series b/queue-5.2/series index 836028d833d..8c6bd6fda84 100644 --- a/queue-5.2/series +++ b/queue-5.2/series @@ -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 index 00000000000..5f58820cea0 --- /dev/null +++ b/queue-5.2/staging-bcm2835-camera-ensure-all-buffers-are-returned-on-disable.patch @@ -0,0 +1,103 @@ +From 70ec64ccdaac5d8f634338e33b016c1c99831499 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Sat, 29 Jun 2019 14:13:29 +0200 +Subject: staging: bcm2835-camera: Ensure all buffers are returned on disable + +From: Dave Stevenson + +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 +Signed-off-by: Stefan Wahren +Acked-by: Hans Verkuil +Acked-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..a53856ec0bd --- /dev/null +++ b/queue-5.2/staging-bcm2835-camera-handle-empty-eos-buffers-whilst-streaming.patch @@ -0,0 +1,91 @@ +From a26be06d6d96c10a9ab005e99d93fbb5d3babd98 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Sat, 29 Jun 2019 14:48:23 +0200 +Subject: staging: bcm2835-camera: Handle empty EOS buffers whilst streaming + +From: Dave Stevenson + +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 +Signed-off-by: Stefan Wahren +Acked-by: Hans Verkuil +Acked-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..8608f4a8fd1 --- /dev/null +++ b/queue-5.2/staging-bcm2835-camera-remove-check-of-the-number-of-buffers-supplied.patch @@ -0,0 +1,47 @@ +From bb8e97006d701ae725a177f8f322e5a75fa761b7 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Sat, 29 Jun 2019 14:13:30 +0200 +Subject: staging: bcm2835-camera: Remove check of the number of buffers supplied + +From: Dave Stevenson + +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 +Signed-off-by: Stefan Wahren +Acked-by: Hans Verkuil +Acked-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..7e3731e7bab --- /dev/null +++ b/queue-5.2/staging-bcm2835-camera-replace-spinlock-protecting-context_map-with-mutex.patch @@ -0,0 +1,75 @@ +From 8dedab2903f152aa3cee9ae3d57c828dea0d356e Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Sat, 29 Jun 2019 14:13:17 +0200 +Subject: staging: bcm2835-camera: Replace spinlock protecting context_map with mutex + +From: Dave Stevenson + +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 +Signed-off-by: Stefan Wahren +Acked-by: Hans Verkuil +Acked-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..38a96e3b33e --- /dev/null +++ b/queue-5.2/staging-fsl-dpaa2-ethsw-fix-memory-leak-of-switchdev_work.patch @@ -0,0 +1,32 @@ +From 5555ebbbac822b4fa28db2be15aaf98b3c21af26 Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Sat, 8 Jun 2019 12:50:31 +0100 +Subject: staging: fsl-dpaa2/ethsw: fix memory leak of switchdev_work + +From: Colin Ian King + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..4c3a2aaa4fd --- /dev/null +++ b/queue-5.2/staging-rtl8712-reduce-stack-usage-again.patch @@ -0,0 +1,205 @@ +From fbd6b25009ac76b2034168cd21d5e01f8c2d83d1 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Fri, 28 Jun 2019 14:37:48 +0200 +Subject: staging: rtl8712: reduce stack usage, again + +From: Arnd Bergmann + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..e64c7835c57 --- /dev/null +++ b/queue-5.2/staging-vchiq-make-wait-events-interruptible.patch @@ -0,0 +1,49 @@ +From 77cf3f5dcf35c8f547f075213dbc15146d44cc76 Mon Sep 17 00:00:00 2001 +From: Nicolas Saenz Julienne +Date: Thu, 9 May 2019 16:31:35 +0200 +Subject: staging: vchiq: make wait events interruptible + +From: Nicolas Saenz Julienne + +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 +Acked-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..afdb2779e32 --- /dev/null +++ b/queue-5.2/staging-vchiq-revert-switch-to-wait_for_completion_killable.patch @@ -0,0 +1,241 @@ +From 086efbabdc04563268372aaef4d66039d85ee76c Mon Sep 17 00:00:00 2001 +From: Nicolas Saenz Julienne +Date: Thu, 9 May 2019 16:31:34 +0200 +Subject: staging: vchiq: revert "switch to wait_for_completion_killable" + +From: Nicolas Saenz Julienne + +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 +Acked-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman + +--- + 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("a_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 index 00000000000..a8e14f583c2 --- /dev/null +++ b/queue-5.2/staging-vchiq_2835_arm-revert-quit-using-custom-down_interruptible.patch @@ -0,0 +1,34 @@ +From 061ca1401f96c254e7f179bf97a1fc5c7f47e1e1 Mon Sep 17 00:00:00 2001 +From: Nicolas Saenz Julienne +Date: Thu, 9 May 2019 16:31:33 +0200 +Subject: staging: vchiq_2835_arm: revert "quit using custom down_interruptible()" + +From: Nicolas Saenz Julienne + +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 +Acked-by: Stefan Wahren +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + }