]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 15 Jun 2017 14:26:45 +0000 (16:26 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 15 Jun 2017 14:26:45 +0000 (16:26 +0200)
added patches:
arc-smp-boot-decouple-non-masters-waiting-api-from-jump-to-entry-point.patch
bnxt_en-enhance-autoneg-support.patch
bnxt_en-fix-bnxt_reset-in-the-slow-path-task.patch
bnxt_en-fix-rtnl-lock-usage-on-bnxt_get_port_module_status.patch
bnxt_en-fix-rtnl-lock-usage-on-bnxt_update_link.patch
frv-add-atomic64_add_unless.patch
frv-add-missing-atomic64-operations.patch
kernel-watchdog-prevent-false-hardlockup-on-overloaded-system.patch
kernel-watchdog.c-move-hardlockup-detector-to-separate-file.patch
kernel-watchdog.c-move-shared-definitions-to-nmi.h.patch
mn10300-fix-build-error-of-missing-fpu_save.patch
net-next-ethernet-mediatek-change-the-compatible-string.patch
proc-add-a-schedule-point-in-proc_pid_readdir.patch
r8152-avoid-start_xmit-to-schedule-napi-when-napi-is-disabled.patch
romfs-use-different-way-to-generate-fsid-for-block-or-mtd.patch
sctp-sctp-gso-should-set-feature-with-netif_f_sg-when-calling-skb_segment.patch
sctp-sctp_addr_id2transport-should-verify-the-addr-before-looking-up-assoc.patch
usb-musb-fix-external-abort-on-non-linefetch-for-musb_irq_work.patch
userfaultfd-fix-sigbus-resulting-from-false-rwsem-wakeups.patch
vhost-vsock-handle-vhost_vq_init_access-error.patch

21 files changed:
queue-4.9/arc-smp-boot-decouple-non-masters-waiting-api-from-jump-to-entry-point.patch [new file with mode: 0644]
queue-4.9/bnxt_en-enhance-autoneg-support.patch [new file with mode: 0644]
queue-4.9/bnxt_en-fix-bnxt_reset-in-the-slow-path-task.patch [new file with mode: 0644]
queue-4.9/bnxt_en-fix-rtnl-lock-usage-on-bnxt_get_port_module_status.patch [new file with mode: 0644]
queue-4.9/bnxt_en-fix-rtnl-lock-usage-on-bnxt_update_link.patch [new file with mode: 0644]
queue-4.9/frv-add-atomic64_add_unless.patch [new file with mode: 0644]
queue-4.9/frv-add-missing-atomic64-operations.patch [new file with mode: 0644]
queue-4.9/kernel-watchdog-prevent-false-hardlockup-on-overloaded-system.patch [new file with mode: 0644]
queue-4.9/kernel-watchdog.c-move-hardlockup-detector-to-separate-file.patch [new file with mode: 0644]
queue-4.9/kernel-watchdog.c-move-shared-definitions-to-nmi.h.patch [new file with mode: 0644]
queue-4.9/mn10300-fix-build-error-of-missing-fpu_save.patch [new file with mode: 0644]
queue-4.9/net-next-ethernet-mediatek-change-the-compatible-string.patch [new file with mode: 0644]
queue-4.9/proc-add-a-schedule-point-in-proc_pid_readdir.patch [new file with mode: 0644]
queue-4.9/r8152-avoid-start_xmit-to-schedule-napi-when-napi-is-disabled.patch [new file with mode: 0644]
queue-4.9/romfs-use-different-way-to-generate-fsid-for-block-or-mtd.patch [new file with mode: 0644]
queue-4.9/sctp-sctp-gso-should-set-feature-with-netif_f_sg-when-calling-skb_segment.patch [new file with mode: 0644]
queue-4.9/sctp-sctp_addr_id2transport-should-verify-the-addr-before-looking-up-assoc.patch [new file with mode: 0644]
queue-4.9/series
queue-4.9/usb-musb-fix-external-abort-on-non-linefetch-for-musb_irq_work.patch [new file with mode: 0644]
queue-4.9/userfaultfd-fix-sigbus-resulting-from-false-rwsem-wakeups.patch [new file with mode: 0644]
queue-4.9/vhost-vsock-handle-vhost_vq_init_access-error.patch [new file with mode: 0644]

diff --git a/queue-4.9/arc-smp-boot-decouple-non-masters-waiting-api-from-jump-to-entry-point.patch b/queue-4.9/arc-smp-boot-decouple-non-masters-waiting-api-from-jump-to-entry-point.patch
new file mode 100644 (file)
index 0000000..c3d0624
--- /dev/null
@@ -0,0 +1,81 @@
+From foo@baz Thu Jun 15 16:23:30 CEST 2017
+From: Vineet Gupta <vgupta@synopsys.com>
+Date: Thu, 12 Jan 2017 14:30:29 -0800
+Subject: ARC: smp-boot: Decouple Non masters waiting API from jump to entry point
+
+From: Vineet Gupta <vgupta@synopsys.com>
+
+
+[ Upstream commit bf02454a741b58682a82c314a9a46bed930ed2f7 ]
+
+For run-on-reset SMP configs, non master cores call a routine which
+waits until Master gives it a "go" signal (currently using a shared
+mem flag). The same routine then jumps off the well known entry point of
+all non Master cores i.e. @first_lines_of_secondary
+
+This patch moves out the last part into one single place in early boot
+code.
+
+This is better in terms of absraction (the wait API only waits) and
+returns, leaving out the "jump off to" part.
+
+In actual implementation this requires some restructuring of the early
+boot code as well as Master now jumps to BSS setup explicitly,
+vs. falling thru into it before.
+
+Technically this patch doesn't cause any functional change, it just
+moves the ugly #ifdef'ry from assembly code to "C"
+
+Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
+Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arc/kernel/head.S |   14 +++++++-------
+ arch/arc/kernel/smp.c  |    6 ++++--
+ 2 files changed, 11 insertions(+), 9 deletions(-)
+
+--- a/arch/arc/kernel/head.S
++++ b/arch/arc/kernel/head.S
+@@ -71,14 +71,14 @@ ENTRY(stext)
+       GET_CPU_ID  r5
+       cmp     r5, 0
+       mov.nz  r0, r5
+-#ifdef CONFIG_ARC_SMP_HALT_ON_RESET
+-      ; Non-Master can proceed as system would be booted sufficiently
+-      jnz     first_lines_of_secondary
+-#else
++      bz      .Lmaster_proceed
++
+       ; Non-Masters wait for Master to boot enough and bring them up
+-      jnz     arc_platform_smp_wait_to_boot
+-#endif
+-      ; Master falls thru
++      ; when they resume, tail-call to entry point
++      mov     blink, @first_lines_of_secondary
++      j       arc_platform_smp_wait_to_boot
++
++.Lmaster_proceed:
+ #endif
+       ; Clear BSS before updating any globals
+--- a/arch/arc/kernel/smp.c
++++ b/arch/arc/kernel/smp.c
+@@ -98,14 +98,16 @@ static void arc_default_smp_cpu_kick(int
+ void arc_platform_smp_wait_to_boot(int cpu)
+ {
++      /* for halt-on-reset, we've waited already */
++      if (IS_ENABLED(CONFIG_ARC_SMP_HALT_ON_RESET))
++              return;
++
+       while (wake_flag != cpu)
+               ;
+       wake_flag = 0;
+-      __asm__ __volatile__("j @first_lines_of_secondary       \n");
+ }
+-
+ const char *arc_platform_smp_cpuinfo(void)
+ {
+       return plat_smp_ops.info ? : "";
diff --git a/queue-4.9/bnxt_en-enhance-autoneg-support.patch b/queue-4.9/bnxt_en-enhance-autoneg-support.patch
new file mode 100644 (file)
index 0000000..83043f3
--- /dev/null
@@ -0,0 +1,86 @@
+From foo@baz Thu Jun 15 16:23:30 CEST 2017
+From: Michael Chan <michael.chan@broadcom.com>
+Date: Wed, 16 Nov 2016 21:13:08 -0500
+Subject: bnxt_en: Enhance autoneg support.
+
+From: Michael Chan <michael.chan@broadcom.com>
+
+
+[ Upstream commit 286ef9d64ea7435a1e323d12b44a309e15cbff0e ]
+
+On some dual port NICs, the speed setting on one port can affect the
+available speed on the other port.  Add logic to detect these changes
+and adjust the advertised speed settings when necessary.
+
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c |   23 +++++++++++++++++++++++
+ drivers/net/ethernet/broadcom/bnxt/bnxt.h |    1 +
+ 2 files changed, 24 insertions(+)
+
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -1499,6 +1499,7 @@ static int bnxt_async_event_process(stru
+                       netdev_warn(bp->dev, "Link speed %d no longer supported\n",
+                                   speed);
+               }
++              set_bit(BNXT_LINK_SPEED_CHNG_SP_EVENT, &bp->sp_event);
+               /* fall thru */
+       }
+       case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE:
+@@ -5110,6 +5111,7 @@ static int bnxt_update_link(struct bnxt
+       struct hwrm_port_phy_qcfg_input req = {0};
+       struct hwrm_port_phy_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+       u8 link_up = link_info->link_up;
++      u16 diff;
+       bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_PHY_QCFG, -1, -1);
+@@ -5197,6 +5199,23 @@ static int bnxt_update_link(struct bnxt
+               link_info->link_up = 0;
+       }
+       mutex_unlock(&bp->hwrm_cmd_lock);
++
++      diff = link_info->support_auto_speeds ^ link_info->advertising;
++      if ((link_info->support_auto_speeds | diff) !=
++          link_info->support_auto_speeds) {
++              /* An advertised speed is no longer supported, so we need to
++               * update the advertisement settings.  See bnxt_reset() for
++               * comments about the rtnl_lock() sequence below.
++               */
++              clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
++              rtnl_lock();
++              link_info->advertising = link_info->support_auto_speeds;
++              if (test_bit(BNXT_STATE_OPEN, &bp->state) &&
++                  (link_info->autoneg & BNXT_AUTONEG_SPEED))
++                      bnxt_hwrm_set_link_setting(bp, true, false);
++              set_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
++              rtnl_unlock();
++      }
+       return 0;
+ }
+@@ -6126,6 +6145,10 @@ static void bnxt_sp_task(struct work_str
+       if (test_and_clear_bit(BNXT_RX_NTP_FLTR_SP_EVENT, &bp->sp_event))
+               bnxt_cfg_ntp_filters(bp);
+       if (test_and_clear_bit(BNXT_LINK_CHNG_SP_EVENT, &bp->sp_event)) {
++              if (test_and_clear_bit(BNXT_LINK_SPEED_CHNG_SP_EVENT,
++                                     &bp->sp_event))
++                      bnxt_hwrm_phy_qcaps(bp);
++
+               rc = bnxt_update_link(bp, true);
+               if (rc)
+                       netdev_err(bp->dev, "SP task can't update link (rc: %x)\n",
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+@@ -1089,6 +1089,7 @@ struct bnxt {
+ #define BNXT_RESET_TASK_SILENT_SP_EVENT       11
+ #define BNXT_GENEVE_ADD_PORT_SP_EVENT 12
+ #define BNXT_GENEVE_DEL_PORT_SP_EVENT 13
++#define BNXT_LINK_SPEED_CHNG_SP_EVENT 14
+       struct bnxt_pf_info     pf;
+ #ifdef CONFIG_BNXT_SRIOV
diff --git a/queue-4.9/bnxt_en-fix-bnxt_reset-in-the-slow-path-task.patch b/queue-4.9/bnxt_en-fix-bnxt_reset-in-the-slow-path-task.patch
new file mode 100644 (file)
index 0000000..d03e216
--- /dev/null
@@ -0,0 +1,101 @@
+From foo@baz Thu Jun 15 16:23:30 CEST 2017
+From: Michael Chan <michael.chan@broadcom.com>
+Date: Wed, 25 Jan 2017 02:55:07 -0500
+Subject: bnxt_en: Fix bnxt_reset() in the slow path task.
+
+From: Michael Chan <michael.chan@broadcom.com>
+
+
+[ Upstream commit a551ee94ea723b4af9b827c7460f108bc13425ee ]
+
+In bnxt_sp_task(), we set a bit BNXT_STATE_IN_SP_TASK so that bnxt_close()
+will synchronize and wait for bnxt_sp_task() to finish.  Some functions
+in bnxt_sp_task() require us to clear BNXT_STATE_IN_SP_TASK and then
+acquire rtnl_lock() to prevent race conditions.
+
+There are some bugs related to this logic. This patch refactors the code
+to have common bnxt_rtnl_lock_sp() and bnxt_rtnl_unlock_sp() to handle
+the RTNL and the clearing/setting of the bit.  Multiple functions will
+need the same logic.  We also need to move bnxt_reset() to the end of
+bnxt_sp_task().  Functions that clear BNXT_STATE_IN_SP_TASK must be the
+last functions to be called in bnxt_sp_task().  The common scheme will
+handle the condition properly.
+
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c |   38 +++++++++++++++++++-----------
+ 1 file changed, 25 insertions(+), 13 deletions(-)
+
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -6080,23 +6080,32 @@ bnxt_restart_timer:
+       mod_timer(&bp->timer, jiffies + bp->current_interval);
+ }
+-/* Only called from bnxt_sp_task() */
+-static void bnxt_reset(struct bnxt *bp, bool silent)
++static void bnxt_rtnl_lock_sp(struct bnxt *bp)
+ {
+-      /* bnxt_reset_task() calls bnxt_close_nic() which waits
+-       * for BNXT_STATE_IN_SP_TASK to clear.
+-       * If there is a parallel dev_close(), bnxt_close() may be holding
++      /* We are called from bnxt_sp_task which has BNXT_STATE_IN_SP_TASK
++       * set.  If the device is being closed, bnxt_close() may be holding
+        * rtnl() and waiting for BNXT_STATE_IN_SP_TASK to clear.  So we
+        * must clear BNXT_STATE_IN_SP_TASK before holding rtnl().
+        */
+       clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
+       rtnl_lock();
+-      if (test_bit(BNXT_STATE_OPEN, &bp->state))
+-              bnxt_reset_task(bp, silent);
++}
++
++static void bnxt_rtnl_unlock_sp(struct bnxt *bp)
++{
+       set_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
+       rtnl_unlock();
+ }
++/* Only called from bnxt_sp_task() */
++static void bnxt_reset(struct bnxt *bp, bool silent)
++{
++      bnxt_rtnl_lock_sp(bp);
++      if (test_bit(BNXT_STATE_OPEN, &bp->state))
++              bnxt_reset_task(bp, silent);
++      bnxt_rtnl_unlock_sp(bp);
++}
++
+ static void bnxt_cfg_ntp_filters(struct bnxt *);
+ static void bnxt_sp_task(struct work_struct *work)
+@@ -6142,18 +6151,21 @@ static void bnxt_sp_task(struct work_str
+               bnxt_hwrm_tunnel_dst_port_free(
+                       bp, TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE);
+       }
+-      if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event))
+-              bnxt_reset(bp, false);
+-
+-      if (test_and_clear_bit(BNXT_RESET_TASK_SILENT_SP_EVENT, &bp->sp_event))
+-              bnxt_reset(bp, true);
+-
+       if (test_and_clear_bit(BNXT_HWRM_PORT_MODULE_SP_EVENT, &bp->sp_event))
+               bnxt_get_port_module_status(bp);
+       if (test_and_clear_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event))
+               bnxt_hwrm_port_qstats(bp);
++      /* These functions below will clear BNXT_STATE_IN_SP_TASK.  They
++       * must be the last functions to be called before exiting.
++       */
++      if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event))
++              bnxt_reset(bp, false);
++
++      if (test_and_clear_bit(BNXT_RESET_TASK_SILENT_SP_EVENT, &bp->sp_event))
++              bnxt_reset(bp, true);
++
+       smp_mb__before_atomic();
+       clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
+ }
diff --git a/queue-4.9/bnxt_en-fix-rtnl-lock-usage-on-bnxt_get_port_module_status.patch b/queue-4.9/bnxt_en-fix-rtnl-lock-usage-on-bnxt_get_port_module_status.patch
new file mode 100644 (file)
index 0000000..b9e5c21
--- /dev/null
@@ -0,0 +1,48 @@
+From foo@baz Thu Jun 15 16:23:30 CEST 2017
+From: Michael Chan <michael.chan@broadcom.com>
+Date: Wed, 25 Jan 2017 02:55:09 -0500
+Subject: bnxt_en: Fix RTNL lock usage on bnxt_get_port_module_status().
+
+From: Michael Chan <michael.chan@broadcom.com>
+
+
+[ Upstream commit 90c694bb71819fb5bd3501ac397307d7e41ddeca ]
+
+bnxt_get_port_module_status() calls bnxt_update_link() which expects
+RTNL to be held.  In bnxt_sp_task() that does not hold RTNL, we need to
+call it with a prior call to bnxt_rtnl_lock_sp() and the call needs to
+be moved to the end of bnxt_sp_task().
+
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c |    9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -6158,9 +6158,6 @@ static void bnxt_sp_task(struct work_str
+               bnxt_hwrm_tunnel_dst_port_free(
+                       bp, TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE);
+       }
+-      if (test_and_clear_bit(BNXT_HWRM_PORT_MODULE_SP_EVENT, &bp->sp_event))
+-              bnxt_get_port_module_status(bp);
+-
+       if (test_and_clear_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event))
+               bnxt_hwrm_port_qstats(bp);
+@@ -6182,6 +6179,12 @@ static void bnxt_sp_task(struct work_str
+                       netdev_err(bp->dev, "SP task can't update link (rc: %x)\n",
+                                  rc);
+       }
++      if (test_and_clear_bit(BNXT_HWRM_PORT_MODULE_SP_EVENT, &bp->sp_event)) {
++              bnxt_rtnl_lock_sp(bp);
++              if (test_bit(BNXT_STATE_OPEN, &bp->state))
++                      bnxt_get_port_module_status(bp);
++              bnxt_rtnl_unlock_sp(bp);
++      }
+       if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event))
+               bnxt_reset(bp, false);
diff --git a/queue-4.9/bnxt_en-fix-rtnl-lock-usage-on-bnxt_update_link.patch b/queue-4.9/bnxt_en-fix-rtnl-lock-usage-on-bnxt_update_link.patch
new file mode 100644 (file)
index 0000000..5e01869
--- /dev/null
@@ -0,0 +1,99 @@
+From foo@baz Thu Jun 15 16:23:30 CEST 2017
+From: Michael Chan <michael.chan@broadcom.com>
+Date: Wed, 25 Jan 2017 02:55:08 -0500
+Subject: bnxt_en: Fix RTNL lock usage on bnxt_update_link().
+
+From: Michael Chan <michael.chan@broadcom.com>
+
+
+[ Upstream commit 0eaa24b971ae251ae9d3be23f77662a655532063 ]
+
+bnxt_update_link() is called from multiple code paths.  Most callers,
+such as open, ethtool, already hold RTNL.  Only the caller bnxt_sp_task()
+does not.  So it is a bug to take RTNL inside bnxt_update_link().
+
+Fix it by removing the RTNL inside bnxt_update_link().  The function
+now expects the caller to always hold RTNL.
+
+In bnxt_sp_task(), call bnxt_rtnl_lock_sp() before calling
+bnxt_update_link().  We also need to move the call to the end of
+bnxt_sp_task() since it will be clearing the BNXT_STATE_IN_SP_TASK bit.
+
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c |   37 ++++++++++++++----------------
+ 1 file changed, 18 insertions(+), 19 deletions(-)
+
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -5204,17 +5204,12 @@ static int bnxt_update_link(struct bnxt
+       if ((link_info->support_auto_speeds | diff) !=
+           link_info->support_auto_speeds) {
+               /* An advertised speed is no longer supported, so we need to
+-               * update the advertisement settings.  See bnxt_reset() for
+-               * comments about the rtnl_lock() sequence below.
++               * update the advertisement settings.  Caller holds RTNL
++               * so we can modify link settings.
+                */
+-              clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
+-              rtnl_lock();
+               link_info->advertising = link_info->support_auto_speeds;
+-              if (test_bit(BNXT_STATE_OPEN, &bp->state) &&
+-                  (link_info->autoneg & BNXT_AUTONEG_SPEED))
++              if (link_info->autoneg & BNXT_AUTONEG_SPEED)
+                       bnxt_hwrm_set_link_setting(bp, true, false);
+-              set_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
+-              rtnl_unlock();
+       }
+       return 0;
+ }
+@@ -6130,7 +6125,6 @@ static void bnxt_cfg_ntp_filters(struct
+ static void bnxt_sp_task(struct work_struct *work)
+ {
+       struct bnxt *bp = container_of(work, struct bnxt, sp_task);
+-      int rc;
+       set_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
+       smp_mb__after_atomic();
+@@ -6144,16 +6138,6 @@ static void bnxt_sp_task(struct work_str
+       if (test_and_clear_bit(BNXT_RX_NTP_FLTR_SP_EVENT, &bp->sp_event))
+               bnxt_cfg_ntp_filters(bp);
+-      if (test_and_clear_bit(BNXT_LINK_CHNG_SP_EVENT, &bp->sp_event)) {
+-              if (test_and_clear_bit(BNXT_LINK_SPEED_CHNG_SP_EVENT,
+-                                     &bp->sp_event))
+-                      bnxt_hwrm_phy_qcaps(bp);
+-
+-              rc = bnxt_update_link(bp, true);
+-              if (rc)
+-                      netdev_err(bp->dev, "SP task can't update link (rc: %x)\n",
+-                                 rc);
+-      }
+       if (test_and_clear_bit(BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT, &bp->sp_event))
+               bnxt_hwrm_exec_fwd_req(bp);
+       if (test_and_clear_bit(BNXT_VXLAN_ADD_PORT_SP_EVENT, &bp->sp_event)) {
+@@ -6183,6 +6167,21 @@ static void bnxt_sp_task(struct work_str
+       /* These functions below will clear BNXT_STATE_IN_SP_TASK.  They
+        * must be the last functions to be called before exiting.
+        */
++      if (test_and_clear_bit(BNXT_LINK_CHNG_SP_EVENT, &bp->sp_event)) {
++              int rc = 0;
++
++              if (test_and_clear_bit(BNXT_LINK_SPEED_CHNG_SP_EVENT,
++                                     &bp->sp_event))
++                      bnxt_hwrm_phy_qcaps(bp);
++
++              bnxt_rtnl_lock_sp(bp);
++              if (test_bit(BNXT_STATE_OPEN, &bp->state))
++                      rc = bnxt_update_link(bp, true);
++              bnxt_rtnl_unlock_sp(bp);
++              if (rc)
++                      netdev_err(bp->dev, "SP task can't update link (rc: %x)\n",
++                                 rc);
++      }
+       if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event))
+               bnxt_reset(bp, false);
diff --git a/queue-4.9/frv-add-atomic64_add_unless.patch b/queue-4.9/frv-add-atomic64_add_unless.patch
new file mode 100644 (file)
index 0000000..67f232b
--- /dev/null
@@ -0,0 +1,56 @@
+From foo@baz Thu Jun 15 16:23:30 CEST 2017
+From: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+Date: Tue, 24 Jan 2017 15:18:21 -0800
+Subject: frv: add atomic64_add_unless()
+
+From: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+
+
+[ Upstream commit 545d58f677b21401f6de1ac12c25cc109f903ace ]
+
+The build of frv allmodconfig was failing with the error:
+lib/atomic64_test.c:209:9: error:
+
+       implicit declaration of function 'atomic64_add_unless'
+
+All the atomic64 operations were defined in frv, but
+atomic64_add_unless() was not done.
+
+Implement atomic64_add_unless() as done in other arches.
+
+Link: http://lkml.kernel.org/r/1484781236-6698-1-git-send-email-sudipm.mukherjee@gmail.com
+Signed-off-by: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>
+Cc: David Howells <dhowells@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/frv/include/asm/atomic.h |   16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/arch/frv/include/asm/atomic.h
++++ b/arch/frv/include/asm/atomic.h
+@@ -161,6 +161,22 @@ static __inline__ int __atomic_add_unles
+       return c;
+ }
++static inline int atomic64_add_unless(atomic64_t *v, long long i, long long u)
++{
++      long long c, old;
++
++      c = atomic64_read(v);
++      for (;;) {
++              if (unlikely(c == u))
++                      break;
++              old = atomic64_cmpxchg(v, c, c + i);
++              if (likely(old == c))
++                      break;
++              c = old;
++      }
++      return c != u;
++}
++
+ #define ATOMIC_OP(op)                                                 \
+ static inline int atomic_fetch_##op(int i, atomic_t *v)                       \
+ {                                                                     \
diff --git a/queue-4.9/frv-add-missing-atomic64-operations.patch b/queue-4.9/frv-add-missing-atomic64-operations.patch
new file mode 100644 (file)
index 0000000..37c5290
--- /dev/null
@@ -0,0 +1,59 @@
+From foo@baz Thu Jun 15 16:23:30 CEST 2017
+From: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+Date: Tue, 24 Jan 2017 15:18:43 -0800
+Subject: frv: add missing atomic64 operations
+
+From: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+
+
+[ Upstream commit 4180c4c170a5a33b9987b314d248a9d572d89ab0 ]
+
+Some more atomic64 operations were missing and as a result frv
+allmodconfig was failing.  Add the missing operations.
+
+Link: http://lkml.kernel.org/r/1485193844-12850-1-git-send-email-sudip.mukherjee@codethink.co.uk
+Signed-off-by: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>
+Cc: David Howells <dhowells@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/frv/include/asm/atomic.h |   19 ++++++++++++++++++-
+ 1 file changed, 18 insertions(+), 1 deletion(-)
+
+--- a/arch/frv/include/asm/atomic.h
++++ b/arch/frv/include/asm/atomic.h
+@@ -139,7 +139,7 @@ static inline void atomic64_dec(atomic64
+ #define atomic64_sub_and_test(i,v)    (atomic64_sub_return((i), (v)) == 0)
+ #define atomic64_dec_and_test(v)      (atomic64_dec_return((v)) == 0)
+ #define atomic64_inc_and_test(v)      (atomic64_inc_return((v)) == 0)
+-
++#define atomic64_inc_not_zero(v)      atomic64_add_unless((v), 1, 0)
+ #define atomic_cmpxchg(v, old, new)   (cmpxchg(&(v)->counter, old, new))
+ #define atomic_xchg(v, new)           (xchg(&(v)->counter, new))
+@@ -177,6 +177,23 @@ static inline int atomic64_add_unless(at
+       return c != u;
+ }
++static inline long long atomic64_dec_if_positive(atomic64_t *v)
++{
++      long long c, old, dec;
++
++      c = atomic64_read(v);
++      for (;;) {
++              dec = c - 1;
++              if (unlikely(dec < 0))
++                      break;
++              old = atomic64_cmpxchg((v), c, dec);
++              if (likely(old == c))
++                      break;
++              c = old;
++      }
++              return dec;
++}
++
+ #define ATOMIC_OP(op)                                                 \
+ static inline int atomic_fetch_##op(int i, atomic_t *v)                       \
+ {                                                                     \
diff --git a/queue-4.9/kernel-watchdog-prevent-false-hardlockup-on-overloaded-system.patch b/queue-4.9/kernel-watchdog-prevent-false-hardlockup-on-overloaded-system.patch
new file mode 100644 (file)
index 0000000..0d1c14e
--- /dev/null
@@ -0,0 +1,107 @@
+From foo@baz Thu Jun 15 16:23:30 CEST 2017
+From: Don Zickus <dzickus@redhat.com>
+Date: Tue, 24 Jan 2017 15:17:53 -0800
+Subject: kernel/watchdog: prevent false hardlockup on overloaded system
+
+From: Don Zickus <dzickus@redhat.com>
+
+
+[ Upstream commit b94f51183b0617e7b9b4fb4137d4cf1cab7547c2 ]
+
+On an overloaded system, it is possible that a change in the watchdog
+threshold can be delayed long enough to trigger a false positive.
+
+This can easily be achieved by having a cpu spinning indefinitely on a
+task, while another cpu updates watchdog threshold.
+
+What happens is while trying to park the watchdog threads, the hrtimers
+on the other cpus trigger and reprogram themselves with the new slower
+watchdog threshold.  Meanwhile, the nmi watchdog is still programmed
+with the old faster threshold.
+
+Because the one cpu is blocked, it prevents the thread parking on the
+other cpus from completing, which is needed to shutdown the nmi watchdog
+and reprogram it correctly.  As a result, a false positive from the nmi
+watchdog is reported.
+
+Fix this by setting a park_in_progress flag to block all lockups until
+the parking is complete.
+
+Fix provided by Ulrich Obergfell.
+
+[akpm@linux-foundation.org: s/park_in_progress/watchdog_park_in_progress/]
+Link: http://lkml.kernel.org/r/1481041033-192236-1-git-send-email-dzickus@redhat.com
+Signed-off-by: Don Zickus <dzickus@redhat.com>
+Reviewed-by: Aaron Tomlin <atomlin@redhat.com>
+Cc: Ulrich Obergfell <uobergfe@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+
+Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/nmi.h   |    1 +
+ kernel/watchdog.c     |    9 +++++++++
+ kernel/watchdog_hld.c |    3 +++
+ 3 files changed, 13 insertions(+)
+
+--- a/include/linux/nmi.h
++++ b/include/linux/nmi.h
+@@ -110,6 +110,7 @@ extern int watchdog_user_enabled;
+ extern int watchdog_thresh;
+ extern unsigned long watchdog_enabled;
+ extern unsigned long *watchdog_cpumask_bits;
++extern atomic_t watchdog_park_in_progress;
+ #ifdef CONFIG_SMP
+ extern int sysctl_softlockup_all_cpu_backtrace;
+ extern int sysctl_hardlockup_all_cpu_backtrace;
+--- a/kernel/watchdog.c
++++ b/kernel/watchdog.c
+@@ -49,6 +49,8 @@ unsigned long *watchdog_cpumask_bits = c
+ #define for_each_watchdog_cpu(cpu) \
+       for_each_cpu_and((cpu), cpu_online_mask, &watchdog_cpumask)
++atomic_t watchdog_park_in_progress = ATOMIC_INIT(0);
++
+ /*
+  * The 'watchdog_running' variable is set to 1 when the watchdog threads
+  * are registered/started and is set to 0 when the watchdog threads are
+@@ -260,6 +262,9 @@ static enum hrtimer_restart watchdog_tim
+       int duration;
+       int softlockup_all_cpu_backtrace = sysctl_softlockup_all_cpu_backtrace;
++      if (atomic_read(&watchdog_park_in_progress) != 0)
++              return HRTIMER_NORESTART;
++
+       /* kick the hardlockup detector */
+       watchdog_interrupt_count();
+@@ -467,12 +472,16 @@ static int watchdog_park_threads(void)
+ {
+       int cpu, ret = 0;
++      atomic_set(&watchdog_park_in_progress, 1);
++
+       for_each_watchdog_cpu(cpu) {
+               ret = kthread_park(per_cpu(softlockup_watchdog, cpu));
+               if (ret)
+                       break;
+       }
++      atomic_set(&watchdog_park_in_progress, 0);
++
+       return ret;
+ }
+--- a/kernel/watchdog_hld.c
++++ b/kernel/watchdog_hld.c
+@@ -84,6 +84,9 @@ static void watchdog_overflow_callback(s
+       /* Ensure the watchdog never gets throttled */
+       event->hw.interrupts = 0;
++      if (atomic_read(&watchdog_park_in_progress) != 0)
++              return;
++
+       if (__this_cpu_read(watchdog_nmi_touch) == true) {
+               __this_cpu_write(watchdog_nmi_touch, false);
+               return;
diff --git a/queue-4.9/kernel-watchdog.c-move-hardlockup-detector-to-separate-file.patch b/queue-4.9/kernel-watchdog.c-move-hardlockup-detector-to-separate-file.patch
new file mode 100644 (file)
index 0000000..c809764
--- /dev/null
@@ -0,0 +1,578 @@
+From foo@baz Thu Jun 15 16:23:30 CEST 2017
+From: Babu Moger <babu.moger@oracle.com>
+Date: Wed, 14 Dec 2016 15:06:24 -0800
+Subject: kernel/watchdog.c: move hardlockup detector to separate file
+
+From: Babu Moger <babu.moger@oracle.com>
+
+
+[ Upstream commit 73ce0511c43686095efd2f65ef564aab952e07bc ]
+
+Separate hardlockup code from watchdog.c and move it to watchdog_hld.c.
+It is mostly straight forward.  Remove everything inside
+CONFIG_HARDLOCKUP_DETECTORS.  This code will go to file watchdog_hld.c.
+Also update the makefile accordigly.
+
+Link: http://lkml.kernel.org/r/1478034826-43888-3-git-send-email-babu.moger@oracle.com
+Signed-off-by: Babu Moger <babu.moger@oracle.com>
+Acked-by: Don Zickus <dzickus@redhat.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Kosina <jkosina@suse.cz>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: Yaowei Bai <baiyaowei@cmss.chinamobile.com>
+Cc: Aaron Tomlin <atomlin@redhat.com>
+Cc: Ulrich Obergfell <uobergfe@redhat.com>
+Cc: Tejun Heo <tj@kernel.org>
+Cc: Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com>
+Cc: Josh Hunt <johunt@akamai.com>
+Cc: "David S. Miller" <davem@davemloft.net>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/Makefile       |    1 
+ kernel/watchdog.c     |  241 ++------------------------------------------------
+ kernel/watchdog_hld.c |  227 +++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 239 insertions(+), 230 deletions(-)
+ create mode 100644 kernel/watchdog_hld.c
+
+--- a/kernel/Makefile
++++ b/kernel/Makefile
+@@ -84,6 +84,7 @@ obj-$(CONFIG_KPROBES) += kprobes.o
+ obj-$(CONFIG_KGDB) += debug/
+ obj-$(CONFIG_DETECT_HUNG_TASK) += hung_task.o
+ obj-$(CONFIG_LOCKUP_DETECTOR) += watchdog.o
++obj-$(CONFIG_HARDLOCKUP_DETECTOR) += watchdog_hld.o
+ obj-$(CONFIG_SECCOMP) += seccomp.o
+ obj-$(CONFIG_RELAY) += relay.o
+ obj-$(CONFIG_SYSCTL) += utsname_sysctl.o
+--- a/kernel/watchdog.c
++++ b/kernel/watchdog.c
+@@ -24,7 +24,6 @@
+ #include <asm/irq_regs.h>
+ #include <linux/kvm_para.h>
+-#include <linux/perf_event.h>
+ #include <linux/kthread.h>
+ /*
+@@ -100,50 +99,9 @@ static DEFINE_PER_CPU(bool, soft_watchdo
+ static DEFINE_PER_CPU(unsigned long, hrtimer_interrupts);
+ static DEFINE_PER_CPU(unsigned long, soft_lockup_hrtimer_cnt);
+ static DEFINE_PER_CPU(struct task_struct *, softlockup_task_ptr_saved);
+-#ifdef CONFIG_HARDLOCKUP_DETECTOR
+-static DEFINE_PER_CPU(bool, hard_watchdog_warn);
+-static DEFINE_PER_CPU(bool, watchdog_nmi_touch);
+ static DEFINE_PER_CPU(unsigned long, hrtimer_interrupts_saved);
+-static DEFINE_PER_CPU(struct perf_event *, watchdog_ev);
+-#endif
+ static unsigned long soft_lockup_nmi_warn;
+-/* boot commands */
+-/*
+- * Should we panic when a soft-lockup or hard-lockup occurs:
+- */
+-#ifdef CONFIG_HARDLOCKUP_DETECTOR
+-unsigned int __read_mostly hardlockup_panic =
+-                      CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE;
+-static unsigned long hardlockup_allcpu_dumped;
+-/*
+- * We may not want to enable hard lockup detection by default in all cases,
+- * for example when running the kernel as a guest on a hypervisor. In these
+- * cases this function can be called to disable hard lockup detection. This
+- * function should only be executed once by the boot processor before the
+- * kernel command line parameters are parsed, because otherwise it is not
+- * possible to override this in hardlockup_panic_setup().
+- */
+-void hardlockup_detector_disable(void)
+-{
+-      watchdog_enabled &= ~NMI_WATCHDOG_ENABLED;
+-}
+-
+-static int __init hardlockup_panic_setup(char *str)
+-{
+-      if (!strncmp(str, "panic", 5))
+-              hardlockup_panic = 1;
+-      else if (!strncmp(str, "nopanic", 7))
+-              hardlockup_panic = 0;
+-      else if (!strncmp(str, "0", 1))
+-              watchdog_enabled &= ~NMI_WATCHDOG_ENABLED;
+-      else if (!strncmp(str, "1", 1))
+-              watchdog_enabled |= NMI_WATCHDOG_ENABLED;
+-      return 1;
+-}
+-__setup("nmi_watchdog=", hardlockup_panic_setup);
+-#endif
+-
+ unsigned int __read_mostly softlockup_panic =
+                       CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE;
+@@ -264,30 +222,12 @@ void touch_all_softlockup_watchdogs(void
+       wq_watchdog_touch(-1);
+ }
+-#ifdef CONFIG_HARDLOCKUP_DETECTOR
+-void touch_nmi_watchdog(void)
+-{
+-      /*
+-       * Using __raw here because some code paths have
+-       * preemption enabled.  If preemption is enabled
+-       * then interrupts should be enabled too, in which
+-       * case we shouldn't have to worry about the watchdog
+-       * going off.
+-       */
+-      raw_cpu_write(watchdog_nmi_touch, true);
+-      touch_softlockup_watchdog();
+-}
+-EXPORT_SYMBOL(touch_nmi_watchdog);
+-
+-#endif
+-
+ void touch_softlockup_watchdog_sync(void)
+ {
+       __this_cpu_write(softlockup_touch_sync, true);
+       __this_cpu_write(watchdog_touch_ts, 0);
+ }
+-#ifdef CONFIG_HARDLOCKUP_DETECTOR
+ /* watchdog detector functions */
+ static bool is_hardlockup(void)
+ {
+@@ -299,7 +239,6 @@ static bool is_hardlockup(void)
+       __this_cpu_write(hrtimer_interrupts_saved, hrint);
+       return false;
+ }
+-#endif
+ static int is_softlockup(unsigned long touch_ts)
+ {
+@@ -313,77 +252,22 @@ static int is_softlockup(unsigned long t
+       return 0;
+ }
+-#ifdef CONFIG_HARDLOCKUP_DETECTOR
+-
+-static struct perf_event_attr wd_hw_attr = {
+-      .type           = PERF_TYPE_HARDWARE,
+-      .config         = PERF_COUNT_HW_CPU_CYCLES,
+-      .size           = sizeof(struct perf_event_attr),
+-      .pinned         = 1,
+-      .disabled       = 1,
+-};
+-
+-/* Callback function for perf event subsystem */
+-static void watchdog_overflow_callback(struct perf_event *event,
+-               struct perf_sample_data *data,
+-               struct pt_regs *regs)
+-{
+-      /* Ensure the watchdog never gets throttled */
+-      event->hw.interrupts = 0;
+-
+-      if (__this_cpu_read(watchdog_nmi_touch) == true) {
+-              __this_cpu_write(watchdog_nmi_touch, false);
+-              return;
+-      }
+-
+-      /* check for a hardlockup
+-       * This is done by making sure our timer interrupt
+-       * is incrementing.  The timer interrupt should have
+-       * fired multiple times before we overflow'd.  If it hasn't
+-       * then this is a good indication the cpu is stuck
+-       */
+-      if (is_hardlockup()) {
+-              int this_cpu = smp_processor_id();
+-
+-              /* only print hardlockups once */
+-              if (__this_cpu_read(hard_watchdog_warn) == true)
+-                      return;
+-
+-              pr_emerg("Watchdog detected hard LOCKUP on cpu %d", this_cpu);
+-              print_modules();
+-              print_irqtrace_events(current);
+-              if (regs)
+-                      show_regs(regs);
+-              else
+-                      dump_stack();
+-
+-              /*
+-               * Perform all-CPU dump only once to avoid multiple hardlockups
+-               * generating interleaving traces
+-               */
+-              if (sysctl_hardlockup_all_cpu_backtrace &&
+-                              !test_and_set_bit(0, &hardlockup_allcpu_dumped))
+-                      trigger_allbutself_cpu_backtrace();
+-
+-              if (hardlockup_panic)
+-                      nmi_panic(regs, "Hard LOCKUP");
+-
+-              __this_cpu_write(hard_watchdog_warn, true);
+-              return;
+-      }
+-
+-      __this_cpu_write(hard_watchdog_warn, false);
+-      return;
+-}
+-#endif /* CONFIG_HARDLOCKUP_DETECTOR */
+-
+ static void watchdog_interrupt_count(void)
+ {
+       __this_cpu_inc(hrtimer_interrupts);
+ }
+-static int watchdog_nmi_enable(unsigned int cpu);
+-static void watchdog_nmi_disable(unsigned int cpu);
++/*
++ * These two functions are mostly architecture specific
++ * defining them as weak here.
++ */
++int __weak watchdog_nmi_enable(unsigned int cpu)
++{
++      return 0;
++}
++void __weak watchdog_nmi_disable(unsigned int cpu)
++{
++}
+ static int watchdog_enable_all_cpus(void);
+ static void watchdog_disable_all_cpus(void);
+@@ -576,109 +460,6 @@ static void watchdog(unsigned int cpu)
+               watchdog_nmi_disable(cpu);
+ }
+-#ifdef CONFIG_HARDLOCKUP_DETECTOR
+-/*
+- * People like the simple clean cpu node info on boot.
+- * Reduce the watchdog noise by only printing messages
+- * that are different from what cpu0 displayed.
+- */
+-static unsigned long cpu0_err;
+-
+-static int watchdog_nmi_enable(unsigned int cpu)
+-{
+-      struct perf_event_attr *wd_attr;
+-      struct perf_event *event = per_cpu(watchdog_ev, cpu);
+-
+-      /* nothing to do if the hard lockup detector is disabled */
+-      if (!(watchdog_enabled & NMI_WATCHDOG_ENABLED))
+-              goto out;
+-
+-      /* is it already setup and enabled? */
+-      if (event && event->state > PERF_EVENT_STATE_OFF)
+-              goto out;
+-
+-      /* it is setup but not enabled */
+-      if (event != NULL)
+-              goto out_enable;
+-
+-      wd_attr = &wd_hw_attr;
+-      wd_attr->sample_period = hw_nmi_get_sample_period(watchdog_thresh);
+-
+-      /* Try to register using hardware perf events */
+-      event = perf_event_create_kernel_counter(wd_attr, cpu, NULL, watchdog_overflow_callback, NULL);
+-
+-      /* save cpu0 error for future comparision */
+-      if (cpu == 0 && IS_ERR(event))
+-              cpu0_err = PTR_ERR(event);
+-
+-      if (!IS_ERR(event)) {
+-              /* only print for cpu0 or different than cpu0 */
+-              if (cpu == 0 || cpu0_err)
+-                      pr_info("enabled on all CPUs, permanently consumes one hw-PMU counter.\n");
+-              goto out_save;
+-      }
+-
+-      /*
+-       * Disable the hard lockup detector if _any_ CPU fails to set up
+-       * set up the hardware perf event. The watchdog() function checks
+-       * the NMI_WATCHDOG_ENABLED bit periodically.
+-       *
+-       * The barriers are for syncing up watchdog_enabled across all the
+-       * cpus, as clear_bit() does not use barriers.
+-       */
+-      smp_mb__before_atomic();
+-      clear_bit(NMI_WATCHDOG_ENABLED_BIT, &watchdog_enabled);
+-      smp_mb__after_atomic();
+-
+-      /* skip displaying the same error again */
+-      if (cpu > 0 && (PTR_ERR(event) == cpu0_err))
+-              return PTR_ERR(event);
+-
+-      /* vary the KERN level based on the returned errno */
+-      if (PTR_ERR(event) == -EOPNOTSUPP)
+-              pr_info("disabled (cpu%i): not supported (no LAPIC?)\n", cpu);
+-      else if (PTR_ERR(event) == -ENOENT)
+-              pr_warn("disabled (cpu%i): hardware events not enabled\n",
+-                       cpu);
+-      else
+-              pr_err("disabled (cpu%i): unable to create perf event: %ld\n",
+-                      cpu, PTR_ERR(event));
+-
+-      pr_info("Shutting down hard lockup detector on all cpus\n");
+-
+-      return PTR_ERR(event);
+-
+-      /* success path */
+-out_save:
+-      per_cpu(watchdog_ev, cpu) = event;
+-out_enable:
+-      perf_event_enable(per_cpu(watchdog_ev, cpu));
+-out:
+-      return 0;
+-}
+-
+-static void watchdog_nmi_disable(unsigned int cpu)
+-{
+-      struct perf_event *event = per_cpu(watchdog_ev, cpu);
+-
+-      if (event) {
+-              perf_event_disable(event);
+-              per_cpu(watchdog_ev, cpu) = NULL;
+-
+-              /* should be in cleanup, but blocks oprofile */
+-              perf_event_release_kernel(event);
+-      }
+-      if (cpu == 0) {
+-              /* watchdog_nmi_enable() expects this to be zero initially. */
+-              cpu0_err = 0;
+-      }
+-}
+-
+-#else
+-static int watchdog_nmi_enable(unsigned int cpu) { return 0; }
+-static void watchdog_nmi_disable(unsigned int cpu) { return; }
+-#endif /* CONFIG_HARDLOCKUP_DETECTOR */
+-
+ static struct smp_hotplug_thread watchdog_threads = {
+       .store                  = &softlockup_watchdog,
+       .thread_should_run      = watchdog_should_run,
+--- /dev/null
++++ b/kernel/watchdog_hld.c
+@@ -0,0 +1,227 @@
++/*
++ * Detect hard lockups on a system
++ *
++ * started by Don Zickus, Copyright (C) 2010 Red Hat, Inc.
++ *
++ * Note: Most of this code is borrowed heavily from the original softlockup
++ * detector, so thanks to Ingo for the initial implementation.
++ * Some chunks also taken from the old x86-specific nmi watchdog code, thanks
++ * to those contributors as well.
++ */
++
++#define pr_fmt(fmt) "NMI watchdog: " fmt
++
++#include <linux/nmi.h>
++#include <linux/module.h>
++#include <asm/irq_regs.h>
++#include <linux/perf_event.h>
++
++static DEFINE_PER_CPU(bool, hard_watchdog_warn);
++static DEFINE_PER_CPU(bool, watchdog_nmi_touch);
++static DEFINE_PER_CPU(struct perf_event *, watchdog_ev);
++
++/* boot commands */
++/*
++ * Should we panic when a soft-lockup or hard-lockup occurs:
++ */
++unsigned int __read_mostly hardlockup_panic =
++                      CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE;
++static unsigned long hardlockup_allcpu_dumped;
++/*
++ * We may not want to enable hard lockup detection by default in all cases,
++ * for example when running the kernel as a guest on a hypervisor. In these
++ * cases this function can be called to disable hard lockup detection. This
++ * function should only be executed once by the boot processor before the
++ * kernel command line parameters are parsed, because otherwise it is not
++ * possible to override this in hardlockup_panic_setup().
++ */
++void hardlockup_detector_disable(void)
++{
++      watchdog_enabled &= ~NMI_WATCHDOG_ENABLED;
++}
++
++static int __init hardlockup_panic_setup(char *str)
++{
++      if (!strncmp(str, "panic", 5))
++              hardlockup_panic = 1;
++      else if (!strncmp(str, "nopanic", 7))
++              hardlockup_panic = 0;
++      else if (!strncmp(str, "0", 1))
++              watchdog_enabled &= ~NMI_WATCHDOG_ENABLED;
++      else if (!strncmp(str, "1", 1))
++              watchdog_enabled |= NMI_WATCHDOG_ENABLED;
++      return 1;
++}
++__setup("nmi_watchdog=", hardlockup_panic_setup);
++
++void touch_nmi_watchdog(void)
++{
++      /*
++       * Using __raw here because some code paths have
++       * preemption enabled.  If preemption is enabled
++       * then interrupts should be enabled too, in which
++       * case we shouldn't have to worry about the watchdog
++       * going off.
++       */
++      raw_cpu_write(watchdog_nmi_touch, true);
++      touch_softlockup_watchdog();
++}
++EXPORT_SYMBOL(touch_nmi_watchdog);
++
++static struct perf_event_attr wd_hw_attr = {
++      .type           = PERF_TYPE_HARDWARE,
++      .config         = PERF_COUNT_HW_CPU_CYCLES,
++      .size           = sizeof(struct perf_event_attr),
++      .pinned         = 1,
++      .disabled       = 1,
++};
++
++/* Callback function for perf event subsystem */
++static void watchdog_overflow_callback(struct perf_event *event,
++               struct perf_sample_data *data,
++               struct pt_regs *regs)
++{
++      /* Ensure the watchdog never gets throttled */
++      event->hw.interrupts = 0;
++
++      if (__this_cpu_read(watchdog_nmi_touch) == true) {
++              __this_cpu_write(watchdog_nmi_touch, false);
++              return;
++      }
++
++      /* check for a hardlockup
++       * This is done by making sure our timer interrupt
++       * is incrementing.  The timer interrupt should have
++       * fired multiple times before we overflow'd.  If it hasn't
++       * then this is a good indication the cpu is stuck
++       */
++      if (is_hardlockup()) {
++              int this_cpu = smp_processor_id();
++
++              /* only print hardlockups once */
++              if (__this_cpu_read(hard_watchdog_warn) == true)
++                      return;
++
++              pr_emerg("Watchdog detected hard LOCKUP on cpu %d", this_cpu);
++              print_modules();
++              print_irqtrace_events(current);
++              if (regs)
++                      show_regs(regs);
++              else
++                      dump_stack();
++
++              /*
++               * Perform all-CPU dump only once to avoid multiple hardlockups
++               * generating interleaving traces
++               */
++              if (sysctl_hardlockup_all_cpu_backtrace &&
++                              !test_and_set_bit(0, &hardlockup_allcpu_dumped))
++                      trigger_allbutself_cpu_backtrace();
++
++              if (hardlockup_panic)
++                      nmi_panic(regs, "Hard LOCKUP");
++
++              __this_cpu_write(hard_watchdog_warn, true);
++              return;
++      }
++
++      __this_cpu_write(hard_watchdog_warn, false);
++      return;
++}
++
++/*
++ * People like the simple clean cpu node info on boot.
++ * Reduce the watchdog noise by only printing messages
++ * that are different from what cpu0 displayed.
++ */
++static unsigned long cpu0_err;
++
++int watchdog_nmi_enable(unsigned int cpu)
++{
++      struct perf_event_attr *wd_attr;
++      struct perf_event *event = per_cpu(watchdog_ev, cpu);
++
++      /* nothing to do if the hard lockup detector is disabled */
++      if (!(watchdog_enabled & NMI_WATCHDOG_ENABLED))
++              goto out;
++
++      /* is it already setup and enabled? */
++      if (event && event->state > PERF_EVENT_STATE_OFF)
++              goto out;
++
++      /* it is setup but not enabled */
++      if (event != NULL)
++              goto out_enable;
++
++      wd_attr = &wd_hw_attr;
++      wd_attr->sample_period = hw_nmi_get_sample_period(watchdog_thresh);
++
++      /* Try to register using hardware perf events */
++      event = perf_event_create_kernel_counter(wd_attr, cpu, NULL, watchdog_overflow_callback, NULL);
++
++      /* save cpu0 error for future comparision */
++      if (cpu == 0 && IS_ERR(event))
++              cpu0_err = PTR_ERR(event);
++
++      if (!IS_ERR(event)) {
++              /* only print for cpu0 or different than cpu0 */
++              if (cpu == 0 || cpu0_err)
++                      pr_info("enabled on all CPUs, permanently consumes one hw-PMU counter.\n");
++              goto out_save;
++      }
++
++      /*
++       * Disable the hard lockup detector if _any_ CPU fails to set up
++       * set up the hardware perf event. The watchdog() function checks
++       * the NMI_WATCHDOG_ENABLED bit periodically.
++       *
++       * The barriers are for syncing up watchdog_enabled across all the
++       * cpus, as clear_bit() does not use barriers.
++       */
++      smp_mb__before_atomic();
++      clear_bit(NMI_WATCHDOG_ENABLED_BIT, &watchdog_enabled);
++      smp_mb__after_atomic();
++
++      /* skip displaying the same error again */
++      if (cpu > 0 && (PTR_ERR(event) == cpu0_err))
++              return PTR_ERR(event);
++
++      /* vary the KERN level based on the returned errno */
++      if (PTR_ERR(event) == -EOPNOTSUPP)
++              pr_info("disabled (cpu%i): not supported (no LAPIC?)\n", cpu);
++      else if (PTR_ERR(event) == -ENOENT)
++              pr_warn("disabled (cpu%i): hardware events not enabled\n",
++                       cpu);
++      else
++              pr_err("disabled (cpu%i): unable to create perf event: %ld\n",
++                      cpu, PTR_ERR(event));
++
++      pr_info("Shutting down hard lockup detector on all cpus\n");
++
++      return PTR_ERR(event);
++
++      /* success path */
++out_save:
++      per_cpu(watchdog_ev, cpu) = event;
++out_enable:
++      perf_event_enable(per_cpu(watchdog_ev, cpu));
++out:
++      return 0;
++}
++
++void watchdog_nmi_disable(unsigned int cpu)
++{
++      struct perf_event *event = per_cpu(watchdog_ev, cpu);
++
++      if (event) {
++              perf_event_disable(event);
++              per_cpu(watchdog_ev, cpu) = NULL;
++
++              /* should be in cleanup, but blocks oprofile */
++              perf_event_release_kernel(event);
++      }
++      if (cpu == 0) {
++              /* watchdog_nmi_enable() expects this to be zero initially. */
++              cpu0_err = 0;
++      }
++}
diff --git a/queue-4.9/kernel-watchdog.c-move-shared-definitions-to-nmi.h.patch b/queue-4.9/kernel-watchdog.c-move-shared-definitions-to-nmi.h.patch
new file mode 100644 (file)
index 0000000..6af7f97
--- /dev/null
@@ -0,0 +1,154 @@
+From foo@baz Thu Jun 15 16:23:30 CEST 2017
+From: Babu Moger <babu.moger@oracle.com>
+Date: Wed, 14 Dec 2016 15:06:21 -0800
+Subject: kernel/watchdog.c: move shared definitions to nmi.h
+
+From: Babu Moger <babu.moger@oracle.com>
+
+
+[ Upstream commit 249e52e35580fcfe5dad53a7dcd7c1252788749c ]
+
+Patch series "Clean up watchdog handlers", v2.
+
+This is an attempt to cleanup watchdog handlers.  Right now,
+kernel/watchdog.c implements both softlockup and hardlockup detectors.
+Softlockup code is generic.  Hardlockup code is arch specific.  Some
+architectures don't use hardlockup detectors.  They use their own
+watchdog detectors.  To make both these combination work, we have
+numerous #ifdefs in kernel/watchdog.c.
+
+We are trying here to make these handlers independent of each other.
+Also provide an interface for architectures to implement their own
+handlers.  watchdog_nmi_enable and watchdog_nmi_disable will be defined
+as weak such that architectures can override its definitions.
+
+Thanks to Don Zickus for his suggestions.
+Here are our previous discussions
+http://www.spinics.net/lists/sparclinux/msg16543.html
+http://www.spinics.net/lists/sparclinux/msg16441.html
+
+This patch (of 3):
+
+Move shared macros and definitions to nmi.h so that watchdog.c, new file
+watchdog_hld.c or any other architecture specific handler can use those
+definitions.
+
+Link: http://lkml.kernel.org/r/1478034826-43888-2-git-send-email-babu.moger@oracle.com
+Signed-off-by: Babu Moger <babu.moger@oracle.com>
+Acked-by: Don Zickus <dzickus@redhat.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Kosina <jkosina@suse.cz>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: Yaowei Bai <baiyaowei@cmss.chinamobile.com>
+Cc: Aaron Tomlin <atomlin@redhat.com>
+Cc: Ulrich Obergfell <uobergfe@redhat.com>
+Cc: Tejun Heo <tj@kernel.org>
+Cc: Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com>
+Cc: Josh Hunt <johunt@akamai.com>
+Cc: "David S. Miller" <davem@davemloft.net>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/nmi.h |   24 ++++++++++++++++++++++++
+ kernel/watchdog.c   |   28 ++++------------------------
+ 2 files changed, 28 insertions(+), 24 deletions(-)
+
+--- a/include/linux/nmi.h
++++ b/include/linux/nmi.h
+@@ -7,6 +7,23 @@
+ #include <linux/sched.h>
+ #include <asm/irq.h>
++/*
++ * The run state of the lockup detectors is controlled by the content of the
++ * 'watchdog_enabled' variable. Each lockup detector has its dedicated bit -
++ * bit 0 for the hard lockup detector and bit 1 for the soft lockup detector.
++ *
++ * 'watchdog_user_enabled', 'nmi_watchdog_enabled' and 'soft_watchdog_enabled'
++ * are variables that are only used as an 'interface' between the parameters
++ * in /proc/sys/kernel and the internal state bits in 'watchdog_enabled'. The
++ * 'watchdog_thresh' variable is handled differently because its value is not
++ * boolean, and the lockup detectors are 'suspended' while 'watchdog_thresh'
++ * is equal zero.
++ */
++#define NMI_WATCHDOG_ENABLED_BIT   0
++#define SOFT_WATCHDOG_ENABLED_BIT  1
++#define NMI_WATCHDOG_ENABLED      (1 << NMI_WATCHDOG_ENABLED_BIT)
++#define SOFT_WATCHDOG_ENABLED     (1 << SOFT_WATCHDOG_ENABLED_BIT)
++
+ /**
+  * touch_nmi_watchdog - restart NMI watchdog timeout.
+  * 
+@@ -91,9 +108,16 @@ extern int nmi_watchdog_enabled;
+ extern int soft_watchdog_enabled;
+ extern int watchdog_user_enabled;
+ extern int watchdog_thresh;
++extern unsigned long watchdog_enabled;
+ extern unsigned long *watchdog_cpumask_bits;
++#ifdef CONFIG_SMP
+ extern int sysctl_softlockup_all_cpu_backtrace;
+ extern int sysctl_hardlockup_all_cpu_backtrace;
++#else
++#define sysctl_softlockup_all_cpu_backtrace 0
++#define sysctl_hardlockup_all_cpu_backtrace 0
++#endif
++extern bool is_hardlockup(void);
+ struct ctl_table;
+ extern int proc_watchdog(struct ctl_table *, int ,
+                        void __user *, size_t *, loff_t *);
+--- a/kernel/watchdog.c
++++ b/kernel/watchdog.c
+@@ -26,29 +26,12 @@
+ #include <linux/kvm_para.h>
+ #include <linux/kthread.h>
+-/*
+- * The run state of the lockup detectors is controlled by the content of the
+- * 'watchdog_enabled' variable. Each lockup detector has its dedicated bit -
+- * bit 0 for the hard lockup detector and bit 1 for the soft lockup detector.
+- *
+- * 'watchdog_user_enabled', 'nmi_watchdog_enabled' and 'soft_watchdog_enabled'
+- * are variables that are only used as an 'interface' between the parameters
+- * in /proc/sys/kernel and the internal state bits in 'watchdog_enabled'. The
+- * 'watchdog_thresh' variable is handled differently because its value is not
+- * boolean, and the lockup detectors are 'suspended' while 'watchdog_thresh'
+- * is equal zero.
+- */
+-#define NMI_WATCHDOG_ENABLED_BIT   0
+-#define SOFT_WATCHDOG_ENABLED_BIT  1
+-#define NMI_WATCHDOG_ENABLED      (1 << NMI_WATCHDOG_ENABLED_BIT)
+-#define SOFT_WATCHDOG_ENABLED     (1 << SOFT_WATCHDOG_ENABLED_BIT)
+-
+ static DEFINE_MUTEX(watchdog_proc_mutex);
+-#ifdef CONFIG_HARDLOCKUP_DETECTOR
+-static unsigned long __read_mostly watchdog_enabled = SOFT_WATCHDOG_ENABLED|NMI_WATCHDOG_ENABLED;
++#if defined(CONFIG_HAVE_NMI_WATCHDOG) || defined(CONFIG_HARDLOCKUP_DETECTOR)
++unsigned long __read_mostly watchdog_enabled = SOFT_WATCHDOG_ENABLED|NMI_WATCHDOG_ENABLED;
+ #else
+-static unsigned long __read_mostly watchdog_enabled = SOFT_WATCHDOG_ENABLED;
++unsigned long __read_mostly watchdog_enabled = SOFT_WATCHDOG_ENABLED;
+ #endif
+ int __read_mostly nmi_watchdog_enabled;
+ int __read_mostly soft_watchdog_enabled;
+@@ -58,9 +41,6 @@ int __read_mostly watchdog_thresh = 10;
+ #ifdef CONFIG_SMP
+ int __read_mostly sysctl_softlockup_all_cpu_backtrace;
+ int __read_mostly sysctl_hardlockup_all_cpu_backtrace;
+-#else
+-#define sysctl_softlockup_all_cpu_backtrace 0
+-#define sysctl_hardlockup_all_cpu_backtrace 0
+ #endif
+ static struct cpumask watchdog_cpumask __read_mostly;
+ unsigned long *watchdog_cpumask_bits = cpumask_bits(&watchdog_cpumask);
+@@ -229,7 +209,7 @@ void touch_softlockup_watchdog_sync(void
+ }
+ /* watchdog detector functions */
+-static bool is_hardlockup(void)
++bool is_hardlockup(void)
+ {
+       unsigned long hrint = __this_cpu_read(hrtimer_interrupts);
diff --git a/queue-4.9/mn10300-fix-build-error-of-missing-fpu_save.patch b/queue-4.9/mn10300-fix-build-error-of-missing-fpu_save.patch
new file mode 100644 (file)
index 0000000..4468e68
--- /dev/null
@@ -0,0 +1,42 @@
+From foo@baz Thu Jun 15 16:23:30 CEST 2017
+From: Randy Dunlap <rdunlap@infradead.org>
+Date: Tue, 24 Jan 2017 15:18:49 -0800
+Subject: mn10300: fix build error of missing fpu_save()
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+
+[ Upstream commit 3705ccfdd1e8b539225ce20e3925a945cc788d67 ]
+
+When CONFIG_FPU is not enabled on arch/mn10300, <asm/switch_to.h> causes
+a build error with a call to fpu_save():
+
+  kernel/built-in.o: In function `.L410':
+  core.c:(.sched.text+0x28a): undefined reference to `fpu_save'
+
+Fix this by including <asm/fpu.h> in <asm/switch_to.h> so that an empty
+static inline fpu_save() is defined.
+
+Link: http://lkml.kernel.org/r/dc421c4f-4842-4429-1b99-92865c2f24b6@infradead.org
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Reported-by: kbuild test robot <fengguang.wu@intel.com>
+Reviewed-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/mn10300/include/asm/switch_to.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/mn10300/include/asm/switch_to.h
++++ b/arch/mn10300/include/asm/switch_to.h
+@@ -16,7 +16,7 @@
+ struct task_struct;
+ struct thread_struct;
+-#if !defined(CONFIG_LAZY_SAVE_FPU)
++#if defined(CONFIG_FPU) && !defined(CONFIG_LAZY_SAVE_FPU)
+ struct fpu_state_struct;
+ extern asmlinkage void fpu_save(struct fpu_state_struct *);
+ #define switch_fpu(prev, next)                                                \
diff --git a/queue-4.9/net-next-ethernet-mediatek-change-the-compatible-string.patch b/queue-4.9/net-next-ethernet-mediatek-change-the-compatible-string.patch
new file mode 100644 (file)
index 0000000..e1d006f
--- /dev/null
@@ -0,0 +1,40 @@
+From foo@baz Thu Jun 15 16:23:30 CEST 2017
+From: John Crispin <john@phrozen.org>
+Date: Wed, 25 Jan 2017 09:20:55 +0100
+Subject: net-next: ethernet: mediatek: change the compatible string
+
+From: John Crispin <john@phrozen.org>
+
+
+[ Upstream commit 8b901f6bbcf12a20e43105d161bedde093431e61 ]
+
+When the binding was defined, I was not aware that mt2701 was an earlier
+version of the SoC. For sake of consistency, the ethernet driver should
+use mt2701 inside the compat string as this is the earliest SoC with the
+ethernet core.
+
+The ethernet driver is currently of no real use until we finish and
+upstream the DSA driver. There are no users of this binding yet. It should
+be safe to fix this now before it is too late and we need to provide
+backward compatibility for the mt7623-eth compat string.
+
+Reported-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: John Crispin <john@phrozen.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -2518,7 +2518,7 @@ static int mtk_remove(struct platform_de
+ }
+ const struct of_device_id of_mtk_match[] = {
+-      { .compatible = "mediatek,mt7623-eth" },
++      { .compatible = "mediatek,mt2701-eth" },
+       {},
+ };
+ MODULE_DEVICE_TABLE(of, of_mtk_match);
diff --git a/queue-4.9/proc-add-a-schedule-point-in-proc_pid_readdir.patch b/queue-4.9/proc-add-a-schedule-point-in-proc_pid_readdir.patch
new file mode 100644 (file)
index 0000000..23bfbe7
--- /dev/null
@@ -0,0 +1,36 @@
+From foo@baz Thu Jun 15 16:23:30 CEST 2017
+From: Eric Dumazet <edumazet@google.com>
+Date: Tue, 24 Jan 2017 15:18:07 -0800
+Subject: proc: add a schedule point in proc_pid_readdir()
+
+From: Eric Dumazet <edumazet@google.com>
+
+
+[ Upstream commit 3ba4bceef23206349d4130ddf140819b365de7c8 ]
+
+We have seen proc_pid_readdir() invocations holding cpu for more than 50
+ms.  Add a cond_resched() to be gentle with other tasks.
+
+[akpm@linux-foundation.org: coding style fix]
+Link: http://lkml.kernel.org/r/1484238380.15816.42.camel@edumazet-glaptop3.roam.corp.google.com
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+
+Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/proc/base.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -3181,6 +3181,8 @@ int proc_pid_readdir(struct file *file,
+            iter.tgid += 1, iter = next_tgid(ns, iter)) {
+               char name[PROC_NUMBUF];
+               int len;
++
++              cond_resched();
+               if (!has_pid_permissions(ns, iter.task, 2))
+                       continue;
diff --git a/queue-4.9/r8152-avoid-start_xmit-to-schedule-napi-when-napi-is-disabled.patch b/queue-4.9/r8152-avoid-start_xmit-to-schedule-napi-when-napi-is-disabled.patch
new file mode 100644 (file)
index 0000000..5adac5f
--- /dev/null
@@ -0,0 +1,71 @@
+From foo@baz Thu Jun 15 16:23:30 CEST 2017
+From: hayeswang <hayeswang@realtek.com>
+Date: Thu, 26 Jan 2017 09:38:32 +0800
+Subject: r8152: avoid start_xmit to schedule napi when napi is disabled
+
+From: hayeswang <hayeswang@realtek.com>
+
+
+[ Upstream commit de9bf29dd6e4a8a874cb92f8901aed50a9d0b1d3 ]
+
+Stop the tx when the napi is disabled to prevent napi_schedule() is
+called.
+
+Signed-off-by: Hayes Wang <hayeswang@realtek.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/r8152.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/usb/r8152.c
++++ b/drivers/net/usb/r8152.c
+@@ -3158,10 +3158,13 @@ static void set_carrier(struct r8152 *tp
+               if (!netif_carrier_ok(netdev)) {
+                       tp->rtl_ops.enable(tp);
+                       set_bit(RTL8152_SET_RX_MODE, &tp->flags);
++                      netif_stop_queue(netdev);
+                       napi_disable(&tp->napi);
+                       netif_carrier_on(netdev);
+                       rtl_start_rx(tp);
+                       napi_enable(&tp->napi);
++                      netif_wake_queue(netdev);
++                      netif_info(tp, link, netdev, "carrier on\n");
+               }
+       } else {
+               if (netif_carrier_ok(netdev)) {
+@@ -3169,6 +3172,7 @@ static void set_carrier(struct r8152 *tp
+                       napi_disable(&tp->napi);
+                       tp->rtl_ops.disable(tp);
+                       napi_enable(&tp->napi);
++                      netif_info(tp, link, netdev, "carrier off\n");
+               }
+       }
+ }
+@@ -3518,12 +3522,12 @@ static int rtl8152_pre_reset(struct usb_
+       if (!netif_running(netdev))
+               return 0;
++      netif_stop_queue(netdev);
+       napi_disable(&tp->napi);
+       clear_bit(WORK_ENABLE, &tp->flags);
+       usb_kill_urb(tp->intr_urb);
+       cancel_delayed_work_sync(&tp->schedule);
+       if (netif_carrier_ok(netdev)) {
+-              netif_stop_queue(netdev);
+               mutex_lock(&tp->control);
+               tp->rtl_ops.disable(tp);
+               mutex_unlock(&tp->control);
+@@ -3551,10 +3555,10 @@ static int rtl8152_post_reset(struct usb
+               rtl_start_rx(tp);
+               rtl8152_set_rx_mode(netdev);
+               mutex_unlock(&tp->control);
+-              netif_wake_queue(netdev);
+       }
+       napi_enable(&tp->napi);
++      netif_wake_queue(netdev);
+       usb_submit_urb(tp->intr_urb, GFP_KERNEL);
+       if (!list_empty(&tp->rx_done))
diff --git a/queue-4.9/romfs-use-different-way-to-generate-fsid-for-block-or-mtd.patch b/queue-4.9/romfs-use-different-way-to-generate-fsid-for-block-or-mtd.patch
new file mode 100644 (file)
index 0000000..bd47d9d
--- /dev/null
@@ -0,0 +1,96 @@
+From foo@baz Thu Jun 15 16:23:30 CEST 2017
+From: Coly Li <colyli@suse.de>
+Date: Tue, 24 Jan 2017 15:18:46 -0800
+Subject: romfs: use different way to generate fsid for BLOCK or MTD
+
+From: Coly Li <colyli@suse.de>
+
+
+[ Upstream commit f598f82e204ec0b17797caaf1b0311c52d43fb9a ]
+
+Commit 8a59f5d25265 ("fs/romfs: return f_fsid for statfs(2)") generates
+a 64bit id from sb->s_bdev->bd_dev.  This is only correct when romfs is
+defined with CONFIG_ROMFS_ON_BLOCK.  If romfs is only defined with
+CONFIG_ROMFS_ON_MTD, sb->s_bdev is NULL, referencing sb->s_bdev->bd_dev
+will triger an oops.
+
+Richard Weinberger points out that when CONFIG_ROMFS_BACKED_BY_BOTH=y,
+both CONFIG_ROMFS_ON_BLOCK and CONFIG_ROMFS_ON_MTD are defined.
+Therefore when calling huge_encode_dev() to generate a 64bit id, I use
+the follow order to choose parameter,
+
+- CONFIG_ROMFS_ON_BLOCK defined
+  use sb->s_bdev->bd_dev
+- CONFIG_ROMFS_ON_BLOCK undefined and CONFIG_ROMFS_ON_MTD defined
+  use sb->s_dev when,
+- both CONFIG_ROMFS_ON_BLOCK and CONFIG_ROMFS_ON_MTD undefined
+  leave id as 0
+
+When CONFIG_ROMFS_ON_MTD is defined and sb->s_mtd is not NULL, sb->s_dev
+is set to a device ID generated by MTD_BLOCK_MAJOR and mtd index,
+otherwise sb->s_dev is 0.
+
+This is a try-best effort to generate a uniq file system ID, if all the
+above conditions are not meet, f_fsid of this romfs instance will be 0.
+Generally only one romfs can be built on single MTD block device, this
+method is enough to identify multiple romfs instances in a computer.
+
+Link: http://lkml.kernel.org/r/1482928596-115155-1-git-send-email-colyli@suse.de
+Signed-off-by: Coly Li <colyli@suse.de>
+Reported-by: Nong Li <nongli1031@gmail.com>
+Tested-by: Nong Li <nongli1031@gmail.com>
+Cc: Richard Weinberger <richard.weinberger@gmail.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/romfs/super.c |   23 ++++++++++++++++++++++-
+ 1 file changed, 22 insertions(+), 1 deletion(-)
+
+--- a/fs/romfs/super.c
++++ b/fs/romfs/super.c
+@@ -74,6 +74,7 @@
+ #include <linux/highmem.h>
+ #include <linux/pagemap.h>
+ #include <linux/uaccess.h>
++#include <linux/major.h>
+ #include "internal.h"
+ static struct kmem_cache *romfs_inode_cachep;
+@@ -416,7 +417,22 @@ static void romfs_destroy_inode(struct i
+ static int romfs_statfs(struct dentry *dentry, struct kstatfs *buf)
+ {
+       struct super_block *sb = dentry->d_sb;
+-      u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
++      u64 id = 0;
++
++      /* When calling huge_encode_dev(),
++       * use sb->s_bdev->bd_dev when,
++       *   - CONFIG_ROMFS_ON_BLOCK defined
++       * use sb->s_dev when,
++       *   - CONFIG_ROMFS_ON_BLOCK undefined and
++       *   - CONFIG_ROMFS_ON_MTD defined
++       * leave id as 0 when,
++       *   - CONFIG_ROMFS_ON_BLOCK undefined and
++       *   - CONFIG_ROMFS_ON_MTD undefined
++       */
++      if (sb->s_bdev)
++              id = huge_encode_dev(sb->s_bdev->bd_dev);
++      else if (sb->s_dev)
++              id = huge_encode_dev(sb->s_dev);
+       buf->f_type = ROMFS_MAGIC;
+       buf->f_namelen = ROMFS_MAXFN;
+@@ -489,6 +505,11 @@ static int romfs_fill_super(struct super
+       sb->s_flags |= MS_RDONLY | MS_NOATIME;
+       sb->s_op = &romfs_super_ops;
++#ifdef CONFIG_ROMFS_ON_MTD
++      /* Use same dev ID from the underlying mtdblock device */
++      if (sb->s_mtd)
++              sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, sb->s_mtd->index);
++#endif
+       /* read the image superblock and check it */
+       rsb = kmalloc(512, GFP_KERNEL);
+       if (!rsb)
diff --git a/queue-4.9/sctp-sctp-gso-should-set-feature-with-netif_f_sg-when-calling-skb_segment.patch b/queue-4.9/sctp-sctp-gso-should-set-feature-with-netif_f_sg-when-calling-skb_segment.patch
new file mode 100644 (file)
index 0000000..0a89df4
--- /dev/null
@@ -0,0 +1,44 @@
+From foo@baz Thu Jun 15 16:23:30 CEST 2017
+From: Xin Long <lucien.xin@gmail.com>
+Date: Tue, 24 Jan 2017 14:05:16 +0800
+Subject: sctp: sctp gso should set feature with NETIF_F_SG when calling skb_segment
+
+From: Xin Long <lucien.xin@gmail.com>
+
+
+[ Upstream commit 5207f3996338e1db71363fe381c81aaf1e54e4e3 ]
+
+Now sctp gso puts segments into skb's frag_list, then processes these
+segments in skb_segment. But skb_segment handles them only when gs is
+enabled, as it's in the same branch with skb's frags.
+
+Although almost all the NICs support sg other than some old ones, but
+since commit 1e16aa3ddf86 ("net: gso: use feature flag argument in all
+protocol gso handlers"), features &= skb->dev->hw_enc_features, and
+xfrm_output_gso call skb_segment with features = 0, which means sctp
+gso would call skb_segment with sg = 0, and skb_segment would not work
+as expected.
+
+This patch is to fix it by setting features param with NETIF_F_SG when
+calling skb_segment so that it can go the right branch to process the
+skb's frag_list.
+
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sctp/offload.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/sctp/offload.c
++++ b/net/sctp/offload.c
+@@ -68,7 +68,7 @@ static struct sk_buff *sctp_gso_segment(
+               goto out;
+       }
+-      segs = skb_segment(skb, features | NETIF_F_HW_CSUM);
++      segs = skb_segment(skb, features | NETIF_F_HW_CSUM | NETIF_F_SG);
+       if (IS_ERR(segs))
+               goto out;
diff --git a/queue-4.9/sctp-sctp_addr_id2transport-should-verify-the-addr-before-looking-up-assoc.patch b/queue-4.9/sctp-sctp_addr_id2transport-should-verify-the-addr-before-looking-up-assoc.patch
new file mode 100644 (file)
index 0000000..5bd8641
--- /dev/null
@@ -0,0 +1,45 @@
+From foo@baz Thu Jun 15 16:23:30 CEST 2017
+From: Xin Long <lucien.xin@gmail.com>
+Date: Tue, 24 Jan 2017 14:01:53 +0800
+Subject: sctp: sctp_addr_id2transport should verify the addr before looking up assoc
+
+From: Xin Long <lucien.xin@gmail.com>
+
+
+[ Upstream commit 6f29a130613191d3c6335169febe002cba00edf5 ]
+
+sctp_addr_id2transport is a function for sockopt to look up assoc by
+address. As the address is from userspace, it can be a v4-mapped v6
+address. But in sctp protocol stack, it always handles a v4-mapped
+v6 address as a v4 address. So it's necessary to convert it to a v4
+address before looking up assoc by address.
+
+This patch is to fix it by calling sctp_verify_addr in which it can do
+this conversion before calling sctp_endpoint_lookup_assoc, just like
+what sctp_sendmsg and __sctp_connect do for the address from users.
+
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Acked-by: Neil Horman <nhorman@tuxdriver.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sctp/socket.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -235,8 +235,12 @@ static struct sctp_transport *sctp_addr_
+                                             sctp_assoc_t id)
+ {
+       struct sctp_association *addr_asoc = NULL, *id_asoc = NULL;
+-      struct sctp_transport *transport;
++      struct sctp_af *af = sctp_get_af_specific(addr->ss_family);
+       union sctp_addr *laddr = (union sctp_addr *)addr;
++      struct sctp_transport *transport;
++
++      if (sctp_verify_addr(sk, laddr, af->sockaddr_len))
++              return NULL;
+       addr_asoc = sctp_endpoint_lookup_assoc(sctp_sk(sk)->ep,
+                                              laddr,
index c9615c4af79dbddf54dcd63fe80134195d17960a..434adc9176f73c0cc9b9a07573a0dee2cf861be9 100644 (file)
@@ -69,3 +69,23 @@ r8152-avoid-start_xmit-to-call-napi_schedule-during-autosuspend.patch
 r8152-check-rx-after-napi-is-enabled.patch
 r8152-re-schedule-napi-for-tx.patch
 r8152-fix-rtl8152_post_reset-function.patch
+r8152-avoid-start_xmit-to-schedule-napi-when-napi-is-disabled.patch
+net-next-ethernet-mediatek-change-the-compatible-string.patch
+bnxt_en-fix-bnxt_reset-in-the-slow-path-task.patch
+bnxt_en-enhance-autoneg-support.patch
+bnxt_en-fix-rtnl-lock-usage-on-bnxt_update_link.patch
+bnxt_en-fix-rtnl-lock-usage-on-bnxt_get_port_module_status.patch
+sctp-sctp-gso-should-set-feature-with-netif_f_sg-when-calling-skb_segment.patch
+sctp-sctp_addr_id2transport-should-verify-the-addr-before-looking-up-assoc.patch
+usb-musb-fix-external-abort-on-non-linefetch-for-musb_irq_work.patch
+mn10300-fix-build-error-of-missing-fpu_save.patch
+romfs-use-different-way-to-generate-fsid-for-block-or-mtd.patch
+frv-add-atomic64_add_unless.patch
+frv-add-missing-atomic64-operations.patch
+proc-add-a-schedule-point-in-proc_pid_readdir.patch
+userfaultfd-fix-sigbus-resulting-from-false-rwsem-wakeups.patch
+kernel-watchdog.c-move-hardlockup-detector-to-separate-file.patch
+kernel-watchdog.c-move-shared-definitions-to-nmi.h.patch
+kernel-watchdog-prevent-false-hardlockup-on-overloaded-system.patch
+vhost-vsock-handle-vhost_vq_init_access-error.patch
+arc-smp-boot-decouple-non-masters-waiting-api-from-jump-to-entry-point.patch
diff --git a/queue-4.9/usb-musb-fix-external-abort-on-non-linefetch-for-musb_irq_work.patch b/queue-4.9/usb-musb-fix-external-abort-on-non-linefetch-for-musb_irq_work.patch
new file mode 100644 (file)
index 0000000..ae4724e
--- /dev/null
@@ -0,0 +1,57 @@
+From foo@baz Thu Jun 15 16:23:30 CEST 2017
+From: Tony Lindgren <tony@atomide.com>
+Date: Tue, 24 Jan 2017 09:18:58 -0600
+Subject: usb: musb: Fix external abort on non-linefetch for musb_irq_work()
+
+From: Tony Lindgren <tony@atomide.com>
+
+
+[ Upstream commit 3ba7b7795b7e8889af1377904c55c7fae9e0c775 ]
+
+While testing musb host mode cable plugging on a BeagleBone, I came across this
+error:
+
+Unhandled fault: external abort on non-linefetch (0x1008) at 0xd1dcfc60
+...
+[<bf668390>] (musb_default_readb [musb_hdrc]) from [<bf668578>] (musb_irq_work+0x1c/0x180 [musb_hdrc])
+[<bf668578>] (musb_irq_work [musb_hdrc]) from [<c0156554>] (process_one_work+0x2b4/0x808)
+[<c0156554>] (process_one_work) from [<c015767c>] (worker_thread+0x3c/0x550)
+[<c015767c>] (worker_thread) from [<c015d568>] (kthread+0x104/0x148)
+[<c015d568>] (kthread) from [<c01078d0>] (ret_from_fork+0x14/0x24)
+
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Bin Liu <b-liu@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/musb/musb_core.c |   11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/drivers/usb/musb/musb_core.c
++++ b/drivers/usb/musb/musb_core.c
+@@ -1909,6 +1909,14 @@ static void musb_pm_runtime_check_sessio
+ static void musb_irq_work(struct work_struct *data)
+ {
+       struct musb *musb = container_of(data, struct musb, irq_work.work);
++      int error;
++
++      error = pm_runtime_get_sync(musb->controller);
++      if (error < 0) {
++              dev_err(musb->controller, "Could not enable: %i\n", error);
++
++              return;
++      }
+       musb_pm_runtime_check_session(musb);
+@@ -1916,6 +1924,9 @@ static void musb_irq_work(struct work_st
+               musb->xceiv_old_state = musb->xceiv->otg->state;
+               sysfs_notify(&musb->controller->kobj, NULL, "mode");
+       }
++
++      pm_runtime_mark_last_busy(musb->controller);
++      pm_runtime_put_autosuspend(musb->controller);
+ }
+ static void musb_recover_from_babble(struct musb *musb)
diff --git a/queue-4.9/userfaultfd-fix-sigbus-resulting-from-false-rwsem-wakeups.patch b/queue-4.9/userfaultfd-fix-sigbus-resulting-from-false-rwsem-wakeups.patch
new file mode 100644 (file)
index 0000000..710f9e0
--- /dev/null
@@ -0,0 +1,187 @@
+From foo@baz Thu Jun 15 16:23:30 CEST 2017
+From: Andrea Arcangeli <aarcange@redhat.com>
+Date: Tue, 24 Jan 2017 15:17:59 -0800
+Subject: userfaultfd: fix SIGBUS resulting from false rwsem wakeups
+
+From: Andrea Arcangeli <aarcange@redhat.com>
+
+
+[ Upstream commit 15a77c6fe494f4b1757d30cd137fe66ab06a38c3 ]
+
+With >=32 CPUs the userfaultfd selftest triggered a graceful but
+unexpected SIGBUS because VM_FAULT_RETRY was returned by
+handle_userfault() despite the UFFDIO_COPY wasn't completed.
+
+This seems caused by rwsem waking the thread blocked in
+handle_userfault() and we can't run up_read() before the wait_event
+sequence is complete.
+
+Keeping the wait_even sequence identical to the first one, would require
+running userfaultfd_must_wait() again to know if the loop should be
+repeated, and it would also require retaking the rwsem and revalidating
+the whole vma status.
+
+It seems simpler to wait the targeted wakeup so that if false wakeups
+materialize we still wait for our specific wakeup event, unless of
+course there are signals or the uffd was released.
+
+Debug code collecting the stack trace of the wakeup showed this:
+
+  $ ./userfaultfd 100 99999
+  nr_pages: 25600, nr_pages_per_cpu: 800
+  bounces: 99998, mode: racing ver poll, userfaults: 32 35 90 232 30 138 69 82 34 30 139 40 40 31 20 19 43 13 15 28 27 38 21 43 56 22 1 17 31 8 4 2
+  bounces: 99997, mode: rnd ver poll, Bus error (core dumped)
+
+    save_stack_trace+0x2b/0x50
+    try_to_wake_up+0x2a6/0x580
+    wake_up_q+0x32/0x70
+    rwsem_wake+0xe0/0x120
+    call_rwsem_wake+0x1b/0x30
+    up_write+0x3b/0x40
+    vm_mmap_pgoff+0x9c/0xc0
+    SyS_mmap_pgoff+0x1a9/0x240
+    SyS_mmap+0x22/0x30
+    entry_SYSCALL_64_fastpath+0x1f/0xbd
+    0xffffffffffffffff
+    FAULT_FLAG_ALLOW_RETRY missing 70
+  CPU: 24 PID: 1054 Comm: userfaultfd Tainted: G        W       4.8.0+ #30
+  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.9.3-0-ge2fc41e-prebuilt.qemu-project.org 04/01/2014
+  Call Trace:
+    dump_stack+0xb8/0x112
+    handle_userfault+0x572/0x650
+    handle_mm_fault+0x12cb/0x1520
+    __do_page_fault+0x175/0x500
+    trace_do_page_fault+0x61/0x270
+    do_async_page_fault+0x19/0x90
+    async_page_fault+0x25/0x30
+
+This always happens when the main userfault selftest thread is running
+clone() while glibc runs either mprotect or mmap (both taking mmap_sem
+down_write()) to allocate the thread stack of the background threads,
+while locking/userfault threads already run at full throttle and are
+susceptible to false wakeups that may cause handle_userfault() to return
+before than expected (which results in graceful SIGBUS at the next
+attempt).
+
+This was reproduced only with >=32 CPUs because the loop to start the
+thread where clone() is too quick with fewer CPUs, while with 32 CPUs
+there's already significant activity on ~32 locking and userfault
+threads when the last background threads are started with clone().
+
+This >=32 CPUs SMP race condition is likely reproducible only with the
+selftest because of the much heavier userfault load it generates if
+compared to real apps.
+
+We'll have to allow "one more" VM_FAULT_RETRY for the WP support and a
+patch floating around that provides it also hidden this problem but in
+reality only is successfully at hiding the problem.
+
+False wakeups could still happen again the second time
+handle_userfault() is invoked, even if it's a so rare race condition
+that getting false wakeups twice in a row is impossible to reproduce.
+This full fix is needed for correctness, the only alternative would be
+to allow VM_FAULT_RETRY to be returned infinitely.  With this fix the WP
+support can stick to a strict "one more" VM_FAULT_RETRY logic (no need
+of returning it infinite times to avoid the SIGBUS).
+
+Link: http://lkml.kernel.org/r/20170111005535.13832-2-aarcange@redhat.com
+Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
+Reported-by: Shubham Kumar Sharma <shubham.kumar.sharma@oracle.com>
+Tested-by: Mike Kravetz <mike.kravetz@oracle.com>
+Acked-by: Hillf Danton <hillf.zj@alibaba-inc.com>
+Cc: Michael Rapoport <RAPOPORT@il.ibm.com>
+Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Cc: Pavel Emelyanov <xemul@parallels.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/userfaultfd.c |   37 +++++++++++++++++++++++++++++++++++--
+ 1 file changed, 35 insertions(+), 2 deletions(-)
+
+--- a/fs/userfaultfd.c
++++ b/fs/userfaultfd.c
+@@ -63,6 +63,7 @@ struct userfaultfd_wait_queue {
+       struct uffd_msg msg;
+       wait_queue_t wq;
+       struct userfaultfd_ctx *ctx;
++      bool waken;
+ };
+ struct userfaultfd_wake_range {
+@@ -86,6 +87,12 @@ static int userfaultfd_wake_function(wai
+       if (len && (start > uwq->msg.arg.pagefault.address ||
+                   start + len <= uwq->msg.arg.pagefault.address))
+               goto out;
++      WRITE_ONCE(uwq->waken, true);
++      /*
++       * The implicit smp_mb__before_spinlock in try_to_wake_up()
++       * renders uwq->waken visible to other CPUs before the task is
++       * waken.
++       */
+       ret = wake_up_state(wq->private, mode);
+       if (ret)
+               /*
+@@ -264,6 +271,7 @@ int handle_userfault(struct fault_env *f
+       struct userfaultfd_wait_queue uwq;
+       int ret;
+       bool must_wait, return_to_userland;
++      long blocking_state;
+       BUG_ON(!rwsem_is_locked(&mm->mmap_sem));
+@@ -333,10 +341,13 @@ int handle_userfault(struct fault_env *f
+       uwq.wq.private = current;
+       uwq.msg = userfault_msg(fe->address, fe->flags, reason);
+       uwq.ctx = ctx;
++      uwq.waken = false;
+       return_to_userland =
+               (fe->flags & (FAULT_FLAG_USER|FAULT_FLAG_KILLABLE)) ==
+               (FAULT_FLAG_USER|FAULT_FLAG_KILLABLE);
++      blocking_state = return_to_userland ? TASK_INTERRUPTIBLE :
++                       TASK_KILLABLE;
+       spin_lock(&ctx->fault_pending_wqh.lock);
+       /*
+@@ -349,8 +360,7 @@ int handle_userfault(struct fault_env *f
+        * following the spin_unlock to happen before the list_add in
+        * __add_wait_queue.
+        */
+-      set_current_state(return_to_userland ? TASK_INTERRUPTIBLE :
+-                        TASK_KILLABLE);
++      set_current_state(blocking_state);
+       spin_unlock(&ctx->fault_pending_wqh.lock);
+       must_wait = userfaultfd_must_wait(ctx, fe->address, fe->flags, reason);
+@@ -362,6 +372,29 @@ int handle_userfault(struct fault_env *f
+               wake_up_poll(&ctx->fd_wqh, POLLIN);
+               schedule();
+               ret |= VM_FAULT_MAJOR;
++
++              /*
++               * False wakeups can orginate even from rwsem before
++               * up_read() however userfaults will wait either for a
++               * targeted wakeup on the specific uwq waitqueue from
++               * wake_userfault() or for signals or for uffd
++               * release.
++               */
++              while (!READ_ONCE(uwq.waken)) {
++                      /*
++                       * This needs the full smp_store_mb()
++                       * guarantee as the state write must be
++                       * visible to other CPUs before reading
++                       * uwq.waken from other CPUs.
++                       */
++                      set_current_state(blocking_state);
++                      if (READ_ONCE(uwq.waken) ||
++                          READ_ONCE(ctx->released) ||
++                          (return_to_userland ? signal_pending(current) :
++                           fatal_signal_pending(current)))
++                              break;
++                      schedule();
++              }
+       }
+       __set_current_state(TASK_RUNNING);
diff --git a/queue-4.9/vhost-vsock-handle-vhost_vq_init_access-error.patch b/queue-4.9/vhost-vsock-handle-vhost_vq_init_access-error.patch
new file mode 100644 (file)
index 0000000..16a86a8
--- /dev/null
@@ -0,0 +1,68 @@
+From foo@baz Thu Jun 15 16:23:30 CEST 2017
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Thu, 19 Jan 2017 10:43:53 +0000
+Subject: vhost/vsock: handle vhost_vq_init_access() error
+
+From: Stefan Hajnoczi <stefanha@redhat.com>
+
+
+[ Upstream commit 0516ffd88fa0d006ee80389ce14a9ca5ae45e845 ]
+
+Propagate the error when vhost_vq_init_access() fails and set
+vq->private_data to NULL.
+
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/vhost/vsock.c |   13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+--- a/drivers/vhost/vsock.c
++++ b/drivers/vhost/vsock.c
+@@ -368,6 +368,7 @@ static void vhost_vsock_handle_rx_kick(s
+ static int vhost_vsock_start(struct vhost_vsock *vsock)
+ {
++      struct vhost_virtqueue *vq;
+       size_t i;
+       int ret;
+@@ -378,19 +379,20 @@ static int vhost_vsock_start(struct vhos
+               goto err;
+       for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) {
+-              struct vhost_virtqueue *vq = &vsock->vqs[i];
++              vq = &vsock->vqs[i];
+               mutex_lock(&vq->mutex);
+               if (!vhost_vq_access_ok(vq)) {
+                       ret = -EFAULT;
+-                      mutex_unlock(&vq->mutex);
+                       goto err_vq;
+               }
+               if (!vq->private_data) {
+                       vq->private_data = vsock;
+-                      vhost_vq_init_access(vq);
++                      ret = vhost_vq_init_access(vq);
++                      if (ret)
++                              goto err_vq;
+               }
+               mutex_unlock(&vq->mutex);
+@@ -400,8 +402,11 @@ static int vhost_vsock_start(struct vhos
+       return 0;
+ err_vq:
++      vq->private_data = NULL;
++      mutex_unlock(&vq->mutex);
++
+       for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) {
+-              struct vhost_virtqueue *vq = &vsock->vqs[i];
++              vq = &vsock->vqs[i];
+               mutex_lock(&vq->mutex);
+               vq->private_data = NULL;