From f6338a922805871d7e3591b6e26e26026659c03b Mon Sep 17 00:00:00 2001 From: Kernel Build Daemon Date: May 25 2023 05:36:14 +0000 Subject: Merge branch 'SLE15-SP4' into SLE15-SP4-AZURE --- diff --git a/blacklist.conf b/blacklist.conf index 6bbd4c8..10d5cb4 100644 --- a/blacklist.conf +++ b/blacklist.conf @@ -817,3 +817,5 @@ f81fead027ecbb525c29d681eb95a222e76306a3 # correction in a comment only 2355370cd941cbb20882cc3f34460f9f2b8f9a18 # already have it as part of a different commit 7fce8d6eccbc31a561d07c79f359ad09f0424347 # already have it as part of a different commit 9dba4d24cbb5524dd39ab1e08886373b17f07ff2 # breaks KABI +d43b020b0f82c088ef8ff3196ef00575a97d200e # bug introduced by 4831967640916 not present +838d6d3461db0fdbf33fc5f8a69c27b50b4a46da # breaks KABI diff --git a/patches.kabi/mt76_poll_msec-kabi-workaround.patch b/patches.kabi/mt76_poll_msec-kabi-workaround.patch new file mode 100644 index 0000000..3fab074 --- /dev/null +++ b/patches.kabi/mt76_poll_msec-kabi-workaround.patch @@ -0,0 +1,31 @@ +From: Takashi Iwai +Subject: kABI workaround for mt76_poll_msec() +Patch-mainline: Never, kABI workaround +References: git-fixes + +Re-create a dummy function __mt76_poll_msec() and re-export for kABI +compatibility, which was converted to a macro in +wifi-mt76-add-flexible-polling-wait-interval-support.patch. + +Signed-off-by: Takashi Iwai + +--- + drivers/net/wireless/mediatek/mt76/util.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/net/wireless/mediatek/mt76/util.c ++++ b/drivers/net/wireless/mediatek/mt76/util.c +@@ -138,4 +138,13 @@ int __mt76_worker_fn(void *ptr) + } + EXPORT_SYMBOL_GPL(__mt76_worker_fn); + ++/* FIXME: re-added for SLE kABI compatibility */ ++#undef __mt76_poll_msec ++bool __mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, ++ int timeout) ++{ ++ return ____mt76_poll_msec(dev, offset, mask, val, timeout, 10); ++} ++EXPORT_SYMBOL_GPL(__mt76_poll_msec); ++ + MODULE_LICENSE("Dual BSD/GPL"); diff --git a/patches.suse/ACPI-bus-Ensure-that-notify-handlers-are-not-running.patch b/patches.suse/ACPI-bus-Ensure-that-notify-handlers-are-not-running.patch new file mode 100644 index 0000000..4469c51 --- /dev/null +++ b/patches.suse/ACPI-bus-Ensure-that-notify-handlers-are-not-running.patch @@ -0,0 +1,34 @@ +From faae443738c6f0dac9b0d3d11d108f6911a989a9 Mon Sep 17 00:00:00 2001 +From: "Rafael J. Wysocki" +Date: Fri, 14 Apr 2023 16:00:48 +0200 +Subject: [PATCH] ACPI: bus: Ensure that notify handlers are not running after removal +Git-commit: faae443738c6f0dac9b0d3d11d108f6911a989a9 +Patch-mainline: v6.4-rc1 +References: git-fixes + +Currently, acpi_device_remove_notify_handler() may return while the +notify handler being removed is still running which may allow the +module holding that handler to be torn down prematurely. + +Address this issue by making acpi_device_remove_notify_handler() wait +for the handling of all the ACPI events in progress to complete before +returning. + +Fixes: 5894b0c46e49 ("ACPI / scan: Move bus operations and notification routines to bus.c") +Signed-off-by: Rafael J. Wysocki +Acked-by: Takashi Iwai + +--- + drivers/acpi/bus.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/acpi/bus.c ++++ b/drivers/acpi/bus.c +@@ -572,6 +572,7 @@ static void acpi_device_remove_notify_ha + else + acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, + acpi_notify_device); ++ acpi_os_wait_events_complete(); + } + + /* Handle events targeting \_SB device (at present only graceful shutdown) */ diff --git a/patches.suse/ARM-9296-1-HP-Jornada-7XX-fix-kernel-doc-warnings.patch b/patches.suse/ARM-9296-1-HP-Jornada-7XX-fix-kernel-doc-warnings.patch new file mode 100644 index 0000000..af57f44 --- /dev/null +++ b/patches.suse/ARM-9296-1-HP-Jornada-7XX-fix-kernel-doc-warnings.patch @@ -0,0 +1,69 @@ +From 46dd6078dbc7e363a8bb01209da67015a1538929 Mon Sep 17 00:00:00 2001 +From: Randy Dunlap +Date: Sun, 23 Apr 2023 06:48:45 +0100 +Subject: [PATCH] ARM: 9296/1: HP Jornada 7XX: fix kernel-doc warnings +Git-commit: 46dd6078dbc7e363a8bb01209da67015a1538929 +Patch-mainline: v6.4-rc2 +References: git-fixes + +Fix kernel-doc warnings from the kernel test robot: + +jornada720_ssp.c:24: warning: Function parameter or member 'jornada_ssp_lock' not described in 'DEFINE_SPINLOCK' +jornada720_ssp.c:24: warning: expecting prototype for arch/arm/mac(). Prototype was for DEFINE_SPINLOCK() instead +jornada720_ssp.c:34: warning: Function parameter or member 'byte' not described in 'jornada_ssp_reverse' +jornada720_ssp.c:57: warning: Function parameter or member 'byte' not described in 'jornada_ssp_byte' +jornada720_ssp.c:85: warning: Function parameter or member 'byte' not described in 'jornada_ssp_inout' + +Link: lore.kernel.org/r/202304210535.tWby3jWF-lkp@intel.com + +Fixes: 69ebb22277a5 ("[ARM] 4506/1: HP Jornada 7XX: Addition of SSP Platform Driver") +Signed-off-by: Randy Dunlap +Reported-by: kernel test robot +Cc: Arnd Bergmann +Cc: Kristoffer Ericson +Cc: patches@armlinux.org.uk +Signed-off-by: Russell King (Oracle) +Acked-by: Takashi Iwai + +--- + arch/arm/mach-sa1100/jornada720_ssp.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/mach-sa1100/jornada720_ssp.c b/arch/arm/mach-sa1100/jornada720_ssp.c +index 1dbe98948ce3..9627c4cf3e41 100644 +--- a/arch/arm/mach-sa1100/jornada720_ssp.c ++++ b/arch/arm/mach-sa1100/jornada720_ssp.c +@@ -1,5 +1,5 @@ + // SPDX-License-Identifier: GPL-2.0-only +-/** ++/* + * arch/arm/mac-sa1100/jornada720_ssp.c + * + * Copyright (C) 2006/2007 Kristoffer Ericson +@@ -26,6 +26,7 @@ static unsigned long jornada_ssp_flags; + + /** + * jornada_ssp_reverse - reverses input byte ++ * @byte: input byte to reverse + * + * we need to reverse all data we receive from the mcu due to its physical location + * returns : 01110111 -> 11101110 +@@ -46,6 +47,7 @@ EXPORT_SYMBOL(jornada_ssp_reverse); + + /** + * jornada_ssp_byte - waits for ready ssp bus and sends byte ++ * @byte: input byte to transmit + * + * waits for fifo buffer to clear and then transmits, if it doesn't then we will + * timeout after rounds. Needs mcu running before its called. +@@ -77,6 +79,7 @@ EXPORT_SYMBOL(jornada_ssp_byte); + + /** + * jornada_ssp_inout - decide if input is command or trading byte ++ * @byte: input byte to send (may be %TXDUMMY) + * + * returns : (jornada_ssp_byte(byte)) on success + * : %-ETIMEDOUT on timeout failure +-- +2.35.3 + diff --git a/patches.suse/ASoC-fsl_micfil-Fix-error-handler-with-pm_runtime_en.patch b/patches.suse/ASoC-fsl_micfil-Fix-error-handler-with-pm_runtime_en.patch new file mode 100644 index 0000000..7355142 --- /dev/null +++ b/patches.suse/ASoC-fsl_micfil-Fix-error-handler-with-pm_runtime_en.patch @@ -0,0 +1,66 @@ +From 17955aba7877a4494d8093ae5498e19469b01d57 Mon Sep 17 00:00:00 2001 +From: Shengjiu Wang +Date: Mon, 8 May 2023 18:16:36 +0800 +Subject: [PATCH] ASoC: fsl_micfil: Fix error handler with pm_runtime_enable +Git-commit: 17955aba7877a4494d8093ae5498e19469b01d57 +Patch-mainline: v6.4-rc3 +References: git-fixes + +There is error message when defer probe happens: + +fsl-micfil-dai 30ca0000.micfil: Unbalanced pm_runtime_enable! + +Fix the error handler with pm_runtime_enable and add +fsl_micfil_remove() for pm_runtime_disable. + +Fixes: 47a70e6fc9a8 ("ASoC: Add MICFIL SoC Digital Audio Interface driver.") +Signed-off-by: Shengjiu Wang + +--- + sound/soc/fsl/fsl_micfil.c | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +--- a/sound/soc/fsl/fsl_micfil.c ++++ b/sound/soc/fsl/fsl_micfil.c +@@ -763,7 +763,7 @@ static int fsl_micfil_probe(struct platf + ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); + if (ret) { + dev_err(&pdev->dev, "failed to pcm register\n"); +- return ret; ++ goto err_pm_disable; + } + + ret = devm_snd_soc_register_component(&pdev->dev, &fsl_micfil_component, +@@ -771,9 +771,21 @@ static int fsl_micfil_probe(struct platf + if (ret) { + dev_err(&pdev->dev, "failed to register component %s\n", + fsl_micfil_component.name); ++ goto err_pm_disable; + } + + return ret; ++ ++err_pm_disable: ++ pm_runtime_disable(&pdev->dev); ++ ++ return ret; ++} ++ ++static int fsl_micfil_remove(struct platform_device *pdev) ++{ ++ pm_runtime_disable(&pdev->dev); ++ return 0; + } + + static int __maybe_unused fsl_micfil_runtime_suspend(struct device *dev) +@@ -834,6 +846,7 @@ static const struct dev_pm_ops fsl_micfi + + static struct platform_driver fsl_micfil_driver = { + .probe = fsl_micfil_probe, ++ .remove = fsl_micfil_remove, + .driver = { + .name = "fsl-micfil-dai", + .pm = &fsl_micfil_pm_ops, diff --git a/patches.suse/IB-hfi1-Fix-SDMA-mmu_rb_node-not-being-evicted-in-LR.patch b/patches.suse/IB-hfi1-Fix-SDMA-mmu_rb_node-not-being-evicted-in-LR.patch new file mode 100644 index 0000000..1daf92f --- /dev/null +++ b/patches.suse/IB-hfi1-Fix-SDMA-mmu_rb_node-not-being-evicted-in-LR.patch @@ -0,0 +1,93 @@ +From 9fe8fec5e43d5a80f43cbf61aaada1b047a1eb61 Mon Sep 17 00:00:00 2001 +From: Patrick Kelsey +Date: Fri, 7 Apr 2023 12:52:39 -0400 +Subject: [PATCH 1/1] IB/hfi1: Fix SDMA mmu_rb_node not being evicted in LRU + order +Git-commit: 9fe8fec5e43d5a80f43cbf61aaada1b047a1eb61 +Patch-mainline: v6.4-rc1 +References: git-fixes + +hfi1_mmu_rb_remove_unless_exact() did not move mmu_rb_node objects in +mmu_rb_handler->lru_list after getting a cache hit on an mmu_rb_node. + +As a result, hfi1_mmu_rb_evict() was not guaranteed to evict truly +least-recently used nodes. + +This could be a performance issue for an application when that +application: +- Uses some long-lived buffers frequently. +- Uses a large number of buffers once. +- Hits the mmu_rb_handler cache size or pinned-page limits, forcing + mmu_rb_handler cache entries to be evicted. + +In this case, the one-time use buffers cause the long-lived buffer +entries to eventually filter to the end of the LRU list where +hfi1_mmu_rb_evict() will consider evicting a frequently-used long-lived +entry instead of evicting one of the one-time use entries. + +Fix this by inserting new mmu_rb_node at the tail of +mmu_rb_handler->lru_list and move mmu_rb_ndoe to the tail of +mmu_rb_handler->lru_list when the mmu_rb_node is a hit in +hfi1_mmu_rb_remove_unless_exact(). Change hfi1_mmu_rb_evict() to evict +from the head of mmu_rb_handler->lru_list instead of the tail. + +Fixes: 0636e9ab8355 ("IB/hfi1: Add cache evict LRU list") +Signed-off-by: Brendan Cunningham +Signed-off-by: Patrick Kelsey +Signed-off-by: Dennis Dalessandro +Link: https://lore.kernel.org/r/168088635931.3027109.10423156330761536044.stgit@252.162.96.66.static.eigbox.net +Signed-off-by: Leon Romanovsky +Acked-by: Nicolas Morey +--- + drivers/infiniband/hw/hfi1/mmu_rb.c | 13 ++++++------- + 1 file changed, 6 insertions(+), 7 deletions(-) + +diff --git a/drivers/infiniband/hw/hfi1/mmu_rb.c b/drivers/infiniband/hw/hfi1/mmu_rb.c +index 7333646021bb..af46ff203342 100644 +--- a/drivers/infiniband/hw/hfi1/mmu_rb.c ++++ b/drivers/infiniband/hw/hfi1/mmu_rb.c +@@ -130,7 +130,7 @@ int hfi1_mmu_rb_insert(struct mmu_rb_handler *handler, + goto unlock; + } + __mmu_int_rb_insert(mnode, &handler->root); +- list_add(&mnode->list, &handler->lru_list); ++ list_add_tail(&mnode->list, &handler->lru_list); + + ret = handler->ops->insert(handler->ops_arg, mnode); + if (ret) { +@@ -181,8 +181,10 @@ bool hfi1_mmu_rb_remove_unless_exact(struct mmu_rb_handler *handler, + spin_lock_irqsave(&handler->lock, flags); + node = __mmu_rb_search(handler, addr, len); + if (node) { +- if (node->addr == addr && node->len == len) ++ if (node->addr == addr && node->len == len) { ++ list_move_tail(&node->list, &handler->lru_list); + goto unlock; ++ } + __mmu_int_rb_remove(node, &handler->root); + list_del(&node->list); /* remove from LRU list */ + ret = true; +@@ -206,8 +208,7 @@ void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg) + INIT_LIST_HEAD(&del_list); + + spin_lock_irqsave(&handler->lock, flags); +- list_for_each_entry_safe_reverse(rbnode, ptr, &handler->lru_list, +- list) { ++ list_for_each_entry_safe(rbnode, ptr, &handler->lru_list, list) { + if (handler->ops->evict(handler->ops_arg, rbnode, evict_arg, + &stop)) { + __mmu_int_rb_remove(rbnode, &handler->root); +@@ -219,9 +220,7 @@ void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg) + } + spin_unlock_irqrestore(&handler->lock, flags); + +- while (!list_empty(&del_list)) { +- rbnode = list_first_entry(&del_list, struct mmu_rb_node, list); +- list_del(&rbnode->list); ++ list_for_each_entry_safe(rbnode, ptr, &del_list, list) { + handler->ops->remove(handler->ops_arg, rbnode); + } + } +-- +2.39.1.1.gbe015eda0162 + diff --git a/patches.suse/IB-hfi1-Fix-bugs-with-non-PAGE_SIZE-end-multi-iovec-.patch b/patches.suse/IB-hfi1-Fix-bugs-with-non-PAGE_SIZE-end-multi-iovec-.patch new file mode 100644 index 0000000..7362d12 --- /dev/null +++ b/patches.suse/IB-hfi1-Fix-bugs-with-non-PAGE_SIZE-end-multi-iovec-.patch @@ -0,0 +1,1147 @@ +From 00cbce5cbf88459cd1aa1d60d0f1df15477df127 Mon Sep 17 00:00:00 2001 +From: Patrick Kelsey +Date: Fri, 7 Apr 2023 12:52:44 -0400 +Subject: [PATCH 1/1] IB/hfi1: Fix bugs with non-PAGE_SIZE-end multi-iovec user + SDMA requests +Git-commit: 00cbce5cbf88459cd1aa1d60d0f1df15477df127 +Patch-mainline: v6.4-rc1 +References: git-fixes + +hfi1 user SDMA request processing has two bugs that can cause data +corruption for user SDMA requests that have multiple payload iovecs +where an iovec other than the tail iovec does not run up to the page +boundary for the buffer pointed to by that iovec.a + +Here are the specific bugs: +1. user_sdma_txadd() does not use struct user_sdma_iovec->iov.iov_len. + Rather, user_sdma_txadd() will add up to PAGE_SIZE bytes from iovec + to the packet, even if some of those bytes are past + iovec->iov.iov_len and are thus not intended to be in the packet. +2. user_sdma_txadd() and user_sdma_send_pkts() fail to advance to the + next iovec in user_sdma_request->iovs when the current iovec + is not PAGE_SIZE and does not contain enough data to complete the + packet. The transmitted packet will contain the wrong data from the + iovec pages. + +This has not been an issue with SDMA packets from hfi1 Verbs or PSM2 +because they only produce iovecs that end short of PAGE_SIZE as the tail +iovec of an SDMA request. + +Fixing these bugs exposes other bugs with the SDMA pin cache +(struct mmu_rb_handler) that get in way of supporting user SDMA requests +with multiple payload iovecs whose buffers do not end at PAGE_SIZE. So +this commit fixes those issues as well. + +Here are the mmu_rb_handler bugs that non-PAGE_SIZE-end multi-iovec +payload user SDMA requests can hit: +1. Overlapping memory ranges in mmu_rb_handler will result in duplicate + pinnings. +2. When extending an existing mmu_rb_handler entry (struct mmu_rb_node), + the mmu_rb code (1) removes the existing entry under a lock, (2) + releases that lock, pins the new pages, (3) then reacquires the lock + to insert the extended mmu_rb_node. + + If someone else comes in and inserts an overlapping entry between (2) + and (3), insert in (3) will fail. + + The failure path code in this case unpins _all_ pages in either the + original mmu_rb_node or the new mmu_rb_node that was inserted between + (2) and (3). +3. In hfi1_mmu_rb_remove_unless_exact(), mmu_rb_node->refcount is + incremented outside of mmu_rb_handler->lock. As a result, mmu_rb_node + could be evicted by another thread that gets mmu_rb_handler->lock and + checks mmu_rb_node->refcount before mmu_rb_node->refcount is + incremented. +4. Related to #2 above, SDMA request submission failure path does not + check mmu_rb_node->refcount before freeing mmu_rb_node object. + + If there are other SDMA requests in progress whose iovecs have + pointers to the now-freed mmu_rb_node(s), those pointers to the + now-freed mmu_rb nodes will be dereferenced when those SDMA requests + complete. + +Fixes: 7be85676f1d1 ("IB/hfi1: Don't remove RB entry when not needed.") +Fixes: 7724105686e7 ("IB/hfi1: add driver files") +Signed-off-by: Brendan Cunningham +Signed-off-by: Patrick Kelsey +Signed-off-by: Dennis Dalessandro +Link: https://lore.kernel.org/r/168088636445.3027109.10054635277810177889.stgit@252.162.96.66.static.eigbox.net +Signed-off-by: Leon Romanovsky +Acked-by: Nicolas Morey +--- + drivers/infiniband/hw/hfi1/ipoib_tx.c | 1 + + drivers/infiniband/hw/hfi1/mmu_rb.c | 66 +-- + drivers/infiniband/hw/hfi1/mmu_rb.h | 8 +- + drivers/infiniband/hw/hfi1/sdma.c | 21 +- + drivers/infiniband/hw/hfi1/sdma.h | 16 +- + drivers/infiniband/hw/hfi1/sdma_txreq.h | 1 + + drivers/infiniband/hw/hfi1/trace_mmu.h | 4 - + drivers/infiniband/hw/hfi1/user_sdma.c | 600 +++++++++++++++--------- + drivers/infiniband/hw/hfi1/user_sdma.h | 5 - + drivers/infiniband/hw/hfi1/verbs.c | 4 +- + drivers/infiniband/hw/hfi1/vnic_sdma.c | 1 + + 11 files changed, 423 insertions(+), 304 deletions(-) + +diff --git a/drivers/infiniband/hw/hfi1/ipoib_tx.c b/drivers/infiniband/hw/hfi1/ipoib_tx.c +index 349eb4139136..8973a081d641 100644 +--- a/drivers/infiniband/hw/hfi1/ipoib_tx.c ++++ b/drivers/infiniband/hw/hfi1/ipoib_tx.c +@@ -215,6 +215,7 @@ static int hfi1_ipoib_build_ulp_payload(struct ipoib_txreq *tx, + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + + ret = sdma_txadd_page(dd, ++ NULL, + txreq, + skb_frag_page(frag), + frag->bv_offset, +diff --git a/drivers/infiniband/hw/hfi1/mmu_rb.c b/drivers/infiniband/hw/hfi1/mmu_rb.c +index af46ff203342..71b9ac018887 100644 +--- a/drivers/infiniband/hw/hfi1/mmu_rb.c ++++ b/drivers/infiniband/hw/hfi1/mmu_rb.c +@@ -126,7 +126,7 @@ int hfi1_mmu_rb_insert(struct mmu_rb_handler *handler, + spin_lock_irqsave(&handler->lock, flags); + node = __mmu_rb_search(handler, mnode->addr, mnode->len); + if (node) { +- ret = -EINVAL; ++ ret = -EEXIST; + goto unlock; + } + __mmu_int_rb_insert(mnode, &handler->root); +@@ -143,6 +143,19 @@ unlock: + return ret; + } + ++/* Caller must hold handler lock */ ++struct mmu_rb_node *hfi1_mmu_rb_get_first(struct mmu_rb_handler *handler, ++ unsigned long addr, unsigned long len) ++{ ++ struct mmu_rb_node *node; ++ ++ trace_hfi1_mmu_rb_search(addr, len); ++ node = __mmu_int_rb_iter_first(&handler->root, addr, (addr + len) - 1); ++ if (node) ++ list_move_tail(&node->list, &handler->lru_list); ++ return node; ++} ++ + /* Caller must hold handler lock */ + static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *handler, + unsigned long addr, +@@ -167,34 +180,6 @@ static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *handler, + return node; + } + +-bool hfi1_mmu_rb_remove_unless_exact(struct mmu_rb_handler *handler, +- unsigned long addr, unsigned long len, +- struct mmu_rb_node **rb_node) +-{ +- struct mmu_rb_node *node; +- unsigned long flags; +- bool ret = false; +- +- if (current->mm != handler->mn.mm) +- return ret; +- +- spin_lock_irqsave(&handler->lock, flags); +- node = __mmu_rb_search(handler, addr, len); +- if (node) { +- if (node->addr == addr && node->len == len) { +- list_move_tail(&node->list, &handler->lru_list); +- goto unlock; +- } +- __mmu_int_rb_remove(node, &handler->root); +- list_del(&node->list); /* remove from LRU list */ +- ret = true; +- } +-unlock: +- spin_unlock_irqrestore(&handler->lock, flags); +- *rb_node = node; +- return ret; +-} +- + void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg) + { + struct mmu_rb_node *rbnode, *ptr; +@@ -225,29 +210,6 @@ void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg) + } + } + +-/* +- * It is up to the caller to ensure that this function does not race with the +- * mmu invalidate notifier which may be calling the users remove callback on +- * 'node'. +- */ +-void hfi1_mmu_rb_remove(struct mmu_rb_handler *handler, +- struct mmu_rb_node *node) +-{ +- unsigned long flags; +- +- if (current->mm != handler->mn.mm) +- return; +- +- /* Validity of handler and node pointers has been checked by caller. */ +- trace_hfi1_mmu_rb_remove(node->addr, node->len); +- spin_lock_irqsave(&handler->lock, flags); +- __mmu_int_rb_remove(node, &handler->root); +- list_del(&node->list); /* remove from LRU list */ +- spin_unlock_irqrestore(&handler->lock, flags); +- +- handler->ops->remove(handler->ops_arg, node); +-} +- + static int mmu_notifier_range_start(struct mmu_notifier *mn, + const struct mmu_notifier_range *range) + { +diff --git a/drivers/infiniband/hw/hfi1/mmu_rb.h b/drivers/infiniband/hw/hfi1/mmu_rb.h +index 7417be2b9dc8..ed75acdb7b83 100644 +--- a/drivers/infiniband/hw/hfi1/mmu_rb.h ++++ b/drivers/infiniband/hw/hfi1/mmu_rb.h +@@ -52,10 +52,8 @@ void hfi1_mmu_rb_unregister(struct mmu_rb_handler *handler); + int hfi1_mmu_rb_insert(struct mmu_rb_handler *handler, + struct mmu_rb_node *mnode); + void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg); +-void hfi1_mmu_rb_remove(struct mmu_rb_handler *handler, +- struct mmu_rb_node *mnode); +-bool hfi1_mmu_rb_remove_unless_exact(struct mmu_rb_handler *handler, +- unsigned long addr, unsigned long len, +- struct mmu_rb_node **rb_node); ++struct mmu_rb_node *hfi1_mmu_rb_get_first(struct mmu_rb_handler *handler, ++ unsigned long addr, ++ unsigned long len); + + #endif /* _HFI1_MMU_RB_H */ +diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c +index 8ed20392e9f0..bb2552dd29c1 100644 +--- a/drivers/infiniband/hw/hfi1/sdma.c ++++ b/drivers/infiniband/hw/hfi1/sdma.c +@@ -1593,22 +1593,7 @@ static inline void sdma_unmap_desc( + struct hfi1_devdata *dd, + struct sdma_desc *descp) + { +- switch (sdma_mapping_type(descp)) { +- case SDMA_MAP_SINGLE: +- dma_unmap_single( +- &dd->pcidev->dev, +- sdma_mapping_addr(descp), +- sdma_mapping_len(descp), +- DMA_TO_DEVICE); +- break; +- case SDMA_MAP_PAGE: +- dma_unmap_page( +- &dd->pcidev->dev, +- sdma_mapping_addr(descp), +- sdma_mapping_len(descp), +- DMA_TO_DEVICE); +- break; +- } ++ system_descriptor_complete(dd, descp); + } + + /* +@@ -3128,7 +3113,7 @@ int ext_coal_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx, + + /* Add descriptor for coalesce buffer */ + tx->desc_limit = MAX_DESC; +- return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, tx, ++ return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, NULL, tx, + addr, tx->tlen); + } + +@@ -3167,10 +3152,12 @@ int _pad_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx) + return rval; + } + } ++ + /* finish the one just added */ + make_tx_sdma_desc( + tx, + SDMA_MAP_NONE, ++ NULL, + dd->sdma_pad_phys, + sizeof(u32) - (tx->packet_len & (sizeof(u32) - 1))); + tx->num_desc++; +diff --git a/drivers/infiniband/hw/hfi1/sdma.h b/drivers/infiniband/hw/hfi1/sdma.h +index b023fc461bd5..95aaec14c6c2 100644 +--- a/drivers/infiniband/hw/hfi1/sdma.h ++++ b/drivers/infiniband/hw/hfi1/sdma.h +@@ -594,6 +594,7 @@ static inline dma_addr_t sdma_mapping_addr(struct sdma_desc *d) + static inline void make_tx_sdma_desc( + struct sdma_txreq *tx, + int type, ++ void *pinning_ctx, + dma_addr_t addr, + size_t len) + { +@@ -612,6 +613,7 @@ static inline void make_tx_sdma_desc( + << SDMA_DESC0_PHY_ADDR_SHIFT) | + (((u64)len & SDMA_DESC0_BYTE_COUNT_MASK) + << SDMA_DESC0_BYTE_COUNT_SHIFT); ++ desc->pinning_ctx = pinning_ctx; + } + + /* helper to extend txreq */ +@@ -643,6 +645,7 @@ static inline void _sdma_close_tx(struct hfi1_devdata *dd, + static inline int _sdma_txadd_daddr( + struct hfi1_devdata *dd, + int type, ++ void *pinning_ctx, + struct sdma_txreq *tx, + dma_addr_t addr, + u16 len) +@@ -652,6 +655,7 @@ static inline int _sdma_txadd_daddr( + make_tx_sdma_desc( + tx, + type, ++ pinning_ctx, + addr, len); + WARN_ON(len > tx->tlen); + tx->num_desc++; +@@ -672,6 +676,7 @@ static inline int _sdma_txadd_daddr( + /** + * sdma_txadd_page() - add a page to the sdma_txreq + * @dd: the device to use for mapping ++ * @pinning_ctx: context to be released at descriptor retirement + * @tx: tx request to which the page is added + * @page: page to map + * @offset: offset within the page +@@ -687,6 +692,7 @@ static inline int _sdma_txadd_daddr( + */ + static inline int sdma_txadd_page( + struct hfi1_devdata *dd, ++ void *pinning_ctx, + struct sdma_txreq *tx, + struct page *page, + unsigned long offset, +@@ -714,8 +720,7 @@ static inline int sdma_txadd_page( + return -ENOSPC; + } + +- return _sdma_txadd_daddr( +- dd, SDMA_MAP_PAGE, tx, addr, len); ++ return _sdma_txadd_daddr(dd, SDMA_MAP_PAGE, pinning_ctx, tx, addr, len); + } + + /** +@@ -749,7 +754,8 @@ static inline int sdma_txadd_daddr( + return rval; + } + +- return _sdma_txadd_daddr(dd, SDMA_MAP_NONE, tx, addr, len); ++ return _sdma_txadd_daddr(dd, SDMA_MAP_NONE, NULL, tx, ++ addr, len); + } + + /** +@@ -795,8 +801,7 @@ static inline int sdma_txadd_kvaddr( + return -ENOSPC; + } + +- return _sdma_txadd_daddr( +- dd, SDMA_MAP_SINGLE, tx, addr, len); ++ return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, NULL, tx, addr, len); + } + + struct iowait_work; +@@ -1030,4 +1035,5 @@ extern uint mod_num_sdma; + + void sdma_update_lmc(struct hfi1_devdata *dd, u64 mask, u32 lid); + ++void system_descriptor_complete(struct hfi1_devdata *dd, struct sdma_desc *descp); + #endif +diff --git a/drivers/infiniband/hw/hfi1/sdma_txreq.h b/drivers/infiniband/hw/hfi1/sdma_txreq.h +index e262fb5c5ec6..fad946cb5e0d 100644 +--- a/drivers/infiniband/hw/hfi1/sdma_txreq.h ++++ b/drivers/infiniband/hw/hfi1/sdma_txreq.h +@@ -19,6 +19,7 @@ + struct sdma_desc { + /* private: don't use directly */ + u64 qw[2]; ++ void *pinning_ctx; + }; + + /** +diff --git a/drivers/infiniband/hw/hfi1/trace_mmu.h b/drivers/infiniband/hw/hfi1/trace_mmu.h +index 187e9244fe5e..57900ebb7702 100644 +--- a/drivers/infiniband/hw/hfi1/trace_mmu.h ++++ b/drivers/infiniband/hw/hfi1/trace_mmu.h +@@ -37,10 +37,6 @@ DEFINE_EVENT(hfi1_mmu_rb_template, hfi1_mmu_rb_search, + TP_PROTO(unsigned long addr, unsigned long len), + TP_ARGS(addr, len)); + +-DEFINE_EVENT(hfi1_mmu_rb_template, hfi1_mmu_rb_remove, +- TP_PROTO(unsigned long addr, unsigned long len), +- TP_ARGS(addr, len)); +- + DEFINE_EVENT(hfi1_mmu_rb_template, hfi1_mmu_mem_invalidate, + TP_PROTO(unsigned long addr, unsigned long len), + TP_ARGS(addr, len)); +diff --git a/drivers/infiniband/hw/hfi1/user_sdma.c b/drivers/infiniband/hw/hfi1/user_sdma.c +index a71c5a36ceba..ae58b48afe07 100644 +--- a/drivers/infiniband/hw/hfi1/user_sdma.c ++++ b/drivers/infiniband/hw/hfi1/user_sdma.c +@@ -24,7 +24,6 @@ + + #include "hfi.h" + #include "sdma.h" +-#include "mmu_rb.h" + #include "user_sdma.h" + #include "verbs.h" /* for the headers */ + #include "common.h" /* for struct hfi1_tid_info */ +@@ -39,11 +38,7 @@ static unsigned initial_pkt_count = 8; + static int user_sdma_send_pkts(struct user_sdma_request *req, u16 maxpkts); + static void user_sdma_txreq_cb(struct sdma_txreq *txreq, int status); + static inline void pq_update(struct hfi1_user_sdma_pkt_q *pq); +-static void user_sdma_free_request(struct user_sdma_request *req, bool unpin); +-static int pin_vector_pages(struct user_sdma_request *req, +- struct user_sdma_iovec *iovec); +-static void unpin_vector_pages(struct mm_struct *mm, struct page **pages, +- unsigned start, unsigned npages); ++static void user_sdma_free_request(struct user_sdma_request *req); + static int check_header_template(struct user_sdma_request *req, + struct hfi1_pkt_header *hdr, u32 lrhlen, + u32 datalen); +@@ -81,6 +76,11 @@ static struct mmu_rb_ops sdma_rb_ops = { + .invalidate = sdma_rb_invalidate + }; + ++static int add_system_pages_to_sdma_packet(struct user_sdma_request *req, ++ struct user_sdma_txreq *tx, ++ struct user_sdma_iovec *iovec, ++ u32 *pkt_remaining); ++ + static int defer_packet_queue( + struct sdma_engine *sde, + struct iowait_work *wait, +@@ -410,6 +410,7 @@ int hfi1_user_sdma_process_request(struct hfi1_filedata *fd, + ret = -EINVAL; + goto free_req; + } ++ + /* Copy the header from the user buffer */ + ret = copy_from_user(&req->hdr, iovec[idx].iov_base + sizeof(info), + sizeof(req->hdr)); +@@ -484,9 +485,8 @@ int hfi1_user_sdma_process_request(struct hfi1_filedata *fd, + memcpy(&req->iovs[i].iov, + iovec + idx++, + sizeof(req->iovs[i].iov)); +- ret = pin_vector_pages(req, &req->iovs[i]); +- if (ret) { +- req->data_iovs = i; ++ if (req->iovs[i].iov.iov_len == 0) { ++ ret = -EINVAL; + goto free_req; + } + req->data_len += req->iovs[i].iov.iov_len; +@@ -584,7 +584,7 @@ free_req: + if (req->seqsubmitted) + wait_event(pq->busy.wait_dma, + (req->seqcomp == req->seqsubmitted - 1)); +- user_sdma_free_request(req, true); ++ user_sdma_free_request(req); + pq_update(pq); + set_comp_state(pq, cq, info.comp_idx, ERROR, ret); + } +@@ -696,48 +696,6 @@ static int user_sdma_txadd_ahg(struct user_sdma_request *req, + return ret; + } + +-static int user_sdma_txadd(struct user_sdma_request *req, +- struct user_sdma_txreq *tx, +- struct user_sdma_iovec *iovec, u32 datalen, +- u32 *queued_ptr, u32 *data_sent_ptr, +- u64 *iov_offset_ptr) +-{ +- int ret; +- unsigned int pageidx, len; +- unsigned long base, offset; +- u64 iov_offset = *iov_offset_ptr; +- u32 queued = *queued_ptr, data_sent = *data_sent_ptr; +- struct hfi1_user_sdma_pkt_q *pq = req->pq; +- +- base = (unsigned long)iovec->iov.iov_base; +- offset = offset_in_page(base + iovec->offset + iov_offset); +- pageidx = (((iovec->offset + iov_offset + base) - (base & PAGE_MASK)) >> +- PAGE_SHIFT); +- len = offset + req->info.fragsize > PAGE_SIZE ? +- PAGE_SIZE - offset : req->info.fragsize; +- len = min((datalen - queued), len); +- ret = sdma_txadd_page(pq->dd, &tx->txreq, iovec->pages[pageidx], +- offset, len); +- if (ret) { +- SDMA_DBG(req, "SDMA txreq add page failed %d\n", ret); +- return ret; +- } +- iov_offset += len; +- queued += len; +- data_sent += len; +- if (unlikely(queued < datalen && pageidx == iovec->npages && +- req->iov_idx < req->data_iovs - 1)) { +- iovec->offset += iov_offset; +- iovec = &req->iovs[++req->iov_idx]; +- iov_offset = 0; +- } +- +- *queued_ptr = queued; +- *data_sent_ptr = data_sent; +- *iov_offset_ptr = iov_offset; +- return ret; +-} +- + static int user_sdma_send_pkts(struct user_sdma_request *req, u16 maxpkts) + { + int ret = 0; +@@ -769,8 +727,7 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, u16 maxpkts) + maxpkts = req->info.npkts - req->seqnum; + + while (npkts < maxpkts) { +- u32 datalen = 0, queued = 0, data_sent = 0; +- u64 iov_offset = 0; ++ u32 datalen = 0; + + /* + * Check whether any of the completions have come back +@@ -863,27 +820,17 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, u16 maxpkts) + goto free_txreq; + } + +- /* +- * If the request contains any data vectors, add up to +- * fragsize bytes to the descriptor. +- */ +- while (queued < datalen && +- (req->sent + data_sent) < req->data_len) { +- ret = user_sdma_txadd(req, tx, iovec, datalen, +- &queued, &data_sent, &iov_offset); +- if (ret) +- goto free_txreq; +- } +- /* +- * The txreq was submitted successfully so we can update +- * the counters. +- */ + req->koffset += datalen; + if (req_opcode(req->info.ctrl) == EXPECTED) + req->tidoffset += datalen; +- req->sent += data_sent; +- if (req->data_len) +- iovec->offset += iov_offset; ++ req->sent += datalen; ++ while (datalen) { ++ ret = add_system_pages_to_sdma_packet(req, tx, iovec, ++ &datalen); ++ if (ret) ++ goto free_txreq; ++ iovec = &req->iovs[req->iov_idx]; ++ } + list_add_tail(&tx->txreq.list, &req->txps); + /* + * It is important to increment this here as it is used to +@@ -920,133 +867,14 @@ free_tx: + static u32 sdma_cache_evict(struct hfi1_user_sdma_pkt_q *pq, u32 npages) + { + struct evict_data evict_data; ++ struct mmu_rb_handler *handler = pq->handler; + + evict_data.cleared = 0; + evict_data.target = npages; +- hfi1_mmu_rb_evict(pq->handler, &evict_data); ++ hfi1_mmu_rb_evict(handler, &evict_data); + return evict_data.cleared; + } + +-static int pin_sdma_pages(struct user_sdma_request *req, +- struct user_sdma_iovec *iovec, +- struct sdma_mmu_node *node, +- int npages) +-{ +- int pinned, cleared; +- struct page **pages; +- struct hfi1_user_sdma_pkt_q *pq = req->pq; +- +- pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL); +- if (!pages) +- return -ENOMEM; +- memcpy(pages, node->pages, node->npages * sizeof(*pages)); +- +- npages -= node->npages; +-retry: +- if (!hfi1_can_pin_pages(pq->dd, current->mm, +- atomic_read(&pq->n_locked), npages)) { +- cleared = sdma_cache_evict(pq, npages); +- if (cleared >= npages) +- goto retry; +- } +- pinned = hfi1_acquire_user_pages(current->mm, +- ((unsigned long)iovec->iov.iov_base + +- (node->npages * PAGE_SIZE)), npages, 0, +- pages + node->npages); +- if (pinned < 0) { +- kfree(pages); +- return pinned; +- } +- if (pinned != npages) { +- unpin_vector_pages(current->mm, pages, node->npages, pinned); +- return -EFAULT; +- } +- kfree(node->pages); +- node->rb.len = iovec->iov.iov_len; +- node->pages = pages; +- atomic_add(pinned, &pq->n_locked); +- return pinned; +-} +- +-static void unpin_sdma_pages(struct sdma_mmu_node *node) +-{ +- if (node->npages) { +- unpin_vector_pages(mm_from_sdma_node(node), node->pages, 0, +- node->npages); +- atomic_sub(node->npages, &node->pq->n_locked); +- } +-} +- +-static int pin_vector_pages(struct user_sdma_request *req, +- struct user_sdma_iovec *iovec) +-{ +- int ret = 0, pinned, npages; +- struct hfi1_user_sdma_pkt_q *pq = req->pq; +- struct sdma_mmu_node *node = NULL; +- struct mmu_rb_node *rb_node; +- struct iovec *iov; +- bool extracted; +- +- extracted = +- hfi1_mmu_rb_remove_unless_exact(pq->handler, +- (unsigned long) +- iovec->iov.iov_base, +- iovec->iov.iov_len, &rb_node); +- if (rb_node) { +- node = container_of(rb_node, struct sdma_mmu_node, rb); +- if (!extracted) { +- atomic_inc(&node->refcount); +- iovec->pages = node->pages; +- iovec->npages = node->npages; +- iovec->node = node; +- return 0; +- } +- } +- +- if (!node) { +- node = kzalloc(sizeof(*node), GFP_KERNEL); +- if (!node) +- return -ENOMEM; +- +- node->rb.addr = (unsigned long)iovec->iov.iov_base; +- node->pq = pq; +- atomic_set(&node->refcount, 0); +- } +- +- iov = &iovec->iov; +- npages = num_user_pages((unsigned long)iov->iov_base, iov->iov_len); +- if (node->npages < npages) { +- pinned = pin_sdma_pages(req, iovec, node, npages); +- if (pinned < 0) { +- ret = pinned; +- goto bail; +- } +- node->npages += pinned; +- npages = node->npages; +- } +- iovec->pages = node->pages; +- iovec->npages = npages; +- iovec->node = node; +- +- ret = hfi1_mmu_rb_insert(req->pq->handler, &node->rb); +- if (ret) { +- iovec->node = NULL; +- goto bail; +- } +- return 0; +-bail: +- unpin_sdma_pages(node); +- kfree(node); +- return ret; +-} +- +-static void unpin_vector_pages(struct mm_struct *mm, struct page **pages, +- unsigned start, unsigned npages) +-{ +- hfi1_release_user_pages(mm, pages + start, npages, false); +- kfree(pages); +-} +- + static int check_header_template(struct user_sdma_request *req, + struct hfi1_pkt_header *hdr, u32 lrhlen, + u32 datalen) +@@ -1388,7 +1216,7 @@ static void user_sdma_txreq_cb(struct sdma_txreq *txreq, int status) + if (req->seqcomp != req->info.npkts - 1) + return; + +- user_sdma_free_request(req, false); ++ user_sdma_free_request(req); + set_comp_state(pq, cq, req->info.comp_idx, state, status); + pq_update(pq); + } +@@ -1399,10 +1227,8 @@ static inline void pq_update(struct hfi1_user_sdma_pkt_q *pq) + wake_up(&pq->wait); + } + +-static void user_sdma_free_request(struct user_sdma_request *req, bool unpin) ++static void user_sdma_free_request(struct user_sdma_request *req) + { +- int i; +- + if (!list_empty(&req->txps)) { + struct sdma_txreq *t, *p; + +@@ -1415,21 +1241,6 @@ static void user_sdma_free_request(struct user_sdma_request *req, bool unpin) + } + } + +- for (i = 0; i < req->data_iovs; i++) { +- struct sdma_mmu_node *node = req->iovs[i].node; +- +- if (!node) +- continue; +- +- req->iovs[i].node = NULL; +- +- if (unpin) +- hfi1_mmu_rb_remove(req->pq->handler, +- &node->rb); +- else +- atomic_dec(&node->refcount); +- } +- + kfree(req->tids); + clear_bit(req->info.comp_idx, req->pq->req_in_use); + } +@@ -1447,6 +1258,368 @@ static inline void set_comp_state(struct hfi1_user_sdma_pkt_q *pq, + idx, state, ret); + } + ++static void unpin_vector_pages(struct mm_struct *mm, struct page **pages, ++ unsigned int start, unsigned int npages) ++{ ++ hfi1_release_user_pages(mm, pages + start, npages, false); ++ kfree(pages); ++} ++ ++static void free_system_node(struct sdma_mmu_node *node) ++{ ++ if (node->npages) { ++ unpin_vector_pages(mm_from_sdma_node(node), node->pages, 0, ++ node->npages); ++ atomic_sub(node->npages, &node->pq->n_locked); ++ } ++ kfree(node); ++} ++ ++static inline void acquire_node(struct sdma_mmu_node *node) ++{ ++ atomic_inc(&node->refcount); ++ WARN_ON(atomic_read(&node->refcount) < 0); ++} ++ ++static inline void release_node(struct mmu_rb_handler *handler, ++ struct sdma_mmu_node *node) ++{ ++ atomic_dec(&node->refcount); ++ WARN_ON(atomic_read(&node->refcount) < 0); ++} ++ ++static struct sdma_mmu_node *find_system_node(struct mmu_rb_handler *handler, ++ unsigned long start, ++ unsigned long end) ++{ ++ struct mmu_rb_node *rb_node; ++ struct sdma_mmu_node *node; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&handler->lock, flags); ++ rb_node = hfi1_mmu_rb_get_first(handler, start, (end - start)); ++ if (!rb_node) { ++ spin_unlock_irqrestore(&handler->lock, flags); ++ return NULL; ++ } ++ node = container_of(rb_node, struct sdma_mmu_node, rb); ++ acquire_node(node); ++ spin_unlock_irqrestore(&handler->lock, flags); ++ ++ return node; ++} ++ ++static int pin_system_pages(struct user_sdma_request *req, ++ uintptr_t start_address, size_t length, ++ struct sdma_mmu_node *node, int npages) ++{ ++ struct hfi1_user_sdma_pkt_q *pq = req->pq; ++ int pinned, cleared; ++ struct page **pages; ++ ++ pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL); ++ if (!pages) ++ return -ENOMEM; ++ ++retry: ++ if (!hfi1_can_pin_pages(pq->dd, current->mm, atomic_read(&pq->n_locked), ++ npages)) { ++ SDMA_DBG(req, "Evicting: nlocked %u npages %u", ++ atomic_read(&pq->n_locked), npages); ++ cleared = sdma_cache_evict(pq, npages); ++ if (cleared >= npages) ++ goto retry; ++ } ++ ++ SDMA_DBG(req, "Acquire user pages start_address %lx node->npages %u npages %u", ++ start_address, node->npages, npages); ++ pinned = hfi1_acquire_user_pages(current->mm, start_address, npages, 0, ++ pages); ++ ++ if (pinned < 0) { ++ kfree(pages); ++ SDMA_DBG(req, "pinned %d", pinned); ++ return pinned; ++ } ++ if (pinned != npages) { ++ unpin_vector_pages(current->mm, pages, node->npages, pinned); ++ SDMA_DBG(req, "npages %u pinned %d", npages, pinned); ++ return -EFAULT; ++ } ++ node->rb.addr = start_address; ++ node->rb.len = length; ++ node->pages = pages; ++ node->npages = npages; ++ atomic_add(pinned, &pq->n_locked); ++ SDMA_DBG(req, "done. pinned %d", pinned); ++ return 0; ++} ++ ++static int add_system_pinning(struct user_sdma_request *req, ++ struct sdma_mmu_node **node_p, ++ unsigned long start, unsigned long len) ++ ++{ ++ struct hfi1_user_sdma_pkt_q *pq = req->pq; ++ struct sdma_mmu_node *node; ++ int ret; ++ ++ node = kzalloc(sizeof(*node), GFP_KERNEL); ++ if (!node) ++ return -ENOMEM; ++ ++ node->pq = pq; ++ ret = pin_system_pages(req, start, len, node, PFN_DOWN(len)); ++ if (ret == 0) { ++ ret = hfi1_mmu_rb_insert(pq->handler, &node->rb); ++ if (ret) ++ free_system_node(node); ++ else ++ *node_p = node; ++ ++ return ret; ++ } ++ ++ kfree(node); ++ return ret; ++} ++ ++static int get_system_cache_entry(struct user_sdma_request *req, ++ struct sdma_mmu_node **node_p, ++ size_t req_start, size_t req_len) ++{ ++ struct hfi1_user_sdma_pkt_q *pq = req->pq; ++ u64 start = ALIGN_DOWN(req_start, PAGE_SIZE); ++ u64 end = PFN_ALIGN(req_start + req_len); ++ struct mmu_rb_handler *handler = pq->handler; ++ int ret; ++ ++ if ((end - start) == 0) { ++ SDMA_DBG(req, ++ "Request for empty cache entry req_start %lx req_len %lx start %llx end %llx", ++ req_start, req_len, start, end); ++ return -EINVAL; ++ } ++ ++ SDMA_DBG(req, "req_start %lx req_len %lu", req_start, req_len); ++ ++ while (1) { ++ struct sdma_mmu_node *node = ++ find_system_node(handler, start, end); ++ u64 prepend_len = 0; ++ ++ SDMA_DBG(req, "node %p start %llx end %llu", node, start, end); ++ if (!node) { ++ ret = add_system_pinning(req, node_p, start, ++ end - start); ++ if (ret == -EEXIST) { ++ /* ++ * Another execution context has inserted a ++ * conficting entry first. ++ */ ++ continue; ++ } ++ return ret; ++ } ++ ++ if (node->rb.addr <= start) { ++ /* ++ * This entry covers at least part of the region. If it doesn't extend ++ * to the end, then this will be called again for the next segment. ++ */ ++ *node_p = node; ++ return 0; ++ } ++ ++ SDMA_DBG(req, "prepend: node->rb.addr %lx, node->refcount %d", ++ node->rb.addr, atomic_read(&node->refcount)); ++ prepend_len = node->rb.addr - start; ++ ++ /* ++ * This node will not be returned, instead a new node ++ * will be. So release the reference. ++ */ ++ release_node(handler, node); ++ ++ /* Prepend a node to cover the beginning of the allocation */ ++ ret = add_system_pinning(req, node_p, start, prepend_len); ++ if (ret == -EEXIST) { ++ /* Another execution context has inserted a conficting entry first. */ ++ continue; ++ } ++ return ret; ++ } ++} ++ ++static int add_mapping_to_sdma_packet(struct user_sdma_request *req, ++ struct user_sdma_txreq *tx, ++ struct sdma_mmu_node *cache_entry, ++ size_t start, ++ size_t from_this_cache_entry) ++{ ++ struct hfi1_user_sdma_pkt_q *pq = req->pq; ++ unsigned int page_offset; ++ unsigned int from_this_page; ++ size_t page_index; ++ void *ctx; ++ int ret; ++ ++ /* ++ * Because the cache may be more fragmented than the memory that is being accessed, ++ * it's not strictly necessary to have a descriptor per cache entry. ++ */ ++ ++ while (from_this_cache_entry) { ++ page_index = PFN_DOWN(start - cache_entry->rb.addr); ++ ++ if (page_index >= cache_entry->npages) { ++ SDMA_DBG(req, ++ "Request for page_index %zu >= cache_entry->npages %u", ++ page_index, cache_entry->npages); ++ return -EINVAL; ++ } ++ ++ page_offset = start - ALIGN_DOWN(start, PAGE_SIZE); ++ from_this_page = PAGE_SIZE - page_offset; ++ ++ if (from_this_page < from_this_cache_entry) { ++ ctx = NULL; ++ } else { ++ /* ++ * In the case they are equal the next line has no practical effect, ++ * but it's better to do a register to register copy than a conditional ++ * branch. ++ */ ++ from_this_page = from_this_cache_entry; ++ ctx = cache_entry; ++ } ++ ++ ret = sdma_txadd_page(pq->dd, ctx, &tx->txreq, ++ cache_entry->pages[page_index], ++ page_offset, from_this_page); ++ if (ret) { ++ /* ++ * When there's a failure, the entire request is freed by ++ * user_sdma_send_pkts(). ++ */ ++ SDMA_DBG(req, ++ "sdma_txadd_page failed %d page_index %lu page_offset %u from_this_page %u", ++ ret, page_index, page_offset, from_this_page); ++ return ret; ++ } ++ start += from_this_page; ++ from_this_cache_entry -= from_this_page; ++ } ++ return 0; ++} ++ ++static int add_system_iovec_to_sdma_packet(struct user_sdma_request *req, ++ struct user_sdma_txreq *tx, ++ struct user_sdma_iovec *iovec, ++ size_t from_this_iovec) ++{ ++ struct mmu_rb_handler *handler = req->pq->handler; ++ ++ while (from_this_iovec > 0) { ++ struct sdma_mmu_node *cache_entry; ++ size_t from_this_cache_entry; ++ size_t start; ++ int ret; ++ ++ start = (uintptr_t)iovec->iov.iov_base + iovec->offset; ++ ret = get_system_cache_entry(req, &cache_entry, start, ++ from_this_iovec); ++ if (ret) { ++ SDMA_DBG(req, "pin system segment failed %d", ret); ++ return ret; ++ } ++ ++ from_this_cache_entry = cache_entry->rb.len - (start - cache_entry->rb.addr); ++ if (from_this_cache_entry > from_this_iovec) ++ from_this_cache_entry = from_this_iovec; ++ ++ ret = add_mapping_to_sdma_packet(req, tx, cache_entry, start, ++ from_this_cache_entry); ++ if (ret) { ++ /* ++ * We're guaranteed that there will be no descriptor ++ * completion callback that releases this node ++ * because only the last descriptor referencing it ++ * has a context attached, and a failure means the ++ * last descriptor was never added. ++ */ ++ release_node(handler, cache_entry); ++ SDMA_DBG(req, "add system segment failed %d", ret); ++ return ret; ++ } ++ ++ iovec->offset += from_this_cache_entry; ++ from_this_iovec -= from_this_cache_entry; ++ } ++ ++ return 0; ++} ++ ++static int add_system_pages_to_sdma_packet(struct user_sdma_request *req, ++ struct user_sdma_txreq *tx, ++ struct user_sdma_iovec *iovec, ++ u32 *pkt_data_remaining) ++{ ++ size_t remaining_to_add = *pkt_data_remaining; ++ /* ++ * Walk through iovec entries, ensure the associated pages ++ * are pinned and mapped, add data to the packet until no more ++ * data remains to be added. ++ */ ++ while (remaining_to_add > 0) { ++ struct user_sdma_iovec *cur_iovec; ++ size_t from_this_iovec; ++ int ret; ++ ++ cur_iovec = iovec; ++ from_this_iovec = iovec->iov.iov_len - iovec->offset; ++ ++ if (from_this_iovec > remaining_to_add) { ++ from_this_iovec = remaining_to_add; ++ } else { ++ /* The current iovec entry will be consumed by this pass. */ ++ req->iov_idx++; ++ iovec++; ++ } ++ ++ ret = add_system_iovec_to_sdma_packet(req, tx, cur_iovec, ++ from_this_iovec); ++ if (ret) ++ return ret; ++ ++ remaining_to_add -= from_this_iovec; ++ } ++ *pkt_data_remaining = remaining_to_add; ++ ++ return 0; ++} ++ ++void system_descriptor_complete(struct hfi1_devdata *dd, ++ struct sdma_desc *descp) ++{ ++ switch (sdma_mapping_type(descp)) { ++ case SDMA_MAP_SINGLE: ++ dma_unmap_single(&dd->pcidev->dev, sdma_mapping_addr(descp), ++ sdma_mapping_len(descp), DMA_TO_DEVICE); ++ break; ++ case SDMA_MAP_PAGE: ++ dma_unmap_page(&dd->pcidev->dev, sdma_mapping_addr(descp), ++ sdma_mapping_len(descp), DMA_TO_DEVICE); ++ break; ++ } ++ ++ if (descp->pinning_ctx) { ++ struct sdma_mmu_node *node = descp->pinning_ctx; ++ ++ release_node(node->rb.handler, node); ++ } ++} ++ + static bool sdma_rb_filter(struct mmu_rb_node *node, unsigned long addr, + unsigned long len) + { +@@ -1493,8 +1666,7 @@ static void sdma_rb_remove(void *arg, struct mmu_rb_node *mnode) + struct sdma_mmu_node *node = + container_of(mnode, struct sdma_mmu_node, rb); + +- unpin_sdma_pages(node); +- kfree(node); ++ free_system_node(node); + } + + static int sdma_rb_invalidate(void *arg, struct mmu_rb_node *mnode) +diff --git a/drivers/infiniband/hw/hfi1/user_sdma.h b/drivers/infiniband/hw/hfi1/user_sdma.h +index ea56eb57e656..a241836371dc 100644 +--- a/drivers/infiniband/hw/hfi1/user_sdma.h ++++ b/drivers/infiniband/hw/hfi1/user_sdma.h +@@ -112,16 +112,11 @@ struct sdma_mmu_node { + struct user_sdma_iovec { + struct list_head list; + struct iovec iov; +- /* number of pages in this vector */ +- unsigned int npages; +- /* array of pinned pages for this vector */ +- struct page **pages; + /* + * offset into the virtual address space of the vector at + * which we last left off. + */ + u64 offset; +- struct sdma_mmu_node *node; + }; + + /* evict operation argument */ +diff --git a/drivers/infiniband/hw/hfi1/verbs.c b/drivers/infiniband/hw/hfi1/verbs.c +index 7f6d7fc7951d..fbdcfecb1768 100644 +--- a/drivers/infiniband/hw/hfi1/verbs.c ++++ b/drivers/infiniband/hw/hfi1/verbs.c +@@ -778,8 +778,8 @@ static int build_verbs_tx_desc( + + /* add icrc, lt byte, and padding to flit */ + if (extra_bytes) +- ret = sdma_txadd_daddr(sde->dd, &tx->txreq, +- sde->dd->sdma_pad_phys, extra_bytes); ++ ret = sdma_txadd_daddr(sde->dd, &tx->txreq, sde->dd->sdma_pad_phys, ++ extra_bytes); + + bail_txadd: + return ret; +diff --git a/drivers/infiniband/hw/hfi1/vnic_sdma.c b/drivers/infiniband/hw/hfi1/vnic_sdma.c +index c3f0f8d877c3..727eedfba332 100644 +--- a/drivers/infiniband/hw/hfi1/vnic_sdma.c ++++ b/drivers/infiniband/hw/hfi1/vnic_sdma.c +@@ -64,6 +64,7 @@ static noinline int build_vnic_ulp_payload(struct sdma_engine *sde, + + /* combine physically continuous fragments later? */ + ret = sdma_txadd_page(sde->dd, ++ NULL, + &tx->txreq, + skb_frag_page(frag), + skb_frag_off(frag), +-- +2.39.1.1.gbe015eda0162 + diff --git a/patches.suse/IB-hifi1-add-a-null-check-of-kzalloc_node-in-hfi1_ip.patch b/patches.suse/IB-hifi1-add-a-null-check-of-kzalloc_node-in-hfi1_ip.patch new file mode 100644 index 0000000..5c2df6b --- /dev/null +++ b/patches.suse/IB-hifi1-add-a-null-check-of-kzalloc_node-in-hfi1_ip.patch @@ -0,0 +1,42 @@ +From c874ad879c2f29ebe040a34b974389875c0d81eb Mon Sep 17 00:00:00 2001 +From: Kang Chen +Date: Mon, 27 Feb 2023 18:02:12 +0800 +Subject: [PATCH 1/1] IB/hifi1: add a null check of kzalloc_node in + hfi1_ipoib_txreq_init +Git-commit: c874ad879c2f29ebe040a34b974389875c0d81eb +Patch-mainline: v6.4-rc1 +References: git-fixes + +kzalloc_node may fails, check it and do the cleanup. + +Fixes: b1151b74ff68 ("IB/hfi1: Fix alloc failure with larger txqueuelen") +Signed-off-by: Kang Chen +Link: https://lore.kernel.org/r/20230227100212.910820-1-void0red@gmail.com +Signed-off-by: Leon Romanovsky +Acked-by: Nicolas Morey +--- + drivers/infiniband/hw/hfi1/ipoib_tx.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/hfi1/ipoib_tx.c b/drivers/infiniband/hw/hfi1/ipoib_tx.c +index 5d9a7b09ca37..349eb4139136 100644 +--- a/drivers/infiniband/hw/hfi1/ipoib_tx.c ++++ b/drivers/infiniband/hw/hfi1/ipoib_tx.c +@@ -737,10 +737,13 @@ int hfi1_ipoib_txreq_init(struct hfi1_ipoib_dev_priv *priv) + txq->tx_ring.shift = ilog2(tx_item_size); + txq->tx_ring.avail = hfi1_ipoib_ring_hwat(txq); + tx_ring = &txq->tx_ring; +- for (j = 0; j < tx_ring_size; j++) ++ for (j = 0; j < tx_ring_size; j++) { + hfi1_txreq_from_idx(tx_ring, j)->sdma_hdr = + kzalloc_node(sizeof(*tx->sdma_hdr), + GFP_KERNEL, priv->dd->node); ++ if (!hfi1_txreq_from_idx(tx_ring, j)->sdma_hdr) ++ goto free_txqs; ++ } + + netif_tx_napi_add(dev, &txq->napi, + hfi1_ipoib_poll_tx_ring, +-- +2.39.1.1.gbe015eda0162 + diff --git a/patches.suse/PCI-ASPM-Remove-pcie_aspm_pm_state_change.patch b/patches.suse/PCI-ASPM-Remove-pcie_aspm_pm_state_change.patch new file mode 100644 index 0000000..13df837 --- /dev/null +++ b/patches.suse/PCI-ASPM-Remove-pcie_aspm_pm_state_change.patch @@ -0,0 +1,90 @@ +From: Kai-Heng Feng +Date: Mon, 11 Jul 2022 18:07:01 -0500 +Subject: PCI/ASPM: Remove pcie_aspm_pm_state_change() +Git-commit: 08d0cc5f34265d1a1e3031f319f594bd1970976c +Patch-mainline: 6.0-rc1 +References: git-fixes + +pcie_aspm_pm_state_change() was introduced at the inception of PCIe ASPM +code, but it can cause some issues. For instance, when ASPM config is +changed via sysfs, those changes won't persist across power state change +because pcie_aspm_pm_state_change() overwrites them. + +Also, if the driver restores L1SS [1] after system resume, the restored +state will also be overwritten by pcie_aspm_pm_state_change(). + +Remove pcie_aspm_pm_state_change(). If there's any hardware that really +needs it to function, a quirk can be used instead. + +[js] no pcie_aspm_pm_state_change() in pci_set_low_power_state(), see below. + +[1] https://lore.kernel.org/linux-pci/20220201123536.12962-1-vidyas@nvidia.com/ +Link: https://lore.kernel.org/r/20220509073639.2048236-1-kai.heng.feng@canonical.com +[bhelgaas: remove additional pcie_aspm_pm_state_change() call in +pci_set_low_power_state(), added by +10aa5377fc8a ("PCI/PM: Split pci_raw_set_power_state()") and moved by +7957d201456f ("PCI/PM: Relocate pci_set_low_power_state()")] +Signed-off-by: Kai-Heng Feng +Signed-off-by: Bjorn Helgaas +Signed-off-by: Jiri Slaby +--- + drivers/pci/pci.c | 3 --- + drivers/pci/pci.h | 2 -- + drivers/pci/pcie/aspm.c | 19 ------------------- + 3 files changed, 24 deletions(-) + +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -1160,9 +1160,6 @@ static int pci_raw_set_power_state(struc + if (need_restore) + pci_restore_bars(dev); + +- if (dev->bus->self) +- pcie_aspm_pm_state_change(dev->bus->self); +- + return 0; + } + +--- a/drivers/pci/pci.h ++++ b/drivers/pci/pci.h +@@ -598,12 +598,10 @@ bool pcie_wait_for_link(struct pci_dev * + #ifdef CONFIG_PCIEASPM + void pcie_aspm_init_link_state(struct pci_dev *pdev); + void pcie_aspm_exit_link_state(struct pci_dev *pdev); +-void pcie_aspm_pm_state_change(struct pci_dev *pdev); + void pcie_aspm_powersave_config_link(struct pci_dev *pdev); + #else + static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) { } + static inline void pcie_aspm_exit_link_state(struct pci_dev *pdev) { } +-static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev) { } + static inline void pcie_aspm_powersave_config_link(struct pci_dev *pdev) { } + #endif + +--- a/drivers/pci/pcie/aspm.c ++++ b/drivers/pci/pcie/aspm.c +@@ -1020,25 +1020,6 @@ out: + up_read(&pci_bus_sem); + } + +-/* @pdev: the root port or switch downstream port */ +-void pcie_aspm_pm_state_change(struct pci_dev *pdev) +-{ +- struct pcie_link_state *link = pdev->link_state; +- +- if (aspm_disabled || !link) +- return; +- /* +- * Devices changed PM state, we should recheck if latency +- * meets all functions' requirement +- */ +- down_read(&pci_bus_sem); +- mutex_lock(&aspm_lock); +- pcie_update_aspm_capable(link->root); +- pcie_config_aspm_path(link); +- mutex_unlock(&aspm_lock); +- up_read(&pci_bus_sem); +-} +- + void pcie_aspm_powersave_config_link(struct pci_dev *pdev) + { + struct pcie_link_state *link = pdev->link_state; diff --git a/patches.suse/RDMA-cm-Trace-icm_send_rej-event-before-the-cm-state.patch b/patches.suse/RDMA-cm-Trace-icm_send_rej-event-before-the-cm-state.patch new file mode 100644 index 0000000..89d4369 --- /dev/null +++ b/patches.suse/RDMA-cm-Trace-icm_send_rej-event-before-the-cm-state.patch @@ -0,0 +1,49 @@ +From bd9de1badac7e4ff6780365d4aa38983f5e2a436 Mon Sep 17 00:00:00 2001 +From: Mark Zhang +Date: Thu, 30 Mar 2023 10:23:51 +0300 +Subject: [PATCH 1/1] RDMA/cm: Trace icm_send_rej event before the cm state is + reset +Git-commit: bd9de1badac7e4ff6780365d4aa38983f5e2a436 +Patch-mainline: v6.4-rc1 +References: git-fixes + +Trace icm_send_rej event before the cm state is reset to idle, so that +correct cm state will be logged. For example when an incoming request is +rejected, the old trace log was: + icm_send_rej: local_id=961102742 remote_id=3829151631 state=IDLE reason=REJ_CONSUMER_DEFINED +With this patch: + icm_send_rej: local_id=312971016 remote_id=3778819983 state=MRA_REQ_SENT reason=REJ_CONSUMER_DEFINED + +Fixes: 8dc105befe16 ("RDMA/cm: Add tracepoints to track MAD send operations") +Signed-off-by: Mark Zhang +Link: https://lore.kernel.org/r/20230330072351.481200-1-markzhang@nvidia.com +Signed-off-by: Leon Romanovsky +Acked-by: Nicolas Morey +--- + drivers/infiniband/core/cm.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c +index 603c0aecc361..ff58058aeadc 100644 +--- a/drivers/infiniband/core/cm.c ++++ b/drivers/infiniband/core/cm.c +@@ -2912,6 +2912,8 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv, + (ari && ari_length > IB_CM_REJ_ARI_LENGTH)) + return -EINVAL; + ++ trace_icm_send_rej(&cm_id_priv->id, reason); ++ + switch (state) { + case IB_CM_REQ_SENT: + case IB_CM_MRA_REQ_RCVD: +@@ -2942,7 +2944,6 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv, + return -EINVAL; + } + +- trace_icm_send_rej(&cm_id_priv->id, reason); + ret = ib_post_send_mad(msg, NULL); + if (ret) { + cm_free_msg(msg); +-- +2.39.1.1.gbe015eda0162 + diff --git a/patches.suse/RDMA-mlx5-Fix-flow-counter-query-via-DEVX.patch b/patches.suse/RDMA-mlx5-Fix-flow-counter-query-via-DEVX.patch new file mode 100644 index 0000000..f1833fc --- /dev/null +++ b/patches.suse/RDMA-mlx5-Fix-flow-counter-query-via-DEVX.patch @@ -0,0 +1,92 @@ +From 3e358ea8614ddfbc59ca7a3f5dff5dde2b350b2c Mon Sep 17 00:00:00 2001 +From: Mark Bloch +Date: Thu, 13 Apr 2023 12:23:09 +0300 +Subject: [PATCH 1/1] RDMA/mlx5: Fix flow counter query via DEVX +Git-commit: 3e358ea8614ddfbc59ca7a3f5dff5dde2b350b2c +Patch-mainline: v6.4-rc1 +References: git-fixes + +Commit cited in "fixes" tag added bulk support for flow counters but it +didn't account that's also possible to query a counter using a non-base id +if the counter was allocated as bulk. + +When a user performs a query, validate the flow counter id given in the +mailbox is inside the valid range taking bulk value into account. + +Fixes: 208d70f562e5 ("IB/mlx5: Support flow counters offset for bulk counters") +Signed-off-by: Mark Bloch +Reviewed-by: Maor Gottlieb +Link: https://lore.kernel.org/r/79d7fbe291690128e44672418934256254d93115.1681377114.git.leon@kernel.org +Signed-off-by: Leon Romanovsky +Acked-by: Nicolas Morey +--- + drivers/infiniband/hw/mlx5/devx.c | 31 ++++++++++++++++++++++++++----- + include/linux/mlx5/mlx5_ifc.h | 3 ++- + 2 files changed, 28 insertions(+), 6 deletions(-) + +diff --git a/drivers/infiniband/hw/mlx5/devx.c b/drivers/infiniband/hw/mlx5/devx.c +index 07037b829c7e..db5fb196c728 100644 +--- a/drivers/infiniband/hw/mlx5/devx.c ++++ b/drivers/infiniband/hw/mlx5/devx.c +@@ -666,7 +666,21 @@ static bool devx_is_valid_obj_id(struct uverbs_attr_bundle *attrs, + obj_id; + + case MLX5_IB_OBJECT_DEVX_OBJ: +- return ((struct devx_obj *)uobj->object)->obj_id == obj_id; ++ { ++ u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); ++ struct devx_obj *devx_uobj = uobj->object; ++ ++ if (opcode == MLX5_CMD_OP_QUERY_FLOW_COUNTER && ++ devx_uobj->flow_counter_bulk_size) { ++ u64 end; ++ ++ end = devx_uobj->obj_id + ++ devx_uobj->flow_counter_bulk_size; ++ return devx_uobj->obj_id <= obj_id && end > obj_id; ++ } ++ ++ return devx_uobj->obj_id == obj_id; ++ } + + default: + return false; +@@ -1517,10 +1531,17 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)( + goto obj_free; + + if (opcode == MLX5_CMD_OP_ALLOC_FLOW_COUNTER) { +- u8 bulk = MLX5_GET(alloc_flow_counter_in, +- cmd_in, +- flow_counter_bulk); +- obj->flow_counter_bulk_size = 128UL * bulk; ++ u32 bulk = MLX5_GET(alloc_flow_counter_in, ++ cmd_in, ++ flow_counter_bulk_log_size); ++ ++ if (bulk) ++ bulk = 1 << bulk; ++ else ++ bulk = 128UL * MLX5_GET(alloc_flow_counter_in, ++ cmd_in, ++ flow_counter_bulk); ++ obj->flow_counter_bulk_size = bulk; + } + + uobj->object = obj; +diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h +index b54339a1b1c6..3976e6266bcc 100644 +--- a/include/linux/mlx5/mlx5_ifc.h ++++ b/include/linux/mlx5/mlx5_ifc.h +@@ -9283,7 +9283,8 @@ struct mlx5_ifc_alloc_flow_counter_in_bits { + u8 reserved_at_20[0x10]; + u8 op_mod[0x10]; + +- u8 reserved_at_40[0x38]; ++ u8 reserved_at_40[0x33]; ++ u8 flow_counter_bulk_log_size[0x5]; + u8 flow_counter_bulk[0x8]; + }; + +-- +2.39.1.1.gbe015eda0162 + diff --git a/patches.suse/RDMA-mlx5-Use-correct-device-num_ports-when-modify-D.patch b/patches.suse/RDMA-mlx5-Use-correct-device-num_ports-when-modify-D.patch new file mode 100644 index 0000000..dea6025 --- /dev/null +++ b/patches.suse/RDMA-mlx5-Use-correct-device-num_ports-when-modify-D.patch @@ -0,0 +1,38 @@ +From 746aa3c8cb1a650ff2583497ac646e505831b9b9 Mon Sep 17 00:00:00 2001 +From: Mark Zhang +Date: Thu, 20 Apr 2023 04:39:06 +0300 +Subject: [PATCH 1/1] RDMA/mlx5: Use correct device num_ports when modify DC +Git-commit: 746aa3c8cb1a650ff2583497ac646e505831b9b9 +Patch-mainline: v6.4-rc1 +References: git-fixes + +Just like other QP types, when modify DC, the port_num should be compared +with dev->num_ports, instead of HCA_CAP.num_ports. Otherwise Multi-port +vHCA on DC may not work. + +Fixes: 776a3906b692 ("IB/mlx5: Add support for DC target QP") +Link: https://lore.kernel.org/r/20230420013906.1244185-1-markzhang@nvidia.com +Signed-off-by: Mark Zhang +Reviewed-by: Maor Gottlieb +Signed-off-by: Jason Gunthorpe +Acked-by: Nicolas Morey +--- + drivers/infiniband/hw/mlx5/qp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c +index 1093d3a0ed43..70ca8ffa9256 100644 +--- a/drivers/infiniband/hw/mlx5/qp.c ++++ b/drivers/infiniband/hw/mlx5/qp.c +@@ -4493,7 +4493,7 @@ static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr, + return -EINVAL; + + if (attr->port_num == 0 || +- attr->port_num > MLX5_CAP_GEN(dev->mdev, num_ports)) { ++ attr->port_num > dev->num_ports) { + mlx5_ib_dbg(dev, "invalid port number %d. number of ports is %d\n", + attr->port_num, dev->num_ports); + return -EINVAL; +-- +2.39.1.1.gbe015eda0162 + diff --git a/patches.suse/RDMA-rdmavt-Delete-unnecessary-NULL-check.patch b/patches.suse/RDMA-rdmavt-Delete-unnecessary-NULL-check.patch new file mode 100644 index 0000000..084c601 --- /dev/null +++ b/patches.suse/RDMA-rdmavt-Delete-unnecessary-NULL-check.patch @@ -0,0 +1,40 @@ +From b73a0b80c69de77d8d4942abb37066531c0169b2 Mon Sep 17 00:00:00 2001 +From: Natalia Petrova +Date: Fri, 3 Mar 2023 15:44:08 +0300 +Subject: [PATCH 1/1] RDMA/rdmavt: Delete unnecessary NULL check +Git-commit: b73a0b80c69de77d8d4942abb37066531c0169b2 +Patch-mainline: v6.4-rc1 +References: git-fixes + +There is no need to check 'rdi->qp_dev' for NULL. The field 'qp_dev' +is created in rvt_register_device() which will fail if the 'qp_dev' +allocation fails in rvt_driver_qp_init(). Overwise this pointer +doesn't changed and passed to rvt_qp_exit() by the next step. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 0acb0cc7ecc1 ("IB/rdmavt: Initialize and teardown of qpn table") +Signed-off-by: Natalia Petrova +Link: https://lore.kernel.org/r/20230303124408.16685-1-n.petrova@fintech.ru +Signed-off-by: Leon Romanovsky +Acked-by: Nicolas Morey +--- + drivers/infiniband/sw/rdmavt/qp.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c +index 3f707e1fa517..2d143a9d2027 100644 +--- a/drivers/infiniband/sw/rdmavt/qp.c ++++ b/drivers/infiniband/sw/rdmavt/qp.c +@@ -464,8 +464,6 @@ void rvt_qp_exit(struct rvt_dev_info *rdi) + if (qps_inuse) + rvt_pr_err(rdi, "QP memory leak! %u still in use\n", + qps_inuse); +- if (!rdi->qp_dev) +- return; + + kfree(rdi->qp_dev->qp_table); + free_qpn_table(&rdi->qp_dev->qpn_table); +-- +2.39.1.1.gbe015eda0162 + diff --git a/patches.suse/RDMA-rxe-Remove-tasklet-call-from-rxe_cq.c.patch b/patches.suse/RDMA-rxe-Remove-tasklet-call-from-rxe_cq.c.patch new file mode 100644 index 0000000..c89f370 --- /dev/null +++ b/patches.suse/RDMA-rxe-Remove-tasklet-call-from-rxe_cq.c.patch @@ -0,0 +1,129 @@ +From 78b26a335310a097d6b22581b706050db42f196c Mon Sep 17 00:00:00 2001 +From: Bob Pearson +Date: Mon, 27 Mar 2023 16:56:44 -0500 +Subject: [PATCH 1/1] RDMA/rxe: Remove tasklet call from rxe_cq.c +Git-commit: 78b26a335310a097d6b22581b706050db42f196c +Patch-mainline: v6.4-rc1 +References: git-fixes + +Remove the tasklet call in rxe_cq.c and also the is_dying in the +cq struct. There is no reason for the rxe driver to defer the call +to the cq completion handler by scheduling a tasklet. rxe_cq_post() +is not called in a hard irq context. + +The rxe driver currently is incorrect because the tasklet call is +made without protecting the cq pointer with a reference from having +the underlying memory freed before the deferred routine is called. +Executing the comp_handler inline fixes this problem. + +Fixes: 8700e3e7c485 ("Soft RoCE driver") +Signed-off-by: Bob Pearson +Link: https://lore.kernel.org/r/20230327215643.10410-1-rpearsonhpe@gmail.com +Acked-by: Zhu Yanjun +Signed-off-by: Leon Romanovsky +Acked-by: Nicolas Morey +--- + drivers/infiniband/sw/rxe/rxe_cq.c | 32 +++------------------------ + drivers/infiniband/sw/rxe/rxe_verbs.c | 2 -- + drivers/infiniband/sw/rxe/rxe_verbs.h | 2 -- + 3 files changed, 3 insertions(+), 33 deletions(-) + +diff --git a/drivers/infiniband/sw/rxe/rxe_cq.c b/drivers/infiniband/sw/rxe/rxe_cq.c +index 66a13c935d50..20ff0c0c4605 100644 +--- a/drivers/infiniband/sw/rxe/rxe_cq.c ++++ b/drivers/infiniband/sw/rxe/rxe_cq.c +@@ -39,21 +39,6 @@ err1: + return -EINVAL; + } + +-static void rxe_send_complete(struct tasklet_struct *t) +-{ +- struct rxe_cq *cq = from_tasklet(cq, t, comp_task); +- unsigned long flags; +- +- spin_lock_irqsave(&cq->cq_lock, flags); +- if (cq->is_dying) { +- spin_unlock_irqrestore(&cq->cq_lock, flags); +- return; +- } +- spin_unlock_irqrestore(&cq->cq_lock, flags); +- +- cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context); +-} +- + int rxe_cq_from_init(struct rxe_dev *rxe, struct rxe_cq *cq, int cqe, + int comp_vector, struct ib_udata *udata, + struct rxe_create_cq_resp __user *uresp) +@@ -79,10 +64,6 @@ int rxe_cq_from_init(struct rxe_dev *rxe, struct rxe_cq *cq, int cqe, + + cq->is_user = uresp; + +- cq->is_dying = false; +- +- tasklet_setup(&cq->comp_task, rxe_send_complete); +- + spin_lock_init(&cq->cq_lock); + cq->ibcq.cqe = cqe; + return 0; +@@ -103,6 +84,7 @@ int rxe_cq_resize_queue(struct rxe_cq *cq, int cqe, + return err; + } + ++/* caller holds reference to cq */ + int rxe_cq_post(struct rxe_cq *cq, struct rxe_cqe *cqe, int solicited) + { + struct ib_event ev; +@@ -136,21 +118,13 @@ int rxe_cq_post(struct rxe_cq *cq, struct rxe_cqe *cqe, int solicited) + if ((cq->notify == IB_CQ_NEXT_COMP) || + (cq->notify == IB_CQ_SOLICITED && solicited)) { + cq->notify = 0; +- tasklet_schedule(&cq->comp_task); ++ ++ cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context); + } + + return 0; + } + +-void rxe_cq_disable(struct rxe_cq *cq) +-{ +- unsigned long flags; +- +- spin_lock_irqsave(&cq->cq_lock, flags); +- cq->is_dying = true; +- spin_unlock_irqrestore(&cq->cq_lock, flags); +-} +- + void rxe_cq_cleanup(struct rxe_pool_entry *arg) + { + struct rxe_cq *cq = container_of(arg, typeof(*cq), pelem); +diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c +index e7ae7e5513f1..065e98583cd6 100644 +--- a/drivers/infiniband/sw/rxe/rxe_verbs.c ++++ b/drivers/infiniband/sw/rxe/rxe_verbs.c +@@ -803,8 +803,6 @@ static int rxe_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata) + { + struct rxe_cq *cq = to_rcq(ibcq); + +- rxe_cq_disable(cq); +- + rxe_drop_ref(cq); + return 0; + } +diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h +index c269ae2a3224..d812093a3916 100644 +--- a/drivers/infiniband/sw/rxe/rxe_verbs.h ++++ b/drivers/infiniband/sw/rxe/rxe_verbs.h +@@ -63,9 +63,7 @@ struct rxe_cq { + struct rxe_queue *queue; + spinlock_t cq_lock; + u8 notify; +- bool is_dying; + bool is_user; +- struct tasklet_struct comp_task; + }; + + enum wqe_state { +-- +2.39.1.1.gbe015eda0162 + diff --git a/patches.suse/RDMA-siw-Fix-potential-page_array-out-of-range-acces.patch b/patches.suse/RDMA-siw-Fix-potential-page_array-out-of-range-acces.patch new file mode 100644 index 0000000..4154a05 --- /dev/null +++ b/patches.suse/RDMA-siw-Fix-potential-page_array-out-of-range-acces.patch @@ -0,0 +1,38 @@ +From 271bfcfb83a9f77cbae3d6e1a16e3c14132922f0 Mon Sep 17 00:00:00 2001 +From: Daniil Dulov +Date: Mon, 27 Feb 2023 01:17:51 -0800 +Subject: [PATCH 1/1] RDMA/siw: Fix potential page_array out of range access +Git-commit: 271bfcfb83a9f77cbae3d6e1a16e3c14132922f0 +Patch-mainline: v6.4-rc1 +References: git-fixes + +When seg is equal to MAX_ARRAY, the loop should break, otherwise +it will result in out of range access. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: b9be6f18cf9e ("rdma/siw: transmit path") +Signed-off-by: Daniil Dulov +Link: https://lore.kernel.org/r/20230227091751.589612-1-d.dulov@aladdin.ru +Signed-off-by: Leon Romanovsky +Acked-by: Nicolas Morey +--- + drivers/infiniband/sw/siw/siw_qp_tx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/sw/siw/siw_qp_tx.c b/drivers/infiniband/sw/siw/siw_qp_tx.c +index 05052b49107f..6bb9e9e81ff4 100644 +--- a/drivers/infiniband/sw/siw/siw_qp_tx.c ++++ b/drivers/infiniband/sw/siw/siw_qp_tx.c +@@ -558,7 +558,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s) + data_len -= plen; + fp_off = 0; + +- if (++seg > (int)MAX_ARRAY) { ++ if (++seg >= (int)MAX_ARRAY) { + siw_dbg_qp(tx_qp(c_tx), "to many fragments\n"); + siw_unmap_pages(iov, kmap_mask, seg-1); + wqe->processed -= c_tx->bytes_unsent; +-- +2.39.1.1.gbe015eda0162 + diff --git a/patches.suse/RDMA-siw-Remove-namespace-check-from-siw_netdev_even.patch b/patches.suse/RDMA-siw-Remove-namespace-check-from-siw_netdev_even.patch new file mode 100644 index 0000000..ffbbcc2 --- /dev/null +++ b/patches.suse/RDMA-siw-Remove-namespace-check-from-siw_netdev_even.patch @@ -0,0 +1,43 @@ +From 266e9b3475ba82212062771fdbc40be0e3c06ec8 Mon Sep 17 00:00:00 2001 +From: Tetsuo Handa +Date: Sun, 2 Apr 2023 14:10:13 +0900 +Subject: [PATCH 1/1] RDMA/siw: Remove namespace check from siw_netdev_event() +Git-commit: 266e9b3475ba82212062771fdbc40be0e3c06ec8 +Patch-mainline: v6.4-rc1 +References: git-fixes + +syzbot is reporting that siw_netdev_event(NETDEV_UNREGISTER) cannot destroy +siw_device created after unshare(CLONE_NEWNET) due to net namespace check. +It seems that this check was by error there and should be removed. + +Reported-by: syzbot +Link: https://syzkaller.appspot.com/bug?extid=5e70d01ee8985ae62a3b +Suggested-by: Jason Gunthorpe +Suggested-by: Leon Romanovsky +Fixes: bdcf26bf9b3a ("rdma/siw: network and RDMA core interface") +Signed-off-by: Tetsuo Handa +Link: https://lore.kernel.org/r/a44e9ac5-44e2-d575-9e30-02483cc7ffd1@I-love.SAKURA.ne.jp +Reviewed-by: Bernard Metzler +Signed-off-by: Leon Romanovsky +Acked-by: Nicolas Morey +--- + drivers/infiniband/sw/siw/siw_main.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/infiniband/sw/siw/siw_main.c b/drivers/infiniband/sw/siw/siw_main.c +index dacc174604bf..65b5cda5457b 100644 +--- a/drivers/infiniband/sw/siw/siw_main.c ++++ b/drivers/infiniband/sw/siw/siw_main.c +@@ -437,9 +437,6 @@ static int siw_netdev_event(struct notifier_block *nb, unsigned long event, + + dev_dbg(&netdev->dev, "siw: event %lu\n", event); + +- if (dev_net(netdev) != &init_net) +- return NOTIFY_OK; +- + base_dev = ib_device_get_by_netdev(netdev, RDMA_DRIVER_SIW); + if (!base_dev) + return NOTIFY_OK; +-- +2.39.1.1.gbe015eda0162 + diff --git a/patches.suse/RDMA-srpt-Add-a-check-for-valid-mad_agent-pointer.patch b/patches.suse/RDMA-srpt-Add-a-check-for-valid-mad_agent-pointer.patch new file mode 100644 index 0000000..a4553a4 --- /dev/null +++ b/patches.suse/RDMA-srpt-Add-a-check-for-valid-mad_agent-pointer.patch @@ -0,0 +1,111 @@ +From eca5cd9474cd26d62f9756f536e2e656d3f62f3a Mon Sep 17 00:00:00 2001 +From: Saravanan Vajravel +Date: Wed, 5 Apr 2023 21:25:49 -0700 +Subject: [PATCH 1/1] RDMA/srpt: Add a check for valid 'mad_agent' pointer +Git-commit: eca5cd9474cd26d62f9756f536e2e656d3f62f3a +Patch-mainline: v6.4-rc1 +References: git-fixes + +When unregistering MAD agent, srpt module has a non-null check +for 'mad_agent' pointer before invoking ib_unregister_mad_agent(). +This check can pass if 'mad_agent' variable holds an error value. +The 'mad_agent' can have an error value for a short window when +srpt_add_one() and srpt_remove_one() is executed simultaneously. + +In srpt module, added a valid pointer check for 'sport->mad_agent' +before unregistering MAD agent. + +This issue can hit when RoCE driver unregisters ib_device + +Stack Trace: +------------ +BUG: kernel NULL pointer dereference, address: 000000000000004d +PGD 145003067 P4D 145003067 PUD 2324fe067 PMD 0 +Oops: 0002 [#1] PREEMPT SMP NOPTI +CPU: 10 PID: 4459 Comm: kworker/u80:0 Kdump: loaded Tainted: P +Hardware name: Dell Inc. PowerEdge R640/06NR82, BIOS 2.5.4 01/13/2020 +Workqueue: bnxt_re bnxt_re_task [bnxt_re] +RIP: 0010:_raw_spin_lock_irqsave+0x19/0x40 +Call Trace: + ib_unregister_mad_agent+0x46/0x2f0 [ib_core] + IPv6: ADDRCONF(NETDEV_CHANGE): bond0: link becomes ready + ? __schedule+0x20b/0x560 + srpt_unregister_mad_agent+0x93/0xd0 [ib_srpt] + srpt_remove_one+0x20/0x150 [ib_srpt] + remove_client_context+0x88/0xd0 [ib_core] + bond0: (slave p2p1): link status definitely up, 100000 Mbps full duplex + disable_device+0x8a/0x160 [ib_core] + bond0: active interface up! + ? kernfs_name_hash+0x12/0x80 + (NULL device *): Bonding Info Received: rdev: 000000006c0b8247 + __ib_unregister_device+0x42/0xb0 [ib_core] + (NULL device *): Master: mode: 4 num_slaves:2 + ib_unregister_device+0x22/0x30 [ib_core] + (NULL device *): Slave: id: 105069936 name:p2p1 link:0 state:0 + bnxt_re_stopqps_and_ib_uninit+0x83/0x90 [bnxt_re] + bnxt_re_alloc_lag+0x12e/0x4e0 [bnxt_re] + +Fixes: a42d985bd5b2 ("ib_srpt: Initial SRP Target merge for v3.3-rc1") +Reviewed-by: Selvin Xavier +Reviewed-by: Kashyap Desai +Signed-off-by: Saravanan Vajravel +Link: https://lore.kernel.org/r/20230406042549.507328-1-saravanan.vajravel@broadcom.com +Reviewed-by: Bart Van Assche +Signed-off-by: Leon Romanovsky +Acked-by: Nicolas Morey +--- + drivers/infiniband/ulp/srpt/ib_srpt.c | 23 +++++++++++++---------- + 1 file changed, 13 insertions(+), 10 deletions(-) + +diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c +index 3c3fae738c3e..25e799dba999 100644 +--- a/drivers/infiniband/ulp/srpt/ib_srpt.c ++++ b/drivers/infiniband/ulp/srpt/ib_srpt.c +@@ -549,6 +549,7 @@ static int srpt_format_guid(char *buf, unsigned int size, const __be64 *guid) + */ + static int srpt_refresh_port(struct srpt_port *sport) + { ++ struct ib_mad_agent *mad_agent; + struct ib_mad_reg_req reg_req; + struct ib_port_modify port_modify; + struct ib_port_attr port_attr; +@@ -593,24 +594,26 @@ static int srpt_refresh_port(struct srpt_port *sport) + set_bit(IB_MGMT_METHOD_GET, reg_req.method_mask); + set_bit(IB_MGMT_METHOD_SET, reg_req.method_mask); + +- sport->mad_agent = ib_register_mad_agent(sport->sdev->device, +- sport->port, +- IB_QPT_GSI, +- ®_req, 0, +- srpt_mad_send_handler, +- srpt_mad_recv_handler, +- sport, 0); +- if (IS_ERR(sport->mad_agent)) { ++ mad_agent = ib_register_mad_agent(sport->sdev->device, ++ sport->port, ++ IB_QPT_GSI, ++ ®_req, 0, ++ srpt_mad_send_handler, ++ srpt_mad_recv_handler, ++ sport, 0); ++ if (IS_ERR(mad_agent)) { + pr_err("%s-%d: MAD agent registration failed (%ld). Note: this is expected if SR-IOV is enabled.\n", + dev_name(&sport->sdev->device->dev), sport->port, +- PTR_ERR(sport->mad_agent)); ++ PTR_ERR(mad_agent)); + sport->mad_agent = NULL; + memset(&port_modify, 0, sizeof(port_modify)); + port_modify.clr_port_cap_mask = IB_PORT_DEVICE_MGMT_SUP; + ib_modify_port(sport->sdev->device, sport->port, 0, + &port_modify); +- ++ return 0; + } ++ ++ sport->mad_agent = mad_agent; + } + + return 0; +-- +2.39.1.1.gbe015eda0162 + diff --git a/patches.suse/USB-dwc3-Fix-a-checkpatch-warning-in-core.c.patch b/patches.suse/USB-dwc3-Fix-a-checkpatch-warning-in-core.c.patch new file mode 100644 index 0000000..d14a3c6 --- /dev/null +++ b/patches.suse/USB-dwc3-Fix-a-checkpatch-warning-in-core.c.patch @@ -0,0 +1,75 @@ +From d090c7a2ab84663185e4abda21d7d83880937c8a Mon Sep 17 00:00:00 2001 +From: Kushagra Verma +Date: Wed, 11 May 2022 21:19:36 +0530 +Subject: [PATCH] USB / dwc3: Fix a checkpatch warning in core.c +Git-commit: d090c7a2ab84663185e4abda21d7d83880937c8a +References: git-fixes +Patch-mainline: v5.19-rc1 + +This patch fixes the following checkpatch.pl warning in core.c: + WARNING: braces {} are not necessary for any arm of this statement + +Signed-off-by: Kushagra Verma +Link: https://lore.kernel.org/r/TYZPR01MB39354534E2F9EE4E022DDAFFF8C89@TYZPR01MB3935.apcprd01.prod.exchangelabs.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/dwc3/core.c | 20 ++++++++------------ + 1 file changed, 8 insertions(+), 12 deletions(-) + +diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c +index 7d023130e145..c78205c5e19f 100644 +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -1266,40 +1266,36 @@ static int dwc3_core_get_phy(struct dwc3 *dwc) + + if (IS_ERR(dwc->usb2_phy)) { + ret = PTR_ERR(dwc->usb2_phy); +- if (ret == -ENXIO || ret == -ENODEV) { ++ if (ret == -ENXIO || ret == -ENODEV) + dwc->usb2_phy = NULL; +- } else { ++ else + return dev_err_probe(dev, ret, "no usb2 phy configured\n"); +- } + } + + if (IS_ERR(dwc->usb3_phy)) { + ret = PTR_ERR(dwc->usb3_phy); +- if (ret == -ENXIO || ret == -ENODEV) { ++ if (ret == -ENXIO || ret == -ENODEV) + dwc->usb3_phy = NULL; +- } else { ++ else + return dev_err_probe(dev, ret, "no usb3 phy configured\n"); +- } + } + + dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy"); + if (IS_ERR(dwc->usb2_generic_phy)) { + ret = PTR_ERR(dwc->usb2_generic_phy); +- if (ret == -ENOSYS || ret == -ENODEV) { ++ if (ret == -ENOSYS || ret == -ENODEV) + dwc->usb2_generic_phy = NULL; +- } else { ++ else + return dev_err_probe(dev, ret, "no usb2 phy configured\n"); +- } + } + + dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy"); + if (IS_ERR(dwc->usb3_generic_phy)) { + ret = PTR_ERR(dwc->usb3_generic_phy); +- if (ret == -ENOSYS || ret == -ENODEV) { ++ if (ret == -ENOSYS || ret == -ENODEV) + dwc->usb3_generic_phy = NULL; +- } else { ++ else + return dev_err_probe(dev, ret, "no usb3 phy configured\n"); +- } + } + + return 0; +-- +2.40.1 + diff --git a/patches.suse/ata-pata_octeon_cf-drop-kernel-doc-notation.patch b/patches.suse/ata-pata_octeon_cf-drop-kernel-doc-notation.patch new file mode 100644 index 0000000..5977691 --- /dev/null +++ b/patches.suse/ata-pata_octeon_cf-drop-kernel-doc-notation.patch @@ -0,0 +1,100 @@ +From 1aff53b2fd903b300dfd71af0064c21fbca313c6 Mon Sep 17 00:00:00 2001 +From: Randy Dunlap +Date: Mon, 13 Feb 2023 13:25:49 -0800 +Subject: [PATCH] ata: pata_octeon_cf: drop kernel-doc notation +Git-commit: 1aff53b2fd903b300dfd71af0064c21fbca313c6 +Patch-mainline: v6.2 +References: git-fixes + +Fix a slew of kernel-doc warnings in pata_octeon_cf.c by changing +all "/**" comments to "/*" since they are not in kernel-doc format. + +Fixes: 3c929c6f5aa7 ("libata: New driver for OCTEON SOC Compact Flash interface (v7).") +Signed-off-by: Randy Dunlap +Reported-by: kernel test robot +Link: https://lore.kernel.org/all/202302101722.5O56RClE-lkp@intel.com/ +Cc: David Daney +Cc: Damien Le Moal +Cc: Mauro Carvalho Chehab +Cc: linux-ide@vger.kernel.org +Signed-off-by: Damien Le Moal +Acked-by: Takashi Iwai + +--- + drivers/ata/pata_octeon_cf.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/ata/pata_octeon_cf.c ++++ b/drivers/ata/pata_octeon_cf.c +@@ -67,7 +67,7 @@ module_param(enable_dma, int, 0444); + MODULE_PARM_DESC(enable_dma, + "Enable use of DMA on interfaces that support it (0=no dma [default], 1=use dma)"); + +-/** ++/* + * Convert nanosecond based time to setting used in the + * boot bus timing register, based on timing multiple + */ +@@ -118,7 +118,7 @@ static void octeon_cf_set_boot_reg_cfg(i + cvmx_write_csr(CVMX_MIO_BOOT_REG_CFGX(cs), reg_cfg.u64); + } + +-/** ++/* + * Called after libata determines the needed PIO mode. This + * function programs the Octeon bootbus regions to support the + * timing requirements of the PIO mode. +@@ -282,7 +282,7 @@ static void octeon_cf_set_dmamode(struct + cvmx_write_csr(cf_port->dma_base + DMA_TIM, dma_tim.u64); + } + +-/** ++/* + * Handle an 8 bit I/O request. + * + * @qc: Queued command +@@ -321,7 +321,7 @@ static unsigned int octeon_cf_data_xfer8 + return buflen; + } + +-/** ++/* + * Handle a 16 bit I/O request. + * + * @qc: Queued command +@@ -376,7 +376,7 @@ static unsigned int octeon_cf_data_xfer1 + return buflen; + } + +-/** ++/* + * Read the taskfile for 16bit non-True IDE only. + */ + static void octeon_cf_tf_read16(struct ata_port *ap, struct ata_taskfile *tf) +@@ -459,7 +459,7 @@ static int octeon_cf_softreset16(struct + return 0; + } + +-/** ++/* + * Load the taskfile for 16bit non-True IDE only. The device_addr is + * not loaded, we do this as part of octeon_cf_exec_command16. + */ +@@ -551,7 +551,7 @@ static void octeon_cf_dma_setup(struct a + DPRINTK("EXIT\n"); + } + +-/** ++/* + * Start a DMA transfer that was already setup + * + * @qc: Information about the DMA +@@ -612,7 +612,7 @@ static void octeon_cf_dma_start(struct a + cvmx_write_csr(cf_port->dma_base + DMA_CFG, mio_boot_dma_cfg.u64); + } + +-/** ++/* + * + * LOCKING: + * spin_lock_irqsave(host lock) diff --git a/patches.suse/can-kvaser_usb-Add-struct-kvaser_usb_busparams.patch b/patches.suse/can-kvaser_usb-Add-struct-kvaser_usb_busparams.patch new file mode 100644 index 0000000..92f3043 --- /dev/null +++ b/patches.suse/can-kvaser_usb-Add-struct-kvaser_usb_busparams.patch @@ -0,0 +1,133 @@ +From 00e5786177649c1e3110f9454fdd34e336597265 Mon Sep 17 00:00:00 2001 +From: Jimmy Assarsson +Date: Mon, 10 Oct 2022 20:52:36 +0200 +Subject: [PATCH] can: kvaser_usb: Add struct kvaser_usb_busparams +Git-commit: 00e5786177649c1e3110f9454fdd34e336597265 +Patch-mainline: v6.2-rc1 +References: git-fixes + +Add struct kvaser_usb_busparams containing the busparameters used in +CMD_{SET,GET}_BUSPARAMS* commands. + +Tested-by: Anssi Hannula +Signed-off-by: Jimmy Assarsson +Link: https://lore.kernel.org/all/20221010185237.319219-11-extja@kvaser.com +Signed-off-by: Marc Kleine-Budde +Acked-by: Takashi Iwai + +--- + drivers/net/can/usb/kvaser_usb/kvaser_usb.h | 8 +++++ + drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 32 ++++++++-------------- + drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 18 ++++-------- + 3 files changed, 27 insertions(+), 31 deletions(-) + +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h +@@ -76,6 +76,14 @@ struct kvaser_usb_tx_urb_context { + int dlc; + }; + ++struct kvaser_usb_busparams { ++ __le32 bitrate; ++ u8 tseg1; ++ u8 tseg2; ++ u8 sjw; ++ u8 nsamples; ++} __packed; ++ + struct kvaser_usb { + struct usb_device *udev; + struct usb_interface *intf; +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +@@ -196,17 +196,9 @@ struct kvaser_cmd_chip_state_event { + #define KVASER_USB_HYDRA_BUS_MODE_CANFD_ISO 0x01 + #define KVASER_USB_HYDRA_BUS_MODE_NONISO 0x02 + struct kvaser_cmd_set_busparams { +- __le32 bitrate; +- u8 tseg1; +- u8 tseg2; +- u8 sjw; +- u8 nsamples; ++ struct kvaser_usb_busparams busparams_arb; + u8 reserved0[4]; +- __le32 bitrate_d; +- u8 tseg1_d; +- u8 tseg2_d; +- u8 sjw_d; +- u8 nsamples_d; ++ struct kvaser_usb_busparams busparams_data; + u8 canfd_mode; + u8 reserved1[7]; + } __packed; +@@ -1538,11 +1530,11 @@ static int kvaser_usb_hydra_set_bittimin + return -ENOMEM; + + cmd->header.cmd_no = CMD_SET_BUSPARAMS_REQ; +- cmd->set_busparams_req.bitrate = cpu_to_le32(bt->bitrate); +- cmd->set_busparams_req.sjw = (u8)sjw; +- cmd->set_busparams_req.tseg1 = (u8)tseg1; +- cmd->set_busparams_req.tseg2 = (u8)tseg2; +- cmd->set_busparams_req.nsamples = 1; ++ cmd->set_busparams_req.busparams_arb.bitrate = cpu_to_le32(bt->bitrate); ++ cmd->set_busparams_req.busparams_arb.sjw = (u8)sjw; ++ cmd->set_busparams_req.busparams_arb.tseg1 = (u8)tseg1; ++ cmd->set_busparams_req.busparams_arb.tseg2 = (u8)tseg2; ++ cmd->set_busparams_req.busparams_arb.nsamples = 1; + + kvaser_usb_hydra_set_cmd_dest_he + (cmd, dev->card_data.hydra.channel_to_he[priv->channel]); +@@ -1572,11 +1564,11 @@ static int kvaser_usb_hydra_set_data_bit + return -ENOMEM; + + cmd->header.cmd_no = CMD_SET_BUSPARAMS_FD_REQ; +- cmd->set_busparams_req.bitrate_d = cpu_to_le32(dbt->bitrate); +- cmd->set_busparams_req.sjw_d = (u8)sjw; +- cmd->set_busparams_req.tseg1_d = (u8)tseg1; +- cmd->set_busparams_req.tseg2_d = (u8)tseg2; +- cmd->set_busparams_req.nsamples_d = 1; ++ cmd->set_busparams_req.busparams_data.bitrate = cpu_to_le32(dbt->bitrate); ++ cmd->set_busparams_req.busparams_data.sjw = (u8)sjw; ++ cmd->set_busparams_req.busparams_data.tseg1 = (u8)tseg1; ++ cmd->set_busparams_req.busparams_data.tseg2 = (u8)tseg2; ++ cmd->set_busparams_req.busparams_data.nsamples = 1; + + if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { + if (priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO) +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +@@ -162,11 +162,7 @@ struct usbcan_cmd_softinfo { + struct kvaser_cmd_busparams { + u8 tid; + u8 channel; +- __le32 bitrate; +- u8 tseg1; +- u8 tseg2; +- u8 sjw; +- u8 no_samp; ++ struct kvaser_usb_busparams busparams; + } __packed; + + struct kvaser_cmd_tx_can { +@@ -1645,15 +1641,15 @@ static int kvaser_usb_leaf_set_bittiming + cmd->len = CMD_HEADER_LEN + sizeof(struct kvaser_cmd_busparams); + cmd->u.busparams.channel = priv->channel; + cmd->u.busparams.tid = 0xff; +- cmd->u.busparams.bitrate = cpu_to_le32(bt->bitrate); +- cmd->u.busparams.sjw = bt->sjw; +- cmd->u.busparams.tseg1 = bt->prop_seg + bt->phase_seg1; +- cmd->u.busparams.tseg2 = bt->phase_seg2; ++ cmd->u.busparams.busparams.bitrate = cpu_to_le32(bt->bitrate); ++ cmd->u.busparams.busparams.sjw = bt->sjw; ++ cmd->u.busparams.busparams.tseg1 = bt->prop_seg + bt->phase_seg1; ++ cmd->u.busparams.busparams.tseg2 = bt->phase_seg2; + + if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) +- cmd->u.busparams.no_samp = 3; ++ cmd->u.busparams.busparams.nsamples = 3; + else +- cmd->u.busparams.no_samp = 1; ++ cmd->u.busparams.busparams.nsamples = 1; + + rc = kvaser_usb_send_cmd(dev, cmd, cmd->len); + diff --git a/patches.suse/can-kvaser_usb-kvaser_usb_leaf-Get-capabilities-from.patch b/patches.suse/can-kvaser_usb-kvaser_usb_leaf-Get-capabilities-from.patch new file mode 100644 index 0000000..fb27539 --- /dev/null +++ b/patches.suse/can-kvaser_usb-kvaser_usb_leaf-Get-capabilities-from.patch @@ -0,0 +1,231 @@ +From 35364f5b41a4917fe94a3f393d149b63ec583297 Mon Sep 17 00:00:00 2001 +From: Jimmy Assarsson +Date: Mon, 10 Oct 2022 20:52:28 +0200 +Subject: [PATCH] can: kvaser_usb: kvaser_usb_leaf: Get capabilities from device +Git-commit: 35364f5b41a4917fe94a3f393d149b63ec583297 +Patch-mainline: v6.2-rc1 +References: git-fixes + +Use the CMD_GET_CAPABILITIES_REQ command to query the device for certain +capabilities. We are only interested in LISTENONLY mode and wither the +device reports CAN error counters. + +Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices") +Reported-by: Anssi Hannula +Tested-by: Anssi Hannula +Signed-off-by: Jimmy Assarsson +Link: https://lore.kernel.org/all/20221010185237.319219-3-extja@kvaser.com +Signed-off-by: Marc Kleine-Budde +Acked-by: Takashi Iwai + +--- + .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 144 +++++++++++++++++- + 1 file changed, 143 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +index 50f2ac8319ff..c87b13dc1048 100644 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +@@ -74,6 +74,8 @@ + #define CMD_TX_ACKNOWLEDGE 50 + #define CMD_CAN_ERROR_EVENT 51 + #define CMD_FLUSH_QUEUE_REPLY 68 ++#define CMD_GET_CAPABILITIES_REQ 95 ++#define CMD_GET_CAPABILITIES_RESP 96 + + #define CMD_LEAF_LOG_MESSAGE 106 + +@@ -83,6 +85,8 @@ + #define KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK BIT(5) + #define KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK BIT(6) + ++#define KVASER_USB_LEAF_SWOPTION_EXT_CAP BIT(12) ++ + /* error factors */ + #define M16C_EF_ACKE BIT(0) + #define M16C_EF_CRCE BIT(1) +@@ -278,6 +282,28 @@ struct leaf_cmd_log_message { + u8 data[8]; + } __packed; + ++/* Sub commands for cap_req and cap_res */ ++#define KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE 0x02 ++#define KVASER_USB_LEAF_CAP_CMD_ERR_REPORT 0x05 ++struct kvaser_cmd_cap_req { ++ __le16 padding0; ++ __le16 cap_cmd; ++ __le16 padding1; ++ __le16 channel; ++} __packed; ++ ++/* Status codes for cap_res */ ++#define KVASER_USB_LEAF_CAP_STAT_OK 0x00 ++#define KVASER_USB_LEAF_CAP_STAT_NOT_IMPL 0x01 ++#define KVASER_USB_LEAF_CAP_STAT_UNAVAIL 0x02 ++struct kvaser_cmd_cap_res { ++ __le16 padding; ++ __le16 cap_cmd; ++ __le16 status; ++ __le32 mask; ++ __le32 value; ++} __packed; ++ + struct kvaser_cmd { + u8 len; + u8 id; +@@ -295,6 +321,8 @@ struct kvaser_cmd { + struct leaf_cmd_chip_state_event chip_state_event; + struct leaf_cmd_error_event error_event; + struct leaf_cmd_log_message log_message; ++ struct kvaser_cmd_cap_req cap_req; ++ struct kvaser_cmd_cap_res cap_res; + } __packed leaf; + + union { +@@ -324,6 +352,7 @@ static const u8 kvaser_usb_leaf_cmd_sizes_leaf[] = { + [CMD_LEAF_LOG_MESSAGE] = kvaser_fsize(u.leaf.log_message), + [CMD_CHIP_STATE_EVENT] = kvaser_fsize(u.leaf.chip_state_event), + [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.leaf.error_event), ++ [CMD_GET_CAPABILITIES_RESP] = kvaser_fsize(u.leaf.cap_res), + /* ignored events: */ + [CMD_FLUSH_QUEUE_REPLY] = CMD_SIZE_ANY, + }; +@@ -606,6 +635,9 @@ static void kvaser_usb_leaf_get_software_info_leaf(struct kvaser_usb *dev, + dev->fw_version = le32_to_cpu(softinfo->fw_version); + dev->max_tx_urbs = le16_to_cpu(softinfo->max_outstanding_tx); + ++ if (sw_options & KVASER_USB_LEAF_SWOPTION_EXT_CAP) ++ dev->card_data.capabilities |= KVASER_USB_CAP_EXT_CAP; ++ + if (dev->driver_info->quirks & KVASER_USB_QUIRK_IGNORE_CLK_FREQ) { + /* Firmware expects bittiming parameters calculated for 16MHz + * clock, regardless of the actual clock +@@ -693,6 +725,116 @@ static int kvaser_usb_leaf_get_card_info(struct kvaser_usb *dev) + return 0; + } + ++static int kvaser_usb_leaf_get_single_capability(struct kvaser_usb *dev, ++ u16 cap_cmd_req, u16 *status) ++{ ++ struct kvaser_usb_dev_card_data *card_data = &dev->card_data; ++ struct kvaser_cmd *cmd; ++ u32 value = 0; ++ u32 mask = 0; ++ u16 cap_cmd_res; ++ int err; ++ int i; ++ ++ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); ++ if (!cmd) ++ return -ENOMEM; ++ ++ cmd->id = CMD_GET_CAPABILITIES_REQ; ++ cmd->u.leaf.cap_req.cap_cmd = cpu_to_le16(cap_cmd_req); ++ cmd->len = CMD_HEADER_LEN + sizeof(struct kvaser_cmd_cap_req); ++ ++ err = kvaser_usb_send_cmd(dev, cmd, cmd->len); ++ if (err) ++ goto end; ++ ++ err = kvaser_usb_leaf_wait_cmd(dev, CMD_GET_CAPABILITIES_RESP, cmd); ++ if (err) ++ goto end; ++ ++ *status = le16_to_cpu(cmd->u.leaf.cap_res.status); ++ ++ if (*status != KVASER_USB_LEAF_CAP_STAT_OK) ++ goto end; ++ ++ cap_cmd_res = le16_to_cpu(cmd->u.leaf.cap_res.cap_cmd); ++ switch (cap_cmd_res) { ++ case KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE: ++ case KVASER_USB_LEAF_CAP_CMD_ERR_REPORT: ++ value = le32_to_cpu(cmd->u.leaf.cap_res.value); ++ mask = le32_to_cpu(cmd->u.leaf.cap_res.mask); ++ break; ++ default: ++ dev_warn(&dev->intf->dev, "Unknown capability command %u\n", ++ cap_cmd_res); ++ break; ++ } ++ ++ for (i = 0; i < dev->nchannels; i++) { ++ if (BIT(i) & (value & mask)) { ++ switch (cap_cmd_res) { ++ case KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE: ++ card_data->ctrlmode_supported |= ++ CAN_CTRLMODE_LISTENONLY; ++ break; ++ case KVASER_USB_LEAF_CAP_CMD_ERR_REPORT: ++ card_data->capabilities |= ++ KVASER_USB_CAP_BERR_CAP; ++ break; ++ } ++ } ++ } ++ ++end: ++ kfree(cmd); ++ ++ return err; ++} ++ ++static int kvaser_usb_leaf_get_capabilities_leaf(struct kvaser_usb *dev) ++{ ++ int err; ++ u16 status; ++ ++ if (!(dev->card_data.capabilities & KVASER_USB_CAP_EXT_CAP)) { ++ dev_info(&dev->intf->dev, ++ "No extended capability support. Upgrade device firmware.\n"); ++ return 0; ++ } ++ ++ err = kvaser_usb_leaf_get_single_capability(dev, ++ KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE, ++ &status); ++ if (err) ++ return err; ++ if (status) ++ dev_info(&dev->intf->dev, ++ "KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE failed %u\n", ++ status); ++ ++ err = kvaser_usb_leaf_get_single_capability(dev, ++ KVASER_USB_LEAF_CAP_CMD_ERR_REPORT, ++ &status); ++ if (err) ++ return err; ++ if (status) ++ dev_info(&dev->intf->dev, ++ "KVASER_USB_LEAF_CAP_CMD_ERR_REPORT failed %u\n", ++ status); ++ ++ return 0; ++} ++ ++static int kvaser_usb_leaf_get_capabilities(struct kvaser_usb *dev) ++{ ++ int err = 0; ++ ++ if (dev->driver_info->family == KVASER_LEAF) ++ err = kvaser_usb_leaf_get_capabilities_leaf(dev); ++ ++ return err; ++} ++ + static void kvaser_usb_leaf_tx_acknowledge(const struct kvaser_usb *dev, + const struct kvaser_cmd *cmd) + { +@@ -1486,7 +1628,7 @@ const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops = { + .dev_get_software_info = kvaser_usb_leaf_get_software_info, + .dev_get_software_details = NULL, + .dev_get_card_info = kvaser_usb_leaf_get_card_info, +- .dev_get_capabilities = NULL, ++ .dev_get_capabilities = kvaser_usb_leaf_get_capabilities, + .dev_set_opt_mode = kvaser_usb_leaf_set_opt_mode, + .dev_start_chip = kvaser_usb_leaf_start_chip, + .dev_stop_chip = kvaser_usb_leaf_stop_chip, +-- +2.35.3 + diff --git a/patches.suse/can-kvaser_usb-kvaser_usb_leaf-Handle-CMD_ERROR_EVEN.patch b/patches.suse/can-kvaser_usb-kvaser_usb_leaf-Handle-CMD_ERROR_EVEN.patch new file mode 100644 index 0000000..e1a8c48 --- /dev/null +++ b/patches.suse/can-kvaser_usb-kvaser_usb_leaf-Handle-CMD_ERROR_EVEN.patch @@ -0,0 +1,186 @@ +From b24cb2d169e0c9dce664a959e1f2aa9781285dc9 Mon Sep 17 00:00:00 2001 +From: Jimmy Assarsson +Date: Mon, 10 Oct 2022 20:52:30 +0200 +Subject: [PATCH] can: kvaser_usb: kvaser_usb_leaf: Handle CMD_ERROR_EVENT +Git-commit: b24cb2d169e0c9dce664a959e1f2aa9781285dc9 +Patch-mainline: v6.2-rc1 +References: git-fixes + +The device will send an error event command, to indicate certain errors. +This indicates a misbehaving driver, and should never occur. + +Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices") +Tested-by: Anssi Hannula +Co-developed-by: Anssi Hannula +Signed-off-by: Anssi Hannula +Signed-off-by: Jimmy Assarsson +Link: https://lore.kernel.org/all/20221010185237.319219-5-extja@kvaser.com +Signed-off-by: Marc Kleine-Budde +Acked-by: Takashi Iwai + +--- + .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 99 +++++++++++++++++++ + 1 file changed, 99 insertions(+) + +diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +index f34ca9a850aa..e391ec247f54 100644 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +@@ -70,6 +70,7 @@ + #define CMD_GET_CARD_INFO_REPLY 35 + #define CMD_GET_SOFTWARE_INFO 38 + #define CMD_GET_SOFTWARE_INFO_REPLY 39 ++#define CMD_ERROR_EVENT 45 + #define CMD_FLUSH_QUEUE 48 + #define CMD_TX_ACKNOWLEDGE 50 + #define CMD_CAN_ERROR_EVENT 51 +@@ -258,6 +259,28 @@ struct usbcan_cmd_can_error_event { + __le16 time; + } __packed; + ++/* CMD_ERROR_EVENT error codes */ ++#define KVASER_USB_LEAF_ERROR_EVENT_TX_QUEUE_FULL 0x8 ++#define KVASER_USB_LEAF_ERROR_EVENT_PARAM 0x9 ++ ++struct leaf_cmd_error_event { ++ u8 tid; ++ u8 error_code; ++ __le16 timestamp[3]; ++ __le16 padding; ++ __le16 info1; ++ __le16 info2; ++} __packed; ++ ++struct usbcan_cmd_error_event { ++ u8 tid; ++ u8 error_code; ++ __le16 info1; ++ __le16 info2; ++ __le16 timestamp; ++ __le16 padding; ++} __packed; ++ + struct kvaser_cmd_ctrl_mode { + u8 tid; + u8 channel; +@@ -321,6 +344,7 @@ struct kvaser_cmd { + struct leaf_cmd_chip_state_event chip_state_event; + struct leaf_cmd_can_error_event can_error_event; + struct leaf_cmd_log_message log_message; ++ struct leaf_cmd_error_event error_event; + struct kvaser_cmd_cap_req cap_req; + struct kvaser_cmd_cap_res cap_res; + } __packed leaf; +@@ -330,6 +354,7 @@ struct kvaser_cmd { + struct usbcan_cmd_rx_can rx_can; + struct usbcan_cmd_chip_state_event chip_state_event; + struct usbcan_cmd_can_error_event can_error_event; ++ struct usbcan_cmd_error_event error_event; + } __packed usbcan; + + struct kvaser_cmd_tx_can tx_can; +@@ -353,6 +378,7 @@ static const u8 kvaser_usb_leaf_cmd_sizes_leaf[] = { + [CMD_CHIP_STATE_EVENT] = kvaser_fsize(u.leaf.chip_state_event), + [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.leaf.can_error_event), + [CMD_GET_CAPABILITIES_RESP] = kvaser_fsize(u.leaf.cap_res), ++ [CMD_ERROR_EVENT] = kvaser_fsize(u.leaf.error_event), + /* ignored events: */ + [CMD_FLUSH_QUEUE_REPLY] = CMD_SIZE_ANY, + }; +@@ -367,6 +393,7 @@ static const u8 kvaser_usb_leaf_cmd_sizes_usbcan[] = { + [CMD_RX_EXT_MESSAGE] = kvaser_fsize(u.usbcan.rx_can), + [CMD_CHIP_STATE_EVENT] = kvaser_fsize(u.usbcan.chip_state_event), + [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.usbcan.can_error_event), ++ [CMD_ERROR_EVENT] = kvaser_fsize(u.usbcan.error_event), + /* ignored events: */ + [CMD_USBCAN_CLOCK_OVERFLOW_EVENT] = CMD_SIZE_ANY, + }; +@@ -1304,6 +1331,74 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev, + netif_rx(skb); + } + ++static void kvaser_usb_leaf_error_event_parameter(const struct kvaser_usb *dev, ++ const struct kvaser_cmd *cmd) ++{ ++ u16 info1 = 0; ++ ++ switch (dev->driver_info->family) { ++ case KVASER_LEAF: ++ info1 = le16_to_cpu(cmd->u.leaf.error_event.info1); ++ break; ++ case KVASER_USBCAN: ++ info1 = le16_to_cpu(cmd->u.usbcan.error_event.info1); ++ break; ++ } ++ ++ /* info1 will contain the offending cmd_no */ ++ switch (info1) { ++ case CMD_SET_CTRL_MODE: ++ dev_warn(&dev->intf->dev, ++ "CMD_SET_CTRL_MODE error in parameter\n"); ++ break; ++ ++ case CMD_SET_BUS_PARAMS: ++ dev_warn(&dev->intf->dev, ++ "CMD_SET_BUS_PARAMS error in parameter\n"); ++ break; ++ ++ default: ++ dev_warn(&dev->intf->dev, ++ "Unhandled parameter error event cmd_no (%u)\n", ++ info1); ++ break; ++ } ++} ++ ++static void kvaser_usb_leaf_error_event(const struct kvaser_usb *dev, ++ const struct kvaser_cmd *cmd) ++{ ++ u8 error_code = 0; ++ ++ switch (dev->driver_info->family) { ++ case KVASER_LEAF: ++ error_code = cmd->u.leaf.error_event.error_code; ++ break; ++ case KVASER_USBCAN: ++ error_code = cmd->u.usbcan.error_event.error_code; ++ break; ++ } ++ ++ switch (error_code) { ++ case KVASER_USB_LEAF_ERROR_EVENT_TX_QUEUE_FULL: ++ /* Received additional CAN message, when firmware TX queue is ++ * already full. Something is wrong with the driver. ++ * This should never happen! ++ */ ++ dev_err(&dev->intf->dev, ++ "Received error event TX_QUEUE_FULL\n"); ++ break; ++ case KVASER_USB_LEAF_ERROR_EVENT_PARAM: ++ kvaser_usb_leaf_error_event_parameter(dev, cmd); ++ break; ++ ++ default: ++ dev_warn(&dev->intf->dev, ++ "Unhandled error event (%d)\n", error_code); ++ break; ++ } ++} ++ + static void kvaser_usb_leaf_start_chip_reply(const struct kvaser_usb *dev, + const struct kvaser_cmd *cmd) + { +@@ -1382,6 +1477,10 @@ static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev, + kvaser_usb_leaf_tx_acknowledge(dev, cmd); + break; + ++ case CMD_ERROR_EVENT: ++ kvaser_usb_leaf_error_event(dev, cmd); ++ break; ++ + /* Ignored commands */ + case CMD_USBCAN_CLOCK_OVERFLOW_EVENT: + if (dev->driver_info->family != KVASER_USBCAN) +-- +2.35.3 + diff --git a/patches.suse/can-kvaser_usb-kvaser_usb_leaf-Rename-leaf-usbcan-_c.patch b/patches.suse/can-kvaser_usb-kvaser_usb_leaf-Rename-leaf-usbcan-_c.patch new file mode 100644 index 0000000..e4902c5 --- /dev/null +++ b/patches.suse/can-kvaser_usb-kvaser_usb_leaf-Rename-leaf-usbcan-_c.patch @@ -0,0 +1,135 @@ +From 7ea56128dbf904a3359bcf9289cccdfa3c85c7e8 Mon Sep 17 00:00:00 2001 +From: Jimmy Assarsson +Date: Mon, 10 Oct 2022 20:52:29 +0200 +Subject: [PATCH] can: kvaser_usb: kvaser_usb_leaf: Rename {leaf,usbcan}_cmd_error_event to {leaf,usbcan}_cmd_can_error_event +Git-commit: 7ea56128dbf904a3359bcf9289cccdfa3c85c7e8 +Patch-mainline: v6.2-rc1 +References: git-fixes + +Prepare for handling CMD_ERROR_EVENT. Rename struct +{leaf,usbcan}_cmd_error_event to {leaf,usbcan}_cmd_can_error_event. + +Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices") +Reported-by: Anssi Hannula +Tested-by: Anssi Hannula +Signed-off-by: Jimmy Assarsson +Link: https://lore.kernel.org/all/20221010185237.319219-4-extja@kvaser.com +Signed-off-by: Marc Kleine-Budde +Acked-by: Takashi Iwai + +--- + .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 38 +++++++++---------- + 1 file changed, 19 insertions(+), 19 deletions(-) + +diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +index c87b13dc1048..f34ca9a850aa 100644 +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +@@ -234,7 +234,7 @@ struct kvaser_cmd_tx_acknowledge_header { + u8 tid; + } __packed; + +-struct leaf_cmd_error_event { ++struct leaf_cmd_can_error_event { + u8 tid; + u8 flags; + __le16 time[3]; +@@ -246,7 +246,7 @@ struct leaf_cmd_error_event { + u8 error_factor; + } __packed; + +-struct usbcan_cmd_error_event { ++struct usbcan_cmd_can_error_event { + u8 tid; + u8 padding; + u8 tx_errors_count_ch0; +@@ -319,7 +319,7 @@ struct kvaser_cmd { + struct leaf_cmd_softinfo softinfo; + struct leaf_cmd_rx_can rx_can; + struct leaf_cmd_chip_state_event chip_state_event; +- struct leaf_cmd_error_event error_event; ++ struct leaf_cmd_can_error_event can_error_event; + struct leaf_cmd_log_message log_message; + struct kvaser_cmd_cap_req cap_req; + struct kvaser_cmd_cap_res cap_res; +@@ -329,7 +329,7 @@ struct kvaser_cmd { + struct usbcan_cmd_softinfo softinfo; + struct usbcan_cmd_rx_can rx_can; + struct usbcan_cmd_chip_state_event chip_state_event; +- struct usbcan_cmd_error_event error_event; ++ struct usbcan_cmd_can_error_event can_error_event; + } __packed usbcan; + + struct kvaser_cmd_tx_can tx_can; +@@ -351,7 +351,7 @@ static const u8 kvaser_usb_leaf_cmd_sizes_leaf[] = { + [CMD_RX_EXT_MESSAGE] = kvaser_fsize(u.leaf.rx_can), + [CMD_LEAF_LOG_MESSAGE] = kvaser_fsize(u.leaf.log_message), + [CMD_CHIP_STATE_EVENT] = kvaser_fsize(u.leaf.chip_state_event), +- [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.leaf.error_event), ++ [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.leaf.can_error_event), + [CMD_GET_CAPABILITIES_RESP] = kvaser_fsize(u.leaf.cap_res), + /* ignored events: */ + [CMD_FLUSH_QUEUE_REPLY] = CMD_SIZE_ANY, +@@ -366,7 +366,7 @@ static const u8 kvaser_usb_leaf_cmd_sizes_usbcan[] = { + [CMD_RX_STD_MESSAGE] = kvaser_fsize(u.usbcan.rx_can), + [CMD_RX_EXT_MESSAGE] = kvaser_fsize(u.usbcan.rx_can), + [CMD_CHIP_STATE_EVENT] = kvaser_fsize(u.usbcan.chip_state_event), +- [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.usbcan.error_event), ++ [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.usbcan.can_error_event), + /* ignored events: */ + [CMD_USBCAN_CLOCK_OVERFLOW_EVENT] = CMD_SIZE_ANY, + }; +@@ -1132,11 +1132,11 @@ static void kvaser_usb_leaf_usbcan_rx_error(const struct kvaser_usb *dev, + + case CMD_CAN_ERROR_EVENT: + es.channel = 0; +- es.status = cmd->u.usbcan.error_event.status_ch0; +- es.txerr = cmd->u.usbcan.error_event.tx_errors_count_ch0; +- es.rxerr = cmd->u.usbcan.error_event.rx_errors_count_ch0; ++ es.status = cmd->u.usbcan.can_error_event.status_ch0; ++ es.txerr = cmd->u.usbcan.can_error_event.tx_errors_count_ch0; ++ es.rxerr = cmd->u.usbcan.can_error_event.rx_errors_count_ch0; + es.usbcan.other_ch_status = +- cmd->u.usbcan.error_event.status_ch1; ++ cmd->u.usbcan.can_error_event.status_ch1; + kvaser_usb_leaf_usbcan_conditionally_rx_error(dev, &es); + + /* The USBCAN firmware supports up to 2 channels. +@@ -1144,13 +1144,13 @@ static void kvaser_usb_leaf_usbcan_rx_error(const struct kvaser_usb *dev, + */ + if (dev->nchannels == MAX_USBCAN_NET_DEVICES) { + es.channel = 1; +- es.status = cmd->u.usbcan.error_event.status_ch1; ++ es.status = cmd->u.usbcan.can_error_event.status_ch1; + es.txerr = +- cmd->u.usbcan.error_event.tx_errors_count_ch1; ++ cmd->u.usbcan.can_error_event.tx_errors_count_ch1; + es.rxerr = +- cmd->u.usbcan.error_event.rx_errors_count_ch1; ++ cmd->u.usbcan.can_error_event.rx_errors_count_ch1; + es.usbcan.other_ch_status = +- cmd->u.usbcan.error_event.status_ch0; ++ cmd->u.usbcan.can_error_event.status_ch0; + kvaser_usb_leaf_usbcan_conditionally_rx_error(dev, &es); + } + break; +@@ -1167,11 +1167,11 @@ static void kvaser_usb_leaf_leaf_rx_error(const struct kvaser_usb *dev, + + switch (cmd->id) { + case CMD_CAN_ERROR_EVENT: +- es.channel = cmd->u.leaf.error_event.channel; +- es.status = cmd->u.leaf.error_event.status; +- es.txerr = cmd->u.leaf.error_event.tx_errors_count; +- es.rxerr = cmd->u.leaf.error_event.rx_errors_count; +- es.leaf.error_factor = cmd->u.leaf.error_event.error_factor; ++ es.channel = cmd->u.leaf.can_error_event.channel; ++ es.status = cmd->u.leaf.can_error_event.status; ++ es.txerr = cmd->u.leaf.can_error_event.tx_errors_count; ++ es.rxerr = cmd->u.leaf.can_error_event.rx_errors_count; ++ es.leaf.error_factor = cmd->u.leaf.can_error_event.error_factor; + break; + case CMD_LEAF_LOG_MESSAGE: + es.channel = cmd->u.leaf.log_message.channel; +-- +2.35.3 + diff --git a/patches.suse/can-kvaser_usb_leaf-Fix-overread-with-an-invalid-com.patch b/patches.suse/can-kvaser_usb_leaf-Fix-overread-with-an-invalid-com.patch new file mode 100644 index 0000000..24cc802 --- /dev/null +++ b/patches.suse/can-kvaser_usb_leaf-Fix-overread-with-an-invalid-com.patch @@ -0,0 +1,143 @@ +From 1499ecaea9d2ba68d5e18d80573b4561a8dc4ee7 Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Mon, 10 Oct 2022 17:08:26 +0200 +Subject: [PATCH] can: kvaser_usb_leaf: Fix overread with an invalid command +Git-commit: 1499ecaea9d2ba68d5e18d80573b4561a8dc4ee7 +Patch-mainline: v6.1-rc1 +References: git-fixes + +For command events read from the device, +kvaser_usb_leaf_read_bulk_callback() verifies that cmd->len does not +exceed the size of the received data, but the actual kvaser_cmd handlers +will happily read any kvaser_cmd fields without checking for cmd->len. + +This can cause an overread if the last cmd in the buffer is shorter than +expected for the command type (with cmd->len showing the actual short +size). + +Maximum overread seems to be 22 bytes (CMD_LEAF_LOG_MESSAGE), some of +which are delivered to userspace as-is. + +Fix that by verifying the length of command before handling it. + +This issue can only occur after RX URBs have been set up, i.e. the +interface has been opened at least once. + +Cc: stable@vger.kernel.org +Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices") +Tested-by: Jimmy Assarsson +Signed-off-by: Anssi Hannula +Signed-off-by: Jimmy Assarsson +Link: https://lore.kernel.org/all/20221010150829.199676-2-extja@kvaser.com +Signed-off-by: Marc Kleine-Budde +Acked-by: Takashi Iwai + +--- + drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 75 +++++++++++++++++++++++ + 1 file changed, 75 insertions(+) + +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +@@ -310,6 +310,38 @@ struct kvaser_cmd { + } u; + } __packed; + ++#define CMD_SIZE_ANY 0xff ++#define kvaser_fsize(field) sizeof_field(struct kvaser_cmd, field) ++ ++static const u8 kvaser_usb_leaf_cmd_sizes_leaf[] = { ++ [CMD_START_CHIP_REPLY] = kvaser_fsize(u.simple), ++ [CMD_STOP_CHIP_REPLY] = kvaser_fsize(u.simple), ++ [CMD_GET_CARD_INFO_REPLY] = kvaser_fsize(u.cardinfo), ++ [CMD_TX_ACKNOWLEDGE] = kvaser_fsize(u.tx_acknowledge_header), ++ [CMD_GET_SOFTWARE_INFO_REPLY] = kvaser_fsize(u.leaf.softinfo), ++ [CMD_RX_STD_MESSAGE] = kvaser_fsize(u.leaf.rx_can), ++ [CMD_RX_EXT_MESSAGE] = kvaser_fsize(u.leaf.rx_can), ++ [CMD_LEAF_LOG_MESSAGE] = kvaser_fsize(u.leaf.log_message), ++ [CMD_CHIP_STATE_EVENT] = kvaser_fsize(u.leaf.chip_state_event), ++ [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.leaf.error_event), ++ /* ignored events: */ ++ [CMD_FLUSH_QUEUE_REPLY] = CMD_SIZE_ANY, ++}; ++ ++static const u8 kvaser_usb_leaf_cmd_sizes_usbcan[] = { ++ [CMD_START_CHIP_REPLY] = kvaser_fsize(u.simple), ++ [CMD_STOP_CHIP_REPLY] = kvaser_fsize(u.simple), ++ [CMD_GET_CARD_INFO_REPLY] = kvaser_fsize(u.cardinfo), ++ [CMD_TX_ACKNOWLEDGE] = kvaser_fsize(u.tx_acknowledge_header), ++ [CMD_GET_SOFTWARE_INFO_REPLY] = kvaser_fsize(u.usbcan.softinfo), ++ [CMD_RX_STD_MESSAGE] = kvaser_fsize(u.usbcan.rx_can), ++ [CMD_RX_EXT_MESSAGE] = kvaser_fsize(u.usbcan.rx_can), ++ [CMD_CHIP_STATE_EVENT] = kvaser_fsize(u.usbcan.chip_state_event), ++ [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.usbcan.error_event), ++ /* ignored events: */ ++ [CMD_USBCAN_CLOCK_OVERFLOW_EVENT] = CMD_SIZE_ANY, ++}; ++ + /* Summary of a kvaser error event, for a unified Leaf/Usbcan error + * handling. Some discrepancies between the two families exist: + * +@@ -397,6 +429,43 @@ static const struct kvaser_usb_dev_cfg k + .bittiming_const = &kvaser_usb_flexc_bittiming_const, + }; + ++static int kvaser_usb_leaf_verify_size(const struct kvaser_usb *dev, ++ const struct kvaser_cmd *cmd) ++{ ++ /* buffer size >= cmd->len ensured by caller */ ++ u8 min_size = 0; ++ ++ switch (dev->driver_info->family) { ++ case KVASER_LEAF: ++ if (cmd->id < ARRAY_SIZE(kvaser_usb_leaf_cmd_sizes_leaf)) ++ min_size = kvaser_usb_leaf_cmd_sizes_leaf[cmd->id]; ++ break; ++ case KVASER_USBCAN: ++ if (cmd->id < ARRAY_SIZE(kvaser_usb_leaf_cmd_sizes_usbcan)) ++ min_size = kvaser_usb_leaf_cmd_sizes_usbcan[cmd->id]; ++ break; ++ } ++ ++ if (min_size == CMD_SIZE_ANY) ++ return 0; ++ ++ if (min_size) { ++ min_size += CMD_HEADER_LEN; ++ if (cmd->len >= min_size) ++ return 0; ++ ++ dev_err_ratelimited(&dev->intf->dev, ++ "Received command %u too short (size %u, needed %u)", ++ cmd->id, cmd->len, min_size); ++ return -EIO; ++ } ++ ++ dev_warn_ratelimited(&dev->intf->dev, ++ "Unhandled command (%d, size %d)\n", ++ cmd->id, cmd->len); ++ return -EINVAL; ++} ++ + static void * + kvaser_usb_leaf_frame_to_cmd(const struct kvaser_usb_net_priv *priv, + const struct sk_buff *skb, int *frame_len, +@@ -504,6 +573,9 @@ static int kvaser_usb_leaf_wait_cmd(cons + end: + kfree(buf); + ++ if (err == 0) ++ err = kvaser_usb_leaf_verify_size(dev, cmd); ++ + return err; + } + +@@ -1135,6 +1207,9 @@ static void kvaser_usb_leaf_stop_chip_re + static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev, + const struct kvaser_cmd *cmd) + { ++ if (kvaser_usb_leaf_verify_size(dev, cmd) < 0) ++ return; ++ + switch (cmd->id) { + case CMD_START_CHIP_REPLY: + kvaser_usb_leaf_start_chip_reply(dev, cmd); diff --git a/patches.suse/configfs-fix-possible-memory-leak-in-configfs_create.patch b/patches.suse/configfs-fix-possible-memory-leak-in-configfs_create.patch new file mode 100644 index 0000000..c2bd1e7 --- /dev/null +++ b/patches.suse/configfs-fix-possible-memory-leak-in-configfs_create.patch @@ -0,0 +1,102 @@ +From c65234b283a65cfbfc94619655e820a5e55199eb Mon Sep 17 00:00:00 2001 +From: Chen Zhongjin +Date: Mon, 17 Oct 2022 09:42:30 +0800 +Subject: [PATCH] configfs: fix possible memory leak in configfs_create_dir() +Git-commit: c65234b283a65cfbfc94619655e820a5e55199eb +Patch-mainline: v6.2-rc1 +References: git-fixes + +kmemleak reported memory leaks in configfs_create_dir(): + +unreferenced object 0xffff888009f6af00 (size 192): + comm "modprobe", pid 3777, jiffies 4295537735 (age 233.784s) + backtrace: + kmem_cache_alloc (mm/slub.c:3250 mm/slub.c:3256 mm/slub.c:3263 mm/slub.c:3273) + new_fragment (./include/linux/slab.h:600 fs/configfs/dir.c:163) + configfs_register_subsystem (fs/configfs/dir.c:1857) + basic_write (drivers/hwtracing/stm/p_basic.c:14) stm_p_basic + do_one_initcall (init/main.c:1296) + do_init_module (kernel/module/main.c:2455) + ... + +unreferenced object 0xffff888003ba7180 (size 96): + comm "modprobe", pid 3777, jiffies 4295537735 (age 233.784s) + backtrace: + kmem_cache_alloc (mm/slub.c:3250 mm/slub.c:3256 mm/slub.c:3263 mm/slub.c:3273) + configfs_new_dirent (./include/linux/slab.h:723 fs/configfs/dir.c:194) + configfs_make_dirent (fs/configfs/dir.c:248) + configfs_create_dir (fs/configfs/dir.c:296) + configfs_attach_group.isra.28 (fs/configfs/dir.c:816 fs/configfs/dir.c:852) + configfs_register_subsystem (fs/configfs/dir.c:1881) + basic_write (drivers/hwtracing/stm/p_basic.c:14) stm_p_basic + do_one_initcall (init/main.c:1296) + do_init_module (kernel/module/main.c:2455) + ... + +This is because the refcount is not correct in configfs_make_dirent(). +For normal stage, the refcount is changing as: + +configfs_register_subsystem() + configfs_create_dir() + configfs_make_dirent() + configfs_new_dirent() # set s_count = 1 + dentry->d_fsdata = configfs_get(sd); # s_count = 2 +... +configfs_unregister_subsystem() + configfs_remove_dir() + remove_dir() + configfs_remove_dirent() # s_count = 1 + dput() ... + *dentry_unlink_inode()* + configfs_d_iput() # s_count = 0, release + +However, if we failed in configfs_create(): + +configfs_register_subsystem() + configfs_create_dir() + configfs_make_dirent() # s_count = 2 + ... + configfs_create() # fail + ->out_remove: + configfs_remove_dirent(dentry) + configfs_put(sd) # s_count = 1 + return PTR_ERR(inode); + +There is no inode in the error path, so the configfs_d_iput() is lost +and makes sd and fragment memory leaked. + +To fix this, when we failed in configfs_create(), manually call +configfs_put(sd) to keep the refcount correct. + +Fixes: 7063fbf22611 ("[PATCH] configfs: User-driven configuration filesystem") +Signed-off-by: Chen Zhongjin +Signed-off-by: Christoph Hellwig +Acked-by: Takashi Iwai + +--- + fs/configfs/dir.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c +index d1f9d2632202..ec6519e1ca3b 100644 +--- a/fs/configfs/dir.c ++++ b/fs/configfs/dir.c +@@ -316,6 +316,7 @@ static int configfs_create_dir(struct config_item *item, struct dentry *dentry, + return 0; + + out_remove: ++ configfs_put(dentry->d_fsdata); + configfs_remove_dirent(dentry); + return PTR_ERR(inode); + } +@@ -382,6 +383,7 @@ int configfs_create_link(struct configfs_dirent *target, struct dentry *parent, + return 0; + + out_remove: ++ configfs_put(dentry->d_fsdata); + configfs_remove_dirent(dentry); + return PTR_ERR(inode); + } +-- +2.35.3 + diff --git a/patches.suse/debugfs-fix-error-when-writing-negative-value-to-ato.patch b/patches.suse/debugfs-fix-error-when-writing-negative-value-to-ato.patch new file mode 100644 index 0000000..41fd9ff --- /dev/null +++ b/patches.suse/debugfs-fix-error-when-writing-negative-value-to-ato.patch @@ -0,0 +1,188 @@ +From d472cf797c4e268613dbce5ec9b95d0bcae19ecb Mon Sep 17 00:00:00 2001 +From: Akinobu Mita +Date: Tue, 20 Sep 2022 02:24:18 +0900 +Subject: [PATCH] debugfs: fix error when writing negative value to atomic_t debugfs file +Git-commit: d472cf797c4e268613dbce5ec9b95d0bcae19ecb +Patch-mainline: v6.2-rc1 +References: git-fixes + +The simple attribute files do not accept a negative value since the commit +488dac0c9237 ("libfs: fix error cast of negative value in +simple_attr_write()"), so we have to use a 64-bit value to write a +negative value for a debugfs file created by debugfs_create_atomic_t(). + +This restores the previous behaviour by introducing +DEFINE_DEBUGFS_ATTRIBUTE_SIGNED for a signed value. + +Link: https://lkml.kernel.org/r/20220919172418.45257-4-akinobu.mita@gmail.com +Fixes: 488dac0c9237 ("libfs: fix error cast of negative value in simple_attr_write()") +Signed-off-by: Akinobu Mita +Reported-by: Zhao Gongyi +Reviewed-by: David Hildenbrand +Reviewed-by: Greg Kroah-Hartman +Cc: Alexander Viro +Cc: Jonathan Corbet +Cc: Oscar Salvador +Cc: Rafael J. Wysocki +Cc: Shuah Khan +Cc: Wei Yongjun +Cc: Yicong Yang +Signed-off-by: Andrew Morton +Acked-by: Takashi Iwai + +--- + Documentation/fault-injection/fault-injection.rst | 10 +++---- + fs/debugfs/file.c | 28 +++++++++++++++++----- + include/linux/debugfs.h | 19 +++++++++++++- + 3 files changed, 43 insertions(+), 14 deletions(-) + +--- a/Documentation/fault-injection/fault-injection.rst ++++ b/Documentation/fault-injection/fault-injection.rst +@@ -79,9 +79,7 @@ configuration of fault-injection capabil + - /sys/kernel/debug/fail*/times: + + specifies how many times failures may happen at most. A value of -1 +- means "no limit". Note, though, that this file only accepts unsigned +- values. So, if you want to specify -1, you better use 'printf' instead +- of 'echo', e.g.: $ printf %#x -1 > times ++ means "no limit". + + - /sys/kernel/debug/fail*/space: + +@@ -259,7 +257,7 @@ Application Examples + echo Y > /sys/kernel/debug/$FAILTYPE/task-filter + echo 10 > /sys/kernel/debug/$FAILTYPE/probability + echo 100 > /sys/kernel/debug/$FAILTYPE/interval +- printf %#x -1 > /sys/kernel/debug/$FAILTYPE/times ++ echo -1 > /sys/kernel/debug/$FAILTYPE/times + echo 0 > /sys/kernel/debug/$FAILTYPE/space + echo 2 > /sys/kernel/debug/$FAILTYPE/verbose + echo 1 > /sys/kernel/debug/$FAILTYPE/ignore-gfp-wait +@@ -313,7 +311,7 @@ Application Examples + echo N > /sys/kernel/debug/$FAILTYPE/task-filter + echo 10 > /sys/kernel/debug/$FAILTYPE/probability + echo 100 > /sys/kernel/debug/$FAILTYPE/interval +- printf %#x -1 > /sys/kernel/debug/$FAILTYPE/times ++ echo -1 > /sys/kernel/debug/$FAILTYPE/times + echo 0 > /sys/kernel/debug/$FAILTYPE/space + echo 2 > /sys/kernel/debug/$FAILTYPE/verbose + echo 1 > /sys/kernel/debug/$FAILTYPE/ignore-gfp-wait +@@ -344,7 +342,7 @@ Application Examples + echo N > /sys/kernel/debug/$FAILTYPE/task-filter + echo 100 > /sys/kernel/debug/$FAILTYPE/probability + echo 0 > /sys/kernel/debug/$FAILTYPE/interval +- printf %#x -1 > /sys/kernel/debug/$FAILTYPE/times ++ echo -1 > /sys/kernel/debug/$FAILTYPE/times + echo 0 > /sys/kernel/debug/$FAILTYPE/space + echo 1 > /sys/kernel/debug/$FAILTYPE/verbose + +--- a/fs/debugfs/file.c ++++ b/fs/debugfs/file.c +@@ -378,8 +378,8 @@ ssize_t debugfs_attr_read(struct file *f + } + EXPORT_SYMBOL_GPL(debugfs_attr_read); + +-ssize_t debugfs_attr_write(struct file *file, const char __user *buf, +- size_t len, loff_t *ppos) ++static ssize_t debugfs_attr_write_xsigned(struct file *file, const char __user *buf, ++ size_t len, loff_t *ppos, bool is_signed) + { + struct dentry *dentry = F_DENTRY(file); + ssize_t ret; +@@ -387,12 +387,28 @@ ssize_t debugfs_attr_write(struct file * + ret = debugfs_file_get(dentry); + if (unlikely(ret)) + return ret; +- ret = simple_attr_write(file, buf, len, ppos); ++ if (is_signed) ++ ret = simple_attr_write_signed(file, buf, len, ppos); ++ else ++ ret = simple_attr_write(file, buf, len, ppos); + debugfs_file_put(dentry); + return ret; + } ++ ++ssize_t debugfs_attr_write(struct file *file, const char __user *buf, ++ size_t len, loff_t *ppos) ++{ ++ return debugfs_attr_write_xsigned(file, buf, len, ppos, false); ++} + EXPORT_SYMBOL_GPL(debugfs_attr_write); + ++ssize_t debugfs_attr_write_signed(struct file *file, const char __user *buf, ++ size_t len, loff_t *ppos) ++{ ++ return debugfs_attr_write_xsigned(file, buf, len, ppos, true); ++} ++EXPORT_SYMBOL_GPL(debugfs_attr_write_signed); ++ + static struct dentry *debugfs_create_mode_unsafe(const char *name, umode_t mode, + struct dentry *parent, void *value, + const struct file_operations *fops, +@@ -738,11 +754,11 @@ static int debugfs_atomic_t_get(void *da + *val = atomic_read((atomic_t *)data); + return 0; + } +-DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t, debugfs_atomic_t_get, ++DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(fops_atomic_t, debugfs_atomic_t_get, + debugfs_atomic_t_set, "%lld\n"); +-DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t_ro, debugfs_atomic_t_get, NULL, ++DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(fops_atomic_t_ro, debugfs_atomic_t_get, NULL, + "%lld\n"); +-DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t_wo, NULL, debugfs_atomic_t_set, ++DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(fops_atomic_t_wo, NULL, debugfs_atomic_t_set, + "%lld\n"); + + /** +--- a/include/linux/debugfs.h ++++ b/include/linux/debugfs.h +@@ -45,7 +45,7 @@ struct debugfs_u32_array { + + extern struct dentry *arch_debugfs_dir; + +-#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt) \ ++#define DEFINE_DEBUGFS_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, __is_signed) \ + static int __fops ## _open(struct inode *inode, struct file *file) \ + { \ + __simple_attr_check_format(__fmt, 0ull); \ +@@ -56,10 +56,16 @@ static const struct file_operations __fo + .open = __fops ## _open, \ + .release = simple_attr_release, \ + .read = debugfs_attr_read, \ +- .write = debugfs_attr_write, \ ++ .write = (__is_signed) ? debugfs_attr_write_signed : debugfs_attr_write, \ + .llseek = no_llseek, \ + } + ++#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt) \ ++ DEFINE_DEBUGFS_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, false) ++ ++#define DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(__fops, __get, __set, __fmt) \ ++ DEFINE_DEBUGFS_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, true) ++ + typedef struct vfsmount *(*debugfs_automount_t)(struct dentry *, void *); + + #if defined(CONFIG_DEBUG_FS) +@@ -102,6 +108,8 @@ ssize_t debugfs_attr_read(struct file *f + size_t len, loff_t *ppos); + ssize_t debugfs_attr_write(struct file *file, const char __user *buf, + size_t len, loff_t *ppos); ++ssize_t debugfs_attr_write_signed(struct file *file, const char __user *buf, ++ size_t len, loff_t *ppos); + + struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry, + struct dentry *new_dir, const char *new_name); +@@ -251,6 +259,13 @@ static inline ssize_t debugfs_attr_write + const char __user *buf, + size_t len, loff_t *ppos) + { ++ return -ENODEV; ++} ++ ++static inline ssize_t debugfs_attr_write_signed(struct file *file, ++ const char __user *buf, ++ size_t len, loff_t *ppos) ++{ + return -ENODEV; + } + diff --git a/patches.suse/dmaengine-idxd-Do-not-enable-user-type-Work-Queue-wi.patch b/patches.suse/dmaengine-idxd-Do-not-enable-user-type-Work-Queue-wi.patch new file mode 100644 index 0000000..c7420e6 --- /dev/null +++ b/patches.suse/dmaengine-idxd-Do-not-enable-user-type-Work-Queue-wi.patch @@ -0,0 +1,78 @@ +From 0ec8ce07394442d722806fe61b901a5b2b17249d Mon Sep 17 00:00:00 2001 +From: Fenghua Yu +Date: Fri, 14 Oct 2022 15:25:41 -0700 +Subject: [PATCH] dmaengine: idxd: Do not enable user type Work Queue without Shared Virtual Addressing +Git-commit: 0ec8ce07394442d722806fe61b901a5b2b17249d +Patch-mainline: v6.1-rc5 +References: git-fixes + +When the idxd_user_drv driver is bound to a Work Queue (WQ) device +without IOMMU or with IOMMU Passthrough without Shared Virtual +Addressing (SVA), the application gains direct access to physical +memory via the device by programming physical address to a submitted +descriptor. This allows direct userspace read and write access to +arbitrary physical memory. This is inconsistent with the security +goals of a good kernel API. + +Unlike vfio_pci driver, the IDXD char device driver does not provide any +ways to pin user pages and translate the address from user VA to IOVA or +PA without IOMMU SVA. Therefore the application has no way to instruct the +device to perform DMA function. This makes the char device not usable for +normal application usage. + +Since user type WQ without SVA cannot be used for normal application usage +and presents the security issue, bind idxd_user_drv driver and enable user +type WQ only when SVA is enabled (i.e. user PASID is enabled). + +Fixes: 448c3de8ac83 ("dmaengine: idxd: create user driver for wq 'device'") +Cc: stable@vger.kernel.org +Suggested-by: Arjan Van De Ven +Signed-off-by: Fenghua Yu +Reviewed-by: Dave Jiang +Reviewed-by: Jerry Snitselaar +Link: https://lore.kernel.org/r/20221014222541.3912195-1-fenghua.yu@intel.com +Signed-off-by: Vinod Koul +Acked-by: Takashi Iwai + +--- + drivers/dma/idxd/cdev.c | 18 ++++++++++++++++++ + include/uapi/linux/idxd.h | 1 + + 2 files changed, 19 insertions(+) + +--- a/drivers/dma/idxd/cdev.c ++++ b/drivers/dma/idxd/cdev.c +@@ -312,6 +312,24 @@ static int idxd_user_drv_probe(struct id + if (idxd->state != IDXD_DEV_ENABLED) + return -ENXIO; + ++ /* ++ * User type WQ is enabled only when SVA is enabled for two reasons: ++ * - If no IOMMU or IOMMU Passthrough without SVA, userspace ++ * can directly access physical address through the WQ. ++ * - The IDXD cdev driver does not provide any ways to pin ++ * user pages and translate the address from user VA to IOVA or ++ * PA without IOMMU SVA. Therefore the application has no way ++ * to instruct the device to perform DMA function. This makes ++ * the cdev not usable for normal application usage. ++ */ ++ if (!device_user_pasid_enabled(idxd)) { ++ idxd->cmd_status = IDXD_SCMD_WQ_USER_NO_IOMMU; ++ dev_dbg(&idxd->pdev->dev, ++ "User type WQ cannot be enabled without SVA.\n"); ++ ++ return -EOPNOTSUPP; ++ } ++ + mutex_lock(&wq->wq_lock); + wq->type = IDXD_WQT_USER; + rc = __drv_enable_wq(wq); +--- a/include/uapi/linux/idxd.h ++++ b/include/uapi/linux/idxd.h +@@ -29,6 +29,7 @@ enum idxd_scmd_stat { + IDXD_SCMD_WQ_NO_SIZE = 0x800e0000, + IDXD_SCMD_WQ_NO_PRIV = 0x800f0000, + IDXD_SCMD_WQ_IRQ_ERR = 0x80100000, ++ IDXD_SCMD_WQ_USER_NO_IOMMU = 0x80110000, + }; + + #define IDXD_SCMD_SOFTERR_MASK 0x80000000 diff --git a/patches.suse/dmaengine-idxd-Only-call-idxd_enable_system_pasid-if.patch b/patches.suse/dmaengine-idxd-Only-call-idxd_enable_system_pasid-if.patch new file mode 100644 index 0000000..177ca9e --- /dev/null +++ b/patches.suse/dmaengine-idxd-Only-call-idxd_enable_system_pasid-if.patch @@ -0,0 +1,98 @@ +From 8ffccd119a5908b240a26182be44c0ff3d1e3d85 Mon Sep 17 00:00:00 2001 +From: Jerry Snitselaar +Date: Sat, 25 Jun 2022 22:16:48 -0700 +Subject: [PATCH] dmaengine: idxd: Only call idxd_enable_system_pasid() if succeeded in enabling SVA feature +Git-commit: 8ffccd119a5908b240a26182be44c0ff3d1e3d85 +Patch-mainline: v5.19-rc6 +References: git-fixes + +On a Sapphire Rapids system if boot without intel_iommu=on, the IDXD +driver will crash during probe in iommu_sva_bind_device(). + +[ 21.423729] BUG: kernel NULL pointer dereference, address: 0000000000000038 +[ 21.445108] #PF: supervisor read access in kernel mode +[ 21.450912] #PF: error_code(0x0000) - not-present page +[ 21.456706] PGD 0 +[ 21.459047] Oops: 0000 [#1] PREEMPT SMP NOPTI +[ 21.464004] CPU: 0 PID: 1420 Comm: kworker/0:3 Not tainted 5.19.0-0.rc3.27.eln120.x86_64 #1 +[ 21.464011] Hardware name: Intel Corporation EAGLESTREAM/EAGLESTREAM, BIOS EGSDCRB1.SYS.0067.D12.2110190954 10/19/2021 +[ 21.464015] Workqueue: events work_for_cpu_fn +[ 21.464030] RIP: 0010:iommu_sva_bind_device+0x1d/0xe0 +[ 21.464046] Code: c3 cc 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 41 57 41 56 49 89 d6 41 55 41 54 55 53 48 83 ec 08 48 8b 87 d8 02 00 00 <48> 8b 40 38 48 8b 50 10 48 83 7a 70 00 48 89 14 24 0f 84 91 00 00 +[ 21.464050] RSP: 0018:ff7245d9096b7db8 EFLAGS: 00010296 +[ 21.464054] RAX: 0000000000000000 RBX: ff1eadeec8a51000 RCX: 0000000000000000 +[ 21.464058] RDX: ff7245d9096b7e24 RSI: 0000000000000000 RDI: ff1eadeec8a510d0 +[ 21.464060] RBP: ff1eadeec8a51000 R08: ffffffffb1a12300 R09: ff1eadffbfce25b4 +[ 21.464062] R10: ffffffffffffffff R11: 0000000000000038 R12: ffffffffc09f8000 +[ 21.464065] R13: ff1eadeec8a510d0 R14: ff7245d9096b7e24 R15: ff1eaddf54429000 +[ 21.464067] FS: 0000000000000000(0000) GS:ff1eadee7f600000(0000) knlGS:0000000000000000 +[ 21.464070] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 21.464072] CR2: 0000000000000038 CR3: 00000008c0e10006 CR4: 0000000000771ef0 +[ 21.464074] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +[ 21.464076] DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400 +[ 21.464078] PKRU: 55555554 +[ 21.464079] Call Trace: +[ 21.464083] +[ 21.464092] idxd_pci_probe+0x259/0x1070 [idxd] +[ 21.464121] local_pci_probe+0x3e/0x80 +[ 21.464132] work_for_cpu_fn+0x13/0x20 +[ 21.464136] process_one_work+0x1c4/0x380 +[ 21.464143] worker_thread+0x1ab/0x380 +[ 21.464147] ? _raw_spin_lock_irqsave+0x23/0x50 +[ 21.464158] ? process_one_work+0x380/0x380 +[ 21.464161] kthread+0xe6/0x110 +[ 21.464168] ? kthread_complete_and_exit+0x20/0x20 +[ 21.464172] ret_from_fork+0x1f/0x30 + +iommu_sva_bind_device() requires SVA has been enabled successfully on +the IDXD device before it's called. Otherwise, iommu_sva_bind_device() +will access a NULL pointer. If Intel IOMMU is disabled, SVA cannot be +enabled and thus idxd_enable_system_pasid() and iommu_sva_bind_device() +should not be called. + +Fixes: 42a1b73852c4 ("dmaengine: idxd: Separate user and kernel pasid enabling") +Cc: Vinod Koul +Cc: linux-kernel@vger.kernel.org +Cc: Dave Jiang +Cc: Fenghua Yu +Link: https://lore.kernel.org/dmaengine/20220623170232.6whonfjuh3m5vcoy@cantor/ +Signed-off-by: Jerry Snitselaar +Acked-by: Fenghua Yu +Link: https://lore.kernel.org/r/20220626051648.14249-1-jsnitsel@redhat.com +Signed-off-by: Vinod Koul +Acked-by: Takashi Iwai + +--- + drivers/dma/idxd/init.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c +index 355fb3ef4cbf..aa3478257ddb 100644 +--- a/drivers/dma/idxd/init.c ++++ b/drivers/dma/idxd/init.c +@@ -512,15 +512,16 @@ static int idxd_probe(struct idxd_device *idxd) + dev_dbg(dev, "IDXD reset complete\n"); + + if (IS_ENABLED(CONFIG_INTEL_IDXD_SVM) && sva) { +- if (iommu_dev_enable_feature(dev, IOMMU_DEV_FEAT_SVA)) ++ if (iommu_dev_enable_feature(dev, IOMMU_DEV_FEAT_SVA)) { + dev_warn(dev, "Unable to turn on user SVA feature.\n"); +- else ++ } else { + set_bit(IDXD_FLAG_USER_PASID_ENABLED, &idxd->flags); + +- if (idxd_enable_system_pasid(idxd)) +- dev_warn(dev, "No in-kernel DMA with PASID.\n"); +- else +- set_bit(IDXD_FLAG_PASID_ENABLED, &idxd->flags); ++ if (idxd_enable_system_pasid(idxd)) ++ dev_warn(dev, "No in-kernel DMA with PASID.\n"); ++ else ++ set_bit(IDXD_FLAG_PASID_ENABLED, &idxd->flags); ++ } + } else if (!sva) { + dev_warn(dev, "User forced SVA off via module param.\n"); + } +-- +2.35.3 + diff --git a/patches.suse/dmaengine-idxd-Separate-user-and-kernel-pasid-enabli.patch b/patches.suse/dmaengine-idxd-Separate-user-and-kernel-pasid-enabli.patch new file mode 100644 index 0000000..2e69a66 --- /dev/null +++ b/patches.suse/dmaengine-idxd-Separate-user-and-kernel-pasid-enabli.patch @@ -0,0 +1,170 @@ +From 42a1b73852c4a176d233a192422b5e1d0ba67cbf Mon Sep 17 00:00:00 2001 +From: Dave Jiang +Date: Wed, 11 May 2022 17:11:57 -0700 +Subject: [PATCH] dmaengine: idxd: Separate user and kernel pasid enabling +Git-commit: 42a1b73852c4a176d233a192422b5e1d0ba67cbf +Patch-mainline: v5.19-rc1 +References: git-fixes + +The idxd driver always gated the pasid enabling under a single knob and +this assumption is incorrect. The pasid used for kernel operation can be +independently toggled and has no dependency on the user pasid (and vice +versa). Split the two so they are independent "enabled" flags. + +Signed-off-by: Dave Jiang +Link: https://lore.kernel.org/r/165231431746.986466.5666862038354800551.stgit@djiang5-desk3.ch.intel.com +Signed-off-by: Vinod Koul +Acked-by: Takashi Iwai + +--- + drivers/dma/idxd/cdev.c | 4 ++-- + drivers/dma/idxd/device.c | 4 ++-- + drivers/dma/idxd/idxd.h | 16 ++++++++++++++-- + drivers/dma/idxd/init.c | 30 +++++++++++++++--------------- + drivers/dma/idxd/sysfs.c | 2 +- + 5 files changed, 34 insertions(+), 22 deletions(-) + +--- a/drivers/dma/idxd/cdev.c ++++ b/drivers/dma/idxd/cdev.c +@@ -99,7 +99,7 @@ static int idxd_cdev_open(struct inode * + ctx->wq = wq; + filp->private_data = ctx; + +- if (device_pasid_enabled(idxd)) { ++ if (device_user_pasid_enabled(idxd)) { + sva = iommu_sva_bind_device(dev, current->mm, NULL); + if (IS_ERR(sva)) { + rc = PTR_ERR(sva); +@@ -152,7 +152,7 @@ static int idxd_cdev_release(struct inod + if (wq_shared(wq)) { + idxd_device_drain_pasid(idxd, ctx->pasid); + } else { +- if (device_pasid_enabled(idxd)) { ++ if (device_user_pasid_enabled(idxd)) { + /* The wq disable in the disable pasid function will drain the wq */ + rc = idxd_wq_disable_pasid(wq); + if (rc < 0) +--- a/drivers/dma/idxd/device.c ++++ b/drivers/dma/idxd/device.c +@@ -962,7 +962,7 @@ static int idxd_wqs_setup(struct idxd_de + if (!wq->group) + continue; + +- if (wq_shared(wq) && !device_swq_supported(idxd)) { ++ if (wq_shared(wq) && !wq_shared_supported(wq)) { + idxd->cmd_status = IDXD_SCMD_WQ_NO_SWQ_SUPPORT; + dev_warn(dev, "No shared wq support but configured.\n"); + return -EINVAL; +@@ -1267,7 +1267,7 @@ int __drv_enable_wq(struct idxd_wq *wq) + + /* Shared WQ checks */ + if (wq_shared(wq)) { +- if (!device_swq_supported(idxd)) { ++ if (!wq_shared_supported(wq)) { + idxd->cmd_status = IDXD_SCMD_WQ_NO_SVM; + dev_dbg(dev, "PASID not enabled and shared wq.\n"); + goto err; +--- a/drivers/dma/idxd/idxd.h ++++ b/drivers/dma/idxd/idxd.h +@@ -241,6 +241,7 @@ enum idxd_device_flag { + IDXD_FLAG_CONFIGURABLE = 0, + IDXD_FLAG_CMD_RUNNING, + IDXD_FLAG_PASID_ENABLED, ++ IDXD_FLAG_USER_PASID_ENABLED, + }; + + struct idxd_dma_dev { +@@ -471,9 +472,20 @@ static inline bool device_pasid_enabled( + return test_bit(IDXD_FLAG_PASID_ENABLED, &idxd->flags); + } + +-static inline bool device_swq_supported(struct idxd_device *idxd) ++static inline bool device_user_pasid_enabled(struct idxd_device *idxd) + { +- return (support_enqcmd && device_pasid_enabled(idxd)); ++ return test_bit(IDXD_FLAG_USER_PASID_ENABLED, &idxd->flags); ++} ++ ++static inline bool wq_pasid_enabled(struct idxd_wq *wq) ++{ ++ return (is_idxd_wq_kernel(wq) && device_pasid_enabled(wq->idxd)) || ++ (is_idxd_wq_user(wq) && device_user_pasid_enabled(wq->idxd)); ++} ++ ++static inline bool wq_shared_supported(struct idxd_wq *wq) ++{ ++ return (support_enqcmd && wq_pasid_enabled(wq)); + } + + enum idxd_portal_prot { +--- a/drivers/dma/idxd/init.c ++++ b/drivers/dma/idxd/init.c +@@ -512,18 +512,15 @@ static int idxd_probe(struct idxd_device + dev_dbg(dev, "IDXD reset complete\n"); + + if (IS_ENABLED(CONFIG_INTEL_IDXD_SVM) && sva) { +- rc = iommu_dev_enable_feature(dev, IOMMU_DEV_FEAT_SVA); +- if (rc == 0) { +- rc = idxd_enable_system_pasid(idxd); +- if (rc < 0) { +- iommu_dev_disable_feature(dev, IOMMU_DEV_FEAT_SVA); +- dev_warn(dev, "Failed to enable PASID. No SVA support: %d\n", rc); +- } else { +- set_bit(IDXD_FLAG_PASID_ENABLED, &idxd->flags); +- } +- } else { +- dev_warn(dev, "Unable to turn on SVA feature.\n"); +- } ++ if (iommu_dev_enable_feature(dev, IOMMU_DEV_FEAT_SVA)) ++ dev_warn(dev, "Unable to turn on user SVA feature.\n"); ++ else ++ set_bit(IDXD_FLAG_USER_PASID_ENABLED, &idxd->flags); ++ ++ if (idxd_enable_system_pasid(idxd)) ++ dev_warn(dev, "No in-kernel DMA with PASID.\n"); ++ else ++ set_bit(IDXD_FLAG_PASID_ENABLED, &idxd->flags); + } else if (!sva) { + dev_warn(dev, "User forced SVA off via module param.\n"); + } +@@ -561,7 +558,8 @@ static int idxd_probe(struct idxd_device + err: + if (device_pasid_enabled(idxd)) + idxd_disable_system_pasid(idxd); +- iommu_dev_disable_feature(dev, IOMMU_DEV_FEAT_SVA); ++ if (device_user_pasid_enabled(idxd)) ++ iommu_dev_disable_feature(dev, IOMMU_DEV_FEAT_SVA); + return rc; + } + +@@ -574,7 +572,8 @@ static void idxd_cleanup(struct idxd_dev + idxd_cleanup_internals(idxd); + if (device_pasid_enabled(idxd)) + idxd_disable_system_pasid(idxd); +- iommu_dev_disable_feature(dev, IOMMU_DEV_FEAT_SVA); ++ if (device_user_pasid_enabled(idxd)) ++ iommu_dev_disable_feature(dev, IOMMU_DEV_FEAT_SVA); + } + + static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) +@@ -693,7 +692,8 @@ static void idxd_remove(struct pci_dev * + free_irq(irq_entry->vector, irq_entry); + pci_free_irq_vectors(pdev); + pci_iounmap(pdev, idxd->reg_base); +- iommu_dev_disable_feature(&pdev->dev, IOMMU_DEV_FEAT_SVA); ++ if (device_user_pasid_enabled(idxd)) ++ iommu_dev_disable_feature(&pdev->dev, IOMMU_DEV_FEAT_SVA); + pci_disable_device(pdev); + destroy_workqueue(idxd->wq); + perfmon_pmu_remove(idxd); +--- a/drivers/dma/idxd/sysfs.c ++++ b/drivers/dma/idxd/sysfs.c +@@ -588,7 +588,7 @@ static ssize_t wq_mode_store(struct devi + if (sysfs_streq(buf, "dedicated")) { + set_bit(WQ_FLAG_DEDICATED, &wq->flags); + wq->threshold = 0; +- } else if (sysfs_streq(buf, "shared") && device_swq_supported(idxd)) { ++ } else if (sysfs_streq(buf, "shared")) { + clear_bit(WQ_FLAG_DEDICATED, &wq->flags); + } else { + return -EINVAL; diff --git a/patches.suse/drivers-base-component-fix-memory-leak-with-using-de.patch b/patches.suse/drivers-base-component-fix-memory-leak-with-using-de.patch new file mode 100644 index 0000000..e3c77b3 --- /dev/null +++ b/patches.suse/drivers-base-component-fix-memory-leak-with-using-de.patch @@ -0,0 +1,33 @@ +From 8deb87b1e810dd558371e88ffd44339fbef27870 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Thu, 2 Feb 2023 15:16:20 +0100 +Subject: [PATCH] drivers: base: component: fix memory leak with using debugfs_lookup() +Git-commit: 8deb87b1e810dd558371e88ffd44339fbef27870 +Patch-mainline: v6.3-rc1 +References: git-fixes + +When calling debugfs_lookup() the result must have dput() called on it, +otherwise the memory will leak over time. To make things simpler, just +call debugfs_lookup_and_remove() instead which handles all of the logic +at once. + +Cc: "Rafael J. Wysocki" +Link: https://lore.kernel.org/r/20230202141621.2296458-1-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/base/component.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/base/component.c ++++ b/drivers/base/component.c +@@ -130,7 +130,7 @@ static void component_master_debugfs_add + + static void component_master_debugfs_del(struct master *m) + { +- debugfs_remove(debugfs_lookup(dev_name(m->parent), component_debugfs_dir)); ++ debugfs_lookup_and_remove(dev_name(m->parent), component_debugfs_dir); + } + + #else diff --git a/patches.suse/drivers-base-dd-fix-memory-leak-with-using-debugfs_l.patch b/patches.suse/drivers-base-dd-fix-memory-leak-with-using-debugfs_l.patch new file mode 100644 index 0000000..10d79f2 --- /dev/null +++ b/patches.suse/drivers-base-dd-fix-memory-leak-with-using-debugfs_l.patch @@ -0,0 +1,38 @@ +From 36c893d3a759ae7c91ee7d4871ebfc7504f08c40 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Thu, 2 Feb 2023 15:16:21 +0100 +Subject: [PATCH] drivers: base: dd: fix memory leak with using debugfs_lookup() +Git-commit: 36c893d3a759ae7c91ee7d4871ebfc7504f08c40 +Patch-mainline: v6.3-rc1 +References: git-fixes + +When calling debugfs_lookup() the result must have dput() called on it, +otherwise the memory will leak over time. To make things simpler, just +call debugfs_lookup_and_remove() instead which handles all of the logic +at once. + +Cc: "Rafael J. Wysocki" +Link: https://lore.kernel.org/r/20230202141621.2296458-2-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Acked-by: Takashi Iwai + +--- + drivers/base/dd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/base/dd.c b/drivers/base/dd.c +index 817ef27a78f7..8def2ba08a82 100644 +--- a/drivers/base/dd.c ++++ b/drivers/base/dd.c +@@ -370,7 +370,7 @@ late_initcall(deferred_probe_initcall); + + static void __exit deferred_probe_exit(void) + { +- debugfs_remove_recursive(debugfs_lookup("devices_deferred", NULL)); ++ debugfs_lookup_and_remove("devices_deferred", NULL); + } + __exitcall(deferred_probe_exit); + +-- +2.35.3 + diff --git a/patches.suse/drm-amdgpu-update-drm_display_info-correctly-when-th.patch b/patches.suse/drm-amdgpu-update-drm_display_info-correctly-when-th.patch new file mode 100644 index 0000000..02e7b39 --- /dev/null +++ b/patches.suse/drm-amdgpu-update-drm_display_info-correctly-when-th.patch @@ -0,0 +1,70 @@ +From 20543be93ca45968f344261c1a997177e51bd7e1 Mon Sep 17 00:00:00 2001 +From: Claudio Suarez +Date: Sun, 17 Oct 2021 13:34:58 +0200 +Subject: [PATCH] drm/amdgpu: update drm_display_info correctly when the edid is read +Git-commit: 20543be93ca45968f344261c1a997177e51bd7e1 +Patch-mainline: v5.17-rc1 +References: git-fixes + +drm_display_info is updated by drm_get_edid() or +drm_connector_update_edid_property(). In the amdgpu driver it is almost +always updated when the edid is read in amdgpu_connector_get_edid(), +but not always. Change amdgpu_connector_get_edid() and +amdgpu_connector_free_edid() to keep drm_display_info updated. + +Reviewed-by: Harry Wentland +Signed-off-by: Claudio Suarez +Signed-off-by: Alex Deucher +Acked-by: Takashi Iwai + +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 5 ++++- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +-- + 2 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +index df1f9b88a53f..e5fc5a1ea394 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +@@ -315,8 +315,10 @@ static void amdgpu_connector_get_edid(struct drm_connector *connector) + if (!amdgpu_connector->edid) { + /* some laptops provide a hardcoded edid in rom for LCDs */ + if (((connector->connector_type == DRM_MODE_CONNECTOR_LVDS) || +- (connector->connector_type == DRM_MODE_CONNECTOR_eDP))) ++ (connector->connector_type == DRM_MODE_CONNECTOR_eDP))) { + amdgpu_connector->edid = amdgpu_connector_get_hardcoded_edid(adev); ++ drm_connector_update_edid_property(connector, amdgpu_connector->edid); ++ } + } + } + +@@ -326,6 +328,7 @@ static void amdgpu_connector_free_edid(struct drm_connector *connector) + + kfree(amdgpu_connector->edid); + amdgpu_connector->edid = NULL; ++ drm_connector_update_edid_property(connector, NULL); + } + + static int amdgpu_connector_ddc_get_modes(struct drm_connector *connector) +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index 0585ae44e555..151f3559e0ae 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -2950,13 +2950,12 @@ void amdgpu_dm_update_connector_after_detect( + aconnector->edid = + (struct edid *)sink->dc_edid.raw_edid; + +- drm_connector_update_edid_property(connector, +- aconnector->edid); + if (aconnector->dc_link->aux_mode) + drm_dp_cec_set_edid(&aconnector->dm_dp_aux.aux, + aconnector->edid); + } + ++ drm_connector_update_edid_property(connector, aconnector->edid); + amdgpu_dm_update_freesync_caps(connector, aconnector->edid); + update_connector_ext_caps(aconnector); + } else { +-- +2.35.3 + diff --git a/patches.suse/libfs-add-DEFINE_SIMPLE_ATTRIBUTE_SIGNED-for-signed-.patch b/patches.suse/libfs-add-DEFINE_SIMPLE_ATTRIBUTE_SIGNED-for-signed-.patch new file mode 100644 index 0000000..92c063c --- /dev/null +++ b/patches.suse/libfs-add-DEFINE_SIMPLE_ATTRIBUTE_SIGNED-for-signed-.patch @@ -0,0 +1,133 @@ +From 2e41f274f9aa71cdcc69dc1f26a3f9304a651804 Mon Sep 17 00:00:00 2001 +From: Akinobu Mita +Date: Tue, 20 Sep 2022 02:24:16 +0900 +Subject: [PATCH] libfs: add DEFINE_SIMPLE_ATTRIBUTE_SIGNED for signed value +Git-commit: 2e41f274f9aa71cdcc69dc1f26a3f9304a651804 +Patch-mainline: v6.2-rc1 +References: git-fixes + +Patch series "fix error when writing negative value to simple attribute +files". + +The simple attribute files do not accept a negative value since the commit +488dac0c9237 ("libfs: fix error cast of negative value in +simple_attr_write()"), but some attribute files want to accept a negative +value. + + +This patch (of 3): + +The simple attribute files do not accept a negative value since the commit +488dac0c9237 ("libfs: fix error cast of negative value in +simple_attr_write()"), so we have to use a 64-bit value to write a +negative value. + +This adds DEFINE_SIMPLE_ATTRIBUTE_SIGNED for a signed value. + +Link: https://lkml.kernel.org/r/20220919172418.45257-1-akinobu.mita@gmail.com +Link: https://lkml.kernel.org/r/20220919172418.45257-2-akinobu.mita@gmail.com +Fixes: 488dac0c9237 ("libfs: fix error cast of negative value in simple_attr_write()") +Signed-off-by: Akinobu Mita +Reported-by: Zhao Gongyi +Reviewed-by: David Hildenbrand +Reviewed-by: Greg Kroah-Hartman +Cc: Alexander Viro +Cc: Jonathan Corbet +Cc: Oscar Salvador +Cc: Rafael J. Wysocki +Cc: Shuah Khan +Cc: Wei Yongjun +Cc: Yicong Yang +Signed-off-by: Andrew Morton +Acked-by: Takashi Iwai + +--- + fs/libfs.c | 22 +++++++++++++++++++--- + include/linux/fs.h | 12 ++++++++++-- + 2 files changed, 29 insertions(+), 5 deletions(-) + +--- a/fs/libfs.c ++++ b/fs/libfs.c +@@ -967,8 +967,8 @@ out: + EXPORT_SYMBOL_GPL(simple_attr_read); + + /* interpret the buffer as a number to call the set function with */ +-ssize_t simple_attr_write(struct file *file, const char __user *buf, +- size_t len, loff_t *ppos) ++static ssize_t simple_attr_write_xsigned(struct file *file, const char __user *buf, ++ size_t len, loff_t *ppos, bool is_signed) + { + struct simple_attr *attr; + unsigned long long val; +@@ -989,7 +989,10 @@ ssize_t simple_attr_write(struct file *f + goto out; + + attr->set_buf[size] = '\0'; +- ret = kstrtoull(attr->set_buf, 0, &val); ++ if (is_signed) ++ ret = kstrtoll(attr->set_buf, 0, &val); ++ else ++ ret = kstrtoull(attr->set_buf, 0, &val); + if (ret) + goto out; + ret = attr->set(attr->data, val); +@@ -999,8 +1002,21 @@ out: + mutex_unlock(&attr->mutex); + return ret; + } ++ ++ssize_t simple_attr_write(struct file *file, const char __user *buf, ++ size_t len, loff_t *ppos) ++{ ++ return simple_attr_write_xsigned(file, buf, len, ppos, false); ++} + EXPORT_SYMBOL_GPL(simple_attr_write); + ++ssize_t simple_attr_write_signed(struct file *file, const char __user *buf, ++ size_t len, loff_t *ppos) ++{ ++ return simple_attr_write_xsigned(file, buf, len, ppos, true); ++} ++EXPORT_SYMBOL_GPL(simple_attr_write_signed); ++ + /** + * generic_fh_to_dentry - generic helper for the fh_to_dentry export operation + * @sb: filesystem to do the file handle conversion on +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -3631,7 +3631,7 @@ void simple_transaction_set(struct file + * All attributes contain a text representation of a numeric value + * that are accessed with the get() and set() functions. + */ +-#define DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt) \ ++#define DEFINE_SIMPLE_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, __is_signed) \ + static int __fops ## _open(struct inode *inode, struct file *file) \ + { \ + __simple_attr_check_format(__fmt, 0ull); \ +@@ -3642,10 +3642,16 @@ static const struct file_operations __fo + .open = __fops ## _open, \ + .release = simple_attr_release, \ + .read = simple_attr_read, \ +- .write = simple_attr_write, \ ++ .write = (__is_signed) ? simple_attr_write_signed : simple_attr_write, \ + .llseek = generic_file_llseek, \ + } + ++#define DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt) \ ++ DEFINE_SIMPLE_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, false) ++ ++#define DEFINE_SIMPLE_ATTRIBUTE_SIGNED(__fops, __get, __set, __fmt) \ ++ DEFINE_SIMPLE_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, true) ++ + static inline __printf(1, 2) + void __simple_attr_check_format(const char *fmt, ...) + { +@@ -3660,6 +3666,8 @@ ssize_t simple_attr_read(struct file *fi + size_t len, loff_t *ppos); + ssize_t simple_attr_write(struct file *file, const char __user *buf, + size_t len, loff_t *ppos); ++ssize_t simple_attr_write_signed(struct file *file, const char __user *buf, ++ size_t len, loff_t *ppos); + + struct ctl_table; + int proc_nr_files(struct ctl_table *table, int write, diff --git a/patches.suse/net-accept-UFOv6-packages-in-virtio_net_hdr_to_skb.patch b/patches.suse/net-accept-UFOv6-packages-in-virtio_net_hdr_to_skb.patch new file mode 100644 index 0000000..820bdff --- /dev/null +++ b/patches.suse/net-accept-UFOv6-packages-in-virtio_net_hdr_to_skb.patch @@ -0,0 +1,73 @@ +Patch-mainline: v5.16-rc7 +Git-commit: 7e5cced9ca84df52d874aca6b632f930b3dc5bc6 +References: git-fixes +From: Willem de Bruijn +Date: Mon, 20 Dec 2021 09:49:01 -0500 +Subject: [PATCH] net: accept UFOv6 packages in virtio_net_hdr_to_skb + +Skb with skb->protocol 0 at the time of virtio_net_hdr_to_skb may have +a protocol inferred from virtio_net_hdr with virtio_net_hdr_set_proto. + +Unlike TCP, UDP does not have separate types for IPv4 and IPv6. Type +VIRTIO_NET_HDR_GSO_UDP is guessed to be IPv4/UDP. As of the below +commit, UFOv6 packets are dropped due to not matching the protocol as +obtained from dev_parse_header_protocol. + +Invert the test to take that L2 protocol field as starting point and +pass both UFOv4 and UFOv6 for VIRTIO_NET_HDR_GSO_UDP. + +Fixes: 924a9bc362a5 ("net: check if protocol extracted by virtio_net_hdr_set_proto is correct") +Link: https://lore.kernel.org/netdev/CABcq3pG9GRCYqFDBAJ48H1vpnnX=41u+MhQnayF1ztLH4WX0Fw@mail.gmail.com/ +Reported-by: Andrew Melnichenko +Signed-off-by: Willem de Bruijn +Link: https://lore.kernel.org/r/20211220144901.2784030-1-willemdebruijn.kernel@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Juergen Gross +--- + include/linux/virtio_net.h | 22 ++++++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h +index 04e87f4b9417..22dd48c82560 100644 +--- a/include/linux/virtio_net.h ++++ b/include/linux/virtio_net.h +@@ -7,6 +7,21 @@ + #include + #include + ++static inline bool virtio_net_hdr_match_proto(__be16 protocol, __u8 gso_type) ++{ ++ switch (gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { ++ case VIRTIO_NET_HDR_GSO_TCPV4: ++ return protocol == cpu_to_be16(ETH_P_IP); ++ case VIRTIO_NET_HDR_GSO_TCPV6: ++ return protocol == cpu_to_be16(ETH_P_IPV6); ++ case VIRTIO_NET_HDR_GSO_UDP: ++ return protocol == cpu_to_be16(ETH_P_IP) || ++ protocol == cpu_to_be16(ETH_P_IPV6); ++ default: ++ return false; ++ } ++} ++ + static inline int virtio_net_hdr_set_proto(struct sk_buff *skb, + const struct virtio_net_hdr *hdr) + { +@@ -88,9 +103,12 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb, + if (!skb->protocol) { + __be16 protocol = dev_parse_header_protocol(skb); + +- virtio_net_hdr_set_proto(skb, hdr); +- if (protocol && protocol != skb->protocol) ++ if (!protocol) ++ virtio_net_hdr_set_proto(skb, hdr); ++ else if (!virtio_net_hdr_match_proto(protocol, hdr->gso_type)) + return -EINVAL; ++ else ++ skb->protocol = protocol; + } + retry: + if (!skb_flow_dissect_flow_keys_basic(NULL, skb, &keys, +-- +2.35.3 + diff --git a/patches.suse/net-skip-virtio_net_hdr_set_proto-if-protocol-alread.patch b/patches.suse/net-skip-virtio_net_hdr_set_proto-if-protocol-alread.patch new file mode 100644 index 0000000..5a423d8 --- /dev/null +++ b/patches.suse/net-skip-virtio_net_hdr_set_proto-if-protocol-alread.patch @@ -0,0 +1,44 @@ +Patch-mainline: v5.16-rc7 +Git-commit: 1ed1d592113959f00cc552c3b9f47ca2d157768f +References: git-fixes +From: Willem de Bruijn +Date: Mon, 20 Dec 2021 09:50:27 -0500 +Subject: [PATCH] net: skip virtio_net_hdr_set_proto if protocol already set + +virtio_net_hdr_set_proto infers skb->protocol from the virtio_net_hdr +gso_type, to avoid packets getting dropped for lack of a proto type. + +Its protocol choice is a guess, especially in the case of UFO, where +the single VIRTIO_NET_HDR_GSO_UDP label covers both UFOv4 and UFOv6. + +Skip this best effort if the field is already initialized. Whether +explicitly from userspace, or implicitly based on an earlier call to +dev_parse_header_protocol (which is more robust, but was introduced +after this patch). + +Fixes: 9d2f67e43b73 ("net/packet: fix packet drop as of virtio gso") +Signed-off-by: Willem de Bruijn +Link: https://lore.kernel.org/r/20211220145027.2784293-1-willemdebruijn.kernel@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Juergen Gross +--- + include/linux/virtio_net.h | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h +index 22dd48c82560..a960de68ac69 100644 +--- a/include/linux/virtio_net.h ++++ b/include/linux/virtio_net.h +@@ -25,6 +25,9 @@ static inline bool virtio_net_hdr_match_proto(__be16 protocol, __u8 gso_type) + static inline int virtio_net_hdr_set_proto(struct sk_buff *skb, + const struct virtio_net_hdr *hdr) + { ++ if (skb->protocol) ++ return 0; ++ + switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { + case VIRTIO_NET_HDR_GSO_TCPV4: + case VIRTIO_NET_HDR_GSO_UDP: +-- +2.35.3 + diff --git a/patches.suse/net-virtio_net_hdr_to_skb-count-transport-header-in-.patch b/patches.suse/net-virtio_net_hdr_to_skb-count-transport-header-in-.patch new file mode 100644 index 0000000..2c6c5a4 --- /dev/null +++ b/patches.suse/net-virtio_net_hdr_to_skb-count-transport-header-in-.patch @@ -0,0 +1,73 @@ +Patch-mainline: v5.16-rc2 +Git-commit: cf9acc90c80ecbee00334aa85d92f4e74014bcff +References: git-fixes +From: Jonathan Davies +Date: Tue, 16 Nov 2021 17:42:42 +0000 +Subject: [PATCH] net: virtio_net_hdr_to_skb: count transport header in UFO + +virtio_net_hdr_to_skb does not set the skb's gso_size and gso_type +correctly for UFO packets received via virtio-net that are a little over +the GSO size. This can lead to problems elsewhere in the networking +stack, e.g. ovs_vport_send dropping over-sized packets if gso_size is +not set. + +This is due to the comparison + + if (skb->len - p_off > gso_size) + +not properly accounting for the transport layer header. + +p_off includes the size of the transport layer header (thlen), so +skb->len - p_off is the size of the TCP/UDP payload. + +gso_size is read from the virtio-net header. For UFO, fragmentation +happens at the IP level so does not need to include the UDP header. + +Hence the calculation could be comparing a TCP/UDP payload length with +an IP payload length, causing legitimate virtio-net packets to have +lack gso_type/gso_size information. + +Example: a UDP packet with payload size 1473 has IP payload size 1481. +If the guest used UFO, it is not fragmented and the virtio-net header's +flags indicate that it is a GSO frame (VIRTIO_NET_HDR_GSO_UDP), with +gso_size = 1480 for an MTU of 1500. skb->len will be 1515 and p_off +will be 42, so skb->len - p_off = 1473. Hence the comparison fails, and +shinfo->gso_size and gso_type are not set as they should be. + +Instead, add the UDP header length before comparing to gso_size when +using UFO. In this way, it is the size of the IP payload that is +compared to gso_size. + +Fixes: 6dd912f82680 ("net: check untrusted gso_size at kernel entry") +Signed-off-by: Jonathan Davies +Reviewed-by: Willem de Bruijn +Signed-off-by: David S. Miller +Signed-off-by: Juergen Gross +--- + include/linux/virtio_net.h | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h +index b465f8f3e554..04e87f4b9417 100644 +--- a/include/linux/virtio_net.h ++++ b/include/linux/virtio_net.h +@@ -120,10 +120,15 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb, + + if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) { + u16 gso_size = __virtio16_to_cpu(little_endian, hdr->gso_size); ++ unsigned int nh_off = p_off; + struct skb_shared_info *shinfo = skb_shinfo(skb); + ++ /* UFO may not include transport header in gso_size. */ ++ if (gso_type & SKB_GSO_UDP) ++ nh_off -= thlen; ++ + /* Too small packets are not really GSO ones. */ +- if (skb->len - p_off > gso_size) { ++ if (skb->len - nh_off > gso_size) { + shinfo->gso_size = gso_size; + shinfo->gso_type = gso_type; + +-- +2.35.3 + diff --git a/patches.suse/power-supply-bq24190-Fix-use-after-free-bug-in-bq241.patch b/patches.suse/power-supply-bq24190-Fix-use-after-free-bug-in-bq241.patch index b0e0de1..fe5bc48 100644 --- a/patches.suse/power-supply-bq24190-Fix-use-after-free-bug-in-bq241.patch +++ b/patches.suse/power-supply-bq24190-Fix-use-after-free-bug-in-bq241.patch @@ -40,11 +40,11 @@ Acked-by: Takashi Iwai --- a/drivers/power/supply/bq24190_charger.c +++ b/drivers/power/supply/bq24190_charger.c -@@ -1847,6 +1847,7 @@ static int bq24190_remove(struct i2c_cli +@@ -1883,6 +1883,7 @@ static __maybe_unused int bq24190_pm_sus struct bq24190_dev_info *bdi = i2c_get_clientdata(client); int error; + cancel_delayed_work_sync(&bdi->input_current_limit_work); - error = pm_runtime_get_sync(bdi->dev); - if (error < 0) { + error = pm_runtime_resume_and_get(bdi->dev); + if (error < 0) dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error); diff --git a/patches.suse/power-supply-bq24190_charger-using-pm_runtime_resume.patch b/patches.suse/power-supply-bq24190_charger-using-pm_runtime_resume.patch new file mode 100644 index 0000000..2f3caac --- /dev/null +++ b/patches.suse/power-supply-bq24190_charger-using-pm_runtime_resume.patch @@ -0,0 +1,184 @@ +From d96a89407e5f682d1cb22569d91784506c784863 Mon Sep 17 00:00:00 2001 +From: Minghao Chi +Date: Tue, 12 Apr 2022 08:30:44 +0000 +Subject: [PATCH] power: supply: bq24190_charger: using pm_runtime_resume_and_get instead of pm_runtime_get_sync +Git-commit: d96a89407e5f682d1cb22569d91784506c784863 +Patch-mainline: v5.19-rc1 +References: git-fixes + +Using pm_runtime_resume_and_get is more appropriate +for simplifing code + +Reported-by: Zeal Robot +Signed-off-by: Minghao Chi +Signed-off-by: Sebastian Reichel +Acked-by: Takashi Iwai + +--- + drivers/power/supply/bq24190_charger.c | 63 +++++++++++---------------------- + 1 file changed, 21 insertions(+), 42 deletions(-) + +--- a/drivers/power/supply/bq24190_charger.c ++++ b/drivers/power/supply/bq24190_charger.c +@@ -446,11 +446,9 @@ static ssize_t bq24190_sysfs_show(struct + if (!info) + return -EINVAL; + +- ret = pm_runtime_get_sync(bdi->dev); +- if (ret < 0) { +- pm_runtime_put_noidle(bdi->dev); ++ ret = pm_runtime_resume_and_get(bdi->dev); ++ if (ret < 0) + return ret; +- } + + ret = bq24190_read_mask(bdi, info->reg, info->mask, info->shift, &v); + if (ret) +@@ -481,11 +479,9 @@ static ssize_t bq24190_sysfs_store(struc + if (ret < 0) + return ret; + +- ret = pm_runtime_get_sync(bdi->dev); +- if (ret < 0) { +- pm_runtime_put_noidle(bdi->dev); ++ ret = pm_runtime_resume_and_get(bdi->dev); ++ if (ret < 0) + return ret; +- } + + ret = bq24190_write_mask(bdi, info->reg, info->mask, info->shift, v); + if (ret) +@@ -504,10 +500,9 @@ static int bq24190_set_charge_mode(struc + struct bq24190_dev_info *bdi = rdev_get_drvdata(dev); + int ret; + +- ret = pm_runtime_get_sync(bdi->dev); ++ ret = pm_runtime_resume_and_get(bdi->dev); + if (ret < 0) { + dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret); +- pm_runtime_put_noidle(bdi->dev); + return ret; + } + +@@ -537,10 +532,9 @@ static int bq24190_vbus_is_enabled(struc + int ret; + u8 val; + +- ret = pm_runtime_get_sync(bdi->dev); ++ ret = pm_runtime_resume_and_get(bdi->dev); + if (ret < 0) { + dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret); +- pm_runtime_put_noidle(bdi->dev); + return ret; + } + +@@ -1081,11 +1075,9 @@ static int bq24190_charger_get_property( + + dev_dbg(bdi->dev, "prop: %d\n", psp); + +- ret = pm_runtime_get_sync(bdi->dev); +- if (ret < 0) { +- pm_runtime_put_noidle(bdi->dev); ++ ret = pm_runtime_resume_and_get(bdi->dev); ++ if (ret < 0) + return ret; +- } + + switch (psp) { + case POWER_SUPPLY_PROP_CHARGE_TYPE: +@@ -1155,11 +1147,9 @@ static int bq24190_charger_set_property( + + dev_dbg(bdi->dev, "prop: %d\n", psp); + +- ret = pm_runtime_get_sync(bdi->dev); +- if (ret < 0) { +- pm_runtime_put_noidle(bdi->dev); ++ ret = pm_runtime_resume_and_get(bdi->dev); ++ if (ret < 0) + return ret; +- } + + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: +@@ -1418,11 +1408,9 @@ static int bq24190_battery_get_property( + dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n"); + dev_dbg(bdi->dev, "prop: %d\n", psp); + +- ret = pm_runtime_get_sync(bdi->dev); +- if (ret < 0) { +- pm_runtime_put_noidle(bdi->dev); ++ ret = pm_runtime_resume_and_get(bdi->dev); ++ if (ret < 0) + return ret; +- } + + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: +@@ -1466,11 +1454,9 @@ static int bq24190_battery_set_property( + dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n"); + dev_dbg(bdi->dev, "prop: %d\n", psp); + +- ret = pm_runtime_get_sync(bdi->dev); +- if (ret < 0) { +- pm_runtime_put_noidle(bdi->dev); ++ ret = pm_runtime_resume_and_get(bdi->dev); ++ if (ret < 0) + return ret; +- } + + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: +@@ -1624,10 +1610,9 @@ static irqreturn_t bq24190_irq_handler_t + int error; + + bdi->irq_event = true; +- error = pm_runtime_get_sync(bdi->dev); ++ error = pm_runtime_resume_and_get(bdi->dev); + if (error < 0) { + dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error); +- pm_runtime_put_noidle(bdi->dev); + return IRQ_NONE; + } + bq24190_check_status(bdi); +@@ -1847,11 +1832,9 @@ static int bq24190_remove(struct i2c_cli + struct bq24190_dev_info *bdi = i2c_get_clientdata(client); + int error; + +- error = pm_runtime_get_sync(bdi->dev); +- if (error < 0) { ++ error = pm_runtime_resume_and_get(bdi->dev); ++ if (error < 0) + dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error); +- pm_runtime_put_noidle(bdi->dev); +- } + + bq24190_register_reset(bdi); + if (bdi->battery) +@@ -1900,11 +1883,9 @@ static __maybe_unused int bq24190_pm_sus + struct bq24190_dev_info *bdi = i2c_get_clientdata(client); + int error; + +- error = pm_runtime_get_sync(bdi->dev); +- if (error < 0) { ++ error = pm_runtime_resume_and_get(bdi->dev); ++ if (error < 0) + dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error); +- pm_runtime_put_noidle(bdi->dev); +- } + + bq24190_register_reset(bdi); + +@@ -1925,11 +1906,9 @@ static __maybe_unused int bq24190_pm_res + bdi->f_reg = 0; + bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */ + +- error = pm_runtime_get_sync(bdi->dev); +- if (error < 0) { ++ error = pm_runtime_resume_and_get(bdi->dev); ++ if (error < 0) + dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error); +- pm_runtime_put_noidle(bdi->dev); +- } + + bq24190_register_reset(bdi); + bq24190_set_config(bdi); diff --git a/patches.suse/s390-ctcm-Fix-return-type-of-ctc-mp-m_tx.patch b/patches.suse/s390-ctcm-Fix-return-type-of-ctc-mp-m_tx.patch new file mode 100644 index 0000000..1299493 --- /dev/null +++ b/patches.suse/s390-ctcm-Fix-return-type-of-ctc-mp-m_tx.patch @@ -0,0 +1,72 @@ +From: Nathan Chancellor +Date: Thu, 3 Nov 2022 10:01:28 -0700 +Subject: s390/ctcm: Fix return type of ctc{mp,}m_tx() +Git-commit: aa5bf80c3c067b82b4362cd6e8e2194623bcaca6 +Patch-mainline: v6.2-rc1 +References: git-fixes bsc#1211686 + +With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG), +indirect call targets are validated against the expected function +pointer prototype to make sure the call target is valid to help mitigate +ROP attacks. If they are not identical, there is a failure at run time, +which manifests as either a kernel panic or thread getting killed. A +proposed warning in clang aims to catch these at compile time, which +reveals: + + drivers/s390/net/ctcm_main.c:1064:21: error: incompatible function pointer types initializing 'netdev_tx_t (*)(struct sk_buff *, struct net_device *)' (aka 'enum netdev_tx (*)(struct sk_buff *, struct net_device *)') with an expression of type 'int (struct sk_buff *, struct net_device *)' [-Werror,-Wincompatible-function-pointer-types-strict] + .ndo_start_xmit = ctcm_tx, + ^~~~~~~ + drivers/s390/net/ctcm_main.c:1072:21: error: incompatible function pointer types initializing 'netdev_tx_t (*)(struct sk_buff *, struct net_device *)' (aka 'enum netdev_tx (*)(struct sk_buff *, struct net_device *)') with an expression of type 'int (struct sk_buff *, struct net_device *)' [-Werror,-Wincompatible-function-pointer-types-strict] + .ndo_start_xmit = ctcmpc_tx, + ^~~~~~~~~ + +->ndo_start_xmit() in 'struct net_device_ops' expects a return type of +'netdev_tx_t', not 'int'. Adjust the return type of ctc{mp,}m_tx() to +match the prototype's to resolve the warning and potential CFI failure, +should s390 select ARCH_SUPPORTS_CFI_CLANG in the future. + +Additionally, while in the area, remove a comment block that is no +longer relevant. + +Link: https://github.com/ClangBuiltLinux/linux/issues/1750 +Reviewed-by: Alexandra Winter +Reviewed-by: Kees Cook +Signed-off-by: Nathan Chancellor +Signed-off-by: David S. Miller +Acked-by: Miroslav Franc +--- + drivers/s390/net/ctcm_main.c | 11 ++--------- + 1 file changed, 2 insertions(+), 9 deletions(-) + +diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c +index 37b551bd43bf..bdfab9ea0046 100644 +--- a/drivers/s390/net/ctcm_main.c ++++ b/drivers/s390/net/ctcm_main.c +@@ -825,16 +825,9 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb) + /** + * Start transmission of a packet. + * Called from generic network device layer. +- * +- * skb Pointer to buffer containing the packet. +- * dev Pointer to interface struct. +- * +- * returns 0 if packet consumed, !0 if packet rejected. +- * Note: If we return !0, then the packet is free'd by +- * the generic network layer. + */ + /* first merge version - leaving both functions separated */ +-static int ctcm_tx(struct sk_buff *skb, struct net_device *dev) ++static netdev_tx_t ctcm_tx(struct sk_buff *skb, struct net_device *dev) + { + struct ctcm_priv *priv = dev->ml_priv; + +@@ -877,7 +870,7 @@ static int ctcm_tx(struct sk_buff *skb, struct net_device *dev) + } + + /* unmerged MPC variant of ctcm_tx */ +-static int ctcmpc_tx(struct sk_buff *skb, struct net_device *dev) ++static netdev_tx_t ctcmpc_tx(struct sk_buff *skb, struct net_device *dev) + { + int len = 0; + struct ctcm_priv *priv = dev->ml_priv; + diff --git a/patches.suse/s390-dasd-fix-hanging-blockdevice-after-request-requeue.patch b/patches.suse/s390-dasd-fix-hanging-blockdevice-after-request-requeue.patch new file mode 100644 index 0000000..f7e8087 --- /dev/null +++ b/patches.suse/s390-dasd-fix-hanging-blockdevice-after-request-requeue.patch @@ -0,0 +1,40 @@ +From: Stefan Haberland +Date: Wed, 5 Apr 2023 16:20:17 +0200 +Subject: s390/dasd: fix hanging blockdevice after request requeue +Git-commit: d8898ee50edecacdf0141f26fd90acf43d7e9cd7 +Patch-mainline: v6.4-rc1 +References: git-fixes bsc#1211687 + +The DASD driver does not kick the requeue list when requeuing IO requests +to the blocklayer. This might lead to hanging blockdevice when there is +no other trigger for this. + +Fix by automatically kick the requeue list when requeuing DASD requests +to the blocklayer. + +Fixes: e443343e509a ("s390/dasd: blk-mq conversion") +CC: stable@vger.kernel.org # 4.14+ +Signed-off-by: Stefan Haberland +Reviewed-by: Jan Hoeppner +Reviewed-by: Halil Pasic +Link: https://lore.kernel.org/r/20230405142017.2446986-8-sth@linux.ibm.com +Signed-off-by: Jens Axboe +Acked-by: Miroslav Franc +--- + drivers/s390/block/dasd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c +index 3696931f8015..9fbfce735d56 100644 +--- a/drivers/s390/block/dasd.c ++++ b/drivers/s390/block/dasd.c +@@ -2953,7 +2953,7 @@ static int _dasd_requeue_request(struct dasd_ccw_req *cqr) + return 0; + spin_lock_irq(&cqr->dq->lock); + req = (struct request *) cqr->callback_data; +- blk_mq_requeue_request(req, false); ++ blk_mq_requeue_request(req, true); + spin_unlock_irq(&cqr->dq->lock); + + return 0; + diff --git a/patches.suse/s390-kprobes-fix-current_kprobe-never-cleared-after-kprobes-reenter.patch b/patches.suse/s390-kprobes-fix-current_kprobe-never-cleared-after-kprobes-reenter.patch new file mode 100644 index 0000000..014d35a --- /dev/null +++ b/patches.suse/s390-kprobes-fix-current_kprobe-never-cleared-after-kprobes-reenter.patch @@ -0,0 +1,54 @@ +From: Vasily Gorbik +Date: Wed, 1 Mar 2023 17:58:06 +0100 +Subject: s390/kprobes: fix current_kprobe never cleared after kprobes reenter +Git-commit: cd57953936f2213dfaccce10d20f396956222c7d +Patch-mainline: v6.3-rc1 +References: git-fixes bsc#1211688 + +Recent test_kprobe_missed kprobes kunit test uncovers the following +problem. Once kprobe is triggered from another kprobe (kprobe reenter), +all future kprobes on this cpu are considered as kprobe reenter, thus +pre_handler and post_handler are not being called and kprobes are counted +as "missed". + +Commit b9599798f953 ("[S390] kprobes: activation and deactivation") +introduced a simpler scheme for kprobes (de)activation and status +tracking by using push_kprobe/pop_kprobe, which supposed to work for +both initial kprobe entry as well as kprobe reentry and helps to avoid +handling those two cases differently. The problem is that a sequence of +calls in case of kprobes reenter: +push_kprobe() <- NULL (current_kprobe) +push_kprobe() <- kprobe1 (current_kprobe) +pop_kprobe() -> kprobe1 (current_kprobe) +pop_kprobe() -> kprobe1 (current_kprobe) +leaves "kprobe1" as "current_kprobe" on this cpu, instead of setting it +to NULL. In fact push_kprobe/pop_kprobe can only store a single state +(there is just one prev_kprobe in kprobe_ctlblk). Which is a hack but +sufficient, there is no need to have another prev_kprobe just to store +NULL. To make a simple and backportable fix simply reset "prev_kprobe" +when kprobe is poped from this "stack". No need to worry about +"kprobe_status" in this case, because its value is only checked when +current_kprobe != NULL. + +Cc: stable@vger.kernel.org +Fixes: b9599798f953 ("[S390] kprobes: activation and deactivation") +Reviewed-by: Heiko Carstens +Signed-off-by: Vasily Gorbik +Signed-off-by: Heiko Carstens +Acked-by: Miroslav Franc +--- + arch/s390/kernel/kprobes.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c +index c505c0ee5f47..e53192a5d593 100644 +--- a/arch/s390/kernel/kprobes.c ++++ b/arch/s390/kernel/kprobes.c +@@ -233,6 +233,7 @@ static void pop_kprobe(struct kprobe_ctlblk *kcb) + { + __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp); + kcb->kprobe_status = kcb->prev_kprobe.status; ++ kcb->prev_kprobe.kp = NULL; + } + NOKPROBE_SYMBOL(pop_kprobe); + diff --git a/patches.suse/s390-kprobes-fix-irq-mask-clobbering-on-kprobe-reenter-from-post_handler.patch b/patches.suse/s390-kprobes-fix-irq-mask-clobbering-on-kprobe-reenter-from-post_handler.patch new file mode 100644 index 0000000..b2f5232 --- /dev/null +++ b/patches.suse/s390-kprobes-fix-irq-mask-clobbering-on-kprobe-reenter-from-post_handler.patch @@ -0,0 +1,82 @@ +From: Vasily Gorbik +Date: Wed, 1 Mar 2023 02:23:08 +0100 +Subject: s390/kprobes: fix irq mask clobbering on kprobe reenter from + post_handler +Git-commit: 42e19e6f04984088b6f9f0507c4c89a8152d9730 +Patch-mainline: v6.3-rc1 +References: git-fixes bsc#1211689 + +Recent test_kprobe_missed kprobes kunit test uncovers the following error +(reported when CONFIG_DEBUG_ATOMIC_SLEEP is enabled): + +BUG: sleeping function called from invalid context at kernel/locking/mutex.c:580 +in_atomic(): 0, irqs_disabled(): 1, non_block: 0, pid: 662, name: kunit_try_catch +preempt_count: 0, expected: 0 +RCU nest depth: 0, expected: 0 +no locks held by kunit_try_catch/662. +irq event stamp: 280 +hardirqs last enabled at (279): [<00000003e60a3d42>] __do_pgm_check+0x17a/0x1c0 +hardirqs last disabled at (280): [<00000003e3bd774a>] kprobe_exceptions_notify+0x27a/0x318 +softirqs last enabled at (0): [<00000003e3c5c890>] copy_process+0x14a8/0x4c80 +softirqs last disabled at (0): [<0000000000000000>] 0x0 +CPU: 46 PID: 662 Comm: kunit_try_catch Tainted: G N 6.2.0-173644-g44c18d77f0c0 #2 +Hardware name: IBM 3931 A01 704 (LPAR) +Call Trace: + [<00000003e60a3a00>] dump_stack_lvl+0x120/0x198 + [<00000003e3d02e82>] __might_resched+0x60a/0x668 + [<00000003e60b9908>] __mutex_lock+0xc0/0x14e0 + [<00000003e60bad5a>] mutex_lock_nested+0x32/0x40 + [<00000003e3f7b460>] unregister_kprobe+0x30/0xd8 + [<00000003e51b2602>] test_kprobe_missed+0xf2/0x268 + [<00000003e51b5406>] kunit_try_run_case+0x10e/0x290 + [<00000003e51b7dfa>] kunit_generic_run_threadfn_adapter+0x62/0xb8 + [<00000003e3ce30f8>] kthread+0x2d0/0x398 + [<00000003e3b96afa>] __ret_from_fork+0x8a/0xe8 + [<00000003e60ccada>] ret_from_fork+0xa/0x40 + +The reason for this error report is that kprobes handling code failed +to restore irqs. + +The problem is that when kprobe is triggered from another kprobe +post_handler current sequence of enable_singlestep / disable_singlestep +is the following: +enable_singlestep <- original kprobe (saves kprobe_saved_imask) +enable_singlestep <- kprobe triggered from post_handler (clobbers kprobe_saved_imask) +disable_singlestep <- kprobe triggered from post_handler (restores kprobe_saved_imask) +disable_singlestep <- original kprobe (restores wrong clobbered kprobe_saved_imask) + +There is just one kprobe_ctlblk per cpu and both calls saves and +loads irq mask to kprobe_saved_imask. To fix the problem simply move +resume_execution (which calls disable_singlestep) before calling +post_handler. This also fixes the problem that post_handler is called +with pt_regs which were not yet adjusted after single-stepping. + +Cc: stable@vger.kernel.org +Fixes: 4ba069b802c2 ("[S390] add kprobes support.") +Reviewed-by: Heiko Carstens +Signed-off-by: Vasily Gorbik +Signed-off-by: Heiko Carstens +Acked-by: Miroslav Franc +--- + arch/s390/kernel/kprobes.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c +index 5e713f318de3..698fce57a2c8 100644 +--- a/arch/s390/kernel/kprobes.c ++++ b/arch/s390/kernel/kprobes.c +@@ -402,12 +402,11 @@ static int post_kprobe_handler(struct pt_regs *regs) + if (!p) + return 0; + ++ resume_execution(p, regs); + if (kcb->kprobe_status != KPROBE_REENTER && p->post_handler) { + kcb->kprobe_status = KPROBE_HIT_SSDONE; + p->post_handler(p, regs, 0); + } +- +- resume_execution(p, regs); + pop_kprobe(kcb); + preempt_enable_no_resched(); + + diff --git a/patches.suse/s390-lcs-Fix-return-type-of-lcs_start_xmit.patch b/patches.suse/s390-lcs-Fix-return-type-of-lcs_start_xmit.patch new file mode 100644 index 0000000..9446227 --- /dev/null +++ b/patches.suse/s390-lcs-Fix-return-type-of-lcs_start_xmit.patch @@ -0,0 +1,64 @@ +From: Nathan Chancellor +Date: Thu, 3 Nov 2022 10:01:30 -0700 +Subject: s390/lcs: Fix return type of lcs_start_xmit() +Git-commit: bb16db8393658e0978c3f0d30ae069e878264fa3 +Patch-mainline: v6.2-rc1 +References: git-fixes bsc#1211690 + +With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG), +indirect call targets are validated against the expected function +pointer prototype to make sure the call target is valid to help mitigate +ROP attacks. If they are not identical, there is a failure at run time, +which manifests as either a kernel panic or thread getting killed. A +proposed warning in clang aims to catch these at compile time, which +reveals: + + drivers/s390/net/lcs.c:2090:21: error: incompatible function pointer types initializing 'netdev_tx_t (*)(struct sk_buff *, struct net_device *)' (aka 'enum netdev_tx (*)(struct sk_buff *, struct net_device *)') with an expression of type 'int (struct sk_buff *, struct net_device *)' [-Werror,-Wincompatible-function-pointer-types-strict] + .ndo_start_xmit = lcs_start_xmit, + ^~~~~~~~~~~~~~ + drivers/s390/net/lcs.c:2097:21: error: incompatible function pointer types initializing 'netdev_tx_t (*)(struct sk_buff *, struct net_device *)' (aka 'enum netdev_tx (*)(struct sk_buff *, struct net_device *)') with an expression of type 'int (struct sk_buff *, struct net_device *)' [-Werror,-Wincompatible-function-pointer-types-strict] + .ndo_start_xmit = lcs_start_xmit, + ^~~~~~~~~~~~~~ + +->ndo_start_xmit() in 'struct net_device_ops' expects a return type of +'netdev_tx_t', not 'int'. Adjust the return type of lcs_start_xmit() to +match the prototype's to resolve the warning and potential CFI failure, +should s390 select ARCH_SUPPORTS_CFI_CLANG in the future. + +Link: https://github.com/ClangBuiltLinux/linux/issues/1750 +Reviewed-by: Alexandra Winter +Reviewed-by: Kees Cook +Signed-off-by: Nathan Chancellor +Signed-off-by: David S. Miller +Acked-by: Miroslav Franc +--- + drivers/s390/net/lcs.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c +index 84c8981317b4..38f312664ce7 100644 +--- a/drivers/s390/net/lcs.c ++++ b/drivers/s390/net/lcs.c +@@ -1519,9 +1519,8 @@ lcs_txbuffer_cb(struct lcs_channel *channel, struct lcs_buffer *buffer) + /** + * Packet transmit function called by network stack + */ +-static int +-__lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb, +- struct net_device *dev) ++static netdev_tx_t __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb, ++ struct net_device *dev) + { + struct lcs_header *header; + int rc = NETDEV_TX_OK; +@@ -1582,8 +1581,7 @@ __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb, + return rc; + } + +-static int +-lcs_start_xmit(struct sk_buff *skb, struct net_device *dev) ++static netdev_tx_t lcs_start_xmit(struct sk_buff *skb, struct net_device *dev) + { + struct lcs_card *card; + int rc; + diff --git a/patches.suse/s390-mem_detect-fix-detect_memory-error-handling.patch b/patches.suse/s390-mem_detect-fix-detect_memory-error-handling.patch new file mode 100644 index 0000000..7b879f3 --- /dev/null +++ b/patches.suse/s390-mem_detect-fix-detect_memory-error-handling.patch @@ -0,0 +1,37 @@ +From: Vasily Gorbik +Date: Fri, 27 Jan 2023 14:03:07 +0100 +Subject: s390/mem_detect: fix detect_memory() error handling +Git-commit: 3400c35a4090704e6c465449616ab7e67a9209e7 +Patch-mainline: v6.3-rc1 +References: git-fixes bsc#1211691 + +Currently if for some reason sclp_early_read_info() fails, +sclp_early_get_memsize() will not set max_physmem_end and it +will stay uninitialized. Any garbage value other than 0 will lead +to detect_memory() taking wrong path or returning a garbage value +as max_physmem_end. To avoid that simply initialize max_physmem_end. + +Fixes: 73045a08cf55 ("s390: unify identity mapping limits handling") +Reported-by: Alexander Gordeev +Reviewed-by: Alexander Gordeev +Signed-off-by: Vasily Gorbik +Signed-off-by: Heiko Carstens +Acked-by: Miroslav Franc +--- + arch/s390/boot/mem_detect.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/s390/boot/mem_detect.c b/arch/s390/boot/mem_detect.c +index 7fa1a32ea0f3..0a5821ef4f1f 100644 +--- a/arch/s390/boot/mem_detect.c ++++ b/arch/s390/boot/mem_detect.c +@@ -165,7 +165,7 @@ static void search_mem_end(void) + + unsigned long detect_memory(void) + { +- unsigned long max_physmem_end; ++ unsigned long max_physmem_end = 0; + + sclp_early_get_memsize(&max_physmem_end); + + diff --git a/patches.suse/s390-netiucv-Fix-return-type-of-netiucv_tx.patch b/patches.suse/s390-netiucv-Fix-return-type-of-netiucv_tx.patch new file mode 100644 index 0000000..bdbec5f --- /dev/null +++ b/patches.suse/s390-netiucv-Fix-return-type-of-netiucv_tx.patch @@ -0,0 +1,59 @@ +From: Nathan Chancellor +Date: Thu, 3 Nov 2022 10:01:29 -0700 +Subject: s390/netiucv: Fix return type of netiucv_tx() +Git-commit: 88d86d18d7cf7e9137c95f9d212bb9fff8a1b4be +Patch-mainline: v6.2-rc1 +References: git-fixes bsc#1211692 + +With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG), +indirect call targets are validated against the expected function +pointer prototype to make sure the call target is valid to help mitigate +ROP attacks. If they are not identical, there is a failure at run time, +which manifests as either a kernel panic or thread getting killed. A +proposed warning in clang aims to catch these at compile time, which +reveals: + + drivers/s390/net/netiucv.c:1854:21: error: incompatible function pointer types initializing 'netdev_tx_t (*)(struct sk_buff *, struct net_device *)' (aka 'enum netdev_tx (*)(struct sk_buff *, struct net_device *)') with an expression of type 'int (struct sk_buff *, struct net_device *)' [-Werror,-Wincompatible-function-pointer-types-strict] + .ndo_start_xmit = netiucv_tx, + ^~~~~~~~~~ + +->ndo_start_xmit() in 'struct net_device_ops' expects a return type of +'netdev_tx_t', not 'int'. Adjust the return type of netiucv_tx() to +match the prototype's to resolve the warning and potential CFI failure, +should s390 select ARCH_SUPPORTS_CFI_CLANG in the future. + +Additionally, while in the area, remove a comment block that is no +longer relevant. + +Link: https://github.com/ClangBuiltLinux/linux/issues/1750 +Reviewed-by: Alexandra Winter +Reviewed-by: Kees Cook +Signed-off-by: Nathan Chancellor +Signed-off-by: David S. Miller +Acked-by: Miroslav Franc +--- + drivers/s390/net/netiucv.c | 9 +-------- + 1 file changed, 1 insertion(+), 8 deletions(-) + +diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c +index 65aa0a96c21d..66076cada8ae 100644 +--- a/drivers/s390/net/netiucv.c ++++ b/drivers/s390/net/netiucv.c +@@ -1248,15 +1248,8 @@ static int netiucv_close(struct net_device *dev) + /** + * Start transmission of a packet. + * Called from generic network device layer. +- * +- * @param skb Pointer to buffer containing the packet. +- * @param dev Pointer to interface struct. +- * +- * @return 0 if packet consumed, !0 if packet rejected. +- * Note: If we return !0, then the packet is free'd by +- * the generic network layer. + */ +-static int netiucv_tx(struct sk_buff *skb, struct net_device *dev) ++static netdev_tx_t netiucv_tx(struct sk_buff *skb, struct net_device *dev) + { + struct netiucv_priv *privptr = netdev_priv(dev); + int rc; + diff --git a/patches.suse/s390-qdio-fix-do_sqbs-inline-assembly-constraint.patch b/patches.suse/s390-qdio-fix-do_sqbs-inline-assembly-constraint.patch new file mode 100644 index 0000000..5ad8cbf --- /dev/null +++ b/patches.suse/s390-qdio-fix-do_sqbs-inline-assembly-constraint.patch @@ -0,0 +1,62 @@ +From: Heiko Carstens +Date: Thu, 11 May 2023 17:04:41 +0200 +Subject: s390/qdio: fix do_sqbs() inline assembly constraint +Git-commit: 2862a2fdfae875888e3c1c3634e3422e01d98147 +Patch-mainline: v6.4-rc3 +References: git-fixes bsc#1211693 + +Use "a" constraint instead of "d" constraint to pass the state parameter to +the do_sqbs() inline assembly. This prevents that general purpose register +zero is used for the state parameter. + +If the compiler would select general purpose register zero this would be +problematic for the used instruction in rsy format: the register used for +the state parameter is a base register. If the base register is general +purpose register zero the contents of the register are unexpectedly ignored +when the instruction is executed. + +This only applies to z/VM guests using QIOASSIST with dedicated (pass through) +QDIO-based devices such as FCP [zfcp driver] as well as real OSA or +HiperSockets [qeth driver]. + +A possible symptom for this case using zfcp is the following repeating kernel +message pattern: + +zfcp : A QDIO problem occurred +zfcp : A QDIO problem occurred +zfcp : qdio: ZFCP on SC using AI:1 QEBSM:1 PRI:1 TDD:1 SIGA: W +zfcp : A QDIO problem occurred +zfcp : A QDIO problem occurred + +Each of the qdio problem message can be accompanied by the following entries +for the affected subchannel in +/sys/kernel/debug/s390dbf/qdio_error/hex_ascii for zfcp or qeth: + + ccq: 69.... + SQBS ERROR. + +Reviewed-by: Benjamin Block +Cc: Steffen Maier +Fixes: 8129ee164267 ("[PATCH] s390: qdio V=V pass-through") +Cc: +Signed-off-by: Heiko Carstens +Signed-off-by: Alexander Gordeev +Acked-by: Miroslav Franc +--- + drivers/s390/cio/qdio.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h +index 5ea6249d8180..641f0dbb65a9 100644 +--- a/drivers/s390/cio/qdio.h ++++ b/drivers/s390/cio/qdio.h +@@ -95,7 +95,7 @@ static inline int do_sqbs(u64 token, unsigned char state, int queue, + " lgr 1,%[token]\n" + " .insn rsy,0xeb000000008a,%[qs],%[ccq],0(%[state])" + : [ccq] "+&d" (_ccq), [qs] "+&d" (_queuestart) +- : [state] "d" ((unsigned long)state), [token] "d" (token) ++ : [state] "a" ((unsigned long)state), [token] "d" (token) + : "memory", "cc", "1"); + *count = _ccq & 0xff; + *start = _queuestart & 0xff; + diff --git a/patches.suse/scsi-iscsi_tcp-Fix-UAF-during-login-when-accessing-the-shost-ipaddress.patch b/patches.suse/scsi-iscsi_tcp-Fix-UAF-during-login-when-accessing-the-shost-ipaddress.patch index 89bd3de..08a52f2 100644 --- a/patches.suse/scsi-iscsi_tcp-Fix-UAF-during-login-when-accessing-the-shost-ipaddress.patch +++ b/patches.suse/scsi-iscsi_tcp-Fix-UAF-during-login-when-accessing-the-shost-ipaddress.patch @@ -4,7 +4,7 @@ Subject: scsi: iscsi_tcp: Fix UAF during login when accessing the shost ipaddress Git-commit: f484a794e4ee2a9ce61f52a78e810ac45f3fe3b3 Patch-mainline: v6.2-rc6 -References: git-fixes +References: git-fixes CVE-2023-2162 bsc#1210647 If during iscsi_sw_tcp_session_create() iscsi_tcp_r2tpool_alloc() fails, userspace could be accessing the host's ipaddress attr. If we then free the diff --git a/patches.suse/tools-virtio-compile-with-pthread.patch b/patches.suse/tools-virtio-compile-with-pthread.patch new file mode 100644 index 0000000..4232547 --- /dev/null +++ b/patches.suse/tools-virtio-compile-with-pthread.patch @@ -0,0 +1,36 @@ +Patch-mainline: v5.18-rc1 +Git-commit: f03560a57c1f60db6ac23ffd9714e1c69e2f95c7 +References: git-fixes +From: "Michael S. Tsirkin" +Date: Sun, 20 Mar 2022 07:02:14 -0400 +Subject: [PATCH] tools/virtio: compile with -pthread + +When using pthreads, one has to compile and link with -lpthread, +otherwise e.g. glibc is not guaranteed to be reentrant. + +This replaces -lpthread. + +Reported-by: Matthew Wilcox +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Juergen Gross +--- + tools/virtio/Makefile | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/tools/virtio/Makefile b/tools/virtio/Makefile +index 0d7bbe49359d..1b25cc7c64bb 100644 +--- a/tools/virtio/Makefile ++++ b/tools/virtio/Makefile +@@ -5,7 +5,8 @@ virtio_test: virtio_ring.o virtio_test.o + vringh_test: vringh_test.o vringh.o virtio_ring.o + + CFLAGS += -g -O2 -Werror -Wno-maybe-uninitialized -Wall -I. -I../include/ -I ../../usr/include/ -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD -U_FORTIFY_SOURCE -include ../../include/linux/kconfig.h +-LDFLAGS += -lpthread ++CFLAGS += -pthread ++LDFLAGS += -pthread + vpath %.c ../../drivers/virtio ../../drivers/vhost + mod: + ${MAKE} -C `pwd`/../.. M=`pwd`/vhost_test V=${V} +-- +2.35.3 + diff --git a/patches.suse/tools-virtio-fix-the-vringh-test-for-virtio-ring-cha.patch b/patches.suse/tools-virtio-fix-the-vringh-test-for-virtio-ring-cha.patch new file mode 100644 index 0000000..fc4fb14 --- /dev/null +++ b/patches.suse/tools-virtio-fix-the-vringh-test-for-virtio-ring-cha.patch @@ -0,0 +1,148 @@ +Patch-mainline: v6.2-rc7 +Git-commit: 3f7b75abf41cc4143aa295f62acbb060a012868d +References: git-fixes +From: Shunsuke Mie +Date: Tue, 10 Jan 2023 12:43:10 +0900 +Subject: [PATCH] tools/virtio: fix the vringh test for virtio ring changes + +Fix the build caused by missing kmsan_handle_dma() and is_power_of_2() that +are used in drivers/virtio/virtio_ring.c. + +Signed-off-by: Shunsuke Mie +Message-Id: <20230110034310.779744-1-mie@igel.co.jp> +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Juergen Gross +--- + tools/virtio/linux/bug.h | 8 +++----- + tools/virtio/linux/build_bug.h | 7 +++++++ + tools/virtio/linux/cpumask.h | 7 +++++++ + tools/virtio/linux/gfp.h | 7 +++++++ + tools/virtio/linux/kernel.h | 1 + + tools/virtio/linux/kmsan.h | 12 ++++++++++++ + tools/virtio/linux/scatterlist.h | 1 + + tools/virtio/linux/topology.h | 7 +++++++ + 8 files changed, 45 insertions(+), 5 deletions(-) + create mode 100644 tools/virtio/linux/build_bug.h + create mode 100644 tools/virtio/linux/cpumask.h + create mode 100644 tools/virtio/linux/gfp.h + create mode 100644 tools/virtio/linux/kmsan.h + create mode 100644 tools/virtio/linux/topology.h + +diff --git a/tools/virtio/linux/bug.h b/tools/virtio/linux/bug.h +index 813baf13f62a..51a919083d9b 100644 +--- a/tools/virtio/linux/bug.h ++++ b/tools/virtio/linux/bug.h +@@ -1,13 +1,11 @@ + /* SPDX-License-Identifier: GPL-2.0 */ +-#ifndef BUG_H +-#define BUG_H ++#ifndef _LINUX_BUG_H ++#define _LINUX_BUG_H + + #include + + #define BUG_ON(__BUG_ON_cond) assert(!(__BUG_ON_cond)) + +-#define BUILD_BUG_ON(x) +- + #define BUG() abort() + +-#endif /* BUG_H */ ++#endif /* _LINUX_BUG_H */ +diff --git a/tools/virtio/linux/build_bug.h b/tools/virtio/linux/build_bug.h +new file mode 100644 +index 000000000000..cdbb75e28a60 +--- /dev/null ++++ b/tools/virtio/linux/build_bug.h +@@ -0,0 +1,7 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#ifndef _LINUX_BUILD_BUG_H ++#define _LINUX_BUILD_BUG_H ++ ++#define BUILD_BUG_ON(x) ++ ++#endif /* _LINUX_BUILD_BUG_H */ +diff --git a/tools/virtio/linux/cpumask.h b/tools/virtio/linux/cpumask.h +new file mode 100644 +index 000000000000..307da69d6b26 +--- /dev/null ++++ b/tools/virtio/linux/cpumask.h +@@ -0,0 +1,7 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#ifndef _LINUX_CPUMASK_H ++#define _LINUX_CPUMASK_H ++ ++#include ++ ++#endif /* _LINUX_CPUMASK_H */ +diff --git a/tools/virtio/linux/gfp.h b/tools/virtio/linux/gfp.h +new file mode 100644 +index 000000000000..43d146f236f1 +--- /dev/null ++++ b/tools/virtio/linux/gfp.h +@@ -0,0 +1,7 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#ifndef __LINUX_GFP_H ++#define __LINUX_GFP_H ++ ++#include ++ ++#endif +diff --git a/tools/virtio/linux/kernel.h b/tools/virtio/linux/kernel.h +index 21593bf97755..8b877167933d 100644 +--- a/tools/virtio/linux/kernel.h ++++ b/tools/virtio/linux/kernel.h +@@ -10,6 +10,7 @@ + #include + + #include ++#include + #include + #include + #include +diff --git a/tools/virtio/linux/kmsan.h b/tools/virtio/linux/kmsan.h +new file mode 100644 +index 000000000000..272b5aa285d5 +--- /dev/null ++++ b/tools/virtio/linux/kmsan.h +@@ -0,0 +1,12 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#ifndef _LINUX_KMSAN_H ++#define _LINUX_KMSAN_H ++ ++#include ++ ++inline void kmsan_handle_dma(struct page *page, size_t offset, size_t size, ++ enum dma_data_direction dir) ++{ ++} ++ ++#endif /* _LINUX_KMSAN_H */ +diff --git a/tools/virtio/linux/scatterlist.h b/tools/virtio/linux/scatterlist.h +index 369ee308b668..74d9e1825748 100644 +--- a/tools/virtio/linux/scatterlist.h ++++ b/tools/virtio/linux/scatterlist.h +@@ -2,6 +2,7 @@ + #ifndef SCATTERLIST_H + #define SCATTERLIST_H + #include ++#include + + struct scatterlist { + unsigned long page_link; +diff --git a/tools/virtio/linux/topology.h b/tools/virtio/linux/topology.h +new file mode 100644 +index 000000000000..910794afb993 +--- /dev/null ++++ b/tools/virtio/linux/topology.h +@@ -0,0 +1,7 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#ifndef _LINUX_TOPOLOGY_H ++#define _LINUX_TOPOLOGY_H ++ ++#include ++ ++#endif /* _LINUX_TOPOLOGY_H */ +-- +2.35.3 + diff --git a/patches.suse/tools-virtio-fix-virtio_test-execution.patch b/patches.suse/tools-virtio-fix-virtio_test-execution.patch new file mode 100644 index 0000000..c08cd61 --- /dev/null +++ b/patches.suse/tools-virtio-fix-virtio_test-execution.patch @@ -0,0 +1,36 @@ +Patch-mainline: 5.17 +Git-commit: 32f1b53fe8f03d962423ba81f8e92af5839814da +References: git-fixes +From: Stefano Garzarella +Date: Tue, 18 Jan 2022 16:06:31 +0100 +Subject: [PATCH] tools/virtio: fix virtio_test execution + +virtio_test hangs on __vring_new_virtqueue() because `vqs_list_lock` +is not initialized. + +Let's initialize it in vdev_info_init(). + +Signed-off-by: Stefano Garzarella +Link: https://lore.kernel.org/r/20220118150631.167015-1-sgarzare@redhat.com +Signed-off-by: Michael S. Tsirkin +Acked-by: Jason Wang +Signed-off-by: Juergen Gross +--- + tools/virtio/virtio_test.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c +index cb3f29c09aff..23f142af544a 100644 +--- a/tools/virtio/virtio_test.c ++++ b/tools/virtio/virtio_test.c +@@ -130,6 +130,7 @@ static void vdev_info_init(struct vdev_info* dev, unsigned long long features) + memset(dev, 0, sizeof *dev); + dev->vdev.features = features; + INIT_LIST_HEAD(&dev->vdev.vqs); ++ spin_lock_init(&dev->vdev.vqs_list_lock); + dev->buf_size = 1024; + dev->buf = malloc(dev->buf_size); + assert(dev->buf); +-- +2.35.3 + diff --git a/patches.suse/tools-virtio-initialize-spinlocks-in-vring_test.c.patch b/patches.suse/tools-virtio-initialize-spinlocks-in-vring_test.c.patch new file mode 100644 index 0000000..8bc89e6 --- /dev/null +++ b/patches.suse/tools-virtio-initialize-spinlocks-in-vring_test.c.patch @@ -0,0 +1,46 @@ +Patch-mainline: v6.2-rc3 +Git-commit: c262f75cb6bb5a63828e72ce3b8fe808e5029479 +References: git-fixes +From: =?UTF-8?q?Ricardo=20Ca=C3=B1uelo?= +Date: Wed, 12 Oct 2022 08:29:49 +0200 +Subject: [PATCH] tools/virtio: initialize spinlocks in vring_test.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The virtio_device vqs_list spinlocks must be initialized before use to +prevent functions that manipulate the device virtualqueues, such as +vring_new_virtqueue(), from blocking indefinitely. + +Signed-off-by: Ricardo Cañuelo +Message-Id: <20221012062949.1526176-1-ricardo.canuelo@collabora.com> +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Xuan Zhuo +Signed-off-by: Juergen Gross +--- + tools/virtio/vringh_test.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tools/virtio/vringh_test.c b/tools/virtio/vringh_test.c +index fa87b58bd5fa..98ff808d6f0c 100644 +--- a/tools/virtio/vringh_test.c ++++ b/tools/virtio/vringh_test.c +@@ -308,6 +308,7 @@ static int parallel_test(u64 features, + + gvdev.vdev.features = features; + INIT_LIST_HEAD(&gvdev.vdev.vqs); ++ spin_lock_init(&gvdev.vdev.vqs_list_lock); + gvdev.to_host_fd = to_host[1]; + gvdev.notifies = 0; + +@@ -455,6 +456,7 @@ int main(int argc, char *argv[]) + getrange = getrange_iov; + vdev.features = 0; + INIT_LIST_HEAD(&vdev.vqs); ++ spin_lock_init(&vdev.vqs_list_lock); + + while (argv[1]) { + if (strcmp(argv[1], "--indirect") == 0) +-- +2.35.3 + diff --git a/patches.suse/usb-dwc3-Align-DWC3_EP_-flag-macros.patch b/patches.suse/usb-dwc3-Align-DWC3_EP_-flag-macros.patch new file mode 100644 index 0000000..3434cdd --- /dev/null +++ b/patches.suse/usb-dwc3-Align-DWC3_EP_-flag-macros.patch @@ -0,0 +1,53 @@ +From d1a4683747fe62905047b1ccd50405bc445cf86f Mon Sep 17 00:00:00 2001 +From: Jack Pham +Date: Thu, 21 Oct 2021 11:01:29 -0700 +Subject: [PATCH] usb: dwc3: Align DWC3_EP_* flag macros +Git-commit: d1a4683747fe62905047b1ccd50405bc445cf86f +References: git-fixes +Patch-mainline: v5.16-rc1 + +Fix the DWC3_EP_* flag macros so that the definitions are all +lined up on the same tab column for consistent style. + +No functional change. + +Signed-off-by: Jack Pham +Link: https://lore.kernel.org/r/20211021180129.27938-2-jackp@codeaurora.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/dwc3/core.h | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/usb/dwc3/core.h ++++ b/drivers/usb/dwc3/core.h +@@ -711,13 +711,13 @@ struct dwc3_ep { + + u32 saved_state; + unsigned int flags; +-#define DWC3_EP_ENABLED BIT(0) +-#define DWC3_EP_STALL BIT(1) +-#define DWC3_EP_WEDGE BIT(2) +-#define DWC3_EP_TRANSFER_STARTED BIT(3) +-#define DWC3_EP_END_TRANSFER_PENDING BIT(4) +-#define DWC3_EP_PENDING_REQUEST BIT(5) +-#define DWC3_EP_DELAY_START BIT(6) ++#define DWC3_EP_ENABLED BIT(0) ++#define DWC3_EP_STALL BIT(1) ++#define DWC3_EP_WEDGE BIT(2) ++#define DWC3_EP_TRANSFER_STARTED BIT(3) ++#define DWC3_EP_END_TRANSFER_PENDING BIT(4) ++#define DWC3_EP_PENDING_REQUEST BIT(5) ++#define DWC3_EP_DELAY_START BIT(6) + #define DWC3_EP_WAIT_TRANSFER_COMPLETE BIT(7) + #define DWC3_EP_IGNORE_NEXT_NOSTREAM BIT(8) + #define DWC3_EP_FORCE_RESTART_STREAM BIT(9) +@@ -725,7 +725,7 @@ struct dwc3_ep { + #define DWC3_EP_PENDING_CLEAR_STALL BIT(11) + + /* This last one is specific to EP0 */ +-#define DWC3_EP0_DIR_IN BIT(31) ++#define DWC3_EP0_DIR_IN BIT(31) + + /* + * IMPORTANT: we *know* we have 256 TRBs in our @trb_pool, so we will diff --git a/patches.suse/usb-dwc3-Fix-a-repeated-word-checkpatch-warning.patch b/patches.suse/usb-dwc3-Fix-a-repeated-word-checkpatch-warning.patch new file mode 100644 index 0000000..7742600 --- /dev/null +++ b/patches.suse/usb-dwc3-Fix-a-repeated-word-checkpatch-warning.patch @@ -0,0 +1,35 @@ +From d1b39dd5819a0ea5e09fb2c7f7bcb2e127cdbd89 Mon Sep 17 00:00:00 2001 +From: Kushagra Verma +Date: Fri, 20 May 2022 17:40:46 +0530 +Subject: [PATCH] usb: dwc3: Fix a repeated word checkpatch warning +Git-commit: d1b39dd5819a0ea5e09fb2c7f7bcb2e127cdbd89 +References: git-fixes +Patch-mainline: v6.0-rc1 + +Fixes a repeated word checkpatch warning in ep0.c by removing the repeated +'only' word. + +Signed-off-by: Kushagra Verma +Link: https://lore.kernel.org/r/HK0PR01MB2801996E815208393170010FF8D39@HK0PR01MB2801.apcprd01.prod.exchangelabs.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/dwc3/ep0.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c +index 5d642660fd15..2a510e84eef4 100644 +--- a/drivers/usb/dwc3/ep0.c ++++ b/drivers/usb/dwc3/ep0.c +@@ -473,7 +473,7 @@ static int dwc3_ep0_handle_device(struct dwc3 *dwc, + case USB_DEVICE_REMOTE_WAKEUP: + break; + /* +- * 9.4.1 says only only for SS, in AddressState only for ++ * 9.4.1 says only for SS, in AddressState only for + * default control pipe + */ + case USB_DEVICE_U1_ENABLE: +-- +2.40.1 + diff --git a/patches.suse/usb-dwc3-Fix-ep0-handling-when-getting-reset-while-d.patch b/patches.suse/usb-dwc3-Fix-ep0-handling-when-getting-reset-while-d.patch new file mode 100644 index 0000000..88b02f9 --- /dev/null +++ b/patches.suse/usb-dwc3-Fix-ep0-handling-when-getting-reset-while-d.patch @@ -0,0 +1,136 @@ +From 9d778f0c5f95ca5aa2ff628ea281978697e8d89b Mon Sep 17 00:00:00 2001 +From: Mayank Rana +Date: Wed, 4 May 2022 12:36:41 -0700 +Subject: [PATCH] usb: dwc3: Fix ep0 handling when getting reset while doing + control transfer +Git-commit: 9d778f0c5f95ca5aa2ff628ea281978697e8d89b +References: git-fixes +Patch-mainline: v5.19-rc1 + +According to the databook ep0 should be in setup phase during reset. +If host issues reset between control transfers, ep0 will be in an +invalid state. Fix this by issuing stall and restart on ep0 if it +is not in setup phase. + +Also SW needs to complete pending control transfer and setup core for +next setup stage as per data book. Hence check ep0 state during reset +interrupt handling and make sure active transfers on ep0 out/in +endpoint are stopped by queuing ENDXFER command for that endpoint and +restart ep0 out again to receive next setup packet. + +Signed-off-by: Mayank Rana +Link: https://lore.kernel.org/r/1651693001-29891-1-git-send-email-quic_mrana@quicinc.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/dwc3/ep0.c | 11 ++++++++--- + drivers/usb/dwc3/gadget.c | 27 +++++++++++++++++++++++++-- + drivers/usb/dwc3/gadget.h | 2 ++ + 3 files changed, 35 insertions(+), 5 deletions(-) + +diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c +index 6615f641b34f..5d642660fd15 100644 +--- a/drivers/usb/dwc3/ep0.c ++++ b/drivers/usb/dwc3/ep0.c +@@ -218,7 +218,7 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request, + return ret; + } + +-static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc) ++void dwc3_ep0_stall_and_restart(struct dwc3 *dwc) + { + struct dwc3_ep *dep; + +@@ -1088,13 +1088,18 @@ void dwc3_ep0_send_delayed_status(struct dwc3 *dwc) + __dwc3_ep0_do_control_status(dwc, dwc->eps[direction]); + } + +-static void dwc3_ep0_end_control_data(struct dwc3 *dwc, struct dwc3_ep *dep) ++void dwc3_ep0_end_control_data(struct dwc3 *dwc, struct dwc3_ep *dep) + { + struct dwc3_gadget_ep_cmd_params params; + u32 cmd; + int ret; + +- if (!dep->resource_index) ++ /* ++ * For status/DATA OUT stage, TRB will be queued on ep0 out ++ * endpoint for which resource index is zero. Hence allow ++ * queuing ENDXFER command for ep0 out endpoint. ++ */ ++ if (!dep->resource_index && dep->number) + return; + + cmd = DWC3_DEPCMD_ENDTRANSFER; +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index 4f54f0ef21df..8c366fa82105 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -882,12 +882,13 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, unsigned int action) + reg |= DWC3_DALEPENA_EP(dep->number); + dwc3_writel(dwc->regs, DWC3_DALEPENA, reg); + ++ dep->trb_dequeue = 0; ++ dep->trb_enqueue = 0; ++ + if (usb_endpoint_xfer_control(desc)) + goto out; + + /* Initialize the TRB ring */ +- dep->trb_dequeue = 0; +- dep->trb_enqueue = 0; + memset(dep->trb_pool, 0, + sizeof(struct dwc3_trb) * DWC3_TRB_NUM); + +@@ -2741,6 +2742,7 @@ static int __dwc3_gadget_start(struct dwc3 *dwc) + + /* begin to receive SETUP packets */ + dwc->ep0state = EP0_SETUP_PHASE; ++ dwc->ep0_bounced = false; + dwc->link_state = DWC3_LINK_STATE_SS_DIS; + dwc->delayed_status = false; + dwc3_ep0_out_start(dwc); +@@ -3820,6 +3822,27 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) + } + + dwc3_reset_gadget(dwc); ++ ++ /* ++ * From SNPS databook section 8.1.2, the EP0 should be in setup ++ * phase. So ensure that EP0 is in setup phase by issuing a stall ++ * and restart if EP0 is not in setup phase. ++ */ ++ if (dwc->ep0state != EP0_SETUP_PHASE) { ++ unsigned int dir; ++ ++ dir = !!dwc->ep0_expect_in; ++ if (dwc->ep0state == EP0_DATA_PHASE) ++ dwc3_ep0_end_control_data(dwc, dwc->eps[dir]); ++ else ++ dwc3_ep0_end_control_data(dwc, dwc->eps[!dir]); ++ ++ dwc->eps[0]->trb_enqueue = 0; ++ dwc->eps[1]->trb_enqueue = 0; ++ ++ dwc3_ep0_stall_and_restart(dwc); ++ } ++ + /* + * In the Synopsis DesignWare Cores USB3 Databook Rev. 3.30a + * Section 4.1.2 Table 4-2, it states that during a USB reset, the SW +diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h +index f763380e672e..55a56cf67d73 100644 +--- a/drivers/usb/dwc3/gadget.h ++++ b/drivers/usb/dwc3/gadget.h +@@ -110,6 +110,8 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, + void dwc3_ep0_interrupt(struct dwc3 *dwc, + const struct dwc3_event_depevt *event); + void dwc3_ep0_out_start(struct dwc3 *dwc); ++void dwc3_ep0_end_control_data(struct dwc3 *dwc, struct dwc3_ep *dep); ++void dwc3_ep0_stall_and_restart(struct dwc3 *dwc); + int __dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value); + int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value); + int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request, +-- +2.40.1 + diff --git a/patches.suse/usb-dwc3-drd-use-helper-to-get-role-switch-default-m.patch b/patches.suse/usb-dwc3-drd-use-helper-to-get-role-switch-default-m.patch new file mode 100644 index 0000000..92fb1ad --- /dev/null +++ b/patches.suse/usb-dwc3-drd-use-helper-to-get-role-switch-default-m.patch @@ -0,0 +1,43 @@ +From 26f94fe8e739641e96c50f70eb6e78ef1693d9ca Mon Sep 17 00:00:00 2001 +From: Chunfeng Yun +Date: Thu, 15 Jul 2021 17:07:51 +0800 +Subject: [PATCH] usb: dwc3: drd: use helper to get role-switch-default-mode +Git-commit: 26f94fe8e739641e96c50f70eb6e78ef1693d9ca +References: git-fixes +Patch-mainline: v5.15-rc1 + +Use the new helper usb_get_role_switch_default_mode() to +get property of "role-switch-default-mode" + +Signed-off-by: Chunfeng Yun +Link: https://lore.kernel.org/r/1626340078-29111-7-git-send-email-chunfeng.yun@mediatek.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/dwc3/drd.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c +index 8fcbac10510c..d7f76835137f 100644 +--- a/drivers/usb/dwc3/drd.c ++++ b/drivers/usb/dwc3/drd.c +@@ -541,14 +541,10 @@ static enum usb_role dwc3_usb_role_switch_get(struct usb_role_switch *sw) + static int dwc3_setup_role_switch(struct dwc3 *dwc) + { + struct usb_role_switch_desc dwc3_role_switch = {NULL}; +- const char *str; + u32 mode; +- int ret; + +- ret = device_property_read_string(dwc->dev, "role-switch-default-mode", +- &str); +- if (ret >= 0 && !strncmp(str, "host", strlen("host"))) { +- dwc->role_switch_default_mode = USB_DR_MODE_HOST; ++ dwc->role_switch_default_mode = usb_get_role_switch_default_mode(dwc->dev); ++ if (dwc->role_switch_default_mode == USB_DR_MODE_HOST) { + mode = DWC3_GCTL_PRTCAP_HOST; + } else { + dwc->role_switch_default_mode = USB_DR_MODE_PERIPHERAL; +-- +2.40.1 + diff --git a/patches.suse/usb-dwc3-ep0-Don-t-prepare-beyond-Setup-stage.patch b/patches.suse/usb-dwc3-ep0-Don-t-prepare-beyond-Setup-stage.patch new file mode 100644 index 0000000..490c0fa --- /dev/null +++ b/patches.suse/usb-dwc3-ep0-Don-t-prepare-beyond-Setup-stage.patch @@ -0,0 +1,87 @@ +From c96683798e272366866a5c0ce3073c0b5a256db7 Mon Sep 17 00:00:00 2001 +From: Thinh Nguyen +Date: Thu, 21 Apr 2022 19:22:50 -0700 +Subject: [PATCH] usb: dwc3: ep0: Don't prepare beyond Setup stage +Git-commit: c96683798e272366866a5c0ce3073c0b5a256db7 +References: git-fixes +Patch-mainline: v5.19-rc1 + +Since we can't guarantee that the host won't send new Setup packet +before going through the device-initiated disconnect, don't prepare +beyond the Setup stage and keep the device in EP0_SETUP_PHASE. This +ensures that the device-initated disconnect sequence can go through +gracefully. Note that the controller won't service the End Transfer +command if it can't DMA out the Setup packet. + +Signed-off-by: Thinh Nguyen +Link: https://lore.kernel.org/r/6bacec56ecabb2c6e49a09cedfcac281fdc97de0.1650593829.git.Thinh.Nguyen@synopsys.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/dwc3/ep0.c | 2 +- + drivers/usb/dwc3/gadget.c | 29 +++++++++++++++++------------ + 2 files changed, 18 insertions(+), 13 deletions(-) + +diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c +index aa8476da222d..6615f641b34f 100644 +--- a/drivers/usb/dwc3/ep0.c ++++ b/drivers/usb/dwc3/ep0.c +@@ -813,7 +813,7 @@ static void dwc3_ep0_inspect_setup(struct dwc3 *dwc, + int ret = -EINVAL; + u32 len; + +- if (!dwc->gadget_driver) ++ if (!dwc->gadget_driver || !dwc->connected) + goto out; + + trace_dwc3_ctrl_req(ctrl); +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index 3c0a6c83ea43..5e3311e3cc16 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -2514,6 +2514,23 @@ static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc) + spin_lock_irqsave(&dwc->lock, flags); + dwc->connected = false; + ++ /* ++ * Per databook, when we want to stop the gadget, if a control transfer ++ * is still in process, complete it and get the core into setup phase. ++ */ ++ if (dwc->ep0state != EP0_SETUP_PHASE) { ++ int ret; ++ ++ reinit_completion(&dwc->ep0_in_setup); ++ ++ spin_unlock_irqrestore(&dwc->lock, flags); ++ ret = wait_for_completion_timeout(&dwc->ep0_in_setup, ++ msecs_to_jiffies(DWC3_PULL_UP_TIMEOUT)); ++ spin_lock_irqsave(&dwc->lock, flags); ++ if (ret == 0) ++ dev_warn(dwc->dev, "timed out waiting for SETUP phase\n"); ++ } ++ + /* + * In the Synopsys DesignWare Cores USB3 Databook Rev. 3.30a + * Section 4.1.8 Table 4-7, it states that for a device-initiated +@@ -2546,18 +2563,6 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) + return 0; + + dwc->softconnect = is_on; +- /* +- * Per databook, when we want to stop the gadget, if a control transfer +- * is still in process, complete it and get the core into setup phase. +- */ +- if (!is_on && dwc->ep0state != EP0_SETUP_PHASE) { +- reinit_completion(&dwc->ep0_in_setup); +- +- ret = wait_for_completion_timeout(&dwc->ep0_in_setup, +- msecs_to_jiffies(DWC3_PULL_UP_TIMEOUT)); +- if (ret == 0) +- dev_warn(dwc->dev, "timed out waiting for SETUP phase\n"); +- } + + /* + * Avoid issuing a runtime resume if the device is already in the +-- +2.40.1 + diff --git a/patches.suse/usb-dwc3-gadget-Avoid-duplicate-requests-to-enable-R.patch b/patches.suse/usb-dwc3-gadget-Avoid-duplicate-requests-to-enable-R.patch index 0bba31e..130ed6c 100644 --- a/patches.suse/usb-dwc3-gadget-Avoid-duplicate-requests-to-enable-R.patch +++ b/patches.suse/usb-dwc3-gadget-Avoid-duplicate-requests-to-enable-R.patch @@ -28,7 +28,7 @@ Signed-off-by: Oliver Neukum --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c -@@ -2328,9 +2328,6 @@ static int dwc3_gadget_pullup(struct usb +@@ -2345,9 +2345,6 @@ static int dwc3_gadget_pullup(struct usb is_on = !!is_on; @@ -36,9 +36,9 @@ Signed-off-by: Oliver Neukum - return 0; - dwc->softconnect = is_on; + /* - * Per databook, when we want to stop the gadget, if a control transfer -@@ -2366,6 +2363,11 @@ static int dwc3_gadget_pullup(struct usb +@@ -2371,6 +2368,11 @@ static int dwc3_gadget_pullup(struct usb pm_runtime_put(dwc->dev); return 0; } diff --git a/patches.suse/usb-dwc3-gadget-Delay-issuing-End-Transfer.patch b/patches.suse/usb-dwc3-gadget-Delay-issuing-End-Transfer.patch new file mode 100644 index 0000000..a6c4d06 --- /dev/null +++ b/patches.suse/usb-dwc3-gadget-Delay-issuing-End-Transfer.patch @@ -0,0 +1,65 @@ +From f66eef8fb8989a7193cafc3870f7c7b2b97f16cb Mon Sep 17 00:00:00 2001 +From: Thinh Nguyen +Date: Thu, 21 Apr 2022 19:23:03 -0700 +Subject: [PATCH] usb: dwc3: gadget: Delay issuing End Transfer +Git-commit: f66eef8fb8989a7193cafc3870f7c7b2b97f16cb +References: git-fixes +Patch-mainline: v5.19-rc1 + +If the controller hasn't DMA'ed the Setup data from its fifo, it won't +process the End Transfer command. Polling for the command completion may +block the driver from servicing the Setup phase and cause a timeout. +Previously we only check and delay issuing End Transfer in the case of +endpoint dequeue. Let's do that for all End Transfer scenarios. + +Signed-off-by: Thinh Nguyen +Link: https://lore.kernel.org/r/2fcf3b5d90068d549589a57a27a79f76c6769b04.1650593829.git.Thinh.Nguyen@synopsys.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/dwc3/gadget.c | 22 ++++++++++++---------- + 1 file changed, 12 insertions(+), 10 deletions(-) + +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index 4f445f836d32..4f54f0ef21df 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -2062,16 +2062,6 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, + if (r == req) { + struct dwc3_request *t; + +- /* +- * If a Setup packet is received but yet to DMA out, the controller will +- * not process the End Transfer command of any endpoint. Polling of its +- * DEPCMD.CmdAct may block setting up TRB for Setup packet, causing a +- * timeout. Delay issuing the End Transfer command until the Setup TRB is +- * prepared. +- */ +- if (dwc->ep0state != EP0_SETUP_PHASE && !dwc->delayed_status) +- dep->flags |= DWC3_EP_DELAY_STOP; +- + /* wait until it is processed */ + dwc3_stop_active_transfer(dep, true, true); + +@@ -3701,6 +3691,18 @@ void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, + (dep->flags & DWC3_EP_END_TRANSFER_PENDING)) + return; + ++ /* ++ * If a Setup packet is received but yet to DMA out, the controller will ++ * not process the End Transfer command of any endpoint. Polling of its ++ * DEPCMD.CmdAct may block setting up TRB for Setup packet, causing a ++ * timeout. Delay issuing the End Transfer command until the Setup TRB is ++ * prepared. ++ */ ++ if (dwc->ep0state != EP0_SETUP_PHASE && !dwc->delayed_status) { ++ dep->flags |= DWC3_EP_DELAY_STOP; ++ return; ++ } ++ + /* + * NOTICE: We are violating what the Databook says about the + * EndTransfer command. Ideally we would _always_ wait for the +-- +2.40.1 + diff --git a/patches.suse/usb-dwc3-gadget-Improve-dwc3_gadget_suspend-and-dwc3.patch b/patches.suse/usb-dwc3-gadget-Improve-dwc3_gadget_suspend-and-dwc3.patch new file mode 100644 index 0000000..c0add48 --- /dev/null +++ b/patches.suse/usb-dwc3-gadget-Improve-dwc3_gadget_suspend-and-dwc3.patch @@ -0,0 +1,111 @@ +From c8540870af4ce6ddeb27a7bb5498b75fb29b643c Mon Sep 17 00:00:00 2001 +From: Roger Quadros +Date: Wed, 3 May 2023 14:00:48 +0300 +Subject: [PATCH] usb: dwc3: gadget: Improve dwc3_gadget_suspend() and + dwc3_gadget_resume() +Git-commit: c8540870af4ce6ddeb27a7bb5498b75fb29b643c +References: git-fixes +Patch-mainline: v6.4-rc3 + +Prevent -ETIMEDOUT error on .suspend(). +e.g. If gadget driver is loaded and we are connected to a USB host, +all transfers must be stopped before stopping the controller else +we will not get a clean stop i.e. dwc3_gadget_run_stop() will take +several seconds to complete and will return -ETIMEDOUT. + +Handle error cases properly in dwc3_gadget_suspend(). +Simplify dwc3_gadget_resume() by using the introduced helper function. + +Fixes: 9f8a67b65a49 ("usb: dwc3: gadget: fix gadget suspend/resume") +Cc: stable@vger.kernel.org +Suggested-by: Thinh Nguyen +Signed-off-by: Roger Quadros +Acked-by: Thinh Nguyen +Link: https://lore.kernel.org/r/20230503110048.30617-1-rogerq@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/dwc3/gadget.c | 50 ++++++++++++++++++++++++++++++++-------------- + 1 file changed, 35 insertions(+), 15 deletions(-) + +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -2352,6 +2352,21 @@ static int dwc3_gadget_soft_disconnect(s + return dwc3_gadget_run_stop(dwc, false, false); + } + ++static int dwc3_gadget_soft_connect(struct dwc3 *dwc) ++{ ++ /* ++ * In the Synopsys DWC_usb31 1.90a programming guide section ++ * 4.1.9, it specifies that for a reconnect after a ++ * device-initiated disconnect requires a core soft reset ++ * (DCTL.CSftRst) before enabling the run/stop bit. ++ */ ++ dwc3_core_soft_reset(dwc); ++ ++ dwc3_event_buffers_setup(dwc); ++ __dwc3_gadget_start(dwc); ++ return dwc3_gadget_run_stop(dwc, true, false); ++} ++ + static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) + { + struct dwc3 *dwc = gadget_to_dwc(g); +@@ -2388,21 +2403,11 @@ static int dwc3_gadget_pullup(struct usb + return 0; + } + +- if (!is_on) { ++ if (!is_on) + ret = dwc3_gadget_soft_disconnect(dwc); +- } else { +- /* +- * In the Synopsys DWC_usb31 1.90a programming guide section +- * 4.1.9, it specifies that for a reconnect after a +- * device-initiated disconnect requires a core soft reset +- * (DCTL.CSftRst) before enabling the run/stop bit. +- */ +- dwc3_core_soft_reset(dwc); ++ else ++ ret = dwc3_gadget_soft_connect(dwc); + +- dwc3_event_buffers_setup(dwc); +- __dwc3_gadget_start(dwc); +- ret = dwc3_gadget_run_stop(dwc, true, false); +- } + + pm_runtime_put(dwc->dev); + +@@ -4271,14 +4276,29 @@ void dwc3_gadget_exit(struct dwc3 *dwc) + + int dwc3_gadget_suspend(struct dwc3 *dwc) + { ++ int ret; ++ + if (!dwc->gadget_driver) + return 0; + +- dwc3_gadget_run_stop(dwc, false, false); ++ ret = dwc3_gadget_soft_disconnect(dwc); ++ if (ret) ++ goto err; ++ + dwc3_disconnect_gadget(dwc); +- __dwc3_gadget_stop(dwc); + + return 0; ++ ++err: ++ /* ++ * Attempt to reset the controller's state. Likely no ++ * communication can be established until the host ++ * performs a port reset. ++ */ ++ if (dwc->softconnect) ++ dwc3_gadget_soft_connect(dwc); ++ ++ return ret; + } + + int dwc3_gadget_resume(struct dwc3 *dwc) diff --git a/patches.suse/usb-dwc3-gadget-Only-End-Transfer-for-ep0-data-phase.patch b/patches.suse/usb-dwc3-gadget-Only-End-Transfer-for-ep0-data-phase.patch new file mode 100644 index 0000000..2e5aa36 --- /dev/null +++ b/patches.suse/usb-dwc3-gadget-Only-End-Transfer-for-ep0-data-phase.patch @@ -0,0 +1,51 @@ +From ace17b6ee4f92ab0375d12a1b42494f8590a96b6 Mon Sep 17 00:00:00 2001 +From: Thinh Nguyen +Date: Thu, 21 Apr 2022 19:22:57 -0700 +Subject: [PATCH] usb: dwc3: gadget: Only End Transfer for ep0 data phase +Git-commit: ace17b6ee4f92ab0375d12a1b42494f8590a96b6 +References: git-fixes +Patch-mainline: v5.19-rc1 + +The driver shouldn't be able to issue End Transfer to the control +endpoint at anytime. Typically we should only do so in error cases such +as invalid/unexpected direction of Data Phase as described in the +control transfer flow of the programming guide. It _may_ end started +data phase during controller deinitialization from soft disconnect or +driver removal. However, that should not happen because the driver +should be maintained in EP0_SETUP_PHASE during driver tear-down. On +soft-connect, the controller should be reset from a soft-reset and there +should be no issue starting the control endpoint. + +Signed-off-by: Thinh Nguyen +Link: https://lore.kernel.org/r/3c6643678863a26702e4115e9e19d7d94a30d49c.1650593829.git.Thinh.Nguyen@synopsys.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/dwc3/gadget.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index 5e3311e3cc16..4f445f836d32 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -3685,6 +3685,17 @@ static void dwc3_reset_gadget(struct dwc3 *dwc) + void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, + bool interrupt) + { ++ struct dwc3 *dwc = dep->dwc; ++ ++ /* ++ * Only issue End Transfer command to the control endpoint of a started ++ * Data Phase. Typically we should only do so in error cases such as ++ * invalid/unexpected direction as described in the control transfer ++ * flow of the programming guide. ++ */ ++ if (dep->number <= 1 && dwc->ep0state != EP0_DATA_PHASE) ++ return; ++ + if (!(dep->flags & DWC3_EP_TRANSFER_STARTED) || + (dep->flags & DWC3_EP_DELAY_STOP) || + (dep->flags & DWC3_EP_END_TRANSFER_PENDING)) +-- +2.40.1 + diff --git a/patches.suse/usb-dwc3-gadget-Stall-and-restart-EP0-if-host-is-unr.patch b/patches.suse/usb-dwc3-gadget-Stall-and-restart-EP0-if-host-is-unr.patch new file mode 100644 index 0000000..4a18d45 --- /dev/null +++ b/patches.suse/usb-dwc3-gadget-Stall-and-restart-EP0-if-host-is-unr.patch @@ -0,0 +1,119 @@ +From 02435a739b81ae24aff5d6e930efef9458e2af3c Mon Sep 17 00:00:00 2001 +From: Wesley Cheng +Date: Thu, 13 Apr 2023 12:57:40 -0700 +Subject: [PATCH] usb: dwc3: gadget: Stall and restart EP0 if host is + unresponsive +Git-commit: 02435a739b81ae24aff5d6e930efef9458e2af3c +References: git-fixes +Patch-mainline: v6.4-rc1 + +It was observed that there are hosts that may complete pending SETUP +transactions before the stop active transfers and controller halt occurs, +leading to lingering endxfer commands on DEPs on subsequent pullup/gadget +start iterations. + + dwc3_gadget_ep_disable name=ep8in flags=0x3009 direction=1 + dwc3_gadget_ep_disable name=ep4in flags=1 direction=1 + dwc3_gadget_ep_disable name=ep3out flags=1 direction=0 + usb_gadget_disconnect deactivated=0 connected=0 ret=0 + +The sequence shows that the USB gadget disconnect (dwc3_gadget_pullup(0)) +routine completed successfully, allowing for the USB gadget to proceed with +a USB gadget connect. However, if this occurs the system runs into an +issue where: + + BUG: spinlock already unlocked on CPU + spin_bug+0x0 + dwc3_remove_requests+0x278 + dwc3_ep0_out_start+0xb0 + __dwc3_gadget_start+0x25c + +This is due to the pending endxfers, leading to gadget start (w/o lock +held) to execute the remove requests, which will unlock the dwc3 +spinlock as part of giveback. + +To mitigate this, resolve the pending endxfers on the pullup disable +path by re-locating the SETUP phase check after stop active transfers, since +that is where the DWC3_EP_DELAY_STOP is potentially set. This also allows +for handling of a host that may be unresponsive by using the completion +timeout to trigger the stall and restart for EP0. + +Fixes: c96683798e27 ("usb: dwc3: ep0: Don't prepare beyond Setup stage") +Cc: stable@vger.kernel.org +Acked-by: Thinh Nguyen +Signed-off-by: Wesley Cheng +Link: https://lore.kernel.org/r/20230413195742.11821-2-quic_wcheng@quicinc.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/dwc3/gadget.c | 46 ++++++++++++++++++++++++++++++++-------------- + 1 file changed, 32 insertions(+), 14 deletions(-) + +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -2292,26 +2292,17 @@ static int __dwc3_gadget_start(struct dw + static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc) + { + unsigned long flags; ++ int ret; + + spin_lock_irqsave(&dwc->lock, flags); + dwc->connected = false; + + /* +- * Per databook, when we want to stop the gadget, if a control transfer +- * is still in process, complete it and get the core into setup phase. ++ * Attempt to end pending SETUP status phase, and not wait for the ++ * function to do so. + */ +- if (dwc->ep0state != EP0_SETUP_PHASE) { +- int ret; +- +- reinit_completion(&dwc->ep0_in_setup); +- +- spin_unlock_irqrestore(&dwc->lock, flags); +- ret = wait_for_completion_timeout(&dwc->ep0_in_setup, +- msecs_to_jiffies(DWC3_PULL_UP_TIMEOUT)); +- spin_lock_irqsave(&dwc->lock, flags); +- if (ret == 0) +- dev_warn(dwc->dev, "timed out waiting for SETUP phase\n"); +- } ++ if (dwc->delayed_status) ++ dwc3_ep0_send_delayed_status(dwc); + + /* + * In the Synopsys DesignWare Cores USB3 Databook Rev. 3.30a +@@ -2325,6 +2316,33 @@ static int dwc3_gadget_soft_disconnect(s + spin_unlock_irqrestore(&dwc->lock, flags); + + /* ++ * Per databook, when we want to stop the gadget, if a control transfer ++ * is still in process, complete it and get the core into setup phase. ++ * In case the host is unresponsive to a SETUP transaction, forcefully ++ * stall the transfer, and move back to the SETUP phase, so that any ++ * pending endxfers can be executed. ++ */ ++ if (dwc->ep0state != EP0_SETUP_PHASE) { ++ reinit_completion(&dwc->ep0_in_setup); ++ ++ ret = wait_for_completion_timeout(&dwc->ep0_in_setup, ++ msecs_to_jiffies(DWC3_PULL_UP_TIMEOUT)); ++ if (ret == 0) { ++ unsigned int dir; ++ ++ dev_warn(dwc->dev, "wait for SETUP phase timed out\n"); ++ spin_lock_irqsave(&dwc->lock, flags); ++ dir = !!dwc->ep0_expect_in; ++ if (dwc->ep0state == EP0_DATA_PHASE) ++ dwc3_ep0_end_control_data(dwc, dwc->eps[dir]); ++ else ++ dwc3_ep0_end_control_data(dwc, dwc->eps[!dir]); ++ dwc3_ep0_stall_and_restart(dwc); ++ spin_unlock_irqrestore(&dwc->lock, flags); ++ } ++ } ++ ++ /* + * Note: if the GEVNTCOUNT indicates events in the event buffer, the + * driver needs to acknowledge them before the controller can halt. + * Simply let the interrupt handler acknowledges and handle the diff --git a/patches.suse/usb-dwc3-gadget-Wait-for-ep0-xfers-to-complete-durin.patch b/patches.suse/usb-dwc3-gadget-Wait-for-ep0-xfers-to-complete-durin.patch index 5c53bed..c4aad09 100644 --- a/patches.suse/usb-dwc3-gadget-Wait-for-ep0-xfers-to-complete-durin.patch +++ b/patches.suse/usb-dwc3-gadget-Wait-for-ep0-xfers-to-complete-durin.patch @@ -55,7 +55,7 @@ Signed-off-by: Oliver Neukum +#define DWC3_EP_DELAY_STOP BIT(13) /* This last one is specific to EP0 */ - #define DWC3_EP0_DIR_IN BIT(31) + #define DWC3_EP0_DIR_IN BIT(31) --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -271,6 +271,7 @@ void dwc3_ep0_out_start(struct dwc3 *dwc diff --git a/patches.suse/usb-dwc3-remove-a-possible-unnecessary-out-of-memory.patch b/patches.suse/usb-dwc3-remove-a-possible-unnecessary-out-of-memory.patch new file mode 100644 index 0000000..ce07c8f --- /dev/null +++ b/patches.suse/usb-dwc3-remove-a-possible-unnecessary-out-of-memory.patch @@ -0,0 +1,40 @@ +From 4ea150889ad70dfae540e761c485b28bd1009486 Mon Sep 17 00:00:00 2001 +From: Kushagra Verma +Date: Mon, 2 May 2022 14:37:14 +0530 +Subject: [PATCH] usb: dwc3: remove a possible unnecessary 'out of memory' + message +Git-commit: 4ea150889ad70dfae540e761c485b28bd1009486 +References: git-fixes +Patch-mainline: v5.19-rc1 + +This patch removes a possible unnecessary out of memory message from +core.c as reported by checkpatch.pl: + WARNING: Possible unnecessary 'out of memory' message + +Signed-off-by: Kushagra Verma +Link: https://lore.kernel.org/r/SI2PR01MB392926A7AFB821410770D7CFF8C19@SI2PR01MB3929.apcprd01.prod.exchangelabs.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/dwc3/core.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c +index 2345a54b848b..7d023130e145 100644 +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -964,10 +964,8 @@ static void dwc3_set_incr_burst_type(struct dwc3 *dwc) + return; + + vals = kcalloc(ntype, sizeof(u32), GFP_KERNEL); +- if (!vals) { +- dev_err(dev, "Error to get memory\n"); ++ if (!vals) + return; +- } + + /* Get INCR burst type, and parse it */ + ret = device_property_read_u32_array(dev, +-- +2.40.1 + diff --git a/patches.suse/usb-gadget-u_ether-Fix-host-MAC-address-case.patch b/patches.suse/usb-gadget-u_ether-Fix-host-MAC-address-case.patch new file mode 100644 index 0000000..4ac5ac0 --- /dev/null +++ b/patches.suse/usb-gadget-u_ether-Fix-host-MAC-address-case.patch @@ -0,0 +1,58 @@ +From 3c0f4f09c063e143822393d99cb2b19a85451c07 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Konrad=20Gr=C3=A4fe?= +Date: Fri, 5 May 2023 16:36:40 +0200 +Subject: [PATCH] usb: gadget: u_ether: Fix host MAC address case +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Git-commit: 3c0f4f09c063e143822393d99cb2b19a85451c07 +References: git-fixes +Patch-mainline: v6.4-rc3 + +The CDC-ECM specification [1] requires to send the host MAC address as +an uppercase hexadecimal string in chapter "5.4 Ethernet Networking +Functional Descriptor": + The Unicode character is chosen from the set of values 30h through + 39h and 41h through 46h (0-9 and A-F). + +However, snprintf(.., "%pm", ..) generates a lowercase MAC address +string. While most host drivers are tolerant to this, UsbNcm.sys on +Windows 10 is not. Instead it uses a different MAC address with all +bytes set to zero including and after the first byte containing a +lowercase letter. On Windows 11 Microsoft fixed it, but apparently they +did not backport the fix. + +This change fixes the issue by upper-casing the MAC to comply with the +specification. + +[1]: https://www.usb.org/document-library/class-definitions-communication-devices-12, file ECM120.pdf + +Fixes: bcd4a1c40bee ("usb: gadget: u_ether: construct with default values and add setters/getters") +Cc: stable@vger.kernel.org +Signed-off-by: Konrad Gräfe +Link: https://lore.kernel.org/r/20230505143640.443014-1-k.graefe@gateware.de +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum +--- + drivers/usb/gadget/function/u_ether.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/gadget/function/u_ether.c ++++ b/drivers/usb/gadget/function/u_ether.c +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + #include + + #include "u_ether.h" +@@ -977,6 +978,8 @@ int gether_get_host_addr_cdc(struct net_ + dev = netdev_priv(net); + snprintf(host_addr, len, "%pm", dev->host_mac); + ++ string_upper(host_addr, host_addr); ++ + return strlen(host_addr); + } + EXPORT_SYMBOL_GPL(gether_get_host_addr_cdc); diff --git a/patches.suse/vdpa-fix-use-after-free-on-vp_vdpa_remove.patch b/patches.suse/vdpa-fix-use-after-free-on-vp_vdpa_remove.patch new file mode 100644 index 0000000..53ddfc9 --- /dev/null +++ b/patches.suse/vdpa-fix-use-after-free-on-vp_vdpa_remove.patch @@ -0,0 +1,59 @@ +Patch-mainline: 5.17 +Git-commit: eb057b44dbe35ae14527830236a92f51de8f9184 +References: git-fixes +From: Zhang Min +Date: Tue, 1 Mar 2022 17:10:59 +0800 +Subject: [PATCH] vdpa: fix use-after-free on vp_vdpa_remove + +When vp_vdpa driver is unbind, vp_vdpa is freed in vdpa_unregister_device +and then vp_vdpa->mdev.pci_dev is dereferenced in vp_modern_remove, +triggering use-after-free. + +Call Trace of unbinding driver free vp_vdpa : +do_syscall_64 + vfs_write + kernfs_fop_write_iter + device_release_driver_internal + pci_device_remove + vp_vdpa_remove + vdpa_unregister_device + kobject_release + device_release + kfree + +Call Trace of dereference vp_vdpa->mdev.pci_dev: +vp_modern_remove + pci_release_selected_regions + pci_release_region + pci_resource_len + pci_resource_end + (dev)->resource[(bar)].end + +Signed-off-by: Zhang Min +Signed-off-by: Yi Wang +Link: https://lore.kernel.org/r/20220301091059.46869-1-wang.yi59@zte.com.cn +Signed-off-by: Michael S. Tsirkin +Fixes: 64b9f64f80a6 ("vdpa: introduce virtio pci driver") +Reviewed-by: Stefano Garzarella +Signed-off-by: Juergen Gross +--- + drivers/vdpa/virtio_pci/vp_vdpa.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/vdpa/virtio_pci/vp_vdpa.c b/drivers/vdpa/virtio_pci/vp_vdpa.c +index a57e381e830b..cce101e6a940 100644 +--- a/drivers/vdpa/virtio_pci/vp_vdpa.c ++++ b/drivers/vdpa/virtio_pci/vp_vdpa.c +@@ -533,8 +533,8 @@ static void vp_vdpa_remove(struct pci_dev *pdev) + { + struct vp_vdpa *vp_vdpa = pci_get_drvdata(pdev); + +- vdpa_unregister_device(&vp_vdpa->vdpa); + vp_modern_remove(&vp_vdpa->mdev); ++ vdpa_unregister_device(&vp_vdpa->vdpa); + } + + static struct pci_driver vp_vdpa_driver = { +-- +2.35.3 + diff --git a/patches.suse/vhost-net-Clear-the-pending-messages-when-the-backen.patch b/patches.suse/vhost-net-Clear-the-pending-messages-when-the-backen.patch new file mode 100644 index 0000000..e578482 --- /dev/null +++ b/patches.suse/vhost-net-Clear-the-pending-messages-when-the-backen.patch @@ -0,0 +1,82 @@ +Patch-mainline: v6.2-rc7 +Git-commit: 9526f9a2b762af16be94a72aca5d65c677d28f50 +References: git-fixes +From: Eric Auger +Date: Tue, 17 Jan 2023 10:15:18 -0500 +Subject: [PATCH] vhost/net: Clear the pending messages when the backend is + removed + +When the vhost iotlb is used along with a guest virtual iommu +and the guest gets rebooted, some MISS messages may have been +recorded just before the reboot and spuriously executed by +the virtual iommu after the reboot. + +As vhost does not have any explicit reset user API, +VHOST_NET_SET_BACKEND looks a reasonable point where to clear +the pending messages, in case the backend is removed. + +Export vhost_clear_msg() and call it in vhost_net_set_backend() +when fd == -1. + +Signed-off-by: Eric Auger +Suggested-by: Jason Wang +Fixes: 6b1e6cc7855b0 ("vhost: new device IOTLB API") +Message-Id: <20230117151518.44725-3-eric.auger@redhat.com> +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Juergen Gross +--- + drivers/vhost/net.c | 3 +++ + drivers/vhost/vhost.c | 3 ++- + drivers/vhost/vhost.h | 1 + + 3 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c +index 9af19b0cf3b7..4c538b30fd76 100644 +--- a/drivers/vhost/net.c ++++ b/drivers/vhost/net.c +@@ -1511,6 +1511,9 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd) + nvq = &n->vqs[index]; + mutex_lock(&vq->mutex); + ++ if (fd == -1) ++ vhost_clear_msg(&n->dev); ++ + /* Verify that ring has been setup correctly. */ + if (!vhost_vq_access_ok(vq)) { + r = -EFAULT; +diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c +index cbe72bfd2f1f..43c9770b86e5 100644 +--- a/drivers/vhost/vhost.c ++++ b/drivers/vhost/vhost.c +@@ -661,7 +661,7 @@ void vhost_dev_stop(struct vhost_dev *dev) + } + EXPORT_SYMBOL_GPL(vhost_dev_stop); + +-static void vhost_clear_msg(struct vhost_dev *dev) ++void vhost_clear_msg(struct vhost_dev *dev) + { + struct vhost_msg_node *node, *n; + +@@ -679,6 +679,7 @@ static void vhost_clear_msg(struct vhost_dev *dev) + + spin_unlock(&dev->iotlb_lock); + } ++EXPORT_SYMBOL_GPL(vhost_clear_msg); + + void vhost_dev_cleanup(struct vhost_dev *dev) + { +diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h +index d9109107af08..790b296271f1 100644 +--- a/drivers/vhost/vhost.h ++++ b/drivers/vhost/vhost.h +@@ -181,6 +181,7 @@ long vhost_dev_ioctl(struct vhost_dev *, unsigned int ioctl, void __user *argp); + long vhost_vring_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *argp); + bool vhost_vq_access_ok(struct vhost_virtqueue *vq); + bool vhost_log_access_ok(struct vhost_dev *); ++void vhost_clear_msg(struct vhost_dev *dev); + + int vhost_get_vq_desc(struct vhost_virtqueue *, + struct iovec iov[], unsigned int iov_count, +-- +2.35.3 + diff --git a/patches.suse/virtio-net-Keep-stop-to-follow-mirror-sequence-of-op.patch b/patches.suse/virtio-net-Keep-stop-to-follow-mirror-sequence-of-op.patch new file mode 100644 index 0000000..d7090bb --- /dev/null +++ b/patches.suse/virtio-net-Keep-stop-to-follow-mirror-sequence-of-op.patch @@ -0,0 +1,42 @@ +Patch-mainline: v6.2-rc7 +Git-commit: 63b114042d8a9c02d9939889177c36dbdb17a588 +References: git-fixes +From: Parav Pandit +Date: Thu, 2 Feb 2023 18:35:16 +0200 +Subject: [PATCH] virtio-net: Keep stop() to follow mirror sequence of open() + +Cited commit in fixes tag frees rxq xdp info while RQ NAPI is +still enabled and packet processing may be ongoing. + +Follow the mirror sequence of open() in the stop() callback. +This ensures that when rxq info is unregistered, no rx +packet processing is ongoing. + +Fixes: 754b8a21a96d ("virtio_net: setup xdp_rxq_info") +Acked-by: Michael S. Tsirkin +Reviewed-by: Jiri Pirko +Signed-off-by: Parav Pandit +Link: https://lore.kernel.org/r/20230202163516.12559-1-parav@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Juergen Gross +--- + drivers/net/virtio_net.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index 6df14dd5bf46..61e33e4dd0cd 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -2158,8 +2158,8 @@ static int virtnet_close(struct net_device *dev) + cancel_delayed_work_sync(&vi->refill); + + for (i = 0; i < vi->max_queue_pairs; i++) { +- xdp_rxq_info_unreg(&vi->rq[i].xdp_rxq); + napi_disable(&vi->rq[i].napi); ++ xdp_rxq_info_unreg(&vi->rq[i].xdp_rxq); + virtnet_napi_tx_disable(&vi->sq[i].napi); + } + +-- +2.35.3 + diff --git a/patches.suse/virtio-net-execute-xdp_do_flush-before-napi_complete.patch b/patches.suse/virtio-net-execute-xdp_do_flush-before-napi_complete.patch new file mode 100644 index 0000000..c854738 --- /dev/null +++ b/patches.suse/virtio-net-execute-xdp_do_flush-before-napi_complete.patch @@ -0,0 +1,62 @@ +Patch-mainline: v6.2-rc7 +Git-commit: ad7e615f646c9b5b2cf655cdfb9d91a28db4f25a +References: git-fixes +From: Magnus Karlsson +Date: Wed, 25 Jan 2023 08:48:59 +0100 +Subject: [PATCH] virtio-net: execute xdp_do_flush() before + napi_complete_done() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Make sure that xdp_do_flush() is always executed before +napi_complete_done(). This is important for two reasons. First, a +redirect to an XSKMAP assumes that a call to xdp_do_redirect() from +napi context X on CPU Y will be followed by a xdp_do_flush() from the +same napi context and CPU. This is not guaranteed if the +napi_complete_done() is executed before xdp_do_flush(), as it tells +the napi logic that it is fine to schedule napi context X on another +CPU. Details from a production system triggering this bug using the +veth driver can be found following the first link below. + +The second reason is that the XDP_REDIRECT logic in itself relies on +being inside a single NAPI instance through to the xdp_do_flush() call +for RCU protection of all in-kernel data structures. Details can be +found in the second link below. + +Fixes: 186b3c998c50 ("virtio-net: support XDP_REDIRECT") +Signed-off-by: Magnus Karlsson +Acked-by: Toke Høiland-Jørgensen +Link: https://lore.kernel.org/r/20221220185903.1105011-1-sbohrer@cloudflare.com +Link: https://lore.kernel.org/all/20210624160609.292325-1-toke@redhat.com/ +Acked-by: Michael S. Tsirkin +Signed-off-by: Jakub Kicinski +Signed-off-by: Juergen Gross +--- + drivers/net/virtio_net.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index 18b3de854aeb..6df14dd5bf46 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -1677,13 +1677,13 @@ static int virtnet_poll(struct napi_struct *napi, int budget) + + received = virtnet_receive(rq, budget, &xdp_xmit); + ++ if (xdp_xmit & VIRTIO_XDP_REDIR) ++ xdp_do_flush(); ++ + /* Out of packets? */ + if (received < budget) + virtqueue_napi_complete(napi, rq->vq, received); + +- if (xdp_xmit & VIRTIO_XDP_REDIR) +- xdp_do_flush(); +- + if (xdp_xmit & VIRTIO_XDP_TX) { + sq = virtnet_xdp_get_sq(vi); + if (virtqueue_kick_prepare(sq->vq) && virtqueue_notify(sq->vq)) { +-- +2.35.3 + diff --git a/patches.suse/virtio_net-bugfix-overflow-inside-xdp_linearize_page.patch b/patches.suse/virtio_net-bugfix-overflow-inside-xdp_linearize_page.patch new file mode 100644 index 0000000..fde1c3b --- /dev/null +++ b/patches.suse/virtio_net-bugfix-overflow-inside-xdp_linearize_page.patch @@ -0,0 +1,57 @@ +Patch-mainline: v6.3 +Git-commit: 853618d5886bf94812f31228091cd37d308230f7 +References: git-fixes +From: Xuan Zhuo +Date: Fri, 14 Apr 2023 14:08:35 +0800 +Subject: [PATCH] virtio_net: bugfix overflow inside xdp_linearize_page() + +Here we copy the data from the original buf to the new page. But we +not check that it may be overflow. + +As long as the size received(including vnethdr) is greater than 3840 +(PAGE_SIZE -VIRTIO_XDP_HEADROOM). Then the memcpy will overflow. + +And this is completely possible, as long as the MTU is large, such +as 4096. In our test environment, this will cause crash. Since crash is +caused by the written memory, it is meaningless, so I do not include it. + +Fixes: 72979a6c3590 ("virtio_net: xdp, add slowpath case for non contiguous buffers") +Signed-off-by: Xuan Zhuo +Acked-by: Jason Wang +Acked-by: Michael S. Tsirkin +Signed-off-by: David S. Miller +Signed-off-by: Juergen Gross +--- + drivers/net/virtio_net.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index 2396c28c0122..ea1bd4bb326d 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -814,8 +814,13 @@ static struct page *xdp_linearize_page(struct receive_queue *rq, + int page_off, + unsigned int *len) + { +- struct page *page = alloc_page(GFP_ATOMIC); ++ int tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); ++ struct page *page; ++ ++ if (page_off + *len + tailroom > PAGE_SIZE) ++ return NULL; + ++ page = alloc_page(GFP_ATOMIC); + if (!page) + return NULL; + +@@ -823,7 +828,6 @@ static struct page *xdp_linearize_page(struct receive_queue *rq, + page_off += *len; + + while (--*num_buf) { +- int tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + unsigned int buflen; + void *buf; + int off; +-- +2.35.3 + diff --git a/patches.suse/virtio_net-split-free_unused_bufs.patch b/patches.suse/virtio_net-split-free_unused_bufs.patch new file mode 100644 index 0000000..174d9c7 --- /dev/null +++ b/patches.suse/virtio_net-split-free_unused_bufs.patch @@ -0,0 +1,88 @@ +Patch-mainline: v6.0-rc1 +Git-commit: 6e345f8c7cd029ad3aaece15ad4425ac26e4eb63 +References: git-fixes +From: Xuan Zhuo +Date: Mon, 1 Aug 2022 14:38:59 +0800 +Subject: [PATCH] virtio_net: split free_unused_bufs() + +This patch separates two functions for freeing sq buf and rq buf from +free_unused_bufs(). + +When supporting the enable/disable tx/rq queue in the future, it is +necessary to support separate recovery of a sq buf or a rq buf. + +Signed-off-by: Xuan Zhuo +Acked-by: Jason Wang +Message-Id: <20220801063902.129329-40-xuanzhuo@linux.alibaba.com> +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Juergen Gross +--- + drivers/net/virtio_net.c | 41 ++++++++++++++++++++++++---------------- + 1 file changed, 25 insertions(+), 16 deletions(-) + +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index 204bfe49d6b4..8cad913926e5 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -3168,6 +3168,27 @@ static void free_receive_page_frags(struct virtnet_info *vi) + put_page(vi->rq[i].alloc_frag.page); + } + ++static void virtnet_sq_free_unused_buf(struct virtqueue *vq, void *buf) ++{ ++ if (!is_xdp_frame(buf)) ++ dev_kfree_skb(buf); ++ else ++ xdp_return_frame(ptr_to_xdp(buf)); ++} ++ ++static void virtnet_rq_free_unused_buf(struct virtqueue *vq, void *buf) ++{ ++ struct virtnet_info *vi = vq->vdev->priv; ++ int i = vq2rxq(vq); ++ ++ if (vi->mergeable_rx_bufs) ++ put_page(virt_to_head_page(buf)); ++ else if (vi->big_packets) ++ give_pages(&vi->rq[i], buf); ++ else ++ put_page(virt_to_head_page(buf)); ++} ++ + static void free_unused_bufs(struct virtnet_info *vi) + { + void *buf; +@@ -3175,26 +3196,14 @@ static void free_unused_bufs(struct virtnet_info *vi) + + for (i = 0; i < vi->max_queue_pairs; i++) { + struct virtqueue *vq = vi->sq[i].vq; +- while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) { +- if (!is_xdp_frame(buf)) +- dev_kfree_skb(buf); +- else +- xdp_return_frame(ptr_to_xdp(buf)); +- } ++ while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) ++ virtnet_sq_free_unused_buf(vq, buf); + } + + for (i = 0; i < vi->max_queue_pairs; i++) { + struct virtqueue *vq = vi->rq[i].vq; +- +- while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) { +- if (vi->mergeable_rx_bufs) { +- put_page(virt_to_head_page(buf)); +- } else if (vi->big_packets) { +- give_pages(&vi->rq[i], buf); +- } else { +- put_page(virt_to_head_page(buf)); +- } +- } ++ while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) ++ virtnet_rq_free_unused_buf(vq, buf); + } + } + +-- +2.35.3 + diff --git a/patches.suse/virtio_net-suppress-cpu-stall-when-free_unused_bufs.patch b/patches.suse/virtio_net-suppress-cpu-stall-when-free_unused_bufs.patch new file mode 100644 index 0000000..fc51b31 --- /dev/null +++ b/patches.suse/virtio_net-suppress-cpu-stall-when-free_unused_bufs.patch @@ -0,0 +1,42 @@ +Patch-mainline: v6.4-rc1 +Git-commit: f8bb5104394560e29017c25bcade4c6b7aabd108 +References: git-fixes +From: Wenliang Wang +Date: Thu, 4 May 2023 10:27:06 +0800 +Subject: [PATCH] virtio_net: suppress cpu stall when free_unused_bufs + +For multi-queue and large ring-size use case, the following error +occurred when free_unused_bufs: +rcu: INFO: rcu_sched self-detected stall on CPU. + +Fixes: 986a4f4d452d ("virtio_net: multiqueue support") +Signed-off-by: Wenliang Wang +Acked-by: Michael S. Tsirkin +Signed-off-by: David S. Miller +Signed-off-by: Juergen Gross +--- + drivers/net/virtio_net.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index 8d8038538fc4..a12ae26db0e2 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -3560,12 +3560,14 @@ static void free_unused_bufs(struct virtnet_info *vi) + struct virtqueue *vq = vi->sq[i].vq; + while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) + virtnet_sq_free_unused_buf(vq, buf); ++ cond_resched(); + } + + for (i = 0; i < vi->max_queue_pairs; i++) { + struct virtqueue *vq = vi->rq[i].vq; + while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) + virtnet_rq_free_unused_buf(vq, buf); ++ cond_resched(); + } + } + +-- +2.35.3 + diff --git a/patches.suse/wifi-mt76-add-flexible-polling-wait-interval-support.patch b/patches.suse/wifi-mt76-add-flexible-polling-wait-interval-support.patch new file mode 100644 index 0000000..bcdf0a2 --- /dev/null +++ b/patches.suse/wifi-mt76-add-flexible-polling-wait-interval-support.patch @@ -0,0 +1,78 @@ +From 35effe6c0c24adcf0f732bb1c3d75573d4c88e63 Mon Sep 17 00:00:00 2001 +From: Deren Wu +Date: Sat, 14 Jan 2023 12:56:46 +0800 +Subject: [PATCH] wifi: mt76: add flexible polling wait-interval support +Git-commit: 35effe6c0c24adcf0f732bb1c3d75573d4c88e63 +Patch-mainline: v6.3-rc1 +References: git-fixes + +The default waiting unit is 10ms and the value is too much for +data path related control. Provide a new API mt76_poll_msec_tick() +to support different cases, such as 1ms polling waiting kick. + +Reviewed-by: Lorenzo Bianconi +Signed-off-by: Deren Wu +Signed-off-by: Felix Fietkau +Acked-by: Takashi Iwai + +--- + drivers/net/wireless/mediatek/mt76/mt76.h | 9 +++++---- + drivers/net/wireless/mediatek/mt76/util.c | 10 +++++----- + 2 files changed, 10 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h +index f351a37c47f7..4a1d8be06b0a 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76.h ++++ b/drivers/net/wireless/mediatek/mt76/mt76.h +@@ -909,10 +909,11 @@ bool __mt76_poll(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, + + #define mt76_poll(dev, ...) __mt76_poll(&((dev)->mt76), __VA_ARGS__) + +-bool __mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, +- int timeout); +- +-#define mt76_poll_msec(dev, ...) __mt76_poll_msec(&((dev)->mt76), __VA_ARGS__) ++bool ____mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, ++ int timeout, int kick); ++#define __mt76_poll_msec(...) ____mt76_poll_msec(__VA_ARGS__, 10) ++#define mt76_poll_msec(dev, ...) ____mt76_poll_msec(&((dev)->mt76), __VA_ARGS__, 10) ++#define mt76_poll_msec_tick(dev, ...) ____mt76_poll_msec(&((dev)->mt76), __VA_ARGS__) + + void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs); + void mt76_pci_disable_aspm(struct pci_dev *pdev); +diff --git a/drivers/net/wireless/mediatek/mt76/util.c b/drivers/net/wireless/mediatek/mt76/util.c +index 581964425468..fc76c66ff1a5 100644 +--- a/drivers/net/wireless/mediatek/mt76/util.c ++++ b/drivers/net/wireless/mediatek/mt76/util.c +@@ -24,23 +24,23 @@ bool __mt76_poll(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, + } + EXPORT_SYMBOL_GPL(__mt76_poll); + +-bool __mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, +- int timeout) ++bool ____mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, ++ int timeout, int tick) + { + u32 cur; + +- timeout /= 10; ++ timeout /= tick; + do { + cur = __mt76_rr(dev, offset) & mask; + if (cur == val) + return true; + +- usleep_range(10000, 20000); ++ usleep_range(1000 * tick, 2000 * tick); + } while (timeout-- > 0); + + return false; + } +-EXPORT_SYMBOL_GPL(__mt76_poll_msec); ++EXPORT_SYMBOL_GPL(____mt76_poll_msec); + + int mt76_wcid_alloc(u32 *mask, int size) + { +-- +2.35.3 + diff --git a/patches.suse/wifi-mt76-mt7921e-fix-probe-timeout-after-reboot.patch b/patches.suse/wifi-mt76-mt7921e-fix-probe-timeout-after-reboot.patch new file mode 100644 index 0000000..cc4f69f --- /dev/null +++ b/patches.suse/wifi-mt76-mt7921e-fix-probe-timeout-after-reboot.patch @@ -0,0 +1,50 @@ +From c397fc1e6365a2a9e5540a85b2c1d4ea412aa0e2 Mon Sep 17 00:00:00 2001 +From: Quan Zhou +Date: Sat, 18 Mar 2023 15:41:12 +0800 +Subject: [PATCH] wifi: mt76: mt7921e: fix probe timeout after reboot +Git-commit: c397fc1e6365a2a9e5540a85b2c1d4ea412aa0e2 +Patch-mainline: v6.4-rc1 +References: git-fixes + +In system warm reboot scene, due to the polling timeout(now 1000us) +is too short to wait dma idle in time, it may make driver probe fail +with error code -ETIMEDOUT. Meanwhile, we also found the dma may take +around 70ms to enter idle state. Change the polling idle timeout to +100ms to avoid the probabilistic probe fail. + +Tested pass with 5000 times warm reboot on x86 platform. + +[4.477496] pci 0000:01:00.0: attach allowed to drvr mt7921e [internal device] +[4.478306] mt7921e 0000:01:00.0: ASIC revision: 79610010 +[4.480063] mt7921e: probe of 0000:01:00.0 failed with error -110 + +Fixes: 0a1059d0f060 ("mt76: mt7921: move mt7921_dma_reset in dma.c") +Signed-off-by: Quan Zhou +Signed-off-by: Deren Wu +Signed-off-by: Felix Fietkau +Acked-by: Takashi Iwai + +--- + drivers/net/wireless/mediatek/mt76/mt7921/dma.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c +index 1d85c0c10049..28207172c4ef 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c +@@ -90,9 +90,9 @@ static int mt7921_dma_disable(struct mt7921_dev *dev, bool force) + MT_WFDMA0_GLO_CFG_OMIT_RX_INFO | + MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2); + +- if (!mt76_poll(dev, MT_WFDMA0_GLO_CFG, +- MT_WFDMA0_GLO_CFG_TX_DMA_BUSY | +- MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 1000)) ++ if (!mt76_poll_msec_tick(dev, MT_WFDMA0_GLO_CFG, ++ MT_WFDMA0_GLO_CFG_TX_DMA_BUSY | ++ MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 100, 1)) + return -ETIMEDOUT; + + return 0; +-- +2.35.3 + diff --git a/patches.suse/wifi-mt76-mt7921e-improve-reliability-of-dma-reset.patch b/patches.suse/wifi-mt76-mt7921e-improve-reliability-of-dma-reset.patch new file mode 100644 index 0000000..b721952 --- /dev/null +++ b/patches.suse/wifi-mt76-mt7921e-improve-reliability-of-dma-reset.patch @@ -0,0 +1,107 @@ +From 87714bf6ed1589813e473db5471e6e9857755764 Mon Sep 17 00:00:00 2001 +From: Quan Zhou +Date: Thu, 13 Apr 2023 05:11:13 +0800 +Subject: [PATCH] wifi: mt76: mt7921e: improve reliability of dma reset +Git-commit: 87714bf6ed1589813e473db5471e6e9857755764 +Patch-mainline: v6.4-rc1 +References: git-fixes + +The hardware team has advised the driver that it is necessary to first put +WFDMA into an idle state before resetting the WFDMA. Otherwise, the WFDMA +may enter an unknown state where it cannot be polled with the right state +successfully. To ensure that the DMA can work properly while a stressful +cold reboot test was being made, we have reordered the programming sequence +in the driver based on the hardware team's guidance. + +The patch would modify the WFDMA disabling flow from + +"DMA reset -> disabling DMASHDL -> disabling WFDMA -> polling and waiting +until DMA idle" to "disabling WFDMA -> polling and waiting for DMA idle -> +disabling DMASHDL -> DMA reset. + +Where he polling and waiting until WFDMA is idle is coordinated with the +operation of disabling WFDMA. Even while WFDMA is being disabled, it can +still handle Tx/Rx requests. The additional polling allows sufficient time +for WFDMA to process the last T/Rx request. When the idle state of WFDMA is +reached, it is a reliable indication that DMASHDL is also idle to ensure it +is safe to disable it and perform the DMA reset. + +Fixes: 0a1059d0f060 ("mt76: mt7921: move mt7921_dma_reset in dma.c") +Co-developed-by: Sean Wang +Signed-off-by: Sean Wang +Co-developed-by: Deren Wu +Signed-off-by: Deren Wu +Co-developed-by: Wang Zhao +Signed-off-by: Wang Zhao +Signed-off-by: Quan Zhou +Signed-off-by: Felix Fietkau +Acked-by: Takashi Iwai + +--- + .../net/wireless/mediatek/mt76/mt7921/dma.c | 36 ++++++++++--------- + 1 file changed, 20 insertions(+), 16 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c +index 28207172c4ef..f0a80c2b476a 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c +@@ -66,22 +66,6 @@ static void mt7921_dma_prefetch(struct mt7921_dev *dev) + + static int mt7921_dma_disable(struct mt7921_dev *dev, bool force) + { +- if (force) { +- /* reset */ +- mt76_clear(dev, MT_WFDMA0_RST, +- MT_WFDMA0_RST_DMASHDL_ALL_RST | +- MT_WFDMA0_RST_LOGIC_RST); +- +- mt76_set(dev, MT_WFDMA0_RST, +- MT_WFDMA0_RST_DMASHDL_ALL_RST | +- MT_WFDMA0_RST_LOGIC_RST); +- } +- +- /* disable dmashdl */ +- mt76_clear(dev, MT_WFDMA0_GLO_CFG_EXT0, +- MT_WFDMA0_CSR_TX_DMASHDL_ENABLE); +- mt76_set(dev, MT_DMASHDL_SW_CONTROL, MT_DMASHDL_DMASHDL_BYPASS); +- + /* disable WFDMA0 */ + mt76_clear(dev, MT_WFDMA0_GLO_CFG, + MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN | +@@ -95,6 +79,22 @@ static int mt7921_dma_disable(struct mt7921_dev *dev, bool force) + MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 100, 1)) + return -ETIMEDOUT; + ++ /* disable dmashdl */ ++ mt76_clear(dev, MT_WFDMA0_GLO_CFG_EXT0, ++ MT_WFDMA0_CSR_TX_DMASHDL_ENABLE); ++ mt76_set(dev, MT_DMASHDL_SW_CONTROL, MT_DMASHDL_DMASHDL_BYPASS); ++ ++ if (force) { ++ /* reset */ ++ mt76_clear(dev, MT_WFDMA0_RST, ++ MT_WFDMA0_RST_DMASHDL_ALL_RST | ++ MT_WFDMA0_RST_LOGIC_RST); ++ ++ mt76_set(dev, MT_WFDMA0_RST, ++ MT_WFDMA0_RST_DMASHDL_ALL_RST | ++ MT_WFDMA0_RST_LOGIC_RST); ++ } ++ + return 0; + } + +@@ -301,6 +301,10 @@ void mt7921_dma_cleanup(struct mt7921_dev *dev) + MT_WFDMA0_GLO_CFG_OMIT_RX_INFO | + MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2); + ++ mt76_poll_msec_tick(dev, MT_WFDMA0_GLO_CFG, ++ MT_WFDMA0_GLO_CFG_TX_DMA_BUSY | ++ MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 100, 1); ++ + /* reset */ + mt76_clear(dev, MT_WFDMA0_RST, + MT_WFDMA0_RST_DMASHDL_ALL_RST | +-- +2.35.3 + diff --git a/patches.suse/x86-alternative-Make-debug-alternative-selective.patch b/patches.suse/x86-alternative-Make-debug-alternative-selective.patch new file mode 100644 index 0000000..f32e6da --- /dev/null +++ b/patches.suse/x86-alternative-Make-debug-alternative-selective.patch @@ -0,0 +1,188 @@ +From: Peter Zijlstra +Date: Wed, 8 Feb 2023 18:10:51 +0100 +Subject: x86/alternative: Make debug-alternative selective +Git-commit: 6becb5026b8192e0ed6619d6e7793c2f1288244f +Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git#master +Patch-mainline: Queued in subsystem maintainer repository +References: bsc#1206578 + +Using debug-alternative generates a *LOT* of output, extend it a bit +to select which of the many rewrites it reports on. + +[js] no IBT, drop the hunk + +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Borislav Petkov (AMD) +Link: https://lore.kernel.org/r/20230208171431.253636689@infradead.org +Signed-off-by: Jiri Slaby +--- + arch/x86/kernel/alternative.c | 56 +++++++++++++++++++++++++----------------- + 1 file changed, 34 insertions(+), 22 deletions(-) + +--- a/arch/x86/kernel/alternative.c ++++ b/arch/x86/kernel/alternative.c +@@ -37,11 +37,23 @@ EXPORT_SYMBOL_GPL(alternatives_patched); + + #define MAX_PATCH_LEN (255-1) + +-static int __initdata_or_module debug_alternative; ++#define DA_ALL (~0) ++#define DA_ALT 0x01 ++#define DA_RET 0x02 ++#define DA_RETPOLINE 0x04 ++#define DA_ENDBR 0x08 ++#define DA_SMP 0x10 ++ ++static unsigned int __initdata_or_module debug_alternative; + + static int __init debug_alt(char *str) + { +- debug_alternative = 1; ++ if (str && *str == '=') ++ str++; ++ ++ if (!str || kstrtouint(str, 0, &debug_alternative)) ++ debug_alternative = DA_ALL; ++ + return 1; + } + __setup("debug-alternative", debug_alt); +@@ -55,15 +67,15 @@ static int __init setup_noreplace_smp(ch + } + __setup("noreplace-smp", setup_noreplace_smp); + +-#define DPRINTK(fmt, args...) \ ++#define DPRINTK(type, fmt, args...) \ + do { \ +- if (debug_alternative) \ ++ if (debug_alternative & DA_##type) \ + printk(KERN_DEBUG pr_fmt(fmt) "\n", ##args); \ + } while (0) + +-#define DUMP_BYTES(buf, len, fmt, args...) \ ++#define DUMP_BYTES(type, buf, len, fmt, args...) \ + do { \ +- if (unlikely(debug_alternative)) { \ ++ if (unlikely(debug_alternative & DA_##type)) { \ + int j; \ + \ + if (!(len)) \ +@@ -146,7 +158,7 @@ recompute_jump(struct alt_instr *a, u8 * + tgt_rip = next_rip + o_dspl; + n_dspl = tgt_rip - orig_insn; + +- DPRINTK("target RIP: %px, new_displ: 0x%x", tgt_rip, n_dspl); ++ DPRINTK(ALT, "target RIP: %px, new_displ: 0x%x", tgt_rip, n_dspl); + + if (tgt_rip - orig_insn >= 0) { + if (n_dspl - 2 <= 127) +@@ -181,7 +193,7 @@ five_byte_jmp: + + done: + +- DPRINTK("final displ: 0x%08x, JMP 0x%lx", ++ DPRINTK(ALT, "final displ: 0x%08x, JMP 0x%lx", + n_dspl, (unsigned long)orig_insn + n_dspl + repl_len); + } + +@@ -215,7 +227,7 @@ static __always_inline int optimize_nops + add_nops(instr + off, nnops); + local_irq_restore(flags); + +- DUMP_BYTES(instr, instrlen, "%px: [%d:%d) optimized NOPs: ", instr, off, i); ++ DUMP_BYTES(ALT, instr, instrlen, "%px: [%d:%d) optimized NOPs: ", instr, off, i); + + return nnops; + } +@@ -268,7 +280,7 @@ void __init_or_module noinline apply_alt + u8 *instr, *replacement; + u8 insn_buff[MAX_PATCH_LEN]; + +- DPRINTK("alt table %px, -> %px", start, end); ++ DPRINTK(ALT, "alt table %px, -> %px", start, end); + /* + * The scan order should be from start to end. A later scanned + * alternative code can overwrite previously scanned alternative code. +@@ -297,15 +309,15 @@ void __init_or_module noinline apply_alt + if (!boot_cpu_has(feature) == !(a->cpuid & ALTINSTR_FLAG_INV)) + goto next; + +- DPRINTK("feat: %s%d*32+%d, old: (%pS (%px) len: %d), repl: (%px, len: %d)", ++ DPRINTK(ALT, "feat: %s%d*32+%d, old: (%pS (%px) len: %d), repl: (%px, len: %d)", + (a->cpuid & ALTINSTR_FLAG_INV) ? "!" : "", + feature >> 5, + feature & 0x1f, + instr, instr, a->instrlen, + replacement, a->replacementlen); + +- DUMP_BYTES(instr, a->instrlen, "%px: old_insn: ", instr); +- DUMP_BYTES(replacement, a->replacementlen, "%px: rpl_insn: ", replacement); ++ DUMP_BYTES(ALT, instr, a->instrlen, "%px: old_insn: ", instr); ++ DUMP_BYTES(ALT, replacement, a->replacementlen, "%px: rpl_insn: ", replacement); + + memcpy(insn_buff, replacement, a->replacementlen); + insn_buff_sz = a->replacementlen; +@@ -318,7 +330,7 @@ void __init_or_module noinline apply_alt + */ + if (a->replacementlen == 5 && *insn_buff == 0xe8) { + *(s32 *)(insn_buff + 1) += replacement - instr; +- DPRINTK("Fix CALL offset: 0x%x, CALL 0x%lx", ++ DPRINTK(ALT, "Fix CALL offset: 0x%x, CALL 0x%lx", + *(s32 *)(insn_buff + 1), + (unsigned long)instr + *(s32 *)(insn_buff + 1) + 5); + } +@@ -329,7 +341,7 @@ void __init_or_module noinline apply_alt + for (; insn_buff_sz < a->instrlen; insn_buff_sz++) + insn_buff[insn_buff_sz] = 0x90; + +- DUMP_BYTES(insn_buff, insn_buff_sz, "%px: final_insn: ", instr); ++ DUMP_BYTES(ALT, insn_buff, insn_buff_sz, "%px: final_insn: ", instr); + + text_poke_early(instr, insn_buff, insn_buff_sz); + +@@ -493,15 +505,15 @@ void __init_or_module noinline apply_ret + continue; + } + +- DPRINTK("retpoline at: %pS (%px) len: %d to: %pS", ++ DPRINTK(RETPOLINE, "retpoline at: %pS (%px) len: %d to: %pS", + addr, addr, insn.length, + addr + insn.length + insn.immediate.value); + + len = patch_retpoline(addr, &insn, bytes); + if (len == insn.length) { + optimize_nops(bytes, len); +- DUMP_BYTES(((u8*)addr), len, "%px: orig: ", addr); +- DUMP_BYTES(((u8*)bytes), len, "%px: repl: ", addr); ++ DUMP_BYTES(RETPOLINE, ((u8*)addr), len, "%px: orig: ", addr); ++ DUMP_BYTES(RETPOLINE, ((u8*)bytes), len, "%px: repl: ", addr); + text_poke_early(addr, bytes, len); + } + } +@@ -558,14 +570,14 @@ void __init_or_module noinline apply_ret + addr, dest, 5, addr)) + continue; + +- DPRINTK("return thunk at: %pS (%px) len: %d to: %pS", ++ DPRINTK(RET, "return thunk at: %pS (%px) len: %d to: %pS", + addr, addr, insn.length, + addr + insn.length + insn.immediate.value); + + len = patch_return(addr, &insn, bytes); + if (len == insn.length) { +- DUMP_BYTES(((u8*)addr), len, "%px: orig: ", addr); +- DUMP_BYTES(((u8*)bytes), len, "%px: repl: ", addr); ++ DUMP_BYTES(RET, ((u8*)addr), len, "%px: orig: ", addr); ++ DUMP_BYTES(RET, ((u8*)bytes), len, "%px: repl: ", addr); + text_poke_early(addr, bytes, len); + } + } +@@ -654,7 +666,7 @@ void __init_or_module alternatives_smp_m + smp->locks_end = locks_end; + smp->text = text; + smp->text_end = text_end; +- DPRINTK("locks %p -> %p, text %p -> %p, name %s\n", ++ DPRINTK(SMP, "locks %p -> %p, text %p -> %p, name %s\n", + smp->locks, smp->locks_end, + smp->text, smp->text_end, smp->name); + diff --git a/patches.suse/x86-alternative-Support-relocations-in-alternatives.patch b/patches.suse/x86-alternative-Support-relocations-in-alternatives.patch new file mode 100644 index 0000000..d2bdea3 --- /dev/null +++ b/patches.suse/x86-alternative-Support-relocations-in-alternatives.patch @@ -0,0 +1,363 @@ +From: Peter Zijlstra +Date: Wed, 8 Feb 2023 18:10:52 +0100 +Subject: x86/alternative: Support relocations in alternatives +Git-commit: 270a69c4485d7d07516d058bcc0473c90ee22185 +Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git#master +Patch-mainline: Queued in subsystem maintainer repository +References: bsc#1206578 + +A little while ago someone (Kirill) ran into the whole 'alternatives don't +do relocations nonsense' again and I got annoyed enough to actually look +at the code. + +Since the whole alternative machinery already fully decodes the +instructions it is simple enough to adjust immediates and displacement +when needed. Specifically, the immediates for IP modifying instructions +(JMP, CALL, Jcc) and the displacement for RIP-relative instructions. + + [ bp: Massage comment some more and get rid of third loop in + apply_relocation(). ] + +[js] declare 'next, i' out of 'for' loop. + +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Borislav Petkov (AMD) +Link: https://lore.kernel.org/r/20230208171431.313857925@infradead.org +Signed-off-by: Jiri Slaby +--- + arch/x86/kernel/alternative.c | 261 +++++++++++++++++++++++++-------------- + tools/objtool/arch/x86/special.c | 8 - + 2 files changed, 173 insertions(+), 96 deletions(-) + +--- a/arch/x86/kernel/alternative.c ++++ b/arch/x86/kernel/alternative.c +@@ -133,71 +133,6 @@ extern s32 __smp_locks[], __smp_locks_en + void text_poke_early(void *addr, const void *opcode, size_t len); + + /* +- * Are we looking at a near JMP with a 1 or 4-byte displacement. +- */ +-static inline bool is_jmp(const u8 opcode) +-{ +- return opcode == 0xeb || opcode == 0xe9; +-} +- +-static void __init_or_module +-recompute_jump(struct alt_instr *a, u8 *orig_insn, u8 *repl_insn, u8 *insn_buff) +-{ +- u8 *next_rip, *tgt_rip; +- s32 n_dspl, o_dspl; +- int repl_len; +- +- if (a->replacementlen != 5) +- return; +- +- o_dspl = *(s32 *)(insn_buff + 1); +- +- /* next_rip of the replacement JMP */ +- next_rip = repl_insn + a->replacementlen; +- /* target rip of the replacement JMP */ +- tgt_rip = next_rip + o_dspl; +- n_dspl = tgt_rip - orig_insn; +- +- DPRINTK(ALT, "target RIP: %px, new_displ: 0x%x", tgt_rip, n_dspl); +- +- if (tgt_rip - orig_insn >= 0) { +- if (n_dspl - 2 <= 127) +- goto two_byte_jmp; +- else +- goto five_byte_jmp; +- /* negative offset */ +- } else { +- if (((n_dspl - 2) & 0xff) == (n_dspl - 2)) +- goto two_byte_jmp; +- else +- goto five_byte_jmp; +- } +- +-two_byte_jmp: +- n_dspl -= 2; +- +- insn_buff[0] = 0xeb; +- insn_buff[1] = (s8)n_dspl; +- add_nops(insn_buff + 2, 3); +- +- repl_len = 2; +- goto done; +- +-five_byte_jmp: +- n_dspl -= 5; +- +- insn_buff[0] = 0xe9; +- *(s32 *)&insn_buff[1] = n_dspl; +- +- repl_len = 5; +- +-done: +- +- DPRINTK(ALT, "final displ: 0x%08x, JMP 0x%lx", +- n_dspl, (unsigned long)orig_insn + n_dspl + repl_len); +-} +- +-/* + * optimize_nops_range() - Optimize a sequence of single byte NOPs (0x90) + * + * @instr: instruction byte stream +@@ -264,6 +199,140 @@ static void __init_or_module noinline op + } + + /* ++ * In this context, "source" is where the instructions are placed in the ++ * section .altinstr_replacement, for example during kernel build by the ++ * toolchain. ++ * "Destination" is where the instructions are being patched in by this ++ * machinery. ++ * ++ * The source offset is: ++ * ++ * src_imm = target - src_next_ip (1) ++ * ++ * and the target offset is: ++ * ++ * dst_imm = target - dst_next_ip (2) ++ * ++ * so rework (1) as an expression for target like: ++ * ++ * target = src_imm + src_next_ip (1a) ++ * ++ * and substitute in (2) to get: ++ * ++ * dst_imm = (src_imm + src_next_ip) - dst_next_ip (3) ++ * ++ * Now, since the instruction stream is 'identical' at src and dst (it ++ * is being copied after all) it can be stated that: ++ * ++ * src_next_ip = src + ip_offset ++ * dst_next_ip = dst + ip_offset (4) ++ * ++ * Substitute (4) in (3) and observe ip_offset being cancelled out to ++ * obtain: ++ * ++ * dst_imm = src_imm + (src + ip_offset) - (dst + ip_offset) ++ * = src_imm + src - dst + ip_offset - ip_offset ++ * = src_imm + src - dst (5) ++ * ++ * IOW, only the relative displacement of the code block matters. ++ */ ++ ++#define apply_reloc_n(n_, p_, d_) \ ++ do { \ ++ s32 v = *(s##n_ *)(p_); \ ++ v += (d_); \ ++ BUG_ON((v >> 31) != (v >> (n_-1))); \ ++ *(s##n_ *)(p_) = (s##n_)v; \ ++ } while (0) ++ ++ ++static __always_inline ++void apply_reloc(int n, void *ptr, uintptr_t diff) ++{ ++ switch (n) { ++ case 1: apply_reloc_n(8, ptr, diff); break; ++ case 2: apply_reloc_n(16, ptr, diff); break; ++ case 4: apply_reloc_n(32, ptr, diff); break; ++ default: BUG(); ++ } ++} ++ ++static __always_inline ++bool need_reloc(unsigned long offset, u8 *src, size_t src_len) ++{ ++ u8 *target = src + offset; ++ /* ++ * If the target is inside the patched block, it's relative to the ++ * block itself and does not need relocation. ++ */ ++ return (target < src || target > src + src_len); ++} ++ ++static void __init_or_module noinline ++apply_relocation(u8 *buf, size_t len, u8 *dest, u8 *src, size_t src_len) ++{ ++ int next, i = 0; ++ for (; i < len; i = next) { ++ struct insn insn; ++ ++ if (WARN_ON_ONCE(insn_decode_kernel(&insn, &buf[i]))) ++ return; ++ ++ next = i + insn.length; ++ ++ switch (insn.opcode.bytes[0]) { ++ case 0x0f: ++ if (insn.opcode.bytes[1] < 0x80 || ++ insn.opcode.bytes[1] > 0x8f) ++ break; ++ ++ fallthrough; /* Jcc.d32 */ ++ case 0x70 ... 0x7f: /* Jcc.d8 */ ++ case JMP8_INSN_OPCODE: ++ case JMP32_INSN_OPCODE: ++ case CALL_INSN_OPCODE: ++ if (need_reloc(next + insn.immediate.value, src, src_len)) { ++ apply_reloc(insn.immediate.nbytes, ++ buf + i + insn_offset_immediate(&insn), ++ src - dest); ++ } ++ ++ /* ++ * Where possible, convert JMP.d32 into JMP.d8. ++ */ ++ if (insn.opcode.bytes[0] == JMP32_INSN_OPCODE) { ++ s32 imm = insn.immediate.value; ++ imm += src - dest; ++ imm += JMP32_INSN_SIZE - JMP8_INSN_SIZE; ++ if ((imm >> 31) == (imm >> 7)) { ++ buf[i+0] = JMP8_INSN_OPCODE; ++ buf[i+1] = (s8)imm; ++ ++ memset(&buf[i+2], INT3_INSN_OPCODE, insn.length - 2); ++ } ++ } ++ break; ++ } ++ ++ if (insn_rip_relative(&insn)) { ++ if (need_reloc(next + insn.displacement.value, src, src_len)) { ++ apply_reloc(insn.displacement.nbytes, ++ buf + i + insn_offset_displacement(&insn), ++ src - dest); ++ } ++ } ++ ++ ++ /* ++ * See if this and any potentially following NOPs can be ++ * optimized. ++ */ ++ if (insn.length == 1 && insn.opcode.bytes[0] == 0x90) ++ next = i + optimize_nops_range(buf, len, i); ++ } ++} ++ ++/* + * Replace instructions with better alternatives for this CPU type. This runs + * before SMP is initialized to avoid SMP problems with self modifying code. + * This implies that asymmetric systems where APs have less capabilities than +@@ -306,8 +374,10 @@ void __init_or_module noinline apply_alt + * - feature not present but ALTINSTR_FLAG_INV is set to mean, + * patch if feature is *NOT* present. + */ +- if (!boot_cpu_has(feature) == !(a->cpuid & ALTINSTR_FLAG_INV)) +- goto next; ++ if (!boot_cpu_has(feature) == !(a->cpuid & ALTINSTR_FLAG_INV)) { ++ optimize_nops(instr, a->instrlen); ++ continue; ++ } + + DPRINTK(ALT, "feat: %s%d*32+%d, old: (%pS (%px) len: %d), repl: (%px, len: %d)", + (a->cpuid & ALTINSTR_FLAG_INV) ? "!" : "", +@@ -316,37 +386,19 @@ void __init_or_module noinline apply_alt + instr, instr, a->instrlen, + replacement, a->replacementlen); + +- DUMP_BYTES(ALT, instr, a->instrlen, "%px: old_insn: ", instr); +- DUMP_BYTES(ALT, replacement, a->replacementlen, "%px: rpl_insn: ", replacement); +- + memcpy(insn_buff, replacement, a->replacementlen); + insn_buff_sz = a->replacementlen; + +- /* +- * 0xe8 is a relative jump; fix the offset. +- * +- * Instruction length is checked before the opcode to avoid +- * accessing uninitialized bytes for zero-length replacements. +- */ +- if (a->replacementlen == 5 && *insn_buff == 0xe8) { +- *(s32 *)(insn_buff + 1) += replacement - instr; +- DPRINTK(ALT, "Fix CALL offset: 0x%x, CALL 0x%lx", +- *(s32 *)(insn_buff + 1), +- (unsigned long)instr + *(s32 *)(insn_buff + 1) + 5); +- } +- +- if (a->replacementlen && is_jmp(replacement[0])) +- recompute_jump(a, instr, replacement, insn_buff); +- + for (; insn_buff_sz < a->instrlen; insn_buff_sz++) + insn_buff[insn_buff_sz] = 0x90; + ++ apply_relocation(insn_buff, a->instrlen, instr, replacement, a->replacementlen); ++ ++ DUMP_BYTES(ALT, instr, a->instrlen, "%px: old_insn: ", instr); ++ DUMP_BYTES(ALT, replacement, a->replacementlen, "%px: rpl_insn: ", replacement); + DUMP_BYTES(ALT, insn_buff, insn_buff_sz, "%px: final_insn: ", instr); + + text_poke_early(instr, insn_buff, insn_buff_sz); +- +-next: +- optimize_nops(instr, a->instrlen); + } + } + +@@ -851,6 +903,35 @@ static void __init int3_selftest(void) + unregister_die_notifier(&int3_exception_nb); + } + ++static __initdata int __alt_reloc_selftest_addr; ++ ++__visible noinline void __init __alt_reloc_selftest(void *arg) ++{ ++ WARN_ON(arg != &__alt_reloc_selftest_addr); ++} ++ ++static noinline void __init alt_reloc_selftest(void) ++{ ++ /* ++ * Tests apply_relocation(). ++ * ++ * This has a relative immediate (CALL) in a place other than the first ++ * instruction and additionally on x86_64 we get a RIP-relative LEA: ++ * ++ * lea 0x0(%rip),%rdi # 5d0: R_X86_64_PC32 .init.data+0x5566c ++ * call +0 # 5d5: R_X86_64_PLT32 __alt_reloc_selftest-0x4 ++ * ++ * Getting this wrong will either crash and burn or tickle the WARN ++ * above. ++ */ ++ asm_inline volatile ( ++ ALTERNATIVE("", "lea %[mem], %%" _ASM_ARG1 "; call __alt_reloc_selftest;", X86_FEATURE_ALWAYS) ++ : /* output */ ++ : [mem] "m" (__alt_reloc_selftest_addr) ++ : _ASM_ARG1 ++ ); ++} ++ + void __init alternative_instructions(void) + { + int3_selftest(); +@@ -927,6 +1008,8 @@ void __init alternative_instructions(voi + + restart_nmi(); + alternatives_patched = 1; ++ ++ alt_reloc_selftest(); + } + + /** +--- a/tools/objtool/arch/x86/special.c ++++ b/tools/objtool/arch/x86/special.c +@@ -42,13 +42,7 @@ bool arch_support_alt_relocation(struct + struct instruction *insn, + struct reloc *reloc) + { +- /* +- * The x86 alternatives code adjusts the offsets only when it +- * encounters a branch instruction at the very beginning of the +- * replacement group. +- */ +- return insn->offset == special_alt->new_off && +- (insn->type == INSN_CALL || is_jump(insn)); ++ return true; + } + + /* diff --git a/patches.suse/x86-lib-memmove-Decouple-ERMS-from-FSRM.patch b/patches.suse/x86-lib-memmove-Decouple-ERMS-from-FSRM.patch new file mode 100644 index 0000000..d1b897d --- /dev/null +++ b/patches.suse/x86-lib-memmove-Decouple-ERMS-from-FSRM.patch @@ -0,0 +1,58 @@ +From: "Borislav Petkov (AMD)" +Date: Sun, 26 Feb 2023 21:04:26 +0100 +Subject: x86/lib/memmove: Decouple ERMS from FSRM +Git-commit: 14e4ec9c3e9164c6719f98d8a3065c487be2aaa5 +Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git#master +Patch-mainline: Queued in subsystem maintainer repository +References: bsc#1206578 + +Up until now it was perceived that FSRM is an improvement to ERMS and +thus it was made dependent on latter. + +However, there are AMD BIOSes out there which allow for disabling of +either features and thus preventing kernels from booting due to the CMP +disappearing and thus breaking the logic in the memmove() function. + +Similar observation happens on some VM migration scenarios. + +Patch the proper sequences depending on which feature is enabled. + +Reported-by: Daniel Verkamp +Reported-by: Jiri Slaby +Signed-off-by: Borislav Petkov (AMD) +Link: https://lore.kernel.org/r/Y/yK0dyzI0MMdTie@zn.tnic +Signed-off-by: Jiri Slaby +--- + arch/x86/lib/memmove_64.S | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +--- a/arch/x86/lib/memmove_64.S ++++ b/arch/x86/lib/memmove_64.S +@@ -37,10 +37,12 @@ SYM_FUNC_START(__memmove) + cmp %rdi, %r8 + jg 2f + +- /* FSRM implies ERMS => no length checks, do the copy directly */ ++#define CHECK_LEN cmp $0x20, %rdx; jb 1f ++#define MEMMOVE_BYTES movq %rdx, %rcx; rep movsb; RET + .Lmemmove_begin_forward: +- ALTERNATIVE "cmp $0x20, %rdx; jb 1f", "", X86_FEATURE_FSRM +- ALTERNATIVE "", "jmp .Lmemmove_erms", X86_FEATURE_ERMS ++ ALTERNATIVE_2 __stringify(CHECK_LEN), \ ++ __stringify(CHECK_LEN; MEMMOVE_BYTES), X86_FEATURE_ERMS, \ ++ __stringify(MEMMOVE_BYTES), X86_FEATURE_FSRM + + /* + * movsq instruction have many startup latency +@@ -206,11 +208,6 @@ SYM_FUNC_START(__memmove) + movb %r11b, (%rdi) + 13: + RET +- +-.Lmemmove_erms: +- movq %rdx, %rcx +- rep movsb +- RET + SYM_FUNC_END(__memmove) + SYM_FUNC_END_ALIAS(memmove) + EXPORT_SYMBOL(__memmove) diff --git a/scripts/git_sort/tests/Docker/opensuse-15.4.Dockerfile b/scripts/git_sort/tests/Docker/opensuse-15.4.Dockerfile index 1d5cbc7..38868cb 100644 --- a/scripts/git_sort/tests/Docker/opensuse-15.4.Dockerfile +++ b/scripts/git_sort/tests/Docker/opensuse-15.4.Dockerfile @@ -12,7 +12,7 @@ RUN git config --global user.name "Your Name" COPY Kernel.gpg /tmp RUN rpmkeys --import /tmp/Kernel.gpg -RUN zypper -n ar https://download.opensuse.org/repositories/Kernel:/tools/SLE_15_SP4/Kernel:tools.repo +RUN zypper -n ar -f https://download.opensuse.org/repositories/Kernel:/tools/SLE_15_SP4/Kernel:tools.repo RUN zypper -n in python3-pygit2 quilt FROM packages diff --git a/scripts/git_sort/tests/Docker/opensuse-tumbleweed.Dockerfile b/scripts/git_sort/tests/Docker/opensuse-tumbleweed.Dockerfile index af6cfbc..a3956e5 100644 --- a/scripts/git_sort/tests/Docker/opensuse-tumbleweed.Dockerfile +++ b/scripts/git_sort/tests/Docker/opensuse-tumbleweed.Dockerfile @@ -12,7 +12,7 @@ RUN git config --global user.name "Your Name" COPY Kernel.gpg /tmp RUN rpmkeys --import /tmp/Kernel.gpg -RUN zypper -n ar https://download.opensuse.org/repositories/Kernel:/tools/openSUSE_Factory/Kernel:tools.repo +RUN zypper -n ar -f https://download.opensuse.org/repositories/Kernel:/tools/openSUSE_Factory/Kernel:tools.repo RUN zypper -n in --from Kernel_tools quilt FROM packages diff --git a/scripts/git_sort/tests/Docker/sle12-sp4.Dockerfile b/scripts/git_sort/tests/Docker/sle12-sp4.Dockerfile index 49d8f9c..e5c6989 100644 --- a/scripts/git_sort/tests/Docker/sle12-sp4.Dockerfile +++ b/scripts/git_sort/tests/Docker/sle12-sp4.Dockerfile @@ -2,15 +2,13 @@ FROM registry.suse.de/suse/containers/sle-server/12-sp4/containers/suse/sles12sp4:latest AS base RUN rpm -e container-suseconnect -RUN zypper -n ar http://download.suse.de/ibs/SUSE:/SLE-12:/GA/standard/SUSE:SLE-12:GA.repo -RUN zypper -n ar http://download.suse.de/ibs/SUSE:/SLE-12:/Update/standard/SUSE:SLE-12:Update.repo -RUN zypper -n ar http://download.suse.de/install/SLP/SLE-12-SP4-Server-GM/$(rpm -E %_arch)/DVD1/ DVD1 -RUN zypper -n ar http://download.suse.de/install/SLP/SLE-12-SP4-Server-GM/$(rpm -E %_arch)/DVD2/ DVD2 -RUN zypper -n ar http://download.suse.de/install/SLP/SLE-12-SP4-Server-GM/$(rpm -E %_arch)/DVD3/ DVD3 +RUN zypper -n ar -f http://download.suse.de/ibs/SUSE:/SLE-12:/GA/standard/SUSE:SLE-12:GA.repo +RUN zypper -n ar -f http://download.suse.de/ibs/SUSE:/SLE-12:/Update/standard/SUSE:SLE-12:Update.repo +RUN zypper -n ar -f http://download.suse.de/install/SLP/SLE-12-SP4-Server-GM/$(rpm -E %_arch)/DVD1/ DVD1 +RUN zypper -n ar -f http://download.suse.de/install/SLP/SLE-12-SP4-Server-GM/$(rpm -E %_arch)/DVD2/ DVD2 +RUN zypper -n ar -f http://download.suse.de/install/SLP/SLE-12-SP4-Server-GM/$(rpm -E %_arch)/DVD3/ DVD3 # RUN zypper -n ar -G http://updates.suse.de/SUSE/Products/SLE-SDK/12-SP4/$(rpm -E %_arch)/product/ SDK -RUN zypper -n ar http://download.suse.de/update/build.suse.de/SUSE/Updates/SLE-SERVER/12-SP4/$(rpm -E %_arch)/update/SUSE:Updates:SLE-SERVER:12-SP4:$(rpm -E %_arch).repo - -RUN zypper -n ref +RUN zypper -n ar -f http://download.suse.de/update/build.suse.de/SUSE/Updates/SLE-SERVER/12-SP4/$(rpm -E %_arch)/update/SUSE:Updates:SLE-SERVER:12-SP4:$(rpm -E %_arch).repo FROM base AS packages @@ -21,7 +19,7 @@ RUN git config --global user.name "Your Name" COPY Kernel.gpg /tmp RUN rpmkeys --import /tmp/Kernel.gpg -RUN zypper -n ar https://download.opensuse.org/repositories/Kernel:/tools/SLE_12_SP4/Kernel:tools.repo +RUN zypper -n ar -f https://download.opensuse.org/repositories/Kernel:/tools/SLE_12_SP4/Kernel:tools.repo RUN zypper -n in python3-pygit2 quilt FROM packages diff --git a/scripts/git_sort/tests/Docker/sle12-sp5.Dockerfile b/scripts/git_sort/tests/Docker/sle12-sp5.Dockerfile index f5e2f58..92bf25c 100644 --- a/scripts/git_sort/tests/Docker/sle12-sp5.Dockerfile +++ b/scripts/git_sort/tests/Docker/sle12-sp5.Dockerfile @@ -2,15 +2,13 @@ FROM registry.suse.de/suse/containers/sle-server/12-sp5/containers/suse/sles12sp5:latest AS base RUN rpm -e container-suseconnect -RUN zypper -n ar http://download.suse.de/ibs/SUSE:/SLE-12:/GA/standard/SUSE:SLE-12:GA.repo -RUN zypper -n ar http://download.suse.de/ibs/SUSE:/SLE-12:/Update/standard/SUSE:SLE-12:Update.repo -RUN zypper -n ar http://download.suse.de/install/SLP/SLE-12-SP5-Server-GM/$(rpm -E %_arch)/DVD1/ DVD1 -RUN zypper -n ar http://download.suse.de/install/SLP/SLE-12-SP5-Server-GM/$(rpm -E %_arch)/DVD2/ DVD2 -RUN zypper -n ar http://download.suse.de/install/SLP/SLE-12-SP5-Server-GM/$(rpm -E %_arch)/DVD3/ DVD3 +RUN zypper -n ar -f http://download.suse.de/ibs/SUSE:/SLE-12:/GA/standard/SUSE:SLE-12:GA.repo +RUN zypper -n ar -f http://download.suse.de/ibs/SUSE:/SLE-12:/Update/standard/SUSE:SLE-12:Update.repo +RUN zypper -n ar -f http://download.suse.de/install/SLP/SLE-12-SP5-Server-GM/$(rpm -E %_arch)/DVD1/ DVD1 +RUN zypper -n ar -f http://download.suse.de/install/SLP/SLE-12-SP5-Server-GM/$(rpm -E %_arch)/DVD2/ DVD2 +RUN zypper -n ar -f http://download.suse.de/install/SLP/SLE-12-SP5-Server-GM/$(rpm -E %_arch)/DVD3/ DVD3 # RUN zypper -n ar -G http://updates.suse.de/SUSE/Products/SLE-SDK/12-SP5/$(rpm -E %_arch)/product/ SDK -RUN zypper -n ar http://download.suse.de/update/build.suse.de/SUSE/Updates/SLE-SERVER/12-SP5/$(rpm -E %_arch)/update/SUSE:Updates:SLE-SERVER:12-SP5:$(rpm -E %_arch).repo - -RUN zypper -n ref +RUN zypper -n ar -f http://download.suse.de/update/build.suse.de/SUSE/Updates/SLE-SERVER/12-SP5/$(rpm -E %_arch)/update/SUSE:Updates:SLE-SERVER:12-SP5:$(rpm -E %_arch).repo FROM base AS packages @@ -21,7 +19,7 @@ RUN git config --global user.name "Your Name" COPY Kernel.gpg /tmp RUN rpmkeys --import /tmp/Kernel.gpg -RUN zypper -n ar https://download.opensuse.org/repositories/Kernel:/tools/SLE_12_SP5/Kernel:tools.repo +RUN zypper -n ar -f https://download.opensuse.org/repositories/Kernel:/tools/SLE_12_SP5/Kernel:tools.repo RUN zypper -n in python3-pygit2 quilt FROM packages diff --git a/scripts/git_sort/tests/Docker/sle15.Dockerfile b/scripts/git_sort/tests/Docker/sle15.Dockerfile index 4d1cc54..8b36b2f 100644 --- a/scripts/git_sort/tests/Docker/sle15.Dockerfile +++ b/scripts/git_sort/tests/Docker/sle15.Dockerfile @@ -2,8 +2,8 @@ FROM registry.suse.de/suse/sle-15/update/images/suse/sle15:latest AS base RUN rpm -e container-suseconnect -RUN zypper -n ar http://download.suse.de/ibs/SUSE:/SLE-15:/GA/standard/SUSE:SLE-15:GA.repo -RUN zypper -n ar http://download.suse.de/ibs/SUSE:/SLE-15:/Update/standard/SUSE:SLE-15:Update.repo +RUN zypper -n ar -f http://download.suse.de/ibs/SUSE:/SLE-15:/GA/standard/SUSE:SLE-15:GA.repo +RUN zypper -n ar -f http://download.suse.de/ibs/SUSE:/SLE-15:/Update/standard/SUSE:SLE-15:Update.repo RUN zypper -n ref FROM base AS packages @@ -15,7 +15,7 @@ RUN git config --global user.name "Your Name" COPY Kernel.gpg /tmp RUN rpmkeys --import /tmp/Kernel.gpg -RUN zypper -n ar https://download.opensuse.org/repositories/Kernel:/tools/SLE_15/Kernel:tools.repo +RUN zypper -n ar -f https://download.opensuse.org/repositories/Kernel:/tools/SLE_15/Kernel:tools.repo RUN zypper -n in python3-pygit2 quilt FROM packages diff --git a/series.conf b/series.conf index 5090628..64d4955 100644 --- a/series.conf +++ b/series.conf @@ -1342,6 +1342,7 @@ patches.suse/usb-gadget-f_uac2-add-volume-and-mute-support.patch patches.suse/usb-dwc3-dwc3-qcom-Fix-typo-in-the-dwc3-vbus-overrid.patch patches.suse/usb-common-add-helper-to-get-role-switch-default-mod.patch + patches.suse/usb-dwc3-drd-use-helper-to-get-role-switch-default-m.patch patches.suse/usb-mtu3-support-property-role-switch-default-mode.patch patches.suse/usb-mtu3-support-option-to-disable-usb2-ports.patch patches.suse/usb-mtu3-add-new-helpers-for-host-suspend-resume.patch @@ -6514,6 +6515,7 @@ patches.suse/usb-gadget-uvc-rename-function-to-be-more-consistent.patch patches.suse/usb-musb-Balance-list-entry-in-musb_gadget_queue.patch patches.suse/USB-chipidea-fix-interrupt-deadlock.patch + patches.suse/usb-dwc3-Align-DWC3_EP_-flag-macros.patch patches.suse/thunderbolt-Enable-retry-logic-for-intra-domain-cont.patch patches.suse/thunderbolt-Fix-Wrestrict-warning.patch patches.suse/USB-iowarrior-fix-control-message-timeouts.patch @@ -7341,6 +7343,7 @@ patches.suse/net-mlx5-E-Switch-return-error-if-encap-isn-t-suppor.patch patches.suse/net-usb-r8152-Add-MAC-passthrough-support-for-more-L.patch patches.suse/net-dpaa2-eth-fix-use-after-free-in-dpaa2_eth_remove.patch + patches.suse/net-virtio_net_hdr_to_skb-count-transport-header-in-.patch patches.suse/NFC-reorganize-the-functions-in-nci_request.patch patches.suse/NFC-reorder-the-logic-in-nfc_-un-register_device.patch patches.suse/NFC-add-NCI_UNREG-flag-to-eliminate-the-race.patch @@ -8147,6 +8150,8 @@ patches.suse/ax25-NPD-bug-when-detaching-AX25-device.patch patches.suse/qlcnic-potential-dereference-null-pointer-of-rx_queu.patch patches.suse/mac80211-fix-locking-in-ieee80211_start_ap-error-pat.patch + patches.suse/net-accept-UFOv6-packages-in-virtio_net_hdr_to_skb.patch + patches.suse/net-skip-virtio_net_hdr_set_proto-if-protocol-alread.patch patches.suse/igb-fix-deadlock-caused-by-taking-RTNL-in-RPM-resume.patch patches.suse/bonding-fix-ad_actor_system-option-setting-to-defaul.patch patches.suse/fjes-Check-for-error-irq.patch @@ -8444,6 +8449,7 @@ patches.suse/drm-radeon-radeon_kms-Fix-a-NULL-pointer-dereference.patch patches.suse/drm-amd-display-Fix-bug-in-debugfs-crc_win_update-en.patch patches.suse/drm-amd-display-Fix-out-of-bounds-access-on-DNC31-st.patch + patches.suse/drm-amdgpu-update-drm_display_info-correctly-when-th.patch patches.suse/drm-amd-amdgpu-fix-psp-tmr-bo-pin-count-leak-in-SRIO.patch patches.suse/drm-amd-amdgpu-fix-gmc-bo-pin-count-leak-in-SRIOV.patch patches.suse/gpu-host1x-Drop-excess-kernel-doc-entry-key.patch @@ -10627,6 +10633,8 @@ patches.suse/btrfs-add-missing-run-of-delayed-items-after-unlink-.patch patches.suse/virtio_console-break-out-of-buf-poll-on-remove.patch patches.suse/virtio-blk-Don-t-use-MAX_DISCARD_SEGMENTS-if-max_dis.patch + patches.suse/vdpa-fix-use-after-free-on-vp_vdpa_remove.patch + patches.suse/tools-virtio-fix-virtio_test-execution.patch patches.suse/x86-speculation-rename-retpoline_amd-to-retpoline_lfence.patch patches.suse/x86-speculation-add-eibrs-retpoline-options.patch patches.suse/documentation-hw-vuln-update-spectre-doc.patch @@ -12117,6 +12125,7 @@ patches.suse/Documentation-Fix-duplicate-statement-about-raw_spin.patch patches.suse/ACPI-CPPC-Avoid-out-of-bounds-access-when-parsing-_C.patch patches.suse/vhost_vdpa-don-t-setup-irq-offloading-when-irq_num-0.patch + patches.suse/tools-virtio-compile-with-pthread.patch patches.suse/watchdog-rti-wdt-Add-missing-pm_runtime_disable-in-p.patch patches.suse/Watchdog-sp5100_tco-Move-timer-initialization-into-f.patch patches.suse/Watchdog-sp5100_tco-Refactor-MMIO-base-address-initi.patch @@ -13707,6 +13716,7 @@ patches.suse/dmaengine-idxd-update-IAA-definitions-for-user-heade.patch patches.suse/dmaengine-idxd-set-DMA_INTERRUPT-cap-bit.patch patches.suse/dmaengine-idxd-Fix-the-error-handling-path-in-idxd_c.patch + patches.suse/dmaengine-idxd-Separate-user-and-kernel-pasid-enabli.patch patches.suse/dmaengine-zynqmp_dma-In-struct-zynqmp_dma_chan-fix-d.patch patches.suse/dmaengine-idxd-add-missing-callback-function-to-supp.patch patches.suse/dmaengine-stm32-mdma-remove-GISR1-register.patch @@ -13757,6 +13767,7 @@ patches.suse/watchdog-rti-wdt-Fix-pm_runtime_get_sync-error-check.patch patches.suse/watchdog-wdat_wdt-Stop-watchdog-when-rebooting-the-s.patch patches.suse/watchdog-ts4800_wdt-Fix-refcount-leak-in-ts4800_wdt_.patch + patches.suse/power-supply-bq24190_charger-using-pm_runtime_resume.patch patches.suse/power-supply-axp288_fuel_gauge-Fix-battery-reporting.patch patches.suse/power-supply-axp288_fuel_gauge-Drop-BIOS-version-che.patch patches.suse/0011-dm-verity-set-DM_TARGET_IMMUTABLE-feature-flag.patch @@ -13878,15 +13889,21 @@ patches.suse/usb-typec-mux-Check-dev_set_name-return-value.patch patches.suse/usb-dwc2-gadget-don-t-reset-gadget-s-driver-bus.patch patches.suse/usb-ehci-omap-drop-unused-ehci_read-function.patch + patches.suse/usb-dwc3-remove-a-possible-unnecessary-out-of-memory.patch patches.suse/usb-dwc3-gadget-Prevent-repeat-pullup.patch patches.suse/usb-dwc3-gadget-Refactor-pullup.patch patches.suse/usb-dwc3-gadget-Don-t-modify-GEVNTCOUNT-in-pullup.patch + patches.suse/usb-dwc3-ep0-Don-t-prepare-beyond-Setup-stage.patch + patches.suse/usb-dwc3-gadget-Only-End-Transfer-for-ep0-data-phase.patch + patches.suse/usb-dwc3-gadget-Delay-issuing-End-Transfer.patch + patches.suse/USB-dwc3-Fix-a-checkpatch-warning-in-core.c.patch patches.suse/usb-core-hcd-Add-support-for-deferring-roothub-regis.patch patches.suse/xhci-Set-HCD-flag-to-defer-primary-roothub-registrat.patch patches.suse/xhci-Allow-host-runtime-PM-as-default-for-Intel-Alde.patch patches.suse/thunderbolt-Use-different-lane-for-second-DisplayPor.patch patches.suse/thunderbolt-Fix-buffer-allocation-of-devices-with-no.patch patches.suse/usb-isp1760-Fix-out-of-bounds-array-access.patch + patches.suse/usb-dwc3-Fix-ep0-handling-when-getting-reset-while-d.patch patches.suse/usb-dwc3-gadget-Move-null-pinter-check-to-proper-pla.patch patches.suse/USB-serial-pl2303-fix-type-detection-for-odd-device.patch patches.suse/USB-serial-option-add-Quectel-BG95-modem.patch @@ -14394,6 +14411,7 @@ patches.suse/dmaengine-qcom-bam_dma-fix-runtime-PM-underflow.patch patches.suse/dmaengine-idxd-force-wq-context-cleanup-on-device-di.patch patches.suse/dmaengine-at_xdma-handle-errors-of-at_xdmac_alloc_de.patch + patches.suse/dmaengine-idxd-Only-call-idxd_enable_system_pasid-if.patch patches.suse/dmaengine-pl330-Fix-lockdep-warning-about-non-static.patch patches.suse/dmaengine-lgm-Fix-an-error-handling-path-in-intel_ld.patch patches.suse/dt-bindings-dma-allwinner-sun50i-a64-dma-Fix-min-max.patch @@ -15066,6 +15084,7 @@ patches.suse/usb-gadget-bdc-fix-typo-in-comment.patch patches.suse/usb-gadget-uvc-call-uvc-uvcg_warn-on-completed-statu.patch patches.suse/usb-musb-remove-schedule-work-called-after-flush.patch + patches.suse/usb-dwc3-Fix-a-repeated-word-checkpatch-warning.patch patches.suse/usb-dwc3-core-Deprecate-GCTL.CORESOFTRESET.patch patches.suse/usb-dwc3-core-Host-wake-up-support-from-system-suspe.patch patches.suse/usb-dwc3-qcom-Add-helper-functions-to-enable-disable.patch @@ -15166,6 +15185,7 @@ patches.suse/dmaengine-dw-axi-dmac-ignore-interrupt-if-no-descrip.patch patches.suse/dmaengine-imx-dma-Cast-of_device_get_match_data-with.patch patches.suse/dmaengine-sprd-Cleanup-in-.remove-after-pm_runtime_g.patch + patches.suse/PCI-ASPM-Remove-pcie_aspm_pm_state_change.patch patches.suse/PCI-endpoint-Don-t-stop-controller-when-unbinding-en.patch patches.suse/PCI-portdrv-Don-t-disable-AER-reporting-in-get_port_.patch patches.suse/PCI-AER-Iterate-over-error-counters-instead-of-error.patch @@ -15625,6 +15645,7 @@ patches.suse/dpaa2-eth-trace-the-allocated-address-instead-of-pag.patch patches.suse/drm-shmem-helper-Add-missing-vunmap-on-error.patch patches.suse/drm-gem-Properly-annotate-WW-context-on-drm_gem_lock.patch + patches.suse/virtio_net-split-free_unused_bufs.patch patches.suse/ALSA-hda-realtek-Add-quirk-for-another-Asus-K42JZ-mo.patch patches.suse/ALSA-hda-conexant-Add-quirk-for-LENOVO-20149-Noteboo.patch patches.suse/ALSA-scarlett2-Add-Focusrite-Clarett-8Pre-support.patch @@ -16790,6 +16811,7 @@ patches.suse/ipv4-Handle-attempt-to-delete-multipath-route-when-f.patch patches.suse/mISDN-hfcpci-Fix-use-after-free-bug-in-hfcpci_softir.patch patches.suse/macvlan-enforce-a-consistent-minimal-mtu.patch + patches.suse/can-kvaser_usb_leaf-Fix-overread-with-an-invalid-com.patch patches.suse/can-kvaser_usb-Fix-use-of-uninitialized-completion.patch patches.suse/can-kvaser_usb_leaf-Fix-TX-queue-out-of-sync-after-r.patch patches.suse/can-kvaser_usb_leaf-Fix-CAN-state-after-restart.patch @@ -17172,6 +17194,7 @@ patches.suse/mmc-sdhci-esdhc-imx-use-the-correct-host-caps-for-MM.patch patches.suse/spi-stm32-Print-summary-callbacks-suppressed-message.patch patches.suse/spi-stm32-fix-stm32_spi_prepare_mbr-that-halves-spi-.patch + patches.suse/dmaengine-idxd-Do-not-enable-user-type-Work-Queue-wi.patch patches.suse/dmaengine-pxa_dma-use-platform_get_irq_optional.patch patches.suse/dmaengine-mv_xor_v2-Fix-a-resource-leak-in-mv_xor_v2.patch patches.suse/dmaengine-ti-k3-udma-glue-fix-memory-leak-when-regis.patch @@ -17669,6 +17692,8 @@ patches.suse/nilfs2-fix-shift-out-of-bounds-due-to-too-large-expo.patch patches.suse/lib-fonts-fix-undefined-behavior-in-bit-shift-for-ge.patch patches.suse/ocfs2-fix-memory-leak-in-ocfs2_stack_glue_init.patch + patches.suse/libfs-add-DEFINE_SIMPLE_ATTRIBUTE_SIGNED-for-signed-.patch + patches.suse/debugfs-fix-error-when-writing-negative-value-to-ato.patch patches.suse/ocfs2-fix-memory-leak-in-ocfs2_mount_volume.patch patches.suse/acct-fix-potential-integer-overflow-in-encode_comp_t.patch patches.suse/infiniband-READ-is-data-destination-not-source.patch @@ -17717,6 +17742,7 @@ patches.suse/xprtrdma-Fix-regbuf-data-not-freed-in-rpcrdma_req_cr.patch patches.suse/SUNRPC-Fix-missing-release-socket-in-rpc_sockname.patch patches.suse/NFSv4.x-Fail-client-initialisation-if-state-manager-.patch + patches.suse/configfs-fix-possible-memory-leak-in-configfs_create.patch patches.suse/media-videobuf-dma-contig-use-dma_mmap_coherent.patch patches.suse/0040-bfq-fix-waker_bfqq-inconsistency-crash.patch patches.suse/drivers-md-md-bitmap-check-the-return-value-of-md_bitmap_get_counter-3bd5.patch @@ -17921,15 +17947,22 @@ patches.suse/ARM-9256-1-NWFPE-avoid-compiler-generated-__aeabi_ul.patch patches.suse/ibmveth-Always-stop-tx-queues-during-close.patch patches.suse/can-m_can-is_lec_err-clean-up-LEC-error-handling.patch + patches.suse/can-kvaser_usb-kvaser_usb_leaf-Get-capabilities-from.patch + patches.suse/can-kvaser_usb-kvaser_usb_leaf-Rename-leaf-usbcan-_c.patch + patches.suse/can-kvaser_usb-kvaser_usb_leaf-Handle-CMD_ERROR_EVEN.patch patches.suse/can-kvaser_usb_leaf-Set-Warning-state-even-without-b.patch patches.suse/can-kvaser_usb_leaf-Fix-wrong-CAN-state-after-stoppi.patch patches.suse/can-kvaser_usb_leaf-Fix-bogus-restart-events.patch + patches.suse/can-kvaser_usb-Add-struct-kvaser_usb_busparams.patch patches.suse/wifi-rtl8xxxu-gen2-Turn-on-the-rate-control.patch patches.suse/brcmfmac-return-error-when-getting-invalid-max_flowr.patch patches.suse/gve-Reduce-alloc-and-copy-costs-in-the-GQ-rx-path.patch patches.suse/octeontx2-af-Allow-mkex-profile-without-DMAC-and-add.patch patches.suse/net-mana-Assign-interrupts-to-CPUs-based-on-NUMA-nod.patch patches.suse/hamradio-baycom_epp-Fix-return-type-of-baycom_send_p.patch + patches.suse/s390-ctcm-Fix-return-type-of-ctc-mp-m_tx.patch + patches.suse/s390-netiucv-Fix-return-type-of-netiucv_tx.patch + patches.suse/s390-lcs-Fix-return-type-of-lcs_start_xmit.patch patches.suse/gve-Fix-error-return-code-in-gve_prefill_rx_pages.patch patches.suse/net-mana-Add-support-for-auxiliary-device.patch patches.suse/net-mana-Record-the-physical-address-for-doorbell-pa.patch @@ -18347,6 +18380,7 @@ patches.suse/x86-kexec-Fix-double-free-of-elf-header-buffer.patch patches.suse/x86-asm-Fix-an-assembler-warning-with-current-binuti.patch patches.suse/x86-bugs-Flush-IBP-in-ib_prctl_set.patch + patches.suse/tools-virtio-initialize-spinlocks-in-vring_test.c.patch patches.suse/virtio_pci-modify-ENOENT-to-EINVAL.patch patches.suse/vdpa_sim-fix-possible-memory-leak-in-vdpasim_net_ini.patch patches.suse/vhost-vsock-Fix-error-handling-in-vhost_vsock_init.patch @@ -18637,6 +18671,8 @@ patches.suse/ASoC-Intel-sof_rt5682-always-set-dpcm_capture-for-am.patch patches.suse/ASoC-Intel-sof_cs42l42-always-set-dpcm_capture-for-a.patch patches.suse/ASoC-cs42l56-fix-DT-probe.patch + patches.suse/vhost-net-Clear-the-pending-messages-when-the-backen.patch + patches.suse/tools-virtio-fix-the-vringh-test-for-virtio-ring-cha.patch patches.suse/platform-x86-thinkpad_acpi-Fix-thinklight-LED-bright.patch patches.suse/platform-x86-touchscreen_dmi-Add-Chuwi-Vi8-CWI501-DM.patch patches.suse/watchdog-diag288_wdt-do-not-use-stack-buffers-for-ha.patch @@ -18644,6 +18680,7 @@ patches.suse/bus-sunxi-rsb-Fix-error-handling-in-sunxi_rsb_init.patch patches.suse/arm64-dts-imx8mm-Fix-pad-control-for-UART1_DTE_RX.patch patches.suse/qede-execute-xdp_do_flush-before-napi_complete_done.patch + patches.suse/virtio-net-execute-xdp_do_flush-before-napi_complete.patch patches.suse/bpf-Fix-a-possible-task-gone-issue-with-bpf_send_signal-_thread-helpers.patch patches.suse/sfc-correctly-advertise-tunneled-IPv6-segmentation.patch patches.suse/net-rose-Fix-to-not-accept-on-connected-socket.patch @@ -18657,6 +18694,7 @@ patches.suse/selftests-net-udpgso_bench_rx-tx-Stop-when-wrong-CLI.patch patches.suse/selftests-net-udpgso_bench-Fix-racing-bug-between-th.patch patches.suse/selftests-net-udpgso_bench_tx-Cater-for-pending-data.patch + patches.suse/virtio-net-Keep-stop-to-follow-mirror-sequence-of-op.patch patches.suse/can-j1939-fix-errant-WARN_ON_ONCE-in-j1939_session_d.patch patches.suse/ata-libata-Fix-sata_down_spd_limit-when-no-link-spee.patch patches.suse/mm-memcg-fix-NULL-pointer-in-mem_cgroup_track_foreign_dirty_slowpath.patch @@ -18766,6 +18804,7 @@ patches.suse/mmc-sdio-fix-possible-resource-leaks-in-some-error-p.patch patches.suse/mmc-mmc_spi-fix-error-handling-in-mmc_spi_probe.patch patches.suse/mmc-jz4740-Work-around-bug-on-JZ4760-B.patch + patches.suse/ata-pata_octeon_cf-drop-kernel-doc-notation.patch patches.suse/ALSA-hda-conexant-add-a-new-hda-codec-SN6180.patch patches.suse/ALSA-hda-realtek-fixed-wrong-gpio-assigned.patch patches.suse/ALSA-hda-realtek-fix-mute-micmute-LEDs-don-t-work-fo-5007b848ff22.patch @@ -18859,6 +18898,7 @@ patches.suse/thermal-intel-intel_pch-Add-support-for-Wellsburg-PC.patch patches.suse/thermal-intel-powerclamp-Fix-cur_state-for-multi-pac.patch patches.suse/thermal-drivers-hisi-Drop-second-sensor-hi3660.patch + patches.suse/s390-mem_detect-fix-detect_memory-error-handling.patch patches.suse/arm64-cpufeature-Fix-field-sign-for-DIT-hwcap-detection.patch patches.suse/arm64-Avoid-repeated-AA64MMFR1_EL1-register-read-on-.patch patches.suse/ACPI-Don-t-build-ACPICA-with-Os.patch @@ -18914,6 +18954,7 @@ patches.suse/msft-hv-2767-hv_netvsc-Check-status-in-SEND_RNDIS_PKT-completion-.patch patches.suse/dt-bindings-net-snps-dwmac-Fix-snps-reset-delays-us-.patch patches.suse/wifi-mt76-dma-free-rx_head-in-mt76_dma_rx_cleanup.patch + patches.suse/wifi-mt76-add-flexible-polling-wait-interval-support.patch patches.suse/wifi-iwl3945-Add-missing-check-for-create_singlethre.patch patches.suse/wifi-iwl4965-Add-missing-check-for-create_singlethre.patch patches.suse/wifi-mwifiex-Add-missing-compatible-string-for-SD878.patch @@ -19177,6 +19218,8 @@ patches.suse/driver-core-fix-resource-leak-in-device_add.patch patches.suse/drivers-base-transport_class-fix-possible-memory-lea.patch patches.suse/drivers-base-transport_class-fix-resource-leak-when-.patch + patches.suse/drivers-base-component-fix-memory-leak-with-using-de.patch + patches.suse/drivers-base-dd-fix-memory-leak-with-using-debugfs_l.patch patches.suse/driver-core-fw_devlink-Add-DL_FLAG_CYCLE-support-to-.patch patches.suse/RDMA-cxgb4-remove-unnecessary-NULL-check-in-__c4iw_p.patch patches.suse/RDMA-core-Refactor-rdma_bind_addr.patch @@ -19321,6 +19364,8 @@ patches.suse/rtc-pm8xxx-fix-set-alarm-race.patch patches.suse/rtc-allow-rtc_read_alarm-without-read_alarm-callback.patch patches.suse/s390-extmem-return-correct-segment-type-in-__segment_load.patch + patches.suse/s390-kprobes-fix-irq-mask-clobbering-on-kprobe-reenter-from-post_handler.patch + patches.suse/s390-kprobes-fix-current_kprobe-never-cleared-after-kprobes-reenter.patch patches.suse/nvme-auth-fix-an-error-code-in-nvme_auth_process_dhc.patch patches.suse/nvme-fabrics-show-well-known-discovery-name.patch patches.suse/ACPI-x86-utils-Add-Cezanne-to-the-list-for-forcing-S.patch @@ -19725,6 +19770,7 @@ patches.suse/writeback-cgroup-fix-null-ptr-deref-write-in-bdi_spl.patch patches.suse/nilfs2-initialize-unused-bytes-in-segment-summary-bl.patch patches.suse/net-sched-sch_qfq-prevent-slab-out-of-bounds-in-qfq_.patch + patches.suse/virtio_net-bugfix-overflow-inside-xdp_linearize_page.patch patches.suse/sfc-Fix-use-after-free-due-to-selftest_work.patch patches.suse/bnxt_en-Do-not-initialize-PTP-on-older-P3-P4-chips.patch patches.suse/e1000e-Disable-TSO-on-i219-LM-card-to-increase-speed.patch @@ -19815,10 +19861,12 @@ patches.suse/hwmon-pmbus-fsp-3y-Fix-functionality-bitmask-in-FSP-.patch patches.suse/ACPI-processor-Fix-evaluating-_PDC-method-when-runni.patch patches.suse/ACPI-VIOT-Initialize-the-correct-IOMMU-fwspec.patch + patches.suse/ACPI-bus-Ensure-that-notify-handlers-are-not-running.patch patches.suse/crypto-safexcel-Cleanup-ring-IRQ-workqueues-on-load-.patch patches.suse/crypto-caam-Clear-some-memory-in-instantiate_rng.patch patches.suse/crypto-sa2ul-Select-CRYPTO_DES.patch patches.suse/crypto-drbg-Only-fail-when-jent-is-unavailable-in-FI.patch + patches.suse/s390-dasd-fix-hanging-blockdevice-after-request-requeue.patch patches.suse/nvmet-fix-Identify-Namespace-handling.patch patches.suse/nvmet-fix-Identify-Controller-handling.patch patches.suse/nvmet-fix-Identify-Active-Namespace-ID-list-handling.patch @@ -19873,7 +19921,9 @@ patches.suse/wifi-mt76-handle-failure-of-vzalloc-in-mt7615_coredu.patch patches.suse/wifi-mt76-add-missing-locking-to-protect-against-con.patch patches.suse/wifi-mt76-mt7921e-Set-memory-space-enable-in-PCI_COM.patch + patches.suse/wifi-mt76-mt7921e-fix-probe-timeout-after-reboot.patch patches.suse/wifi-mt76-fix-6GHz-high-channel-not-be-scanned.patch + patches.suse/wifi-mt76-mt7921e-improve-reliability-of-dma-reset.patch patches.suse/Revert-Bluetooth-btsdio-fix-use-after-free-bug-in-bt.patch patches.suse/bluetooth-Perform-careful-capability-checks-in-hci_s.patch patches.suse/net-mana-Rename-mana_refill_rxoob-and-remove-some-em.patch @@ -19906,6 +19956,7 @@ patches.suse/USB-dwc3-fix-runtime-pm-imbalance-on-unbind.patch patches.suse/usb-chipidea-fix-missing-goto-in-ci_hdrc_probe.patch patches.suse/usb-mtu3-fix-kernel-panic-at-qmu-transfer-done-irq-h.patch + patches.suse/usb-dwc3-gadget-Stall-and-restart-EP0-if-host-is-unr.patch patches.suse/USB-core-Add-routines-for-endpoint-checks-in-old-dri.patch patches.suse/serial-8250_bcm7271-Fix-arbitration-handling.patch patches.suse/tty-Prevent-writing-chars-during-tcsetattr-TCSADRAIN.patch @@ -19936,7 +19987,18 @@ patches.suse/swiotlb-relocate-PageHighMem-test-away-from-rmem_swi.patch patches.suse/xfs-verify-buffer-contents-when-we-skip-log-replay.patch patches.suse/NFS-Cleanup-unused-rpc_clnt-variable.patch + patches.suse/IB-hifi1-add-a-null-check-of-kzalloc_node-in-hfi1_ip.patch + patches.suse/RDMA-siw-Fix-potential-page_array-out-of-range-acces.patch + patches.suse/RDMA-rdmavt-Delete-unnecessary-NULL-check.patch patches.suse/RDMA-mlx4-Prevent-shift-wrapping-in-set_user_sq_size.patch + patches.suse/RDMA-rxe-Remove-tasklet-call-from-rxe_cq.c.patch + patches.suse/RDMA-siw-Remove-namespace-check-from-siw_netdev_even.patch + patches.suse/RDMA-cm-Trace-icm_send_rej-event-before-the-cm-state.patch + patches.suse/RDMA-srpt-Add-a-check-for-valid-mad_agent-pointer.patch + patches.suse/IB-hfi1-Fix-SDMA-mmu_rb_node-not-being-evicted-in-LR.patch + patches.suse/IB-hfi1-Fix-bugs-with-non-PAGE_SIZE-end-multi-iovec-.patch + patches.suse/RDMA-mlx5-Fix-flow-counter-query-via-DEVX.patch + patches.suse/RDMA-mlx5-Use-correct-device-num_ports-when-modify-D.patch patches.suse/clk-at91-clk-sam9x60-pll-fix-return-value-check.patch patches.suse/clk-add-missing-of_node_put-in-assigned-clocks-prope.patch patches.suse/clk-rockchip-rk3399-allow-clk_cifout-to-force-clk_ci.patch @@ -19985,6 +20047,7 @@ patches.suse/sfc-Fix-module-EEPROM-reporting-for-QSFP-modules.patch patches.suse/netfilter-nf_tables-deactivate-anonymous-set-from-pr.patch patches.suse/igc-read-before-write-to-SRRCTL-register.patch + patches.suse/virtio_net-suppress-cpu-stall-when-free_unused_bufs.patch patches.suse/ALSA-hda-realtek-Add-quirk-for-ThinkPad-P1-Gen-6.patch patches.suse/ALSA-hda-realtek-Add-quirk-for-ASUS-UM3402YAR-using-.patch patches.suse/ALSA-hda-realtek-support-HP-Pavilion-Aero-13-be0xxx-.patch @@ -20005,6 +20068,7 @@ patches.suse/drm-amdgpu-disable-sdma-ecc-irq-only-when-sdma-RAS-i.patch patches.suse/drm-amdgpu-gfx-disable-gfx9-cp_ecc_error_irq-only-wh.patch patches.suse/fbdev-arcfb-Fix-error-handling-in-arcfb_probe.patch + patches.suse/ARM-9296-1-HP-Jornada-7XX-fix-kernel-doc-warnings.patch patches.suse/selftests-sgx-Add-test_encl.elf-to-TEST_FILES.patch patches.suse/media-netup_unidvb-fix-use-after-free-at-del_timer.patch patches.suse/media-ttusb-dec-fix-memory-leak-in-ttusb_dec_exit_dv.patch @@ -20038,16 +20102,20 @@ patches.suse/ALSA-usb-audio-Add-a-sample-rate-workaround-for-Line.patch patches.suse/ALSA-hda-realtek-Apply-HP-B-O-top-speaker-profile-to.patch patches.suse/ALSA-hda-realtek-Fix-mute-and-micmute-LEDs-for-yet-a.patch + patches.suse/ASoC-fsl_micfil-Fix-error-handler-with-pm_runtime_en.patch patches.suse/ALSA-hda-Fix-Oops-by-9.1-surround-channel-names.patch patches.suse/ALSA-cs46xx-mark-snd_cs46xx_download_image-as-static.patch patches.suse/ALSA-hda-Add-NVIDIA-codec-IDs-a3-through-a7-to-patch.patch + patches.suse/s390-qdio-fix-do_sqbs-inline-assembly-constraint.patch patches.suse/Documentation-filesystems-sharedsubtree-add-section-.patch patches.suse/Documentation-filesystems-ramfs-rootfs-initramfs-use.patch patches.suse/drm-exynos-fix-g2d_open-close-helper-function-defini.patch patches.suse/drm-msm-dp-unregister-audio-driver-during-unbind.patch patches.suse/drm-msm-dpu-Remove-duplicate-register-defines-from-I.patch + patches.suse/usb-dwc3-gadget-Improve-dwc3_gadget_suspend-and-dwc3.patch patches.suse/usb-dwc3-debugfs-Resume-dwc3-before-accessing-regist.patch patches.suse/usb-typec-altmodes-displayport-fix-pin_assignment_sh.patch + patches.suse/usb-gadget-u_ether-Fix-host-MAC-address-case.patch patches.suse/xhci-pci-Only-run-d3cold-avoidance-quirk-for-s2idle.patch patches.suse/xhci-Fix-incorrect-tracking-of-free-space-on-transfe.patch patches.suse/thunderbolt-Clear-registers-properly-when-auto-clear.patch @@ -20090,6 +20158,9 @@ patches.suse/char-pcmcia-synclink_cs-Fix-use-after-free-in-mgslpc.patch patches.suse/keys-Fix-linking-a-duplicate-key-to-a-keyring-s-asso.patch patches.suse/iwlwifi-cfg-Add-missing-MODULE_FIRMWARE-for-pnvm.patch + patches.suse/x86-alternative-Make-debug-alternative-selective.patch + patches.suse/x86-alternative-Support-relocations-in-alternatives.patch + patches.suse/x86-lib-memmove-Decouple-ERMS-from-FSRM.patch ######################################################## # kbuild/module infrastructure fixes @@ -20675,6 +20746,7 @@ patches.kabi/RDMA-mana-hide-new-rdma_driver_ids.patch patches.kabi/media-dvb_frontend-kabi-workaround.patch patches.kabi/media-dvb_net-kabi-workaround.patch + patches.kabi/mt76_poll_msec-kabi-workaround.patch ######################################################## # SLE15-SP3 OOT performance patches evaluated but left