From: Greg Kroah-Hartman Date: Tue, 1 Aug 2023 05:57:41 +0000 (+0200) Subject: 6.1-stable patches X-Git-Tag: v5.15.124~46 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=468c92a514f60f4d1a267094221051a8f7dc1ab1;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches 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 --- 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 index 00000000000..75381f407c9 --- /dev/null +++ b/queue-6.1/net-dsa-qca8k-fix-broken-search_and_del.patch @@ -0,0 +1,44 @@ +From ae70dcb9d9ecaf7d9836d3e1b5bef654d7ef5680 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 24 Jul 2023 05:25:30 +0200 +Subject: net: dsa: qca8k: fix broken search_and_del + +From: Christian Marangi + +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 +Cc: stable@vger.kernel.org +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..5e5e4cf1bc9 --- /dev/null +++ b/queue-6.1/net-dsa-qca8k-fix-mdb-add-del-case-with-0-vid.patch @@ -0,0 +1,47 @@ +From dfd739f182b00b02bd7470ed94d112684cc04fa2 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 24 Jul 2023 05:25:31 +0200 +Subject: net: dsa: qca8k: fix mdb add/del case with 0 VID + +From: Christian Marangi + +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 +Cc: stable@vger.kernel.org +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..1f22befe38d --- /dev/null +++ b/queue-6.1/net-dsa-qca8k-fix-search_and_insert-wrong-handling-of-new-rule.patch @@ -0,0 +1,73 @@ +From 80248d4160894d7e40b04111bdbaa4ff93fc4bd7 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +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 + +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 +Cc: stable@vger.kernel.org +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..96e8685e9c3 --- /dev/null +++ b/queue-6.1/proc-vmcore-fix-signedness-bug-in-read_from_oldmem.patch @@ -0,0 +1,45 @@ +From 641db40f3afe7998011bfabc726dba3e698f8196 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Tue, 25 Jul 2023 20:03:16 +0300 +Subject: proc/vmcore: fix signedness bug in read_from_oldmem() + +From: Dan Carpenter + +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 +Reviewed-by: Matthew Wilcox (Oracle) +Acked-by: Baoquan He +Cc: Dave Young +Cc: Vivek Goyal +Cc: Alexey Dobriyan +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + 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; + diff --git a/queue-6.1/series b/queue-6.1/series index 75055ca5f4f..8582101dcd5 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -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 index 00000000000..28629c7feb8 --- /dev/null +++ b/queue-6.1/virtio-net-fix-race-between-set-queues-and-probe.patch @@ -0,0 +1,47 @@ +From 25266128fe16d5632d43ada34c847d7b8daba539 Mon Sep 17 00:00:00 2001 +From: Jason Wang +Date: Tue, 25 Jul 2023 03:20:49 -0400 +Subject: virtio-net: fix race between set queues and probe + +From: Jason Wang + +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 +Acked-by: Michael S. Tsirkin +Reviewed-by: Xuan Zhuo +Link: https://lore.kernel.org/r/20230725072049.617289-1-jasowang@redhat.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..356343a1000 --- /dev/null +++ b/queue-6.1/xen-speed-up-grant-table-reclaim.patch @@ -0,0 +1,143 @@ +From c04e9894846c663f3278a414f34416e6e45bbe68 Mon Sep 17 00:00:00 2001 +From: Demi Marie Obenour +Date: Wed, 26 Jul 2023 12:52:41 -0400 +Subject: xen: speed up grant-table reclaim + +From: Demi Marie Obenour + +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 +Reviewed-by: Juergen Gross +Link: https://lore.kernel.org/r/20230726165354.1252-1-demi@invisiblethingslab.com +Signed-off-by: Juergen Gross +Signed-off-by: Greg Kroah-Hartman +--- + 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 ++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)