]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 4.19
authorSasha Levin <sashal@kernel.org>
Wed, 18 Mar 2020 20:57:35 +0000 (16:57 -0400)
committerSasha Levin <sashal@kernel.org>
Wed, 18 Mar 2020 20:57:35 +0000 (16:57 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
23 files changed:
queue-4.19/acpi-watchdog-allow-disabling-wdat-at-boot.patch [new file with mode: 0644]
queue-4.19/cfg80211-check-reg_rule-for-null-in-handle_channel_c.patch [new file with mode: 0644]
queue-4.19/hid-apple-add-support-for-recent-firmware-on-magic-k.patch [new file with mode: 0644]
queue-4.19/hid-i2c-hid-add-trekstor-surfbook-e11b-to-descriptor.patch [new file with mode: 0644]
queue-4.19/hinic-fix-a-bug-of-setting-hw_ioctxt.patch [new file with mode: 0644]
queue-4.19/hinic-fix-a-irq-affinity-bug.patch [new file with mode: 0644]
queue-4.19/jbd2-fix-data-races-at-struct-journal_head.patch [new file with mode: 0644]
queue-4.19/mac80211-rx-avoid-rcu-list-traversal-under-mutex.patch [new file with mode: 0644]
queue-4.19/net-ks8851-ml-fix-irq-handling-and-locking.patch [new file with mode: 0644]
queue-4.19/net-rmnet-do-not-allow-to-change-mux-id-if-mux-id-is.patch [new file with mode: 0644]
queue-4.19/net-rmnet-fix-bridge-mode-bugs.patch [new file with mode: 0644]
queue-4.19/net-rmnet-fix-null-pointer-dereference-in-rmnet_chan.patch [new file with mode: 0644]
queue-4.19/net-rmnet-fix-null-pointer-dereference-in-rmnet_newl.patch [new file with mode: 0644]
queue-4.19/net-rmnet-fix-packet-forwarding-in-rmnet-bridge-mode.patch [new file with mode: 0644]
queue-4.19/net-rmnet-fix-suspicious-rcu-usage.patch [new file with mode: 0644]
queue-4.19/net-rmnet-remove-rcu_read_lock-in-rmnet_force_unasso.patch [new file with mode: 0644]
queue-4.19/net-rmnet-use-upper-lower-device-infrastructure.patch [new file with mode: 0644]
queue-4.19/net-usb-qmi_wwan-restore-mtu-min-max-values-after-ra.patch [new file with mode: 0644]
queue-4.19/scsi-libfc-free-response-frame-from-gpn_id.patch [new file with mode: 0644]
queue-4.19/series
queue-4.19/sfc-fix-timestamp-reconstruction-at-16-bit-rollover-.patch [new file with mode: 0644]
queue-4.19/signal-avoid-double-atomic-counter-increments-for-us.patch [new file with mode: 0644]
queue-4.19/slip-not-call-free_netdev-before-rtnl_unlock-in-slip.patch [new file with mode: 0644]

diff --git a/queue-4.19/acpi-watchdog-allow-disabling-wdat-at-boot.patch b/queue-4.19/acpi-watchdog-allow-disabling-wdat-at-boot.patch
new file mode 100644 (file)
index 0000000..3c6950d
--- /dev/null
@@ -0,0 +1,74 @@
+From 6794e231b3ec2fd7027926df9e89ccee0c2a6653 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Feb 2020 16:58:45 +0100
+Subject: ACPI: watchdog: Allow disabling WDAT at boot
+
+From: Jean Delvare <jdelvare@suse.de>
+
+[ Upstream commit 3f9e12e0df012c4a9a7fd7eb0d3ae69b459d6b2c ]
+
+In case the WDAT interface is broken, give the user an option to
+ignore it to let a native driver bind to the watchdog device instead.
+
+Signed-off-by: Jean Delvare <jdelvare@suse.de>
+Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/admin-guide/kernel-parameters.txt |  4 ++++
+ drivers/acpi/acpi_watchdog.c                    | 12 +++++++++++-
+ 2 files changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
+index 8bf0c0532046f..1a5101b7e853c 100644
+--- a/Documentation/admin-guide/kernel-parameters.txt
++++ b/Documentation/admin-guide/kernel-parameters.txt
+@@ -136,6 +136,10 @@
+                       dynamic table installation which will install SSDT
+                       tables to /sys/firmware/acpi/tables/dynamic.
++      acpi_no_watchdog        [HW,ACPI,WDT]
++                      Ignore the ACPI-based watchdog interface (WDAT) and let
++                      a native driver control the watchdog device instead.
++
+       acpi_rsdp=      [ACPI,EFI,KEXEC]
+                       Pass the RSDP address to the kernel, mostly used
+                       on machines running EFI runtime service to boot the
+diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c
+index 23cde3d8e8fbb..0bd1899a287f3 100644
+--- a/drivers/acpi/acpi_watchdog.c
++++ b/drivers/acpi/acpi_watchdog.c
+@@ -58,12 +58,14 @@ static bool acpi_watchdog_uses_rtc(const struct acpi_table_wdat *wdat)
+ }
+ #endif
++static bool acpi_no_watchdog;
++
+ static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void)
+ {
+       const struct acpi_table_wdat *wdat = NULL;
+       acpi_status status;
+-      if (acpi_disabled)
++      if (acpi_disabled || acpi_no_watchdog)
+               return NULL;
+       status = acpi_get_table(ACPI_SIG_WDAT, 0,
+@@ -91,6 +93,14 @@ bool acpi_has_watchdog(void)
+ }
+ EXPORT_SYMBOL_GPL(acpi_has_watchdog);
++/* ACPI watchdog can be disabled on boot command line */
++static int __init disable_acpi_watchdog(char *str)
++{
++      acpi_no_watchdog = true;
++      return 1;
++}
++__setup("acpi_no_watchdog", disable_acpi_watchdog);
++
+ void __init acpi_watchdog_init(void)
+ {
+       const struct acpi_wdat_entry *entries;
+-- 
+2.20.1
+
diff --git a/queue-4.19/cfg80211-check-reg_rule-for-null-in-handle_channel_c.patch b/queue-4.19/cfg80211-check-reg_rule-for-null-in-handle_channel_c.patch
new file mode 100644 (file)
index 0000000..0e77c8f
--- /dev/null
@@ -0,0 +1,37 @@
+From 0abed3541ff1343eb08506474530c4830590dc92 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Feb 2020 10:44:50 +0100
+Subject: cfg80211: check reg_rule for NULL in handle_channel_custom()
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit a7ee7d44b57c9ae174088e53a668852b7f4f452d ]
+
+We may end up with a NULL reg_rule after the loop in
+handle_channel_custom() if the bandwidth didn't fit,
+check if this is the case and bail out if so.
+
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Link: https://lore.kernel.org/r/20200221104449.3b558a50201c.I4ad3725c4dacaefd2d18d3cc65ba6d18acd5dbfe@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/reg.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/wireless/reg.c b/net/wireless/reg.c
+index 018c60be153a7..32f575857e415 100644
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -2269,7 +2269,7 @@ static void handle_channel_custom(struct wiphy *wiphy,
+                       break;
+       }
+-      if (IS_ERR(reg_rule)) {
++      if (IS_ERR_OR_NULL(reg_rule)) {
+               pr_debug("Disabling freq %d MHz as custom regd has no rule that fits it\n",
+                        chan->center_freq);
+               if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) {
+-- 
+2.20.1
+
diff --git a/queue-4.19/hid-apple-add-support-for-recent-firmware-on-magic-k.patch b/queue-4.19/hid-apple-add-support-for-recent-firmware-on-magic-k.patch
new file mode 100644 (file)
index 0000000..9d351fd
--- /dev/null
@@ -0,0 +1,37 @@
+From 5607a09d9e367889895784a14787ccf5e1a94578 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Jan 2020 17:26:31 +1100
+Subject: HID: apple: Add support for recent firmware on Magic Keyboards
+
+From: Mansour Behabadi <mansour@oxplot.com>
+
+[ Upstream commit e433be929e63265b7412478eb7ff271467aee2d7 ]
+
+Magic Keyboards with more recent firmware (0x0100) report Fn key differently.
+Without this patch, Fn key may not behave as expected and may not be
+configurable via hid_apple fnmode module parameter.
+
+Signed-off-by: Mansour Behabadi <mansour@oxplot.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-apple.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
+index d0a81a03ddbdd..8ab8f2350bbcd 100644
+--- a/drivers/hid/hid-apple.c
++++ b/drivers/hid/hid-apple.c
+@@ -343,7 +343,8 @@ static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+               unsigned long **bit, int *max)
+ {
+       if (usage->hid == (HID_UP_CUSTOM | 0x0003) ||
+-                      usage->hid == (HID_UP_MSVENDOR | 0x0003)) {
++                      usage->hid == (HID_UP_MSVENDOR | 0x0003) ||
++                      usage->hid == (HID_UP_HPVENDOR2 | 0x0003)) {
+               /* The fn key on Apple USB keyboards */
+               set_bit(EV_REP, hi->input->evbit);
+               hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_FN);
+-- 
+2.20.1
+
diff --git a/queue-4.19/hid-i2c-hid-add-trekstor-surfbook-e11b-to-descriptor.patch b/queue-4.19/hid-i2c-hid-add-trekstor-surfbook-e11b-to-descriptor.patch
new file mode 100644 (file)
index 0000000..d0d7c4b
--- /dev/null
@@ -0,0 +1,43 @@
+From 1570d03109a626318c18b69366573f3d8b0729f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Feb 2020 14:53:07 +0800
+Subject: HID: i2c-hid: add Trekstor Surfbook E11B to descriptor override
+
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+
+[ Upstream commit be0aba826c4a6ba5929def1962a90d6127871969 ]
+
+The Surfbook E11B uses the SIPODEV SP1064 touchpad, which does not supply
+descriptors, so it has to be added to the override list.
+
+BugLink: https://bugs.launchpad.net/bugs/1858299
+Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
+index 10af8585c820d..95052373a8282 100644
+--- a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
++++ b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
+@@ -341,6 +341,14 @@ static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = {
+               },
+               .driver_data = (void *)&sipodev_desc
+       },
++      {
++              .ident = "Trekstor SURFBOOK E11B",
++              .matches = {
++                      DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
++                      DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SURFBOOK E11B"),
++              },
++              .driver_data = (void *)&sipodev_desc
++      },
+       {
+               .ident = "Direkt-Tek DTLAPY116-2",
+               .matches = {
+-- 
+2.20.1
+
diff --git a/queue-4.19/hinic-fix-a-bug-of-setting-hw_ioctxt.patch b/queue-4.19/hinic-fix-a-bug-of-setting-hw_ioctxt.patch
new file mode 100644 (file)
index 0000000..a5ef8e3
--- /dev/null
@@ -0,0 +1,63 @@
+From 0178029ce6522d2d4e415db2e73909c7b734f99b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2020 06:34:43 +0000
+Subject: hinic: fix a bug of setting hw_ioctxt
+
+From: Luo bin <luobin9@huawei.com>
+
+[ Upstream commit d2ed69ce9ed3477e2a9527e6b89fe4689d99510e ]
+
+a reserved field is used to signify prime physical function index
+in the latest firmware version, so we must assign a value to it
+correctly
+
+Signed-off-by: Luo bin <luobin9@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c | 1 +
+ drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h | 2 +-
+ drivers/net/ethernet/huawei/hinic/hinic_hw_if.h  | 1 +
+ 3 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c
+index 6b19607a4caac..9deec13d98e93 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c
+@@ -309,6 +309,7 @@ static int set_hw_ioctxt(struct hinic_hwdev *hwdev, unsigned int rq_depth,
+       }
+       hw_ioctxt.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
++      hw_ioctxt.ppf_idx = HINIC_HWIF_PPF_IDX(hwif);
+       hw_ioctxt.set_cmdq_depth = HW_IOCTXT_SET_CMDQ_DEPTH_DEFAULT;
+       hw_ioctxt.cmdq_depth = 0;
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h
+index 0f5563f3b7798..a011fd2d26270 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h
++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h
+@@ -104,8 +104,8 @@ struct hinic_cmd_hw_ioctxt {
+       u8      rsvd2;
+       u8      rsvd3;
++      u8      ppf_idx;
+       u8      rsvd4;
+-      u8      rsvd5;
+       u16     rq_depth;
+       u16     rx_buf_sz_idx;
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h
+index 5b4760c0e9f53..f683ccbdfca02 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h
++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h
+@@ -146,6 +146,7 @@
+ #define HINIC_HWIF_FUNC_IDX(hwif)       ((hwif)->attr.func_idx)
+ #define HINIC_HWIF_PCI_INTF(hwif)       ((hwif)->attr.pci_intf_idx)
+ #define HINIC_HWIF_PF_IDX(hwif)         ((hwif)->attr.pf_idx)
++#define HINIC_HWIF_PPF_IDX(hwif)        ((hwif)->attr.ppf_idx)
+ #define HINIC_FUNC_TYPE(hwif)           ((hwif)->attr.func_type)
+ #define HINIC_IS_PF(hwif)               (HINIC_FUNC_TYPE(hwif) == HINIC_PF)
+-- 
+2.20.1
+
diff --git a/queue-4.19/hinic-fix-a-irq-affinity-bug.patch b/queue-4.19/hinic-fix-a-irq-affinity-bug.patch
new file mode 100644 (file)
index 0000000..6380840
--- /dev/null
@@ -0,0 +1,58 @@
+From 8986938ca8c5aadbac9a40fe0361ae18e831415f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2020 06:34:42 +0000
+Subject: hinic: fix a irq affinity bug
+
+From: Luo bin <luobin9@huawei.com>
+
+[ Upstream commit 0bff777bd0cba73ad4cd0145696ad284d7e6a99f ]
+
+can not use a local variable as an input parameter of
+irq_set_affinity_hint
+
+Signed-off-by: Luo bin <luobin9@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h | 1 +
+ drivers/net/ethernet/huawei/hinic/hinic_rx.c    | 5 ++---
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h
+index 6c84f83ec2831..d46cfd4fbbbc5 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h
++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h
+@@ -103,6 +103,7 @@ struct hinic_rq {
+       struct hinic_wq         *wq;
++      struct cpumask          affinity_mask;
+       u32                     irq;
+       u16                     msix_entry;
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_rx.c b/drivers/net/ethernet/huawei/hinic/hinic_rx.c
+index 06b24a92ed7d4..3467d84d96c39 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_rx.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_rx.c
+@@ -414,7 +414,6 @@ static int rx_request_irq(struct hinic_rxq *rxq)
+       struct hinic_hwdev *hwdev = nic_dev->hwdev;
+       struct hinic_rq *rq = rxq->rq;
+       struct hinic_qp *qp;
+-      struct cpumask mask;
+       int err;
+       rx_add_napi(rxq);
+@@ -431,8 +430,8 @@ static int rx_request_irq(struct hinic_rxq *rxq)
+       }
+       qp = container_of(rq, struct hinic_qp, rq);
+-      cpumask_set_cpu(qp->q_id % num_online_cpus(), &mask);
+-      return irq_set_affinity_hint(rq->irq, &mask);
++      cpumask_set_cpu(qp->q_id % num_online_cpus(), &rq->affinity_mask);
++      return irq_set_affinity_hint(rq->irq, &rq->affinity_mask);
+ }
+ static void rx_free_irq(struct hinic_rxq *rxq)
+-- 
+2.20.1
+
diff --git a/queue-4.19/jbd2-fix-data-races-at-struct-journal_head.patch b/queue-4.19/jbd2-fix-data-races-at-struct-journal_head.patch
new file mode 100644 (file)
index 0000000..dba6bd8
--- /dev/null
@@ -0,0 +1,110 @@
+From 8e6f4a0c6fdf021a440f96c6e927aed73675e6f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Feb 2020 23:31:11 -0500
+Subject: jbd2: fix data races at struct journal_head
+
+From: Qian Cai <cai@lca.pw>
+
+[ Upstream commit 6c5d911249290f41f7b50b43344a7520605b1acb ]
+
+journal_head::b_transaction and journal_head::b_next_transaction could
+be accessed concurrently as noticed by KCSAN,
+
+ LTP: starting fsync04
+ /dev/zero: Can't open blockdev
+ EXT4-fs (loop0): mounting ext3 file system using the ext4 subsystem
+ EXT4-fs (loop0): mounted filesystem with ordered data mode. Opts: (null)
+ ==================================================================
+ BUG: KCSAN: data-race in __jbd2_journal_refile_buffer [jbd2] / jbd2_write_access_granted [jbd2]
+
+ write to 0xffff99f9b1bd0e30 of 8 bytes by task 25721 on cpu 70:
+  __jbd2_journal_refile_buffer+0xdd/0x210 [jbd2]
+  __jbd2_journal_refile_buffer at fs/jbd2/transaction.c:2569
+  jbd2_journal_commit_transaction+0x2d15/0x3f20 [jbd2]
+  (inlined by) jbd2_journal_commit_transaction at fs/jbd2/commit.c:1034
+  kjournald2+0x13b/0x450 [jbd2]
+  kthread+0x1cd/0x1f0
+  ret_from_fork+0x27/0x50
+
+ read to 0xffff99f9b1bd0e30 of 8 bytes by task 25724 on cpu 68:
+  jbd2_write_access_granted+0x1b2/0x250 [jbd2]
+  jbd2_write_access_granted at fs/jbd2/transaction.c:1155
+  jbd2_journal_get_write_access+0x2c/0x60 [jbd2]
+  __ext4_journal_get_write_access+0x50/0x90 [ext4]
+  ext4_mb_mark_diskspace_used+0x158/0x620 [ext4]
+  ext4_mb_new_blocks+0x54f/0xca0 [ext4]
+  ext4_ind_map_blocks+0xc79/0x1b40 [ext4]
+  ext4_map_blocks+0x3b4/0x950 [ext4]
+  _ext4_get_block+0xfc/0x270 [ext4]
+  ext4_get_block+0x3b/0x50 [ext4]
+  __block_write_begin_int+0x22e/0xae0
+  __block_write_begin+0x39/0x50
+  ext4_write_begin+0x388/0xb50 [ext4]
+  generic_perform_write+0x15d/0x290
+  ext4_buffered_write_iter+0x11f/0x210 [ext4]
+  ext4_file_write_iter+0xce/0x9e0 [ext4]
+  new_sync_write+0x29c/0x3b0
+  __vfs_write+0x92/0xa0
+  vfs_write+0x103/0x260
+  ksys_write+0x9d/0x130
+  __x64_sys_write+0x4c/0x60
+  do_syscall_64+0x91/0xb05
+  entry_SYSCALL_64_after_hwframe+0x49/0xbe
+
+ 5 locks held by fsync04/25724:
+  #0: ffff99f9911093f8 (sb_writers#13){.+.+}, at: vfs_write+0x21c/0x260
+  #1: ffff99f9db4c0348 (&sb->s_type->i_mutex_key#15){+.+.}, at: ext4_buffered_write_iter+0x65/0x210 [ext4]
+  #2: ffff99f5e7dfcf58 (jbd2_handle){++++}, at: start_this_handle+0x1c1/0x9d0 [jbd2]
+  #3: ffff99f9db4c0168 (&ei->i_data_sem){++++}, at: ext4_map_blocks+0x176/0x950 [ext4]
+  #4: ffffffff99086b40 (rcu_read_lock){....}, at: jbd2_write_access_granted+0x4e/0x250 [jbd2]
+ irq event stamp: 1407125
+ hardirqs last  enabled at (1407125): [<ffffffff980da9b7>] __find_get_block+0x107/0x790
+ hardirqs last disabled at (1407124): [<ffffffff980da8f9>] __find_get_block+0x49/0x790
+ softirqs last  enabled at (1405528): [<ffffffff98a0034c>] __do_softirq+0x34c/0x57c
+ softirqs last disabled at (1405521): [<ffffffff97cc67a2>] irq_exit+0xa2/0xc0
+
+ Reported by Kernel Concurrency Sanitizer on:
+ CPU: 68 PID: 25724 Comm: fsync04 Tainted: G L 5.6.0-rc2-next-20200221+ #7
+ Hardware name: HPE ProLiant DL385 Gen10/ProLiant DL385 Gen10, BIOS A40 07/10/2019
+
+The plain reads are outside of jh->b_state_lock critical section which result
+in data races. Fix them by adding pairs of READ|WRITE_ONCE().
+
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Qian Cai <cai@lca.pw>
+Link: https://lore.kernel.org/r/20200222043111.2227-1-cai@lca.pw
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jbd2/transaction.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
+index 04ffef9cea8cc..43693b6797105 100644
+--- a/fs/jbd2/transaction.c
++++ b/fs/jbd2/transaction.c
+@@ -1045,8 +1045,8 @@ static bool jbd2_write_access_granted(handle_t *handle, struct buffer_head *bh,
+       /* For undo access buffer must have data copied */
+       if (undo && !jh->b_committed_data)
+               goto out;
+-      if (jh->b_transaction != handle->h_transaction &&
+-          jh->b_next_transaction != handle->h_transaction)
++      if (READ_ONCE(jh->b_transaction) != handle->h_transaction &&
++          READ_ONCE(jh->b_next_transaction) != handle->h_transaction)
+               goto out;
+       /*
+        * There are two reasons for the barrier here:
+@@ -2467,8 +2467,8 @@ void __jbd2_journal_refile_buffer(struct journal_head *jh)
+        * our jh reference and thus __jbd2_journal_file_buffer() must not
+        * take a new one.
+        */
+-      jh->b_transaction = jh->b_next_transaction;
+-      jh->b_next_transaction = NULL;
++      WRITE_ONCE(jh->b_transaction, jh->b_next_transaction);
++      WRITE_ONCE(jh->b_next_transaction, NULL);
+       if (buffer_freed(bh))
+               jlist = BJ_Forget;
+       else if (jh->b_modified)
+-- 
+2.20.1
+
diff --git a/queue-4.19/mac80211-rx-avoid-rcu-list-traversal-under-mutex.patch b/queue-4.19/mac80211-rx-avoid-rcu-list-traversal-under-mutex.patch
new file mode 100644 (file)
index 0000000..f868d68
--- /dev/null
@@ -0,0 +1,39 @@
+From 58cb42bb8bab2012d2cce235909ac027f60bd233 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Feb 2020 20:03:02 +0530
+Subject: mac80211: rx: avoid RCU list traversal under mutex
+
+From: Madhuparna Bhowmik <madhuparnabhowmik10@gmail.com>
+
+[ Upstream commit 253216ffb2a002a682c6f68bd3adff5b98b71de8 ]
+
+local->sta_mtx is held in __ieee80211_check_fast_rx_iface().
+No need to use list_for_each_entry_rcu() as it also requires
+a cond argument to avoid false lockdep warnings when not used in
+RCU read-side section (with CONFIG_PROVE_RCU_LIST).
+Therefore use list_for_each_entry();
+
+Signed-off-by: Madhuparna Bhowmik <madhuparnabhowmik10@gmail.com>
+Link: https://lore.kernel.org/r/20200223143302.15390-1-madhuparnabhowmik10@gmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/rx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
+index 02d0b22d01141..c7c456c86b0d3 100644
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -4042,7 +4042,7 @@ void __ieee80211_check_fast_rx_iface(struct ieee80211_sub_if_data *sdata)
+       lockdep_assert_held(&local->sta_mtx);
+-      list_for_each_entry_rcu(sta, &local->sta_list, list) {
++      list_for_each_entry(sta, &local->sta_list, list) {
+               if (sdata != sta->sdata &&
+                   (!sta->sdata->bss || sta->sdata->bss != sdata->bss))
+                       continue;
+-- 
+2.20.1
+
diff --git a/queue-4.19/net-ks8851-ml-fix-irq-handling-and-locking.patch b/queue-4.19/net-ks8851-ml-fix-irq-handling-and-locking.patch
new file mode 100644 (file)
index 0000000..11072a3
--- /dev/null
@@ -0,0 +1,102 @@
+From 5bd3d9a00078348bc5582d90bf846433319df9b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Feb 2020 14:38:40 +0100
+Subject: net: ks8851-ml: Fix IRQ handling and locking
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit 44343418d0f2f623cb9da6f5000df793131cbe3b ]
+
+The KS8851 requires that packet RX and TX are mutually exclusive.
+Currently, the driver hopes to achieve this by disabling interrupt
+from the card by writing the card registers and by disabling the
+interrupt on the interrupt controller. This however is racy on SMP.
+
+Replace this approach by expanding the spinlock used around the
+ks_start_xmit() TX path to ks_irq() RX path to assure true mutual
+exclusion and remove the interrupt enabling/disabling, which is
+now not needed anymore. Furthermore, disable interrupts also in
+ks_net_stop(), which was missing before.
+
+Note that a massive improvement here would be to re-use the KS8851
+driver approach, which is to move the TX path into a worker thread,
+interrupt handling to threaded interrupt, and synchronize everything
+with mutexes, but that would be a much bigger rework, for a separate
+patch.
+
+Signed-off-by: Marek Vasut <marex@denx.de>
+Cc: David S. Miller <davem@davemloft.net>
+Cc: Lukas Wunner <lukas@wunner.de>
+Cc: Petr Stetiar <ynezz@true.cz>
+Cc: YueHaibing <yuehaibing@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/micrel/ks8851_mll.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c
+index 9de59facec218..a5525bf977e2c 100644
+--- a/drivers/net/ethernet/micrel/ks8851_mll.c
++++ b/drivers/net/ethernet/micrel/ks8851_mll.c
+@@ -832,14 +832,17 @@ static irqreturn_t ks_irq(int irq, void *pw)
+ {
+       struct net_device *netdev = pw;
+       struct ks_net *ks = netdev_priv(netdev);
++      unsigned long flags;
+       u16 status;
++      spin_lock_irqsave(&ks->statelock, flags);
+       /*this should be the first in IRQ handler */
+       ks_save_cmd_reg(ks);
+       status = ks_rdreg16(ks, KS_ISR);
+       if (unlikely(!status)) {
+               ks_restore_cmd_reg(ks);
++              spin_unlock_irqrestore(&ks->statelock, flags);
+               return IRQ_NONE;
+       }
+@@ -865,6 +868,7 @@ static irqreturn_t ks_irq(int irq, void *pw)
+               ks->netdev->stats.rx_over_errors++;
+       /* this should be the last in IRQ handler*/
+       ks_restore_cmd_reg(ks);
++      spin_unlock_irqrestore(&ks->statelock, flags);
+       return IRQ_HANDLED;
+ }
+@@ -934,6 +938,7 @@ static int ks_net_stop(struct net_device *netdev)
+       /* shutdown RX/TX QMU */
+       ks_disable_qmu(ks);
++      ks_disable_int(ks);
+       /* set powermode to soft power down to save power */
+       ks_set_powermode(ks, PMECR_PM_SOFTDOWN);
+@@ -990,10 +995,9 @@ static netdev_tx_t ks_start_xmit(struct sk_buff *skb, struct net_device *netdev)
+ {
+       netdev_tx_t retv = NETDEV_TX_OK;
+       struct ks_net *ks = netdev_priv(netdev);
++      unsigned long flags;
+-      disable_irq(netdev->irq);
+-      ks_disable_int(ks);
+-      spin_lock(&ks->statelock);
++      spin_lock_irqsave(&ks->statelock, flags);
+       /* Extra space are required:
+       *  4 byte for alignment, 4 for status/length, 4 for CRC
+@@ -1007,9 +1011,7 @@ static netdev_tx_t ks_start_xmit(struct sk_buff *skb, struct net_device *netdev)
+               dev_kfree_skb(skb);
+       } else
+               retv = NETDEV_TX_BUSY;
+-      spin_unlock(&ks->statelock);
+-      ks_enable_int(ks);
+-      enable_irq(netdev->irq);
++      spin_unlock_irqrestore(&ks->statelock, flags);
+       return retv;
+ }
+-- 
+2.20.1
+
diff --git a/queue-4.19/net-rmnet-do-not-allow-to-change-mux-id-if-mux-id-is.patch b/queue-4.19/net-rmnet-do-not-allow-to-change-mux-id-if-mux-id-is.patch
new file mode 100644 (file)
index 0000000..0880bc9
--- /dev/null
@@ -0,0 +1,47 @@
+From 039a1feb432e6998130241a8b84aaa06a94ea726 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2020 12:25:19 +0000
+Subject: net: rmnet: do not allow to change mux id if mux id is duplicated
+
+From: Taehee Yoo <ap420073@gmail.com>
+
+[ Upstream commit 1dc49e9d164cd7e11c81279c83db84a147e14740 ]
+
+Basically, duplicate mux id isn't be allowed.
+So, the creation of rmnet will be failed if there is duplicate mux id
+is existing.
+But, changelink routine doesn't check duplicate mux id.
+
+Test commands:
+    modprobe rmnet
+    ip link add dummy0 type dummy
+    ip link add rmnet0 link dummy0 type rmnet mux_id 1
+    ip link add rmnet1 link dummy0 type rmnet mux_id 2
+    ip link set rmnet1 type rmnet mux_id 1
+
+Fixes: 23790ef12082 ("net: qualcomm: rmnet: Allow to configure flags for existing devices")
+Signed-off-by: Taehee Yoo <ap420073@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
+index b7acedf76aa0b..272a08f521e11 100644
+--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
+@@ -315,6 +315,10 @@ static int rmnet_changelink(struct net_device *dev, struct nlattr *tb[],
+       if (data[IFLA_RMNET_MUX_ID]) {
+               mux_id = nla_get_u16(data[IFLA_RMNET_MUX_ID]);
++              if (rmnet_get_endpoint(port, mux_id)) {
++                      NL_SET_ERR_MSG_MOD(extack, "MUX ID already exists");
++                      return -EINVAL;
++              }
+               ep = rmnet_get_endpoint(port, priv->mux_id);
+               if (!ep)
+                       return -ENODEV;
+-- 
+2.20.1
+
diff --git a/queue-4.19/net-rmnet-fix-bridge-mode-bugs.patch b/queue-4.19/net-rmnet-fix-bridge-mode-bugs.patch
new file mode 100644 (file)
index 0000000..bae8ec3
--- /dev/null
@@ -0,0 +1,360 @@
+From 71513d608d1f582771cf0d8d7e2899e22eea8af2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2020 12:26:02 +0000
+Subject: net: rmnet: fix bridge mode bugs
+
+From: Taehee Yoo <ap420073@gmail.com>
+
+[ Upstream commit d939b6d30bea1a2322bc536b12be0a7c4c2bccd7 ]
+
+In order to attach a bridge interface to the rmnet interface,
+"master" operation is used.
+(e.g. ip link set dummy1 master rmnet0)
+But, in the rmnet_add_bridge(), which is a callback of ->ndo_add_slave()
+doesn't register lower interface.
+So, ->ndo_del_slave() doesn't work.
+There are other problems too.
+1. It couldn't detect circular upper/lower interface relationship.
+2. It couldn't prevent stack overflow because of too deep depth
+of upper/lower interface
+3. It doesn't check the number of lower interfaces.
+4. Panics because of several reasons.
+
+The root problem of these issues is actually the same.
+So, in this patch, these all problems will be fixed.
+
+Test commands:
+    modprobe rmnet
+    ip link add dummy0 type dummy
+    ip link add rmnet0 link dummy0 type rmnet mux_id 1
+    ip link add dummy1 master rmnet0 type dummy
+    ip link add dummy2 master rmnet0 type dummy
+    ip link del rmnet0
+    ip link del dummy2
+    ip link del dummy1
+
+Splat looks like:
+[   41.867595][ T1164] general protection fault, probably for non-canonical address 0xdffffc0000000101I
+[   41.869993][ T1164] KASAN: null-ptr-deref in range [0x0000000000000808-0x000000000000080f]
+[   41.872950][ T1164] CPU: 0 PID: 1164 Comm: ip Not tainted 5.6.0-rc1+ #447
+[   41.873915][ T1164] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
+[   41.875161][ T1164] RIP: 0010:rmnet_unregister_bridge.isra.6+0x71/0xf0 [rmnet]
+[   41.876178][ T1164] Code: 48 89 ef 48 89 c6 5b 5d e9 fc fe ff ff e8 f7 f3 ff ff 48 8d b8 08 08 00 00 48 ba 00 7
+[   41.878925][ T1164] RSP: 0018:ffff8880c4d0f188 EFLAGS: 00010202
+[   41.879774][ T1164] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000101
+[   41.887689][ T1164] RDX: dffffc0000000000 RSI: ffffffffb8cf64f0 RDI: 0000000000000808
+[   41.888727][ T1164] RBP: ffff8880c40e4000 R08: ffffed101b3c0e3c R09: 0000000000000001
+[   41.889749][ T1164] R10: 0000000000000001 R11: ffffed101b3c0e3b R12: 1ffff110189a1e3c
+[   41.890783][ T1164] R13: ffff8880c4d0f200 R14: ffffffffb8d56160 R15: ffff8880ccc2c000
+[   41.891794][ T1164] FS:  00007f4300edc0c0(0000) GS:ffff8880d9c00000(0000) knlGS:0000000000000000
+[   41.892953][ T1164] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[   41.893800][ T1164] CR2: 00007f43003bc8c0 CR3: 00000000ca53e001 CR4: 00000000000606f0
+[   41.894824][ T1164] Call Trace:
+[   41.895274][ T1164]  ? rcu_is_watching+0x2c/0x80
+[   41.895895][ T1164]  rmnet_config_notify_cb+0x1f7/0x590 [rmnet]
+[   41.896687][ T1164]  ? rmnet_unregister_bridge.isra.6+0xf0/0xf0 [rmnet]
+[   41.897611][ T1164]  ? rmnet_unregister_bridge.isra.6+0xf0/0xf0 [rmnet]
+[   41.898508][ T1164]  ? __module_text_address+0x13/0x140
+[   41.899162][ T1164]  notifier_call_chain+0x90/0x160
+[   41.899814][ T1164]  rollback_registered_many+0x660/0xcf0
+[   41.900544][ T1164]  ? netif_set_real_num_tx_queues+0x780/0x780
+[   41.901316][ T1164]  ? __lock_acquire+0xdfe/0x3de0
+[   41.901958][ T1164]  ? memset+0x1f/0x40
+[   41.902468][ T1164]  ? __nla_validate_parse+0x98/0x1ab0
+[   41.903166][ T1164]  unregister_netdevice_many.part.133+0x13/0x1b0
+[   41.903988][ T1164]  rtnl_delete_link+0xbc/0x100
+[ ... ]
+
+Fixes: 60d58f971c10 ("net: qualcomm: rmnet: Implement bridge mode")
+Signed-off-by: Taehee Yoo <ap420073@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/qualcomm/rmnet/rmnet_config.c    | 131 +++++++++---------
+ .../ethernet/qualcomm/rmnet/rmnet_config.h    |   1 +
+ .../net/ethernet/qualcomm/rmnet/rmnet_vnd.c   |   8 --
+ .../net/ethernet/qualcomm/rmnet/rmnet_vnd.h   |   1 -
+ 4 files changed, 64 insertions(+), 77 deletions(-)
+
+diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
+index 01a1d3ff3c944..37786affa9750 100644
+--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
+@@ -22,25 +22,6 @@
+ #include "rmnet_vnd.h"
+ #include "rmnet_private.h"
+-/* Locking scheme -
+- * The shared resource which needs to be protected is realdev->rx_handler_data.
+- * For the writer path, this is using rtnl_lock(). The writer paths are
+- * rmnet_newlink(), rmnet_dellink() and rmnet_force_unassociate_device(). These
+- * paths are already called with rtnl_lock() acquired in. There is also an
+- * ASSERT_RTNL() to ensure that we are calling with rtnl acquired. For
+- * dereference here, we will need to use rtnl_dereference(). Dev list writing
+- * needs to happen with rtnl_lock() acquired for netdev_master_upper_dev_link().
+- * For the reader path, the real_dev->rx_handler_data is called in the TX / RX
+- * path. We only need rcu_read_lock() for these scenarios. In these cases,
+- * the rcu_read_lock() is held in __dev_queue_xmit() and
+- * netif_receive_skb_internal(), so readers need to use rcu_dereference_rtnl()
+- * to get the relevant information. For dev list reading, we again acquire
+- * rcu_read_lock() in rmnet_dellink() for netdev_master_upper_dev_get_rcu().
+- * We also use unregister_netdevice_many() to free all rmnet devices in
+- * rmnet_force_unassociate_device() so we dont lose the rtnl_lock() and free in
+- * same context.
+- */
+-
+ /* Local Definitions and Declarations */
+ static const struct nla_policy rmnet_policy[IFLA_RMNET_MAX + 1] = {
+@@ -60,9 +41,10 @@ rmnet_get_port_rtnl(const struct net_device *real_dev)
+       return rtnl_dereference(real_dev->rx_handler_data);
+ }
+-static int rmnet_unregister_real_device(struct net_device *real_dev,
+-                                      struct rmnet_port *port)
++static int rmnet_unregister_real_device(struct net_device *real_dev)
+ {
++      struct rmnet_port *port = rmnet_get_port_rtnl(real_dev);
++
+       if (port->nr_rmnet_devs)
+               return -EINVAL;
+@@ -102,28 +84,33 @@ static int rmnet_register_real_device(struct net_device *real_dev)
+       return 0;
+ }
+-static void rmnet_unregister_bridge(struct net_device *dev,
+-                                  struct rmnet_port *port)
++static void rmnet_unregister_bridge(struct rmnet_port *port)
+ {
+-      struct rmnet_port *bridge_port;
+-      struct net_device *bridge_dev;
++      struct net_device *bridge_dev, *real_dev, *rmnet_dev;
++      struct rmnet_port *real_port;
+       if (port->rmnet_mode != RMNET_EPMODE_BRIDGE)
+               return;
+-      /* bridge slave handling */
++      rmnet_dev = port->rmnet_dev;
+       if (!port->nr_rmnet_devs) {
+-              bridge_dev = port->bridge_ep;
++              /* bridge device */
++              real_dev = port->bridge_ep;
++              bridge_dev = port->dev;
+-              bridge_port = rmnet_get_port_rtnl(bridge_dev);
+-              bridge_port->bridge_ep = NULL;
+-              bridge_port->rmnet_mode = RMNET_EPMODE_VND;
++              real_port = rmnet_get_port_rtnl(real_dev);
++              real_port->bridge_ep = NULL;
++              real_port->rmnet_mode = RMNET_EPMODE_VND;
+       } else {
++              /* real device */
+               bridge_dev = port->bridge_ep;
+-              bridge_port = rmnet_get_port_rtnl(bridge_dev);
+-              rmnet_unregister_real_device(bridge_dev, bridge_port);
++              port->bridge_ep = NULL;
++              port->rmnet_mode = RMNET_EPMODE_VND;
+       }
++
++      netdev_upper_dev_unlink(bridge_dev, rmnet_dev);
++      rmnet_unregister_real_device(bridge_dev);
+ }
+ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
+@@ -170,6 +157,7 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
+               goto err2;
+       port->rmnet_mode = mode;
++      port->rmnet_dev = dev;
+       hlist_add_head_rcu(&ep->hlnode, &port->muxed_ep[mux_id]);
+@@ -187,8 +175,9 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
+ err2:
+       unregister_netdevice(dev);
++      rmnet_vnd_dellink(mux_id, port, ep);
+ err1:
+-      rmnet_unregister_real_device(real_dev, port);
++      rmnet_unregister_real_device(real_dev);
+ err0:
+       kfree(ep);
+       return err;
+@@ -197,30 +186,32 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
+ static void rmnet_dellink(struct net_device *dev, struct list_head *head)
+ {
+       struct rmnet_priv *priv = netdev_priv(dev);
+-      struct net_device *real_dev;
++      struct net_device *real_dev, *bridge_dev;
++      struct rmnet_port *real_port, *bridge_port;
+       struct rmnet_endpoint *ep;
+-      struct rmnet_port *port;
+-      u8 mux_id;
++      u8 mux_id = priv->mux_id;
+       real_dev = priv->real_dev;
+-      if (!real_dev || !rmnet_is_real_dev_registered(real_dev))
++      if (!rmnet_is_real_dev_registered(real_dev))
+               return;
+-      port = rmnet_get_port_rtnl(real_dev);
+-
+-      mux_id = rmnet_vnd_get_mux(dev);
++      real_port = rmnet_get_port_rtnl(real_dev);
++      bridge_dev = real_port->bridge_ep;
++      if (bridge_dev) {
++              bridge_port = rmnet_get_port_rtnl(bridge_dev);
++              rmnet_unregister_bridge(bridge_port);
++      }
+-      ep = rmnet_get_endpoint(port, mux_id);
++      ep = rmnet_get_endpoint(real_port, mux_id);
+       if (ep) {
+               hlist_del_init_rcu(&ep->hlnode);
+-              rmnet_unregister_bridge(dev, port);
+-              rmnet_vnd_dellink(mux_id, port, ep);
++              rmnet_vnd_dellink(mux_id, real_port, ep);
+               kfree(ep);
+       }
+-      netdev_upper_dev_unlink(real_dev, dev);
+-      rmnet_unregister_real_device(real_dev, port);
++      netdev_upper_dev_unlink(real_dev, dev);
++      rmnet_unregister_real_device(real_dev);
+       unregister_netdevice_queue(dev, head);
+ }
+@@ -232,23 +223,23 @@ static void rmnet_force_unassociate_device(struct net_device *real_dev)
+       unsigned long bkt_ep;
+       LIST_HEAD(list);
+-      ASSERT_RTNL();
+-
+       port = rmnet_get_port_rtnl(real_dev);
+-      rmnet_unregister_bridge(real_dev, port);
+-
+-      hash_for_each_safe(port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) {
+-              netdev_upper_dev_unlink(real_dev, ep->egress_dev);
+-              unregister_netdevice_queue(ep->egress_dev, &list);
+-              rmnet_vnd_dellink(ep->mux_id, port, ep);
+-              hlist_del_init_rcu(&ep->hlnode);
+-              kfree(ep);
++      if (port->nr_rmnet_devs) {
++              /* real device */
++              rmnet_unregister_bridge(port);
++              hash_for_each_safe(port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) {
++                      unregister_netdevice_queue(ep->egress_dev, &list);
++                      netdev_upper_dev_unlink(real_dev, ep->egress_dev);
++                      rmnet_vnd_dellink(ep->mux_id, port, ep);
++                      hlist_del_init_rcu(&ep->hlnode);
++                      kfree(ep);
++              }
++              rmnet_unregister_real_device(real_dev);
++              unregister_netdevice_many(&list);
++      } else {
++              rmnet_unregister_bridge(port);
+       }
+-
+-      unregister_netdevice_many(&list);
+-
+-      rmnet_unregister_real_device(real_dev, port);
+ }
+ static int rmnet_config_notify_cb(struct notifier_block *nb,
+@@ -427,6 +418,9 @@ int rmnet_add_bridge(struct net_device *rmnet_dev,
+       if (port->nr_rmnet_devs > 1)
+               return -EINVAL;
++      if (port->rmnet_mode != RMNET_EPMODE_VND)
++              return -EINVAL;
++
+       if (rmnet_is_real_dev_registered(slave_dev))
+               return -EBUSY;
+@@ -434,9 +428,17 @@ int rmnet_add_bridge(struct net_device *rmnet_dev,
+       if (err)
+               return -EBUSY;
++      err = netdev_master_upper_dev_link(slave_dev, rmnet_dev, NULL, NULL,
++                                         extack);
++      if (err) {
++              rmnet_unregister_real_device(slave_dev);
++              return err;
++      }
++
+       slave_port = rmnet_get_port_rtnl(slave_dev);
+       slave_port->rmnet_mode = RMNET_EPMODE_BRIDGE;
+       slave_port->bridge_ep = real_dev;
++      slave_port->rmnet_dev = rmnet_dev;
+       port->rmnet_mode = RMNET_EPMODE_BRIDGE;
+       port->bridge_ep = slave_dev;
+@@ -448,16 +450,9 @@ int rmnet_add_bridge(struct net_device *rmnet_dev,
+ int rmnet_del_bridge(struct net_device *rmnet_dev,
+                    struct net_device *slave_dev)
+ {
+-      struct rmnet_priv *priv = netdev_priv(rmnet_dev);
+-      struct net_device *real_dev = priv->real_dev;
+-      struct rmnet_port *port, *slave_port;
+-
+-      port = rmnet_get_port_rtnl(real_dev);
+-      port->rmnet_mode = RMNET_EPMODE_VND;
+-      port->bridge_ep = NULL;
++      struct rmnet_port *port = rmnet_get_port_rtnl(slave_dev);
+-      slave_port = rmnet_get_port_rtnl(slave_dev);
+-      rmnet_unregister_real_device(slave_dev, slave_port);
++      rmnet_unregister_bridge(port);
+       netdev_dbg(slave_dev, "removed from rmnet as slave\n");
+       return 0;
+diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h
+index 6a978f486ce10..7691d1abe6e2a 100644
+--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h
++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h
+@@ -37,6 +37,7 @@ struct rmnet_port {
+       u8 rmnet_mode;
+       struct hlist_head muxed_ep[RMNET_MAX_LOGICAL_EP];
+       struct net_device *bridge_ep;
++      struct net_device *rmnet_dev;
+ };
+ extern struct rtnl_link_ops rmnet_link_ops;
+diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c
+index d11c16aeb19ad..ed02926f5fe90 100644
+--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c
++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c
+@@ -276,14 +276,6 @@ int rmnet_vnd_dellink(u8 id, struct rmnet_port *port,
+       return 0;
+ }
+-u8 rmnet_vnd_get_mux(struct net_device *rmnet_dev)
+-{
+-      struct rmnet_priv *priv;
+-
+-      priv = netdev_priv(rmnet_dev);
+-      return priv->mux_id;
+-}
+-
+ int rmnet_vnd_do_flow_control(struct net_device *rmnet_dev, int enable)
+ {
+       netdev_dbg(rmnet_dev, "Setting VND TX queue state to %d\n", enable);
+diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.h
+index 71e4c32869512..22cfdfd5625a4 100644
+--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.h
++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.h
+@@ -25,6 +25,5 @@ int rmnet_vnd_dellink(u8 id, struct rmnet_port *port,
+                     struct rmnet_endpoint *ep);
+ void rmnet_vnd_rx_fixup(struct sk_buff *skb, struct net_device *dev);
+ void rmnet_vnd_tx_fixup(struct sk_buff *skb, struct net_device *dev);
+-u8 rmnet_vnd_get_mux(struct net_device *rmnet_dev);
+ void rmnet_vnd_setup(struct net_device *dev);
+ #endif /* _RMNET_VND_H_ */
+-- 
+2.20.1
+
diff --git a/queue-4.19/net-rmnet-fix-null-pointer-dereference-in-rmnet_chan.patch b/queue-4.19/net-rmnet-fix-null-pointer-dereference-in-rmnet_chan.patch
new file mode 100644 (file)
index 0000000..ac21906
--- /dev/null
@@ -0,0 +1,88 @@
+From 5dd4d1dd8445b087fce858d415743680145442e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2020 12:24:26 +0000
+Subject: net: rmnet: fix NULL pointer dereference in rmnet_changelink()
+
+From: Taehee Yoo <ap420073@gmail.com>
+
+[ Upstream commit 1eb1f43a6e37282348a41e3d68f5e9a6a4359212 ]
+
+In the rmnet_changelink(), it uses IFLA_LINK without checking
+NULL pointer.
+tb[IFLA_LINK] could be NULL pointer.
+So, NULL-ptr-deref could occur.
+
+rmnet already has a lower interface (real_dev).
+So, after this patch, rmnet_changelink() does not use IFLA_LINK anymore.
+
+Test commands:
+    modprobe rmnet
+    ip link add dummy0 type dummy
+    ip link add rmnet0 link dummy0 type rmnet mux_id 1
+    ip link set rmnet0 type rmnet mux_id 2
+
+Splat looks like:
+[   90.578726][ T1131] general protection fault, probably for non-canonical address 0xdffffc0000000000I
+[   90.581121][ T1131] KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
+[   90.582380][ T1131] CPU: 2 PID: 1131 Comm: ip Not tainted 5.6.0-rc1+ #447
+[   90.584285][ T1131] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
+[   90.587506][ T1131] RIP: 0010:rmnet_changelink+0x5a/0x8a0 [rmnet]
+[   90.588546][ T1131] Code: 83 ec 20 48 c1 ea 03 80 3c 02 00 0f 85 6f 07 00 00 48 8b 5e 28 48 b8 00 00 00 00 00 0
+[   90.591447][ T1131] RSP: 0018:ffff8880ce78f1b8 EFLAGS: 00010247
+[   90.592329][ T1131] RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffff8880ce78f8b0
+[   90.593253][ T1131] RDX: 0000000000000000 RSI: ffff8880ce78f4a0 RDI: 0000000000000004
+[   90.594058][ T1131] RBP: ffff8880cf543e00 R08: 0000000000000002 R09: 0000000000000002
+[   90.594859][ T1131] R10: ffffffffc0586a40 R11: 0000000000000000 R12: ffff8880ca47c000
+[   90.595690][ T1131] R13: ffff8880ca47c000 R14: ffff8880cf545000 R15: 0000000000000000
+[   90.596553][ T1131] FS:  00007f21f6c7e0c0(0000) GS:ffff8880da400000(0000) knlGS:0000000000000000
+[   90.597504][ T1131] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[   90.599418][ T1131] CR2: 0000556e413db458 CR3: 00000000c917a002 CR4: 00000000000606e0
+[   90.600289][ T1131] Call Trace:
+[   90.600631][ T1131]  __rtnl_newlink+0x922/0x1270
+[   90.601194][ T1131]  ? lock_downgrade+0x6e0/0x6e0
+[   90.601724][ T1131]  ? rtnl_link_unregister+0x220/0x220
+[   90.602309][ T1131]  ? lock_acquire+0x164/0x3b0
+[   90.602784][ T1131]  ? is_bpf_image_address+0xff/0x1d0
+[   90.603331][ T1131]  ? rtnl_newlink+0x4c/0x90
+[   90.603810][ T1131]  ? kernel_text_address+0x111/0x140
+[   90.604419][ T1131]  ? __kernel_text_address+0xe/0x30
+[   90.604981][ T1131]  ? unwind_get_return_address+0x5f/0xa0
+[   90.605616][ T1131]  ? create_prof_cpu_mask+0x20/0x20
+[   90.606304][ T1131]  ? arch_stack_walk+0x83/0xb0
+[   90.606985][ T1131]  ? stack_trace_save+0x82/0xb0
+[   90.607656][ T1131]  ? stack_trace_consume_entry+0x160/0x160
+[   90.608503][ T1131]  ? deactivate_slab.isra.78+0x2c5/0x800
+[   90.609336][ T1131]  ? kasan_unpoison_shadow+0x30/0x40
+[   90.610096][ T1131]  ? kmem_cache_alloc_trace+0x135/0x350
+[   90.610889][ T1131]  ? rtnl_newlink+0x4c/0x90
+[   90.611512][ T1131]  rtnl_newlink+0x65/0x90
+[ ... ]
+
+Fixes: 23790ef12082 ("net: qualcomm: rmnet: Allow to configure flags for existing devices")
+Signed-off-by: Taehee Yoo <ap420073@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
+index 0fb9375b4f69e..ad46f5aadc0ab 100644
+--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
+@@ -309,10 +309,8 @@ static int rmnet_changelink(struct net_device *dev, struct nlattr *tb[],
+       if (!dev)
+               return -ENODEV;
+-      real_dev = __dev_get_by_index(dev_net(dev),
+-                                    nla_get_u32(tb[IFLA_LINK]));
+-
+-      if (!real_dev || !rmnet_is_real_dev_registered(real_dev))
++      real_dev = priv->real_dev;
++      if (!rmnet_is_real_dev_registered(real_dev))
+               return -ENODEV;
+       port = rmnet_get_port_rtnl(real_dev);
+-- 
+2.20.1
+
diff --git a/queue-4.19/net-rmnet-fix-null-pointer-dereference-in-rmnet_newl.patch b/queue-4.19/net-rmnet-fix-null-pointer-dereference-in-rmnet_newl.patch
new file mode 100644 (file)
index 0000000..07f68fd
--- /dev/null
@@ -0,0 +1,82 @@
+From e5b6928b1f366fce45e4dd763a0c19847c4fcbf2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2020 12:23:52 +0000
+Subject: net: rmnet: fix NULL pointer dereference in rmnet_newlink()
+
+From: Taehee Yoo <ap420073@gmail.com>
+
+[ Upstream commit 93b5cbfa9636d385126f211dca9efa7e3f683202 ]
+
+rmnet registers IFLA_LINK interface as a lower interface.
+But, IFLA_LINK could be NULL.
+In the current code, rmnet doesn't check IFLA_LINK.
+So, panic would occur.
+
+Test commands:
+    modprobe rmnet
+    ip link add rmnet0 type rmnet mux_id 1
+
+Splat looks like:
+[   36.826109][ T1115] general protection fault, probably for non-canonical address 0xdffffc0000000000I
+[   36.838817][ T1115] KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
+[   36.839908][ T1115] CPU: 1 PID: 1115 Comm: ip Not tainted 5.6.0-rc1+ #447
+[   36.840569][ T1115] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
+[   36.841408][ T1115] RIP: 0010:rmnet_newlink+0x54/0x510 [rmnet]
+[   36.841986][ T1115] Code: 83 ec 18 48 c1 e9 03 80 3c 01 00 0f 85 d4 03 00 00 48 8b 6a 28 48 b8 00 00 00 00 00 c
+[   36.843923][ T1115] RSP: 0018:ffff8880b7e0f1c0 EFLAGS: 00010247
+[   36.844756][ T1115] RAX: dffffc0000000000 RBX: ffff8880d14cca00 RCX: 1ffff11016fc1e99
+[   36.845859][ T1115] RDX: 0000000000000000 RSI: ffff8880c3d04000 RDI: 0000000000000004
+[   36.846961][ T1115] RBP: 0000000000000000 R08: ffff8880b7e0f8b0 R09: ffff8880b6ac2d90
+[   36.848020][ T1115] R10: ffffffffc0589a40 R11: ffffed1016d585b7 R12: ffffffff88ceaf80
+[   36.848788][ T1115] R13: ffff8880c3d04000 R14: ffff8880b7e0f8b0 R15: ffff8880c3d04000
+[   36.849546][ T1115] FS:  00007f50ab3360c0(0000) GS:ffff8880da000000(0000) knlGS:0000000000000000
+[   36.851784][ T1115] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[   36.852422][ T1115] CR2: 000055871afe5ab0 CR3: 00000000ae246001 CR4: 00000000000606e0
+[   36.853181][ T1115] Call Trace:
+[   36.853514][ T1115]  __rtnl_newlink+0xbdb/0x1270
+[   36.853967][ T1115]  ? lock_downgrade+0x6e0/0x6e0
+[   36.854420][ T1115]  ? rtnl_link_unregister+0x220/0x220
+[   36.854936][ T1115]  ? lock_acquire+0x164/0x3b0
+[   36.855376][ T1115]  ? is_bpf_image_address+0xff/0x1d0
+[   36.855884][ T1115]  ? rtnl_newlink+0x4c/0x90
+[   36.856304][ T1115]  ? kernel_text_address+0x111/0x140
+[   36.856857][ T1115]  ? __kernel_text_address+0xe/0x30
+[   36.857440][ T1115]  ? unwind_get_return_address+0x5f/0xa0
+[   36.858063][ T1115]  ? create_prof_cpu_mask+0x20/0x20
+[   36.858644][ T1115]  ? arch_stack_walk+0x83/0xb0
+[   36.859171][ T1115]  ? stack_trace_save+0x82/0xb0
+[   36.859710][ T1115]  ? stack_trace_consume_entry+0x160/0x160
+[   36.860357][ T1115]  ? deactivate_slab.isra.78+0x2c5/0x800
+[   36.860928][ T1115]  ? kasan_unpoison_shadow+0x30/0x40
+[   36.861520][ T1115]  ? kmem_cache_alloc_trace+0x135/0x350
+[   36.862125][ T1115]  ? rtnl_newlink+0x4c/0x90
+[   36.864073][ T1115]  rtnl_newlink+0x65/0x90
+[ ... ]
+
+Fixes: ceed73a2cf4a ("drivers: net: ethernet: qualcomm: rmnet: Initial implementation")
+Signed-off-by: Taehee Yoo <ap420073@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
+index 4c476fac78358..0fb9375b4f69e 100644
+--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
+@@ -144,6 +144,11 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
+       int err = 0;
+       u16 mux_id;
++      if (!tb[IFLA_LINK]) {
++              NL_SET_ERR_MSG_MOD(extack, "link not specified");
++              return -EINVAL;
++      }
++
+       real_dev = __dev_get_by_index(src_net, nla_get_u32(tb[IFLA_LINK]));
+       if (!real_dev || !dev)
+               return -ENODEV;
+-- 
+2.20.1
+
diff --git a/queue-4.19/net-rmnet-fix-packet-forwarding-in-rmnet-bridge-mode.patch b/queue-4.19/net-rmnet-fix-packet-forwarding-in-rmnet-bridge-mode.patch
new file mode 100644 (file)
index 0000000..e4fefb5
--- /dev/null
@@ -0,0 +1,61 @@
+From 6a2a199291a61312d4ed8ff14f372ce2433465c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2020 12:26:15 +0000
+Subject: net: rmnet: fix packet forwarding in rmnet bridge mode
+
+From: Taehee Yoo <ap420073@gmail.com>
+
+[ Upstream commit ad3cc31b599ea80f06b29ebdc18b3a39878a48d6 ]
+
+Packet forwarding is not working in rmnet bridge mode.
+Because when a packet is forwarded, skb_push() for an ethernet header
+is needed. But it doesn't call skb_push().
+So, the ethernet header will be lost.
+
+Test commands:
+    modprobe rmnet
+    ip netns add nst
+    ip netns add nst2
+    ip link add veth0 type veth peer name veth1
+    ip link add veth2 type veth peer name veth3
+    ip link set veth1 netns nst
+    ip link set veth3 netns nst2
+
+    ip link add rmnet0 link veth0 type rmnet mux_id 1
+    ip link set veth2 master rmnet0
+    ip link set veth0 up
+    ip link set veth2 up
+    ip link set rmnet0 up
+    ip a a 192.168.100.1/24 dev rmnet0
+
+    ip netns exec nst ip link set veth1 up
+    ip netns exec nst ip a a 192.168.100.2/24 dev veth1
+    ip netns exec nst2 ip link set veth3 up
+    ip netns exec nst2 ip a a 192.168.100.3/24 dev veth3
+    ip netns exec nst2 ping 192.168.100.2
+
+Fixes: 60d58f971c10 ("net: qualcomm: rmnet: Implement bridge mode")
+Signed-off-by: Taehee Yoo <ap420073@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c
+index 5177d0f24947f..c9d43bad1e2fc 100644
+--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c
++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c
+@@ -168,6 +168,9 @@ static int rmnet_map_egress_handler(struct sk_buff *skb,
+ static void
+ rmnet_bridge_handler(struct sk_buff *skb, struct net_device *bridge_dev)
+ {
++      if (skb_mac_header_was_set(skb))
++              skb_push(skb, skb->mac_len);
++
+       if (bridge_dev) {
+               skb->dev = bridge_dev;
+               dev_queue_xmit(skb);
+-- 
+2.20.1
+
diff --git a/queue-4.19/net-rmnet-fix-suspicious-rcu-usage.patch b/queue-4.19/net-rmnet-fix-suspicious-rcu-usage.patch
new file mode 100644 (file)
index 0000000..658fe76
--- /dev/null
@@ -0,0 +1,163 @@
+From 81c76a911b0c97f62ce36e9ae5bf29827809edac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2020 12:24:45 +0000
+Subject: net: rmnet: fix suspicious RCU usage
+
+From: Taehee Yoo <ap420073@gmail.com>
+
+[ Upstream commit 102210f7664442d8c0ce332c006ea90626df745b ]
+
+rmnet_get_port() internally calls rcu_dereference_rtnl(),
+which checks RTNL.
+But rmnet_get_port() could be called by packet path.
+The packet path is not protected by RTNL.
+So, the suspicious RCU usage problem occurs.
+
+Test commands:
+    modprobe rmnet
+    ip netns add nst
+    ip link add veth0 type veth peer name veth1
+    ip link set veth1 netns nst
+    ip link add rmnet0 link veth0 type rmnet mux_id 1
+    ip netns exec nst ip link add rmnet1 link veth1 type rmnet mux_id 1
+    ip netns exec nst ip link set veth1 up
+    ip netns exec nst ip link set rmnet1 up
+    ip netns exec nst ip a a 192.168.100.2/24 dev rmnet1
+    ip link set veth0 up
+    ip link set rmnet0 up
+    ip a a 192.168.100.1/24 dev rmnet0
+    ping 192.168.100.2
+
+Splat looks like:
+[  146.630958][ T1174] WARNING: suspicious RCU usage
+[  146.631735][ T1174] 5.6.0-rc1+ #447 Not tainted
+[  146.632387][ T1174] -----------------------------
+[  146.633151][ T1174] drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c:386 suspicious rcu_dereference_check() !
+[  146.634742][ T1174]
+[  146.634742][ T1174] other info that might help us debug this:
+[  146.634742][ T1174]
+[  146.645992][ T1174]
+[  146.645992][ T1174] rcu_scheduler_active = 2, debug_locks = 1
+[  146.646937][ T1174] 5 locks held by ping/1174:
+[  146.647609][ T1174]  #0: ffff8880c31dea70 (sk_lock-AF_INET){+.+.}, at: raw_sendmsg+0xab8/0x2980
+[  146.662463][ T1174]  #1: ffffffff93925660 (rcu_read_lock_bh){....}, at: ip_finish_output2+0x243/0x2150
+[  146.671696][ T1174]  #2: ffffffff93925660 (rcu_read_lock_bh){....}, at: __dev_queue_xmit+0x213/0x2940
+[  146.673064][ T1174]  #3: ffff8880c19ecd58 (&dev->qdisc_running_key#7){+...}, at: ip_finish_output2+0x714/0x2150
+[  146.690358][ T1174]  #4: ffff8880c5796898 (&dev->qdisc_xmit_lock_key#3){+.-.}, at: sch_direct_xmit+0x1e2/0x1020
+[  146.699875][ T1174]
+[  146.699875][ T1174] stack backtrace:
+[  146.701091][ T1174] CPU: 0 PID: 1174 Comm: ping Not tainted 5.6.0-rc1+ #447
+[  146.705215][ T1174] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
+[  146.706565][ T1174] Call Trace:
+[  146.707102][ T1174]  dump_stack+0x96/0xdb
+[  146.708007][ T1174]  rmnet_get_port.part.9+0x76/0x80 [rmnet]
+[  146.709233][ T1174]  rmnet_egress_handler+0x107/0x420 [rmnet]
+[  146.710492][ T1174]  ? sch_direct_xmit+0x1e2/0x1020
+[  146.716193][ T1174]  rmnet_vnd_start_xmit+0x3d/0xa0 [rmnet]
+[  146.717012][ T1174]  dev_hard_start_xmit+0x160/0x740
+[  146.717854][ T1174]  sch_direct_xmit+0x265/0x1020
+[  146.718577][ T1174]  ? register_lock_class+0x14d0/0x14d0
+[  146.719429][ T1174]  ? dev_watchdog+0xac0/0xac0
+[  146.723738][ T1174]  ? __dev_queue_xmit+0x15fd/0x2940
+[  146.724469][ T1174]  ? lock_acquire+0x164/0x3b0
+[  146.725172][ T1174]  __dev_queue_xmit+0x20c7/0x2940
+[ ... ]
+
+Fixes: ceed73a2cf4a ("drivers: net: ethernet: qualcomm: rmnet: Initial implementation")
+Signed-off-by: Taehee Yoo <ap420073@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c  | 13 ++++++-------
+ drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h  |  2 +-
+ .../net/ethernet/qualcomm/rmnet/rmnet_handlers.c    |  4 ++--
+ 3 files changed, 9 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
+index ad46f5aadc0ab..915165cda996f 100644
+--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
+@@ -391,11 +391,10 @@ struct rtnl_link_ops rmnet_link_ops __read_mostly = {
+       .fill_info      = rmnet_fill_info,
+ };
+-/* Needs either rcu_read_lock() or rtnl lock */
+-struct rmnet_port *rmnet_get_port(struct net_device *real_dev)
++struct rmnet_port *rmnet_get_port_rcu(struct net_device *real_dev)
+ {
+       if (rmnet_is_real_dev_registered(real_dev))
+-              return rcu_dereference_rtnl(real_dev->rx_handler_data);
++              return rcu_dereference_bh(real_dev->rx_handler_data);
+       else
+               return NULL;
+ }
+@@ -421,7 +420,7 @@ int rmnet_add_bridge(struct net_device *rmnet_dev,
+       struct rmnet_port *port, *slave_port;
+       int err;
+-      port = rmnet_get_port(real_dev);
++      port = rmnet_get_port_rtnl(real_dev);
+       /* If there is more than one rmnet dev attached, its probably being
+        * used for muxing. Skip the briding in that case
+@@ -436,7 +435,7 @@ int rmnet_add_bridge(struct net_device *rmnet_dev,
+       if (err)
+               return -EBUSY;
+-      slave_port = rmnet_get_port(slave_dev);
++      slave_port = rmnet_get_port_rtnl(slave_dev);
+       slave_port->rmnet_mode = RMNET_EPMODE_BRIDGE;
+       slave_port->bridge_ep = real_dev;
+@@ -454,11 +453,11 @@ int rmnet_del_bridge(struct net_device *rmnet_dev,
+       struct net_device *real_dev = priv->real_dev;
+       struct rmnet_port *port, *slave_port;
+-      port = rmnet_get_port(real_dev);
++      port = rmnet_get_port_rtnl(real_dev);
+       port->rmnet_mode = RMNET_EPMODE_VND;
+       port->bridge_ep = NULL;
+-      slave_port = rmnet_get_port(slave_dev);
++      slave_port = rmnet_get_port_rtnl(slave_dev);
+       rmnet_unregister_real_device(slave_dev, slave_port);
+       netdev_dbg(slave_dev, "removed from rmnet as slave\n");
+diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h
+index 34ac45a774e72..6a978f486ce10 100644
+--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h
++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h
+@@ -74,7 +74,7 @@ struct rmnet_priv {
+       struct rmnet_priv_stats stats;
+ };
+-struct rmnet_port *rmnet_get_port(struct net_device *real_dev);
++struct rmnet_port *rmnet_get_port_rcu(struct net_device *real_dev);
+ struct rmnet_endpoint *rmnet_get_endpoint(struct rmnet_port *port, u8 mux_id);
+ int rmnet_add_bridge(struct net_device *rmnet_dev,
+                    struct net_device *slave_dev,
+diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c
+index 11167abe5934d..5177d0f24947f 100644
+--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c
++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c
+@@ -193,7 +193,7 @@ rx_handler_result_t rmnet_rx_handler(struct sk_buff **pskb)
+               return RX_HANDLER_PASS;
+       dev = skb->dev;
+-      port = rmnet_get_port(dev);
++      port = rmnet_get_port_rcu(dev);
+       switch (port->rmnet_mode) {
+       case RMNET_EPMODE_VND:
+@@ -226,7 +226,7 @@ void rmnet_egress_handler(struct sk_buff *skb)
+       skb->dev = priv->real_dev;
+       mux_id = priv->mux_id;
+-      port = rmnet_get_port(skb->dev);
++      port = rmnet_get_port_rcu(skb->dev);
+       if (!port)
+               goto drop;
+-- 
+2.20.1
+
diff --git a/queue-4.19/net-rmnet-remove-rcu_read_lock-in-rmnet_force_unasso.patch b/queue-4.19/net-rmnet-remove-rcu_read_lock-in-rmnet_force_unasso.patch
new file mode 100644 (file)
index 0000000..11cb27e
--- /dev/null
@@ -0,0 +1,95 @@
+From 29d7261397c7eb2d97faf547a60f3cbff168d4d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2020 12:25:05 +0000
+Subject: net: rmnet: remove rcu_read_lock in rmnet_force_unassociate_device()
+
+From: Taehee Yoo <ap420073@gmail.com>
+
+[ Upstream commit c026d970102e9af9958edefb4a015702c6aab636 ]
+
+The notifier_call() of the slave interface removes rmnet interface with
+unregister_netdevice_queue().
+But, before calling unregister_netdevice_queue(), it acquires
+rcu readlock.
+In the RCU critical section, sleeping isn't be allowed.
+But, unregister_netdevice_queue() internally calls synchronize_net(),
+which would sleep.
+So, suspicious RCU usage warning occurs.
+
+Test commands:
+    modprobe rmnet
+    ip link add dummy0 type dummy
+    ip link add dummy1 type dummy
+    ip link add rmnet0 link dummy0 type rmnet mux_id 1
+    ip link set dummy1 master rmnet0
+    ip link del dummy0
+
+Splat looks like:
+[   79.639245][ T1195] =============================
+[   79.640134][ T1195] WARNING: suspicious RCU usage
+[   79.640852][ T1195] 5.6.0-rc1+ #447 Not tainted
+[   79.641657][ T1195] -----------------------------
+[   79.642472][ T1195] ./include/linux/rcupdate.h:273 Illegal context switch in RCU read-side critical section!
+[   79.644043][ T1195]
+[   79.644043][ T1195] other info that might help us debug this:
+[   79.644043][ T1195]
+[   79.645682][ T1195]
+[   79.645682][ T1195] rcu_scheduler_active = 2, debug_locks = 1
+[   79.646980][ T1195] 2 locks held by ip/1195:
+[   79.647629][ T1195]  #0: ffffffffa3cf64f0 (rtnl_mutex){+.+.}, at: rtnetlink_rcv_msg+0x457/0x890
+[   79.649312][ T1195]  #1: ffffffffa39256c0 (rcu_read_lock){....}, at: rmnet_config_notify_cb+0xf0/0x590 [rmnet]
+[   79.651717][ T1195]
+[   79.651717][ T1195] stack backtrace:
+[   79.652650][ T1195] CPU: 3 PID: 1195 Comm: ip Not tainted 5.6.0-rc1+ #447
+[   79.653702][ T1195] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
+[   79.655037][ T1195] Call Trace:
+[   79.655560][ T1195]  dump_stack+0x96/0xdb
+[   79.656252][ T1195]  ___might_sleep+0x345/0x440
+[   79.656994][ T1195]  synchronize_net+0x18/0x30
+[   79.661132][ T1195]  netdev_rx_handler_unregister+0x40/0xb0
+[   79.666266][ T1195]  rmnet_unregister_real_device+0x42/0xb0 [rmnet]
+[   79.667211][ T1195]  rmnet_config_notify_cb+0x1f7/0x590 [rmnet]
+[   79.668121][ T1195]  ? rmnet_unregister_bridge.isra.6+0xf0/0xf0 [rmnet]
+[   79.669166][ T1195]  ? rmnet_unregister_bridge.isra.6+0xf0/0xf0 [rmnet]
+[   79.670286][ T1195]  ? __module_text_address+0x13/0x140
+[   79.671139][ T1195]  notifier_call_chain+0x90/0x160
+[   79.671973][ T1195]  rollback_registered_many+0x660/0xcf0
+[   79.672893][ T1195]  ? netif_set_real_num_tx_queues+0x780/0x780
+[   79.675091][ T1195]  ? __lock_acquire+0xdfe/0x3de0
+[   79.675825][ T1195]  ? memset+0x1f/0x40
+[   79.676367][ T1195]  ? __nla_validate_parse+0x98/0x1ab0
+[   79.677290][ T1195]  unregister_netdevice_many.part.133+0x13/0x1b0
+[   79.678163][ T1195]  rtnl_delete_link+0xbc/0x100
+[ ... ]
+
+Fixes: ceed73a2cf4a ("drivers: net: ethernet: qualcomm: rmnet: Initial implementation")
+Signed-off-by: Taehee Yoo <ap420073@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
+index 915165cda996f..b7acedf76aa0b 100644
+--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
+@@ -239,7 +239,6 @@ static void rmnet_force_unassociate_device(struct net_device *dev)
+       port = rmnet_get_port_rtnl(dev);
+-      rcu_read_lock();
+       rmnet_unregister_bridge(dev, port);
+       hash_for_each_safe(port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) {
+@@ -250,7 +249,6 @@ static void rmnet_force_unassociate_device(struct net_device *dev)
+               kfree(ep);
+       }
+-      rcu_read_unlock();
+       unregister_netdevice_many(&list);
+       rmnet_unregister_real_device(real_dev, port);
+-- 
+2.20.1
+
diff --git a/queue-4.19/net-rmnet-use-upper-lower-device-infrastructure.patch b/queue-4.19/net-rmnet-use-upper-lower-device-infrastructure.patch
new file mode 100644 (file)
index 0000000..f69c27c
--- /dev/null
@@ -0,0 +1,199 @@
+From 48ee5debae87fcf50660c50f794fabd54182c4c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Feb 2020 12:25:43 +0000
+Subject: net: rmnet: use upper/lower device infrastructure
+
+From: Taehee Yoo <ap420073@gmail.com>
+
+[ Upstream commit 037f9cdf72fb8a7ff9ec2b5dd05336ec1492bdf1 ]
+
+netdev_upper_dev_link() is useful to manage lower/upper interfaces.
+And this function internally validates looping, maximum depth.
+All or most virtual interfaces that could have a real interface
+(e.g. macsec, macvlan, ipvlan etc.) use lower/upper infrastructure.
+
+Test commands:
+    modprobe rmnet
+    ip link add dummy0 type dummy
+    ip link add rmnet1 link dummy0 type rmnet mux_id 1
+    for i in {2..100}
+    do
+        let A=$i-1
+        ip link add rmnet$i link rmnet$A type rmnet mux_id $i
+    done
+    ip link del dummy0
+
+The purpose of the test commands is to make stack overflow.
+
+Splat looks like:
+[   52.411438][ T1395] BUG: KASAN: slab-out-of-bounds in find_busiest_group+0x27e/0x2c00
+[   52.413218][ T1395] Write of size 64 at addr ffff8880c774bde0 by task ip/1395
+[   52.414841][ T1395]
+[   52.430720][ T1395] CPU: 1 PID: 1395 Comm: ip Not tainted 5.6.0-rc1+ #447
+[   52.496511][ T1395] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
+[   52.513597][ T1395] Call Trace:
+[   52.546516][ T1395]
+[   52.558773][ T1395] Allocated by task 3171537984:
+[   52.588290][ T1395] BUG: unable to handle page fault for address: ffffffffb999e260
+[   52.589311][ T1395] #PF: supervisor read access in kernel mode
+[   52.590529][ T1395] #PF: error_code(0x0000) - not-present page
+[   52.591374][ T1395] PGD d6818067 P4D d6818067 PUD d6819063 PMD 0
+[   52.592288][ T1395] Thread overran stack, or stack corrupted
+[   52.604980][ T1395] Oops: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN PTI
+[   52.605856][ T1395] CPU: 1 PID: 1395 Comm: ip Not tainted 5.6.0-rc1+ #447
+[   52.611764][ T1395] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
+[   52.621520][ T1395] RIP: 0010:stack_depot_fetch+0x10/0x30
+[   52.622296][ T1395] Code: ff e9 f9 fe ff ff 48 89 df e8 9c 1d 91 ff e9 ca fe ff ff cc cc cc cc cc cc cc 89 f8 0
+[   52.627887][ T1395] RSP: 0018:ffff8880c774bb60 EFLAGS: 00010006
+[   52.628735][ T1395] RAX: 00000000001f8880 RBX: ffff8880c774d140 RCX: 0000000000000000
+[   52.631773][ T1395] RDX: 000000000000001d RSI: ffff8880c774bb68 RDI: 0000000000003ff0
+[   52.649584][ T1395] RBP: ffffea00031dd200 R08: ffffed101b43e403 R09: ffffed101b43e403
+[   52.674857][ T1395] R10: 0000000000000001 R11: ffffed101b43e402 R12: ffff8880d900e5c0
+[   52.678257][ T1395] R13: ffff8880c774c000 R14: 0000000000000000 R15: dffffc0000000000
+[   52.694541][ T1395] FS:  00007fe867f6e0c0(0000) GS:ffff8880da000000(0000) knlGS:0000000000000000
+[   52.764039][ T1395] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[   52.815008][ T1395] CR2: ffffffffb999e260 CR3: 00000000c26aa005 CR4: 00000000000606e0
+[   52.862312][ T1395] Call Trace:
+[   52.887133][ T1395] Modules linked in: dummy rmnet veth openvswitch nsh nf_conncount nf_nat nf_conntrack nf_dex
+[   52.936749][ T1395] CR2: ffffffffb999e260
+[   52.965695][ T1395] ---[ end trace 7e32ca99482dbb31 ]---
+[   52.966556][ T1395] RIP: 0010:stack_depot_fetch+0x10/0x30
+[   52.971083][ T1395] Code: ff e9 f9 fe ff ff 48 89 df e8 9c 1d 91 ff e9 ca fe ff ff cc cc cc cc cc cc cc 89 f8 0
+[   53.003650][ T1395] RSP: 0018:ffff8880c774bb60 EFLAGS: 00010006
+[   53.043183][ T1395] RAX: 00000000001f8880 RBX: ffff8880c774d140 RCX: 0000000000000000
+[   53.076480][ T1395] RDX: 000000000000001d RSI: ffff8880c774bb68 RDI: 0000000000003ff0
+[   53.093858][ T1395] RBP: ffffea00031dd200 R08: ffffed101b43e403 R09: ffffed101b43e403
+[   53.112795][ T1395] R10: 0000000000000001 R11: ffffed101b43e402 R12: ffff8880d900e5c0
+[   53.139837][ T1395] R13: ffff8880c774c000 R14: 0000000000000000 R15: dffffc0000000000
+[   53.141500][ T1395] FS:  00007fe867f6e0c0(0000) GS:ffff8880da000000(0000) knlGS:0000000000000000
+[   53.143343][ T1395] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[   53.152007][ T1395] CR2: ffffffffb999e260 CR3: 00000000c26aa005 CR4: 00000000000606e0
+[   53.156459][ T1395] Kernel panic - not syncing: Fatal exception
+[   54.213570][ T1395] Shutting down cpus with NMI
+[   54.354112][ T1395] Kernel Offset: 0x33000000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0x)
+[   54.355687][ T1395] Rebooting in 5 seconds..
+
+Fixes: b37f78f234bf ("net: qualcomm: rmnet: Fix crash on real dev unregistration")
+Signed-off-by: Taehee Yoo <ap420073@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/qualcomm/rmnet/rmnet_config.c    | 35 +++++++++----------
+ 1 file changed, 16 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
+index 272a08f521e11..01a1d3ff3c944 100644
+--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
+@@ -70,9 +70,6 @@ static int rmnet_unregister_real_device(struct net_device *real_dev,
+       kfree(port);
+-      /* release reference on real_dev */
+-      dev_put(real_dev);
+-
+       netdev_dbg(real_dev, "Removed from rmnet\n");
+       return 0;
+ }
+@@ -98,9 +95,6 @@ static int rmnet_register_real_device(struct net_device *real_dev)
+               return -EBUSY;
+       }
+-      /* hold on to real dev for MAP data */
+-      dev_hold(real_dev);
+-
+       for (entry = 0; entry < RMNET_MAX_LOGICAL_EP; entry++)
+               INIT_HLIST_HEAD(&port->muxed_ep[entry]);
+@@ -171,6 +165,10 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
+       if (err)
+               goto err1;
++      err = netdev_upper_dev_link(real_dev, dev, extack);
++      if (err < 0)
++              goto err2;
++
+       port->rmnet_mode = mode;
+       hlist_add_head_rcu(&ep->hlnode, &port->muxed_ep[mux_id]);
+@@ -187,6 +185,8 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
+       return 0;
++err2:
++      unregister_netdevice(dev);
+ err1:
+       rmnet_unregister_real_device(real_dev, port);
+ err0:
+@@ -218,33 +218,30 @@ static void rmnet_dellink(struct net_device *dev, struct list_head *head)
+               rmnet_vnd_dellink(mux_id, port, ep);
+               kfree(ep);
+       }
++      netdev_upper_dev_unlink(real_dev, dev);
+       rmnet_unregister_real_device(real_dev, port);
+       unregister_netdevice_queue(dev, head);
+ }
+-static void rmnet_force_unassociate_device(struct net_device *dev)
++static void rmnet_force_unassociate_device(struct net_device *real_dev)
+ {
+-      struct net_device *real_dev = dev;
+       struct hlist_node *tmp_ep;
+       struct rmnet_endpoint *ep;
+       struct rmnet_port *port;
+       unsigned long bkt_ep;
+       LIST_HEAD(list);
+-      if (!rmnet_is_real_dev_registered(real_dev))
+-              return;
+-
+       ASSERT_RTNL();
+-      port = rmnet_get_port_rtnl(dev);
++      port = rmnet_get_port_rtnl(real_dev);
+-      rmnet_unregister_bridge(dev, port);
++      rmnet_unregister_bridge(real_dev, port);
+       hash_for_each_safe(port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) {
++              netdev_upper_dev_unlink(real_dev, ep->egress_dev);
+               unregister_netdevice_queue(ep->egress_dev, &list);
+               rmnet_vnd_dellink(ep->mux_id, port, ep);
+-
+               hlist_del_init_rcu(&ep->hlnode);
+               kfree(ep);
+       }
+@@ -257,15 +254,15 @@ static void rmnet_force_unassociate_device(struct net_device *dev)
+ static int rmnet_config_notify_cb(struct notifier_block *nb,
+                                 unsigned long event, void *data)
+ {
+-      struct net_device *dev = netdev_notifier_info_to_dev(data);
++      struct net_device *real_dev = netdev_notifier_info_to_dev(data);
+-      if (!dev)
++      if (!rmnet_is_real_dev_registered(real_dev))
+               return NOTIFY_DONE;
+       switch (event) {
+       case NETDEV_UNREGISTER:
+-              netdev_dbg(dev, "Kernel unregister\n");
+-              rmnet_force_unassociate_device(dev);
++              netdev_dbg(real_dev, "Kernel unregister\n");
++              rmnet_force_unassociate_device(real_dev);
+               break;
+       default:
+@@ -486,8 +483,8 @@ static int __init rmnet_init(void)
+ static void __exit rmnet_exit(void)
+ {
+-      unregister_netdevice_notifier(&rmnet_dev_notifier);
+       rtnl_link_unregister(&rmnet_link_ops);
++      unregister_netdevice_notifier(&rmnet_dev_notifier);
+ }
+ module_init(rmnet_init)
+-- 
+2.20.1
+
diff --git a/queue-4.19/net-usb-qmi_wwan-restore-mtu-min-max-values-after-ra.patch b/queue-4.19/net-usb-qmi_wwan-restore-mtu-min-max-values-after-ra.patch
new file mode 100644 (file)
index 0000000..54cfea3
--- /dev/null
@@ -0,0 +1,51 @@
+From fb7b59259996de022105991bfdfa3d3cadb9771b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Feb 2020 14:17:05 +0100
+Subject: net: usb: qmi_wwan: restore mtu min/max values after raw_ip switch
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Daniele Palmas <dnlplm@gmail.com>
+
+[ Upstream commit eae7172f8141eb98e64e6e81acc9e9d5b2add127 ]
+
+usbnet creates network interfaces with min_mtu = 0 and
+max_mtu = ETH_MAX_MTU.
+
+These values are not modified by qmi_wwan when the network interface
+is created initially, allowing, for example, to set mtu greater than 1500.
+
+When a raw_ip switch is done (raw_ip set to 'Y', then set to 'N') the mtu
+values for the network interface are set through ether_setup, with
+min_mtu = ETH_MIN_MTU and max_mtu = ETH_DATA_LEN, not allowing anymore to
+set mtu greater than 1500 (error: mtu greater than device maximum).
+
+The patch restores the original min/max mtu values set by usbnet after a
+raw_ip switch.
+
+Signed-off-by: Daniele Palmas <dnlplm@gmail.com>
+Acked-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/qmi_wwan.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
+index a04f8577d9f21..1d60ccd48ec29 100644
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -274,6 +274,9 @@ static void qmi_wwan_netdev_setup(struct net_device *net)
+               netdev_dbg(net, "mode: raw IP\n");
+       } else if (!net->header_ops) { /* don't bother if already set */
+               ether_setup(net);
++              /* Restoring min/max mtu values set originally by usbnet */
++              net->min_mtu = 0;
++              net->max_mtu = ETH_MAX_MTU;
+               clear_bit(EVENT_NO_IP_ALIGN, &dev->flags);
+               netdev_dbg(net, "mode: Ethernet\n");
+       }
+-- 
+2.20.1
+
diff --git a/queue-4.19/scsi-libfc-free-response-frame-from-gpn_id.patch b/queue-4.19/scsi-libfc-free-response-frame-from-gpn_id.patch
new file mode 100644 (file)
index 0000000..285889f
--- /dev/null
@@ -0,0 +1,37 @@
+From c1aee0bf491aece2df7997dd05a3d09dc2704502 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jan 2020 14:43:19 +0000
+Subject: scsi: libfc: free response frame from GPN_ID
+
+From: Igor Druzhinin <igor.druzhinin@citrix.com>
+
+[ Upstream commit ff6993bb79b9f99bdac0b5378169052931b65432 ]
+
+fc_disc_gpn_id_resp() should be the last function using it so free it here
+to avoid memory leak.
+
+Link: https://lore.kernel.org/r/1579013000-14570-2-git-send-email-igor.druzhinin@citrix.com
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/libfc/fc_disc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c
+index f969a71348ef1..8839f509b19ab 100644
+--- a/drivers/scsi/libfc/fc_disc.c
++++ b/drivers/scsi/libfc/fc_disc.c
+@@ -640,6 +640,8 @@ static void fc_disc_gpn_id_resp(struct fc_seq *sp, struct fc_frame *fp,
+       }
+ out:
+       kref_put(&rdata->kref, fc_rport_destroy);
++      if (!IS_ERR(fp))
++              fc_frame_free(fp);
+ }
+ /**
+-- 
+2.20.1
+
index 6e2bc206b154b03fcffbb3d5723edec2ec9d6734..99a90b52525edacfeade114de55904a444efe0c5 100644 (file)
@@ -7,3 +7,25 @@ mmc-sdhci-omap-fix-busy-detection-by-enabling-mmc_ca.patch
 mmc-core-respect-mmc_cap_need_rsp_busy-for-emmc-slee.patch
 mmc-core-respect-mmc_cap_need_rsp_busy-for-erase-tri.patch
 mmc-core-allow-host-controllers-to-require-r1b-for-c.patch
+acpi-watchdog-allow-disabling-wdat-at-boot.patch
+hid-apple-add-support-for-recent-firmware-on-magic-k.patch
+hid-i2c-hid-add-trekstor-surfbook-e11b-to-descriptor.patch
+cfg80211-check-reg_rule-for-null-in-handle_channel_c.patch
+scsi-libfc-free-response-frame-from-gpn_id.patch
+net-usb-qmi_wwan-restore-mtu-min-max-values-after-ra.patch
+net-ks8851-ml-fix-irq-handling-and-locking.patch
+mac80211-rx-avoid-rcu-list-traversal-under-mutex.patch
+signal-avoid-double-atomic-counter-increments-for-us.patch
+slip-not-call-free_netdev-before-rtnl_unlock-in-slip.patch
+hinic-fix-a-irq-affinity-bug.patch
+hinic-fix-a-bug-of-setting-hw_ioctxt.patch
+net-rmnet-fix-null-pointer-dereference-in-rmnet_newl.patch
+net-rmnet-fix-null-pointer-dereference-in-rmnet_chan.patch
+net-rmnet-fix-suspicious-rcu-usage.patch
+net-rmnet-remove-rcu_read_lock-in-rmnet_force_unasso.patch
+net-rmnet-do-not-allow-to-change-mux-id-if-mux-id-is.patch
+net-rmnet-use-upper-lower-device-infrastructure.patch
+net-rmnet-fix-bridge-mode-bugs.patch
+net-rmnet-fix-packet-forwarding-in-rmnet-bridge-mode.patch
+sfc-fix-timestamp-reconstruction-at-16-bit-rollover-.patch
+jbd2-fix-data-races-at-struct-journal_head.patch
diff --git a/queue-4.19/sfc-fix-timestamp-reconstruction-at-16-bit-rollover-.patch b/queue-4.19/sfc-fix-timestamp-reconstruction-at-16-bit-rollover-.patch
new file mode 100644 (file)
index 0000000..a535d5a
--- /dev/null
@@ -0,0 +1,81 @@
+From 0f92057263e2a25b806bcd414b700f310257d7d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Feb 2020 17:33:19 +0000
+Subject: sfc: fix timestamp reconstruction at 16-bit rollover points
+
+From: Alex Maftei (amaftei) <amaftei@solarflare.com>
+
+[ Upstream commit 23797b98909f34b75fd130369bde86f760db69d0 ]
+
+We can't just use the top bits of the last sync event as they could be
+off-by-one every 65,536 seconds, giving an error in reconstruction of
+65,536 seconds.
+
+This patch uses the difference in the bottom 16 bits (mod 2^16) to
+calculate an offset that needs to be applied to the last sync event to
+get to the current time.
+
+Signed-off-by: Alexandru-Mihai Maftei <amaftei@solarflare.com>
+Acked-by: Martin Habets <mhabets@solarflare.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/sfc/ptp.c | 38 +++++++++++++++++++++++++++++++---
+ 1 file changed, 35 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c
+index cc8fbf398c0d7..d47151dbe804d 100644
+--- a/drivers/net/ethernet/sfc/ptp.c
++++ b/drivers/net/ethernet/sfc/ptp.c
+@@ -563,13 +563,45 @@ efx_ptp_mac_nic_to_ktime_correction(struct efx_nic *efx,
+                                   u32 nic_major, u32 nic_minor,
+                                   s32 correction)
+ {
++      u32 sync_timestamp;
+       ktime_t kt = { 0 };
++      s16 delta;
+       if (!(nic_major & 0x80000000)) {
+               WARN_ON_ONCE(nic_major >> 16);
+-              /* Use the top bits from the latest sync event. */
+-              nic_major &= 0xffff;
+-              nic_major |= (last_sync_timestamp_major(efx) & 0xffff0000);
++
++              /* Medford provides 48 bits of timestamp, so we must get the top
++               * 16 bits from the timesync event state.
++               *
++               * We only have the lower 16 bits of the time now, but we do
++               * have a full resolution timestamp at some point in past. As
++               * long as the difference between the (real) now and the sync
++               * is less than 2^15, then we can reconstruct the difference
++               * between those two numbers using only the lower 16 bits of
++               * each.
++               *
++               * Put another way
++               *
++               * a - b = ((a mod k) - b) mod k
++               *
++               * when -k/2 < (a-b) < k/2. In our case k is 2^16. We know
++               * (a mod k) and b, so can calculate the delta, a - b.
++               *
++               */
++              sync_timestamp = last_sync_timestamp_major(efx);
++
++              /* Because delta is s16 this does an implicit mask down to
++               * 16 bits which is what we need, assuming
++               * MEDFORD_TX_SECS_EVENT_BITS is 16. delta is signed so that
++               * we can deal with the (unlikely) case of sync timestamps
++               * arriving from the future.
++               */
++              delta = nic_major - sync_timestamp;
++
++              /* Recover the fully specified time now, by applying the offset
++               * to the (fully specified) sync time.
++               */
++              nic_major = sync_timestamp + delta;
+               kt = ptp->nic_to_kernel_time(nic_major, nic_minor,
+                                            correction);
+-- 
+2.20.1
+
diff --git a/queue-4.19/signal-avoid-double-atomic-counter-increments-for-us.patch b/queue-4.19/signal-avoid-double-atomic-counter-increments-for-us.patch
new file mode 100644 (file)
index 0000000..9fc318a
--- /dev/null
@@ -0,0 +1,125 @@
+From 3a38128ebe8f369fc952a98c1106e24a63268afe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2020 12:47:14 -0800
+Subject: signal: avoid double atomic counter increments for user accounting
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+[ Upstream commit fda31c50292a5062332fa0343c084bd9f46604d9 ]
+
+When queueing a signal, we increment both the users count of pending
+signals (for RLIMIT_SIGPENDING tracking) and we increment the refcount
+of the user struct itself (because we keep a reference to the user in
+the signal structure in order to correctly account for it when freeing).
+
+That turns out to be fairly expensive, because both of them are atomic
+updates, and particularly under extreme signal handling pressure on big
+machines, you can get a lot of cache contention on the user struct.
+That can then cause horrid cacheline ping-pong when you do these
+multiple accesses.
+
+So change the reference counting to only pin the user for the _first_
+pending signal, and to unpin it when the last pending signal is
+dequeued.  That means that when a user sees a lot of concurrent signal
+queuing - which is the only situation when this matters - the only
+atomic access needed is generally the 'sigpending' count update.
+
+This was noticed because of a particularly odd timing artifact on a
+dual-socket 96C/192T Cascade Lake platform: when you get into bad
+contention, on that machine for some reason seems to be much worse when
+the contention happens in the upper 32-byte half of the cacheline.
+
+As a result, the kernel test robot will-it-scale 'signal1' benchmark had
+an odd performance regression simply due to random alignment of the
+'struct user_struct' (and pointed to a completely unrelated and
+apparently nonsensical commit for the regression).
+
+Avoiding the double increments (and decrements on the dequeueing side,
+of course) makes for much less contention and hugely improved
+performance on that will-it-scale microbenchmark.
+
+Quoting Feng Tang:
+
+ "It makes a big difference, that the performance score is tripled! bump
+  from original 17000 to 54000. Also the gap between 5.0-rc6 and
+  5.0-rc6+Jiri's patch is reduced to around 2%"
+
+[ The "2% gap" is the odd cacheline placement difference on that
+  platform: under the extreme contention case, the effect of which half
+  of the cacheline was hot was 5%, so with the reduced contention the
+  odd timing artifact is reduced too ]
+
+It does help in the non-contended case too, but is not nearly as
+noticeable.
+
+Reported-and-tested-by: Feng Tang <feng.tang@intel.com>
+Cc: Eric W. Biederman <ebiederm@xmission.com>
+Cc: Huang, Ying <ying.huang@intel.com>
+Cc: Philip Li <philip.li@intel.com>
+Cc: Andi Kleen <andi.kleen@intel.com>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/signal.c | 23 ++++++++++++++---------
+ 1 file changed, 14 insertions(+), 9 deletions(-)
+
+diff --git a/kernel/signal.c b/kernel/signal.c
+index 08911bb6fe9ab..c42eaf39b5729 100644
+--- a/kernel/signal.c
++++ b/kernel/signal.c
+@@ -407,27 +407,32 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi
+ {
+       struct sigqueue *q = NULL;
+       struct user_struct *user;
++      int sigpending;
+       /*
+        * Protect access to @t credentials. This can go away when all
+        * callers hold rcu read lock.
++       *
++       * NOTE! A pending signal will hold on to the user refcount,
++       * and we get/put the refcount only when the sigpending count
++       * changes from/to zero.
+        */
+       rcu_read_lock();
+-      user = get_uid(__task_cred(t)->user);
+-      atomic_inc(&user->sigpending);
++      user = __task_cred(t)->user;
++      sigpending = atomic_inc_return(&user->sigpending);
++      if (sigpending == 1)
++              get_uid(user);
+       rcu_read_unlock();
+-      if (override_rlimit ||
+-          atomic_read(&user->sigpending) <=
+-                      task_rlimit(t, RLIMIT_SIGPENDING)) {
++      if (override_rlimit || likely(sigpending <= task_rlimit(t, RLIMIT_SIGPENDING))) {
+               q = kmem_cache_alloc(sigqueue_cachep, flags);
+       } else {
+               print_dropped_signal(sig);
+       }
+       if (unlikely(q == NULL)) {
+-              atomic_dec(&user->sigpending);
+-              free_uid(user);
++              if (atomic_dec_and_test(&user->sigpending))
++                      free_uid(user);
+       } else {
+               INIT_LIST_HEAD(&q->list);
+               q->flags = 0;
+@@ -441,8 +446,8 @@ static void __sigqueue_free(struct sigqueue *q)
+ {
+       if (q->flags & SIGQUEUE_PREALLOC)
+               return;
+-      atomic_dec(&q->user->sigpending);
+-      free_uid(q->user);
++      if (atomic_dec_and_test(&q->user->sigpending))
++              free_uid(q->user);
+       kmem_cache_free(sigqueue_cachep, q);
+ }
+-- 
+2.20.1
+
diff --git a/queue-4.19/slip-not-call-free_netdev-before-rtnl_unlock-in-slip.patch b/queue-4.19/slip-not-call-free_netdev-before-rtnl_unlock-in-slip.patch
new file mode 100644 (file)
index 0000000..ec112be
--- /dev/null
@@ -0,0 +1,38 @@
+From e171a0cf51fda436c0b15893903ede1dd74cb2de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Feb 2020 11:54:35 +0800
+Subject: slip: not call free_netdev before rtnl_unlock in slip_open
+
+From: yangerkun <yangerkun@huawei.com>
+
+[ Upstream commit f596c87005f7b1baeb7d62d9a9e25d68c3dfae10 ]
+
+As the description before netdev_run_todo, we cannot call free_netdev
+before rtnl_unlock, fix it by reorder the code.
+
+Signed-off-by: yangerkun <yangerkun@huawei.com>
+Reviewed-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/slip/slip.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c
+index 93f303ec17e21..5d864f8129556 100644
+--- a/drivers/net/slip/slip.c
++++ b/drivers/net/slip/slip.c
+@@ -863,7 +863,10 @@ static int slip_open(struct tty_struct *tty)
+       tty->disc_data = NULL;
+       clear_bit(SLF_INUSE, &sl->flags);
+       sl_free_netdev(sl->dev);
++      /* do not call free_netdev before rtnl_unlock */
++      rtnl_unlock();
+       free_netdev(sl->dev);
++      return err;
+ err_exit:
+       rtnl_unlock();
+-- 
+2.20.1
+