]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 1 Aug 2023 05:57:41 +0000 (07:57 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 1 Aug 2023 05:57:41 +0000 (07:57 +0200)
added patches:
net-dsa-qca8k-fix-broken-search_and_del.patch
net-dsa-qca8k-fix-mdb-add-del-case-with-0-vid.patch
net-dsa-qca8k-fix-search_and_insert-wrong-handling-of-new-rule.patch
proc-vmcore-fix-signedness-bug-in-read_from_oldmem.patch
virtio-net-fix-race-between-set-queues-and-probe.patch
xen-speed-up-grant-table-reclaim.patch

queue-6.1/net-dsa-qca8k-fix-broken-search_and_del.patch [new file with mode: 0644]
queue-6.1/net-dsa-qca8k-fix-mdb-add-del-case-with-0-vid.patch [new file with mode: 0644]
queue-6.1/net-dsa-qca8k-fix-search_and_insert-wrong-handling-of-new-rule.patch [new file with mode: 0644]
queue-6.1/proc-vmcore-fix-signedness-bug-in-read_from_oldmem.patch [new file with mode: 0644]
queue-6.1/series
queue-6.1/virtio-net-fix-race-between-set-queues-and-probe.patch [new file with mode: 0644]
queue-6.1/xen-speed-up-grant-table-reclaim.patch [new file with mode: 0644]

diff --git a/queue-6.1/net-dsa-qca8k-fix-broken-search_and_del.patch b/queue-6.1/net-dsa-qca8k-fix-broken-search_and_del.patch
new file mode 100644 (file)
index 0000000..75381f4
--- /dev/null
@@ -0,0 +1,44 @@
+From ae70dcb9d9ecaf7d9836d3e1b5bef654d7ef5680 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Mon, 24 Jul 2023 05:25:30 +0200
+Subject: net: dsa: qca8k: fix broken search_and_del
+
+From: Christian Marangi <ansuelsmth@gmail.com>
+
+commit ae70dcb9d9ecaf7d9836d3e1b5bef654d7ef5680 upstream.
+
+On deleting an MDB entry for a port, fdb_search_and_del is used.
+An FDB entry can't be modified so it needs to be deleted and readded
+again with the new portmap (and the port deleted as requested)
+
+We use the SEARCH operator to search the entry to edit by vid and mac
+address and then we check the aging if we actually found an entry.
+
+Currently the code suffer from a bug where the searched fdb entry is
+never read again with the found values (if found) resulting in the code
+always returning -EINVAL as aging was always 0.
+
+Fix this by correctly read the fdb entry after it was searched.
+
+Fixes: ba8f870dfa63 ("net: dsa: qca8k: add support for mdb_add/del")
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/dsa/qca/qca8k-common.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/net/dsa/qca/qca8k-common.c
++++ b/drivers/net/dsa/qca/qca8k-common.c
+@@ -330,6 +330,10 @@ static int qca8k_fdb_search_and_del(stru
+       if (ret < 0)
+               goto exit;
++      ret = qca8k_fdb_read(priv, &fdb);
++      if (ret < 0)
++              goto exit;
++
+       /* Rule doesn't exist. Why delete? */
+       if (!fdb.aging) {
+               ret = -EINVAL;
diff --git a/queue-6.1/net-dsa-qca8k-fix-mdb-add-del-case-with-0-vid.patch b/queue-6.1/net-dsa-qca8k-fix-mdb-add-del-case-with-0-vid.patch
new file mode 100644 (file)
index 0000000..5e5e4cf
--- /dev/null
@@ -0,0 +1,47 @@
+From dfd739f182b00b02bd7470ed94d112684cc04fa2 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Mon, 24 Jul 2023 05:25:31 +0200
+Subject: net: dsa: qca8k: fix mdb add/del case with 0 VID
+
+From: Christian Marangi <ansuelsmth@gmail.com>
+
+commit dfd739f182b00b02bd7470ed94d112684cc04fa2 upstream.
+
+The qca8k switch doesn't support using 0 as VID and require a default
+VID to be always set. MDB add/del function doesn't currently handle
+this and are currently setting the default VID.
+
+Fix this by correctly handling this corner case and internally use the
+default VID for VID 0 case.
+
+Fixes: ba8f870dfa63 ("net: dsa: qca8k: add support for mdb_add/del")
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/dsa/qca/qca8k-common.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/net/dsa/qca/qca8k-common.c
++++ b/drivers/net/dsa/qca/qca8k-common.c
+@@ -853,6 +853,9 @@ int qca8k_port_mdb_add(struct dsa_switch
+       const u8 *addr = mdb->addr;
+       u16 vid = mdb->vid;
++      if (!vid)
++              vid = QCA8K_PORT_VID_DEF;
++
+       return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid,
+                                          QCA8K_ATU_STATUS_STATIC);
+ }
+@@ -865,6 +868,9 @@ int qca8k_port_mdb_del(struct dsa_switch
+       const u8 *addr = mdb->addr;
+       u16 vid = mdb->vid;
++      if (!vid)
++              vid = QCA8K_PORT_VID_DEF;
++
+       return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid);
+ }
diff --git a/queue-6.1/net-dsa-qca8k-fix-search_and_insert-wrong-handling-of-new-rule.patch b/queue-6.1/net-dsa-qca8k-fix-search_and_insert-wrong-handling-of-new-rule.patch
new file mode 100644 (file)
index 0000000..1f22bef
--- /dev/null
@@ -0,0 +1,73 @@
+From 80248d4160894d7e40b04111bdbaa4ff93fc4bd7 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Mon, 24 Jul 2023 05:25:29 +0200
+Subject: net: dsa: qca8k: fix search_and_insert wrong handling of new rule
+
+From: Christian Marangi <ansuelsmth@gmail.com>
+
+commit 80248d4160894d7e40b04111bdbaa4ff93fc4bd7 upstream.
+
+On inserting a mdb entry, fdb_search_and_insert is used to add a port to
+the qca8k target entry in the FDB db.
+
+A FDB entry can't be modified so it needs to be removed and insert again
+with the new values.
+
+To detect if an entry already exist, the SEARCH operation is used and we
+check the aging of the entry. If the entry is not 0, the entry exist and
+we proceed to delete it.
+
+Current code have 2 main problem:
+- The condition to check if the FDB entry exist is wrong and should be
+  the opposite.
+- When a FDB entry doesn't exist, aging was never actually set to the
+  STATIC value resulting in allocating an invalid entry.
+
+Fix both problem by adding aging support to the function, calling the
+function with STATIC as aging by default and finally by correct the
+condition to check if the entry actually exist.
+
+Fixes: ba8f870dfa63 ("net: dsa: qca8k: add support for mdb_add/del")
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/dsa/qca/qca8k-common.c |    9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/dsa/qca/qca8k-common.c
++++ b/drivers/net/dsa/qca/qca8k-common.c
+@@ -281,7 +281,7 @@ void qca8k_fdb_flush(struct qca8k_priv *
+ }
+ static int qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask,
+-                                     const u8 *mac, u16 vid)
++                                     const u8 *mac, u16 vid, u8 aging)
+ {
+       struct qca8k_fdb fdb = { 0 };
+       int ret;
+@@ -298,10 +298,12 @@ static int qca8k_fdb_search_and_insert(s
+               goto exit;
+       /* Rule exist. Delete first */
+-      if (!fdb.aging) {
++      if (fdb.aging) {
+               ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
+               if (ret)
+                       goto exit;
++      } else {
++              fdb.aging = aging;
+       }
+       /* Add port to fdb portmask */
+@@ -847,7 +849,8 @@ int qca8k_port_mdb_add(struct dsa_switch
+       const u8 *addr = mdb->addr;
+       u16 vid = mdb->vid;
+-      return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid);
++      return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid,
++                                         QCA8K_ATU_STATUS_STATIC);
+ }
+ int qca8k_port_mdb_del(struct dsa_switch *ds, int port,
diff --git a/queue-6.1/proc-vmcore-fix-signedness-bug-in-read_from_oldmem.patch b/queue-6.1/proc-vmcore-fix-signedness-bug-in-read_from_oldmem.patch
new file mode 100644 (file)
index 0000000..96e8685
--- /dev/null
@@ -0,0 +1,45 @@
+From 641db40f3afe7998011bfabc726dba3e698f8196 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@linaro.org>
+Date: Tue, 25 Jul 2023 20:03:16 +0300
+Subject: proc/vmcore: fix signedness bug in read_from_oldmem()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+commit 641db40f3afe7998011bfabc726dba3e698f8196 upstream.
+
+The bug is the error handling:
+
+       if (tmp < nr_bytes) {
+
+"tmp" can hold negative error codes but because "nr_bytes" is type size_t
+the negative error codes are treated as very high positive values
+(success).  Fix this by changing "nr_bytes" to type ssize_t.  The
+"nr_bytes" variable is used to store values between 1 and PAGE_SIZE and
+they can fit in ssize_t without any issue.
+
+Link: https://lkml.kernel.org/r/b55f7eed-1c65-4adc-95d1-6c7c65a54a6e@moroto.mountain
+Fixes: 5d8de293c224 ("vmcore: convert copy_oldmem_page() to take an iov_iter")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Matthew Wilcox (Oracle) <willy@infradead.org>
+Acked-by: Baoquan He <bhe@redhat.com>
+Cc: Dave Young <dyoung@redhat.com>
+Cc: Vivek Goyal <vgoyal@redhat.com>
+Cc: Alexey Dobriyan <adobriyan@gmail.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/proc/vmcore.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/proc/vmcore.c
++++ b/fs/proc/vmcore.c
+@@ -132,7 +132,7 @@ ssize_t read_from_oldmem(struct iov_iter
+                        u64 *ppos, bool encrypted)
+ {
+       unsigned long pfn, offset;
+-      size_t nr_bytes;
++      ssize_t nr_bytes;
+       ssize_t read = 0, tmp;
+       int idx;
index 75055ca5f4fbbab7a3bd563eee9f87bfd6d7735c..8582101dcd589458f7bd5aad72832e422d8e1003 100644 (file)
@@ -191,3 +191,9 @@ tpm_tis-explicitly-check-for-error-code.patch
 irq-bcm6345-l1-do-not-assume-a-fixed-block-to-cpu-ma.patch
 irqchip-gic-v4.1-properly-lock-vpes-when-doing-a-dir.patch
 locking-rtmutex-fix-task-pi_waiters-integrity.patch
+proc-vmcore-fix-signedness-bug-in-read_from_oldmem.patch
+xen-speed-up-grant-table-reclaim.patch
+virtio-net-fix-race-between-set-queues-and-probe.patch
+net-dsa-qca8k-fix-search_and_insert-wrong-handling-of-new-rule.patch
+net-dsa-qca8k-fix-broken-search_and_del.patch
+net-dsa-qca8k-fix-mdb-add-del-case-with-0-vid.patch
diff --git a/queue-6.1/virtio-net-fix-race-between-set-queues-and-probe.patch b/queue-6.1/virtio-net-fix-race-between-set-queues-and-probe.patch
new file mode 100644 (file)
index 0000000..28629c7
--- /dev/null
@@ -0,0 +1,47 @@
+From 25266128fe16d5632d43ada34c847d7b8daba539 Mon Sep 17 00:00:00 2001
+From: Jason Wang <jasowang@redhat.com>
+Date: Tue, 25 Jul 2023 03:20:49 -0400
+Subject: virtio-net: fix race between set queues and probe
+
+From: Jason Wang <jasowang@redhat.com>
+
+commit 25266128fe16d5632d43ada34c847d7b8daba539 upstream.
+
+A race were found where set_channels could be called after registering
+but before virtnet_set_queues() in virtnet_probe(). Fixing this by
+moving the virtnet_set_queues() before netdevice registering. While at
+it, use _virtnet_set_queues() to avoid holding rtnl as the device is
+not even registered at that time.
+
+Cc: stable@vger.kernel.org
+Fixes: a220871be66f ("virtio-net: correctly enable multiqueue")
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
+Link: https://lore.kernel.org/r/20230725072049.617289-1-jasowang@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/virtio_net.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -3940,6 +3940,8 @@ static int virtnet_probe(struct virtio_d
+       if (vi->has_rss || vi->has_rss_hash_report)
+               virtnet_init_default_rss(vi);
++      _virtnet_set_queues(vi, vi->curr_queue_pairs);
++
+       /* serialize netdev register + virtio_device_ready() with ndo_open() */
+       rtnl_lock();
+@@ -3960,8 +3962,6 @@ static int virtnet_probe(struct virtio_d
+               goto free_unregister_netdev;
+       }
+-      virtnet_set_queues(vi, vi->curr_queue_pairs);
+-
+       /* Assume link up if device can't report link status,
+          otherwise get link status from config. */
+       netif_carrier_off(dev);
diff --git a/queue-6.1/xen-speed-up-grant-table-reclaim.patch b/queue-6.1/xen-speed-up-grant-table-reclaim.patch
new file mode 100644 (file)
index 0000000..356343a
--- /dev/null
@@ -0,0 +1,143 @@
+From c04e9894846c663f3278a414f34416e6e45bbe68 Mon Sep 17 00:00:00 2001
+From: Demi Marie Obenour <demi@invisiblethingslab.com>
+Date: Wed, 26 Jul 2023 12:52:41 -0400
+Subject: xen: speed up grant-table reclaim
+
+From: Demi Marie Obenour <demi@invisiblethingslab.com>
+
+commit c04e9894846c663f3278a414f34416e6e45bbe68 upstream.
+
+When a grant entry is still in use by the remote domain, Linux must put
+it on a deferred list.  Normally, this list is very short, because
+the PV network and block protocols expect the backend to unmap the grant
+first.  However, Qubes OS's GUI protocol is subject to the constraints
+of the X Window System, and as such winds up with the frontend unmapping
+the window first.  As a result, the list can grow very large, resulting
+in a massive memory leak and eventual VM freeze.
+
+To partially solve this problem, make the number of entries that the VM
+will attempt to free at each iteration tunable.  The default is still
+10, but it can be overridden via a module parameter.
+
+This is Cc: stable because (when combined with appropriate userspace
+changes) it fixes a severe performance and stability problem for Qubes
+OS users.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Demi Marie Obenour <demi@invisiblethingslab.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Link: https://lore.kernel.org/r/20230726165354.1252-1-demi@invisiblethingslab.com
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/ABI/testing/sysfs-module |   11 +++++++++
+ drivers/xen/grant-table.c              |   40 +++++++++++++++++++++++----------
+ 2 files changed, 40 insertions(+), 11 deletions(-)
+
+--- a/Documentation/ABI/testing/sysfs-module
++++ b/Documentation/ABI/testing/sysfs-module
+@@ -60,3 +60,14 @@ Description:        Module taint flags:
+                       C   staging driver module
+                       E   unsigned module
+                       ==  =====================
++
++What:         /sys/module/grant_table/parameters/free_per_iteration
++Date:         July 2023
++KernelVersion:        6.5 but backported to all supported stable branches
++Contact:      Xen developer discussion <xen-devel@lists.xenproject.org>
++Description:  Read and write number of grant entries to attempt to free per iteration.
++
++              Note: Future versions of Xen and Linux may provide a better
++              interface for controlling the rate of deferred grant reclaim
++              or may not need it at all.
++Users:                Qubes OS (https://www.qubes-os.org)
+--- a/drivers/xen/grant-table.c
++++ b/drivers/xen/grant-table.c
+@@ -498,14 +498,21 @@ static LIST_HEAD(deferred_list);
+ static void gnttab_handle_deferred(struct timer_list *);
+ static DEFINE_TIMER(deferred_timer, gnttab_handle_deferred);
++static atomic64_t deferred_count;
++static atomic64_t leaked_count;
++static unsigned int free_per_iteration = 10;
++module_param(free_per_iteration, uint, 0600);
++
+ static void gnttab_handle_deferred(struct timer_list *unused)
+ {
+-      unsigned int nr = 10;
++      unsigned int nr = READ_ONCE(free_per_iteration);
++      const bool ignore_limit = nr == 0;
+       struct deferred_entry *first = NULL;
+       unsigned long flags;
++      size_t freed = 0;
+       spin_lock_irqsave(&gnttab_list_lock, flags);
+-      while (nr--) {
++      while ((ignore_limit || nr--) && !list_empty(&deferred_list)) {
+               struct deferred_entry *entry
+                       = list_first_entry(&deferred_list,
+                                          struct deferred_entry, list);
+@@ -515,10 +522,14 @@ static void gnttab_handle_deferred(struc
+               list_del(&entry->list);
+               spin_unlock_irqrestore(&gnttab_list_lock, flags);
+               if (_gnttab_end_foreign_access_ref(entry->ref)) {
++                      uint64_t ret = atomic64_dec_return(&deferred_count);
++
+                       put_free_entry(entry->ref);
+-                      pr_debug("freeing g.e. %#x (pfn %#lx)\n",
+-                               entry->ref, page_to_pfn(entry->page));
++                      pr_debug("freeing g.e. %#x (pfn %#lx), %llu remaining\n",
++                               entry->ref, page_to_pfn(entry->page),
++                               (unsigned long long)ret);
+                       put_page(entry->page);
++                      freed++;
+                       kfree(entry);
+                       entry = NULL;
+               } else {
+@@ -530,21 +541,22 @@ static void gnttab_handle_deferred(struc
+               spin_lock_irqsave(&gnttab_list_lock, flags);
+               if (entry)
+                       list_add_tail(&entry->list, &deferred_list);
+-              else if (list_empty(&deferred_list))
+-                      break;
+       }
+-      if (!list_empty(&deferred_list) && !timer_pending(&deferred_timer)) {
++      if (list_empty(&deferred_list))
++              WARN_ON(atomic64_read(&deferred_count));
++      else if (!timer_pending(&deferred_timer)) {
+               deferred_timer.expires = jiffies + HZ;
+               add_timer(&deferred_timer);
+       }
+       spin_unlock_irqrestore(&gnttab_list_lock, flags);
++      pr_debug("Freed %zu references", freed);
+ }
+ static void gnttab_add_deferred(grant_ref_t ref, struct page *page)
+ {
+       struct deferred_entry *entry;
+       gfp_t gfp = (in_atomic() || irqs_disabled()) ? GFP_ATOMIC : GFP_KERNEL;
+-      const char *what = KERN_WARNING "leaking";
++      uint64_t leaked, deferred;
+       entry = kmalloc(sizeof(*entry), gfp);
+       if (!page) {
+@@ -567,10 +579,16 @@ static void gnttab_add_deferred(grant_re
+                       add_timer(&deferred_timer);
+               }
+               spin_unlock_irqrestore(&gnttab_list_lock, flags);
+-              what = KERN_DEBUG "deferring";
++              deferred = atomic64_inc_return(&deferred_count);
++              leaked = atomic64_read(&leaked_count);
++              pr_debug("deferring g.e. %#x (pfn %#lx) (total deferred %llu, total leaked %llu)\n",
++                       ref, page ? page_to_pfn(page) : -1, deferred, leaked);
++      } else {
++              deferred = atomic64_read(&deferred_count);
++              leaked = atomic64_inc_return(&leaked_count);
++              pr_warn("leaking g.e. %#x (pfn %#lx) (total deferred %llu, total leaked %llu)\n",
++                      ref, page ? page_to_pfn(page) : -1, deferred, leaked);
+       }
+-      printk("%s g.e. %#x (pfn %#lx)\n",
+-             what, ref, page ? page_to_pfn(page) : -1);
+ }
+ int gnttab_try_end_foreign_access(grant_ref_t ref)