From: Greg Kroah-Hartman Date: Mon, 26 Feb 2024 13:13:55 +0000 (+0100) Subject: 6.6-stable patches X-Git-Tag: v4.19.308~51 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c09bed344e94c3dc5c3e1e5f0a09821bd4ccccec;p=thirdparty%2Fkernel%2Fstable-queue.git 6.6-stable patches added patches: arm-ep93xx-add-terminator-to-gpiod_lookup_table.patch dm-integrity-dm-verity-reduce-stack-usage-for-recheck.patch erofs-fix-refcount-on-the-metabuf-used-for-inode-lookup.patch irqchip-gic-v3-its-do-not-assume-vpe-tables-are-preallocated.patch irqchip-mbigen-don-t-use-bus_get_dev_root-to-find-the-parent.patch irqchip-sifive-plic-enable-interrupt-if-needed-before-eoi.patch l2tp-pass-correct-message-length-to-ip6_append_data.patch mptcp-add-needs_id-for-userspace-appending-addr.patch pci-msi-prevent-msi-hardware-interrupt-number-truncation.patch revert-usb-typec-tcpm-reset-counter-when-enter-into-unattached-state-after-try-role.patch serial-amba-pl011-fix-dma-transmission-in-rs485-mode.patch serial-stm32-do-not-always-set-ser_rs485_rx_during_tx-if-rs485-is-enabled.patch usb-cdns3-fix-memory-double-free-when-handle-zero-packet.patch usb-cdns3-fixed-memory-use-after-free-at-cdns3_gadget_ep_disable.patch usb-cdnsp-blocked-some-cdns3-specific-code.patch usb-cdnsp-fixed-issue-with-incorrect-detecting-cdnsp-family-controllers.patch usb-dwc3-gadget-don-t-disconnect-if-not-started.patch usb-gadget-ncm-avoid-dropping-datagrams-of-properly-parsed-ntbs.patch usb-gadget-omap_udc-fix-usb-gadget-regression-on-palm-te.patch usb-roles-don-t-get-set_role-when-usb_role_switch-is-unregistered.patch usb-roles-fix-null-pointer-issue-when-put-module-s-reference.patch --- diff --git a/queue-6.6/arm-ep93xx-add-terminator-to-gpiod_lookup_table.patch b/queue-6.6/arm-ep93xx-add-terminator-to-gpiod_lookup_table.patch new file mode 100644 index 00000000000..1cdadbc0669 --- /dev/null +++ b/queue-6.6/arm-ep93xx-add-terminator-to-gpiod_lookup_table.patch @@ -0,0 +1,37 @@ +From fdf87a0dc26d0550c60edc911cda42f9afec3557 Mon Sep 17 00:00:00 2001 +From: Nikita Shubin +Date: Mon, 5 Feb 2024 11:23:34 +0100 +Subject: ARM: ep93xx: Add terminator to gpiod_lookup_table + +From: Nikita Shubin + +commit fdf87a0dc26d0550c60edc911cda42f9afec3557 upstream. + +Without the terminator, if a con_id is passed to gpio_find() that +does not exist in the lookup table the function will not stop looping +correctly, and eventually cause an oops. + +Cc: stable@vger.kernel.org +Fixes: b2e63555592f ("i2c: gpio: Convert to use descriptors") +Reported-by: Andy Shevchenko +Signed-off-by: Nikita Shubin +Reviewed-by: Linus Walleij +Acked-by: Alexander Sverdlin +Signed-off-by: Alexander Sverdlin +Link: https://lore.kernel.org/r/20240205102337.439002-1-alexander.sverdlin@gmail.com +Signed-off-by: Arnd Bergmann +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm/mach-ep93xx/core.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/arm/mach-ep93xx/core.c ++++ b/arch/arm/mach-ep93xx/core.c +@@ -339,6 +339,7 @@ static struct gpiod_lookup_table ep93xx_ + GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), + GPIO_LOOKUP_IDX("G", 0, NULL, 1, + GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), ++ { } + }, + }; + diff --git a/queue-6.6/dm-integrity-dm-verity-reduce-stack-usage-for-recheck.patch b/queue-6.6/dm-integrity-dm-verity-reduce-stack-usage-for-recheck.patch new file mode 100644 index 00000000000..3857b0bf0d2 --- /dev/null +++ b/queue-6.6/dm-integrity-dm-verity-reduce-stack-usage-for-recheck.patch @@ -0,0 +1,90 @@ +From 66ad2fbcdbeab0edfd40c5d94f32f053b98c2320 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Sat, 24 Feb 2024 14:48:03 +0100 +Subject: dm-integrity, dm-verity: reduce stack usage for recheck + +From: Arnd Bergmann + +commit 66ad2fbcdbeab0edfd40c5d94f32f053b98c2320 upstream. + +The newly added integrity_recheck() function has another larger stack +allocation, just like its caller integrity_metadata(). When it gets +inlined, the combination of the two exceeds the warning limit for 32-bit +architectures and possibly risks an overflow when this is called from +a deep call chain through a file system: + +drivers/md/dm-integrity.c:1767:13: error: stack frame size (1048) exceeds limit (1024) in 'integrity_metadata' [-Werror,-Wframe-larger-than] + 1767 | static void integrity_metadata(struct work_struct *w) + +Since the caller at this point is done using its checksum buffer, +just reuse the same buffer in the new function to avoid the double +allocation. + +[Mikulas: add "noinline" to integrity_recheck and verity_recheck. +These functions are only called on error, so they shouldn't bloat the +stack frame or code size of the caller.] + +Fixes: c88f5e553fe3 ("dm-integrity: recheck the integrity tag after a failure") +Fixes: 9177f3c0dea6 ("dm-verity: recheck the hash after a failure") +Cc: stable@vger.kernel.org +Signed-off-by: Arnd Bergmann +Signed-off-by: Mikulas Patocka +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm-integrity.c | 10 ++++------ + drivers/md/dm-verity-target.c | 4 ++-- + 2 files changed, 6 insertions(+), 8 deletions(-) + +--- a/drivers/md/dm-integrity.c ++++ b/drivers/md/dm-integrity.c +@@ -1701,14 +1701,13 @@ failed: + get_random_bytes(result, ic->tag_size); + } + +-static void integrity_recheck(struct dm_integrity_io *dio) ++static noinline void integrity_recheck(struct dm_integrity_io *dio, char *checksum) + { + struct bio *bio = dm_bio_from_per_bio_data(dio, sizeof(struct dm_integrity_io)); + struct dm_integrity_c *ic = dio->ic; + struct bvec_iter iter; + struct bio_vec bv; + sector_t sector, logical_sector, area, offset; +- char checksum_onstack[max_t(size_t, HASH_MAX_DIGESTSIZE, MAX_TAG_SIZE)]; + struct page *page; + void *buffer; + +@@ -1744,9 +1743,8 @@ static void integrity_recheck(struct dm_ + goto free_ret; + } + +- integrity_sector_checksum(ic, logical_sector, buffer, +- checksum_onstack); +- r = dm_integrity_rw_tag(ic, checksum_onstack, &dio->metadata_block, ++ integrity_sector_checksum(ic, logical_sector, buffer, checksum); ++ r = dm_integrity_rw_tag(ic, checksum, &dio->metadata_block, + &dio->metadata_offset, ic->tag_size, TAG_CMP); + if (r) { + if (r > 0) { +@@ -1861,7 +1859,7 @@ again: + checksums_ptr - checksums, dio->op == REQ_OP_READ ? TAG_CMP : TAG_WRITE); + if (unlikely(r)) { + if (r > 0) { +- integrity_recheck(dio); ++ integrity_recheck(dio, checksums); + goto skip_io; + } + if (likely(checksums != checksums_onstack)) +--- a/drivers/md/dm-verity-target.c ++++ b/drivers/md/dm-verity-target.c +@@ -491,8 +491,8 @@ static int verity_recheck_copy(struct dm + return 0; + } + +-static int verity_recheck(struct dm_verity *v, struct dm_verity_io *io, +- struct bvec_iter start, sector_t cur_block) ++static noinline int verity_recheck(struct dm_verity *v, struct dm_verity_io *io, ++ struct bvec_iter start, sector_t cur_block) + { + struct page *page; + void *buffer; diff --git a/queue-6.6/erofs-fix-refcount-on-the-metabuf-used-for-inode-lookup.patch b/queue-6.6/erofs-fix-refcount-on-the-metabuf-used-for-inode-lookup.patch new file mode 100644 index 00000000000..9854f11409b --- /dev/null +++ b/queue-6.6/erofs-fix-refcount-on-the-metabuf-used-for-inode-lookup.patch @@ -0,0 +1,73 @@ +From 56ee7db31187dc36d501622cb5f1415e88e01c2a Mon Sep 17 00:00:00 2001 +From: Sandeep Dhavale +Date: Wed, 21 Feb 2024 13:03:47 -0800 +Subject: erofs: fix refcount on the metabuf used for inode lookup + +From: Sandeep Dhavale + +commit 56ee7db31187dc36d501622cb5f1415e88e01c2a upstream. + +In erofs_find_target_block() when erofs_dirnamecmp() returns 0, +we do not assign the target metabuf. This causes the caller +erofs_namei()'s erofs_put_metabuf() at the end to be not effective +leaving the refcount on the page. +As the page from metabuf (buf->page) is never put, such page cannot be +migrated or reclaimed. Fix it now by putting the metabuf from +previous loop and assigning the current metabuf to target before +returning so caller erofs_namei() can do the final put as it was +intended. + +Fixes: 500edd095648 ("erofs: use meta buffers for inode lookup") +Cc: # 5.18+ +Signed-off-by: Sandeep Dhavale +Reviewed-by: Gao Xiang +Reviewed-by: Jingbo Xu +Reviewed-by: Chao Yu +Link: https://lore.kernel.org/r/20240221210348.3667795-1-dhavale@google.com +Signed-off-by: Gao Xiang +Signed-off-by: Greg Kroah-Hartman +--- + fs/erofs/namei.c | 28 ++++++++++++++-------------- + 1 file changed, 14 insertions(+), 14 deletions(-) + +--- a/fs/erofs/namei.c ++++ b/fs/erofs/namei.c +@@ -130,24 +130,24 @@ static void *erofs_find_target_block(str + /* string comparison without already matched prefix */ + diff = erofs_dirnamecmp(name, &dname, &matched); + +- if (!diff) { +- *_ndirents = 0; +- goto out; +- } else if (diff > 0) { +- head = mid + 1; +- startprfx = matched; +- +- if (!IS_ERR(candidate)) +- erofs_put_metabuf(target); +- *target = buf; +- candidate = de; +- *_ndirents = ndirents; +- } else { ++ if (diff < 0) { + erofs_put_metabuf(&buf); +- + back = mid - 1; + endprfx = matched; ++ continue; ++ } ++ ++ if (!IS_ERR(candidate)) ++ erofs_put_metabuf(target); ++ *target = buf; ++ if (!diff) { ++ *_ndirents = 0; ++ return de; + } ++ head = mid + 1; ++ startprfx = matched; ++ candidate = de; ++ *_ndirents = ndirents; + continue; + } + out: /* free if the candidate is valid */ diff --git a/queue-6.6/irqchip-gic-v3-its-do-not-assume-vpe-tables-are-preallocated.patch b/queue-6.6/irqchip-gic-v3-its-do-not-assume-vpe-tables-are-preallocated.patch new file mode 100644 index 00000000000..c05f6ccb3e9 --- /dev/null +++ b/queue-6.6/irqchip-gic-v3-its-do-not-assume-vpe-tables-are-preallocated.patch @@ -0,0 +1,55 @@ +From ec4308ecfc887128a468f03fb66b767559c57c23 Mon Sep 17 00:00:00 2001 +From: Oliver Upton +Date: Mon, 19 Feb 2024 18:58:06 +0000 +Subject: irqchip/gic-v3-its: Do not assume vPE tables are preallocated + +From: Oliver Upton + +commit ec4308ecfc887128a468f03fb66b767559c57c23 upstream. + +The GIC/ITS code is designed to ensure to pick up any preallocated LPI +tables on the redistributors, as enabling LPIs is a one-way switch. There +is no such restriction for vLPIs, and for GICv4.1 it is expected to +allocate a new vPE table at boot. + +This works as intended when initializing an ITS, however when setting up a +redistributor in cpu_init_lpis() the early return for preallocated RD +tables skips straight past the GICv4 setup. This all comes to a head when +trying to kexec() into a new kernel, as the new kernel silently fails to +set up GICv4, leading to a complete loss of SGIs and LPIs for KVM VMs. + +Slap a band-aid on the problem by ensuring its_cpu_init_lpis() always +initializes GICv4 on the way out, even if the other RD tables were +preallocated. + +Fixes: 6479450f72c1 ("irqchip/gic-v4: Fix occasional VLPI drop") +Reported-by: George Cherian +Co-developed-by: Marc Zyngier +Signed-off-by: Marc Zyngier +Signed-off-by: Oliver Upton +Signed-off-by: Thomas Gleixner +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20240219185809.286724-2-oliver.upton@linux.dev +Signed-off-by: Greg Kroah-Hartman +--- + drivers/irqchip/irq-gic-v3-its.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/irqchip/irq-gic-v3-its.c ++++ b/drivers/irqchip/irq-gic-v3-its.c +@@ -3181,6 +3181,7 @@ static void its_cpu_init_lpis(void) + val |= GICR_CTLR_ENABLE_LPIS; + writel_relaxed(val, rbase + GICR_CTLR); + ++out: + if (gic_rdists->has_vlpis && !gic_rdists->has_rvpeid) { + void __iomem *vlpi_base = gic_data_rdist_vlpi_base(); + +@@ -3216,7 +3217,6 @@ static void its_cpu_init_lpis(void) + + /* Make sure the GIC has seen the above */ + dsb(sy); +-out: + gic_data_rdist()->flags |= RD_LOCAL_LPI_ENABLED; + pr_info("GICv3: CPU%d: using %s LPI pending table @%pa\n", + smp_processor_id(), diff --git a/queue-6.6/irqchip-mbigen-don-t-use-bus_get_dev_root-to-find-the-parent.patch b/queue-6.6/irqchip-mbigen-don-t-use-bus_get_dev_root-to-find-the-parent.patch new file mode 100644 index 00000000000..f82a5c11aa5 --- /dev/null +++ b/queue-6.6/irqchip-mbigen-don-t-use-bus_get_dev_root-to-find-the-parent.patch @@ -0,0 +1,68 @@ +From fb33a46cd75e18773dd5a414744507d84ae90870 Mon Sep 17 00:00:00 2001 +From: Chen Jun +Date: Tue, 20 Feb 2024 19:14:29 +0800 +Subject: irqchip/mbigen: Don't use bus_get_dev_root() to find the parent + +From: Chen Jun + +commit fb33a46cd75e18773dd5a414744507d84ae90870 upstream. + +bus_get_dev_root() returns sp->dev_root which is set in subsys_register(), +but subsys_register() is not called by platform_bus_init(). + +Therefor for the platform_bus_type, bus_get_dev_root() always returns NULL. +This makes mbigen_of_create_domain() always return -ENODEV. + +Don't try to retrieve the parent via bus_get_dev_root() and +unconditionally hand a NULL pointer to of_platform_device_create() to +fix this. + +Fixes: fea087fc291b ("irqchip/mbigen: move to use bus_get_dev_root()") +Signed-off-by: Chen Jun +Signed-off-by: Thomas Gleixner +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20240220111429.110666-1-chenjun102@huawei.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/irqchip/irq-mbigen.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c +index 5101a3fb11df..58881d313979 100644 +--- a/drivers/irqchip/irq-mbigen.c ++++ b/drivers/irqchip/irq-mbigen.c +@@ -235,22 +235,17 @@ static const struct irq_domain_ops mbigen_domain_ops = { + static int mbigen_of_create_domain(struct platform_device *pdev, + struct mbigen_device *mgn_chip) + { +- struct device *parent; + struct platform_device *child; + struct irq_domain *domain; + struct device_node *np; + u32 num_pins; + int ret = 0; + +- parent = bus_get_dev_root(&platform_bus_type); +- if (!parent) +- return -ENODEV; +- + for_each_child_of_node(pdev->dev.of_node, np) { + if (!of_property_read_bool(np, "interrupt-controller")) + continue; + +- child = of_platform_device_create(np, NULL, parent); ++ child = of_platform_device_create(np, NULL, NULL); + if (!child) { + ret = -ENOMEM; + break; +@@ -273,7 +268,6 @@ static int mbigen_of_create_domain(struct platform_device *pdev, + } + } + +- put_device(parent); + if (ret) + of_node_put(np); + +-- +2.44.0 + diff --git a/queue-6.6/irqchip-sifive-plic-enable-interrupt-if-needed-before-eoi.patch b/queue-6.6/irqchip-sifive-plic-enable-interrupt-if-needed-before-eoi.patch new file mode 100644 index 00000000000..7403568fa76 --- /dev/null +++ b/queue-6.6/irqchip-sifive-plic-enable-interrupt-if-needed-before-eoi.patch @@ -0,0 +1,69 @@ +From 9c92006b896c767218aabe8947b62026a571cfd0 Mon Sep 17 00:00:00 2001 +From: Nam Cao +Date: Wed, 31 Jan 2024 09:19:33 +0100 +Subject: irqchip/sifive-plic: Enable interrupt if needed before EOI + +From: Nam Cao + +commit 9c92006b896c767218aabe8947b62026a571cfd0 upstream. + +RISC-V PLIC cannot "end-of-interrupt" (EOI) disabled interrupts, as +explained in the description of Interrupt Completion in the PLIC spec: + +"The PLIC signals it has completed executing an interrupt handler by +writing the interrupt ID it received from the claim to the claim/complete +register. The PLIC does not check whether the completion ID is the same +as the last claim ID for that target. If the completion ID does not match +an interrupt source that *is currently enabled* for the target, the +completion is silently ignored." + +Commit 69ea463021be ("irqchip/sifive-plic: Fixup EOI failed when masked") +ensured that EOI is successful by enabling interrupt first, before EOI. + +Commit a1706a1c5062 ("irqchip/sifive-plic: Separate the enable and mask +operations") removed the interrupt enabling code from the previous +commit, because it assumes that interrupt should already be enabled at the +point of EOI. + +However, this is incorrect: there is a window after a hart claiming an +interrupt and before irq_desc->lock getting acquired, interrupt can be +disabled during this window. Thus, EOI can be invoked while the interrupt +is disabled, effectively nullify this EOI. This results in the interrupt +never gets asserted again, and the device who uses this interrupt appears +frozen. + +Make sure that interrupt is really enabled before EOI. + +Fixes: a1706a1c5062 ("irqchip/sifive-plic: Separate the enable and mask operations") +Signed-off-by: Nam Cao +Signed-off-by: Thomas Gleixner +Cc: Palmer Dabbelt +Cc: Paul Walmsley +Cc: Samuel Holland +Cc: Marc Zyngier +Cc: Guo Ren +Cc: linux-riscv@lists.infradead.org +Cc: +Link: https://lore.kernel.org/r/20240131081933.144512-1-namcao@linutronix.de +Signed-off-by: Greg Kroah-Hartman +--- + drivers/irqchip/irq-sifive-plic.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/drivers/irqchip/irq-sifive-plic.c ++++ b/drivers/irqchip/irq-sifive-plic.c +@@ -148,7 +148,13 @@ static void plic_irq_eoi(struct irq_data + { + struct plic_handler *handler = this_cpu_ptr(&plic_handlers); + +- writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); ++ if (unlikely(irqd_irq_disabled(d))) { ++ plic_toggle(handler, d->hwirq, 1); ++ writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); ++ plic_toggle(handler, d->hwirq, 0); ++ } else { ++ writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); ++ } + } + + #ifdef CONFIG_SMP diff --git a/queue-6.6/l2tp-pass-correct-message-length-to-ip6_append_data.patch b/queue-6.6/l2tp-pass-correct-message-length-to-ip6_append_data.patch new file mode 100644 index 00000000000..6c827ea609f --- /dev/null +++ b/queue-6.6/l2tp-pass-correct-message-length-to-ip6_append_data.patch @@ -0,0 +1,50 @@ +From 359e54a93ab43d32ee1bff3c2f9f10cb9f6b6e79 Mon Sep 17 00:00:00 2001 +From: Tom Parkin +Date: Tue, 20 Feb 2024 12:21:56 +0000 +Subject: l2tp: pass correct message length to ip6_append_data + +From: Tom Parkin + +commit 359e54a93ab43d32ee1bff3c2f9f10cb9f6b6e79 upstream. + +l2tp_ip6_sendmsg needs to avoid accounting for the transport header +twice when splicing more data into an already partially-occupied skbuff. + +To manage this, we check whether the skbuff contains data using +skb_queue_empty when deciding how much data to append using +ip6_append_data. + +However, the code which performed the calculation was incorrect: + + ulen = len + skb_queue_empty(&sk->sk_write_queue) ? transhdrlen : 0; + +...due to C operator precedence, this ends up setting ulen to +transhdrlen for messages with a non-zero length, which results in +corrupted packets on the wire. + +Add parentheses to correct the calculation in line with the original +intent. + +Fixes: 9d4c75800f61 ("ipv4, ipv6: Fix handling of transhdrlen in __ip{,6}_append_data()") +Cc: David Howells +Cc: stable@vger.kernel.org +Signed-off-by: Tom Parkin +Reviewed-by: Simon Horman +Link: https://lore.kernel.org/r/20240220122156.43131-1-tparkin@katalix.com +Signed-off-by: Paolo Abeni +Signed-off-by: Greg Kroah-Hartman +--- + net/l2tp/l2tp_ip6.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/l2tp/l2tp_ip6.c ++++ b/net/l2tp/l2tp_ip6.c +@@ -627,7 +627,7 @@ static int l2tp_ip6_sendmsg(struct sock + + back_from_confirm: + lock_sock(sk); +- ulen = len + skb_queue_empty(&sk->sk_write_queue) ? transhdrlen : 0; ++ ulen = len + (skb_queue_empty(&sk->sk_write_queue) ? transhdrlen : 0); + err = ip6_append_data(sk, ip_generic_getfrag, msg, + ulen, transhdrlen, &ipc6, + &fl6, (struct rt6_info *)dst, diff --git a/queue-6.6/mptcp-add-needs_id-for-userspace-appending-addr.patch b/queue-6.6/mptcp-add-needs_id-for-userspace-appending-addr.patch new file mode 100644 index 00000000000..bfd8bda2d5b --- /dev/null +++ b/queue-6.6/mptcp-add-needs_id-for-userspace-appending-addr.patch @@ -0,0 +1,100 @@ +From 6c347be62ae963b301ead8e7fa7b9973e6e0d6e1 Mon Sep 17 00:00:00 2001 +From: Geliang Tang +Date: Thu, 15 Feb 2024 19:25:28 +0100 +Subject: mptcp: add needs_id for userspace appending addr + +From: Geliang Tang + +commit 6c347be62ae963b301ead8e7fa7b9973e6e0d6e1 upstream. + +When userspace PM requires to create an ID 0 subflow in "userspace pm +create id 0 subflow" test like this: + + userspace_pm_add_sf $ns2 10.0.3.2 0 + +An ID 1 subflow, in fact, is created. + +Since in mptcp_pm_nl_append_new_local_addr(), 'id 0' will be treated as +no ID is set by userspace, and will allocate a new ID immediately: + + if (!e->addr.id) + e->addr.id = find_next_zero_bit(pernet->id_bitmap, + MPTCP_PM_MAX_ADDR_ID + 1, + 1); + +To solve this issue, a new parameter needs_id is added for +mptcp_userspace_pm_append_new_local_addr() to distinguish between +whether userspace PM has set an ID 0 or whether userspace PM has +not set any address. + +needs_id is true in mptcp_userspace_pm_get_local_id(), but false in +mptcp_pm_nl_announce_doit() and mptcp_pm_nl_subflow_create_doit(). + +Fixes: e5ed101a6028 ("mptcp: userspace pm allow creating id 0 subflow") +Cc: stable@vger.kernel.org +Signed-off-by: Geliang Tang +Reviewed-by: Mat Martineau +Signed-off-by: Matthieu Baerts (NGI0) +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/mptcp/pm_userspace.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +--- a/net/mptcp/pm_userspace.c ++++ b/net/mptcp/pm_userspace.c +@@ -26,7 +26,8 @@ void mptcp_free_local_addr_list(struct m + } + + static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk, +- struct mptcp_pm_addr_entry *entry) ++ struct mptcp_pm_addr_entry *entry, ++ bool needs_id) + { + DECLARE_BITMAP(id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1); + struct mptcp_pm_addr_entry *match = NULL; +@@ -41,7 +42,7 @@ static int mptcp_userspace_pm_append_new + spin_lock_bh(&msk->pm.lock); + list_for_each_entry(e, &msk->pm.userspace_pm_local_addr_list, list) { + addr_match = mptcp_addresses_equal(&e->addr, &entry->addr, true); +- if (addr_match && entry->addr.id == 0) ++ if (addr_match && entry->addr.id == 0 && needs_id) + entry->addr.id = e->addr.id; + id_match = (e->addr.id == entry->addr.id); + if (addr_match && id_match) { +@@ -64,7 +65,7 @@ static int mptcp_userspace_pm_append_new + } + + *e = *entry; +- if (!e->addr.id) ++ if (!e->addr.id && needs_id) + e->addr.id = find_next_zero_bit(id_bitmap, + MPTCP_PM_MAX_ADDR_ID + 1, + 1); +@@ -153,7 +154,7 @@ int mptcp_userspace_pm_get_local_id(stru + if (new_entry.addr.port == msk_sport) + new_entry.addr.port = 0; + +- return mptcp_userspace_pm_append_new_local_addr(msk, &new_entry); ++ return mptcp_userspace_pm_append_new_local_addr(msk, &new_entry, true); + } + + int mptcp_nl_cmd_announce(struct sk_buff *skb, struct genl_info *info) +@@ -195,7 +196,7 @@ int mptcp_nl_cmd_announce(struct sk_buff + goto announce_err; + } + +- err = mptcp_userspace_pm_append_new_local_addr(msk, &addr_val); ++ err = mptcp_userspace_pm_append_new_local_addr(msk, &addr_val, false); + if (err < 0) { + GENL_SET_ERR_MSG(info, "did not match address and id"); + goto announce_err; +@@ -333,7 +334,7 @@ int mptcp_nl_cmd_sf_create(struct sk_buf + } + + local.addr = addr_l; +- err = mptcp_userspace_pm_append_new_local_addr(msk, &local); ++ err = mptcp_userspace_pm_append_new_local_addr(msk, &local, false); + if (err < 0) { + GENL_SET_ERR_MSG(info, "did not match address and id"); + goto create_err; diff --git a/queue-6.6/pci-msi-prevent-msi-hardware-interrupt-number-truncation.patch b/queue-6.6/pci-msi-prevent-msi-hardware-interrupt-number-truncation.patch new file mode 100644 index 00000000000..3141814576a --- /dev/null +++ b/queue-6.6/pci-msi-prevent-msi-hardware-interrupt-number-truncation.patch @@ -0,0 +1,46 @@ +From db744ddd59be798c2627efbfc71f707f5a935a40 Mon Sep 17 00:00:00 2001 +From: Vidya Sagar +Date: Mon, 15 Jan 2024 19:26:49 +0530 +Subject: PCI/MSI: Prevent MSI hardware interrupt number truncation + +From: Vidya Sagar + +commit db744ddd59be798c2627efbfc71f707f5a935a40 upstream. + +While calculating the hardware interrupt number for a MSI interrupt, the +higher bits (i.e. from bit-5 onwards a.k.a domain_nr >= 32) of the PCI +domain number gets truncated because of the shifted value casting to return +type of pci_domain_nr() which is 'int'. This for example is resulting in +same hardware interrupt number for devices 0019:00:00.0 and 0039:00:00.0. + +To address this cast the PCI domain number to 'irq_hw_number_t' before left +shifting it to calculate the hardware interrupt number. + +Please note that this fixes the issue only on 64-bit systems and doesn't +change the behavior for 32-bit systems i.e. the 32-bit systems continue to +have the issue. Since the issue surfaces only if there are too many PCIe +controllers in the system which usually is the case in modern server +systems and they don't tend to run 32-bit kernels. + +Fixes: 3878eaefb89a ("PCI/MSI: Enhance core to support hierarchy irqdomain") +Signed-off-by: Vidya Sagar +Signed-off-by: Thomas Gleixner +Tested-by: Shanker Donthineni +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20240115135649.708536-1-vidyas@nvidia.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/msi/irqdomain.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/pci/msi/irqdomain.c ++++ b/drivers/pci/msi/irqdomain.c +@@ -61,7 +61,7 @@ static irq_hw_number_t pci_msi_domain_ca + + return (irq_hw_number_t)desc->msi_index | + pci_dev_id(dev) << 11 | +- (pci_domain_nr(dev->bus) & 0xFFFFFFFF) << 27; ++ ((irq_hw_number_t)(pci_domain_nr(dev->bus) & 0xFFFFFFFF)) << 27; + } + + static void pci_msi_domain_set_desc(msi_alloc_info_t *arg, diff --git a/queue-6.6/revert-usb-typec-tcpm-reset-counter-when-enter-into-unattached-state-after-try-role.patch b/queue-6.6/revert-usb-typec-tcpm-reset-counter-when-enter-into-unattached-state-after-try-role.patch new file mode 100644 index 00000000000..f794dcdabe9 --- /dev/null +++ b/queue-6.6/revert-usb-typec-tcpm-reset-counter-when-enter-into-unattached-state-after-try-role.patch @@ -0,0 +1,38 @@ +From 23b1d2d99b0f55326f05e7d757fa197c4a95dc5c Mon Sep 17 00:00:00 2001 +From: Ondrej Jirman +Date: Sat, 17 Feb 2024 17:20:21 +0100 +Subject: Revert "usb: typec: tcpm: reset counter when enter into unattached state after try role" + +From: Ondrej Jirman + +commit 23b1d2d99b0f55326f05e7d757fa197c4a95dc5c upstream. + +The reverted commit makes the state machine only ever go from SRC_ATTACH_WAIT +to SNK_TRY in endless loop when toggling. After revert it goes to SRC_ATTACHED +after initially trying SNK_TRY earlier, as it should for toggling to ever detect +the power source mode and the port is again able to provide power to attached +power sinks. + +This reverts commit 2d6d80127006ae3da26b1f21a65eccf957f2d1e5. + +Cc: stable@vger.kernel.org +Fixes: 2d6d80127006 ("usb: typec: tcpm: reset counter when enter into unattached state after try role") +Signed-off-by: Ondrej Jirman +Link: https://lore.kernel.org/r/20240217162023.1719738-1-megi@xff.cz +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/tcpm/tcpm.c | 3 --- + 1 file changed, 3 deletions(-) + +--- a/drivers/usb/typec/tcpm/tcpm.c ++++ b/drivers/usb/typec/tcpm/tcpm.c +@@ -3730,9 +3730,6 @@ static void tcpm_detach(struct tcpm_port + if (tcpm_port_is_disconnected(port)) + port->hard_reset_count = 0; + +- port->try_src_count = 0; +- port->try_snk_count = 0; +- + if (!port->attached) + return; + diff --git a/queue-6.6/serial-amba-pl011-fix-dma-transmission-in-rs485-mode.patch b/queue-6.6/serial-amba-pl011-fix-dma-transmission-in-rs485-mode.patch new file mode 100644 index 00000000000..b2dd7f4ef15 --- /dev/null +++ b/queue-6.6/serial-amba-pl011-fix-dma-transmission-in-rs485-mode.patch @@ -0,0 +1,108 @@ +From 3b69e32e151bc4a4e3c785cbdb1f918d5ee337ed Mon Sep 17 00:00:00 2001 +From: Lino Sanfilippo +Date: Fri, 16 Feb 2024 23:47:08 +0100 +Subject: serial: amba-pl011: Fix DMA transmission in RS485 mode + +From: Lino Sanfilippo + +commit 3b69e32e151bc4a4e3c785cbdb1f918d5ee337ed upstream. + +When DMA is used in RS485 mode make sure that the UARTs tx section is +enabled before the DMA buffers are queued for transmission. + +Cc: stable@vger.kernel.org +Fixes: 8d479237727c ("serial: amba-pl011: add RS485 support") +Signed-off-by: Lino Sanfilippo +Link: https://lore.kernel.org/r/20240216224709.9928-2-l.sanfilippo@kunbus.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/amba-pl011.c | 60 ++++++++++++++++++++-------------------- + 1 file changed, 30 insertions(+), 30 deletions(-) + +--- a/drivers/tty/serial/amba-pl011.c ++++ b/drivers/tty/serial/amba-pl011.c +@@ -1345,11 +1345,41 @@ static void pl011_start_tx_pio(struct ua + } + } + ++static void pl011_rs485_tx_start(struct uart_amba_port *uap) ++{ ++ struct uart_port *port = &uap->port; ++ u32 cr; ++ ++ /* Enable transmitter */ ++ cr = pl011_read(uap, REG_CR); ++ cr |= UART011_CR_TXE; ++ ++ /* Disable receiver if half-duplex */ ++ if (!(port->rs485.flags & SER_RS485_RX_DURING_TX)) ++ cr &= ~UART011_CR_RXE; ++ ++ if (port->rs485.flags & SER_RS485_RTS_ON_SEND) ++ cr &= ~UART011_CR_RTS; ++ else ++ cr |= UART011_CR_RTS; ++ ++ pl011_write(cr, uap, REG_CR); ++ ++ if (port->rs485.delay_rts_before_send) ++ mdelay(port->rs485.delay_rts_before_send); ++ ++ uap->rs485_tx_started = true; ++} ++ + static void pl011_start_tx(struct uart_port *port) + { + struct uart_amba_port *uap = + container_of(port, struct uart_amba_port, port); + ++ if ((uap->port.rs485.flags & SER_RS485_ENABLED) && ++ !uap->rs485_tx_started) ++ pl011_rs485_tx_start(uap); ++ + if (!pl011_dma_tx_start(uap)) + pl011_start_tx_pio(uap); + } +@@ -1431,42 +1461,12 @@ static bool pl011_tx_char(struct uart_am + return true; + } + +-static void pl011_rs485_tx_start(struct uart_amba_port *uap) +-{ +- struct uart_port *port = &uap->port; +- u32 cr; +- +- /* Enable transmitter */ +- cr = pl011_read(uap, REG_CR); +- cr |= UART011_CR_TXE; +- +- /* Disable receiver if half-duplex */ +- if (!(port->rs485.flags & SER_RS485_RX_DURING_TX)) +- cr &= ~UART011_CR_RXE; +- +- if (port->rs485.flags & SER_RS485_RTS_ON_SEND) +- cr &= ~UART011_CR_RTS; +- else +- cr |= UART011_CR_RTS; +- +- pl011_write(cr, uap, REG_CR); +- +- if (port->rs485.delay_rts_before_send) +- mdelay(port->rs485.delay_rts_before_send); +- +- uap->rs485_tx_started = true; +-} +- + /* Returns true if tx interrupts have to be (kept) enabled */ + static bool pl011_tx_chars(struct uart_amba_port *uap, bool from_irq) + { + struct circ_buf *xmit = &uap->port.state->xmit; + int count = uap->fifosize >> 1; + +- if ((uap->port.rs485.flags & SER_RS485_ENABLED) && +- !uap->rs485_tx_started) +- pl011_rs485_tx_start(uap); +- + if (uap->port.x_char) { + if (!pl011_tx_char(uap, uap->port.x_char, from_irq)) + return true; diff --git a/queue-6.6/serial-stm32-do-not-always-set-ser_rs485_rx_during_tx-if-rs485-is-enabled.patch b/queue-6.6/serial-stm32-do-not-always-set-ser_rs485_rx_during_tx-if-rs485-is-enabled.patch new file mode 100644 index 00000000000..1bfd139980e --- /dev/null +++ b/queue-6.6/serial-stm32-do-not-always-set-ser_rs485_rx_during_tx-if-rs485-is-enabled.patch @@ -0,0 +1,45 @@ +From f418ae73311deb901c0110b08d1bbafc20c1820e Mon Sep 17 00:00:00 2001 +From: Lino Sanfilippo +Date: Fri, 16 Feb 2024 23:47:07 +0100 +Subject: serial: stm32: do not always set SER_RS485_RX_DURING_TX if RS485 is enabled + +From: Lino Sanfilippo + +commit f418ae73311deb901c0110b08d1bbafc20c1820e upstream. + +Before commit 07c30ea5861f ("serial: Do not hold the port lock when setting +rx-during-tx GPIO") the SER_RS485_RX_DURING_TX flag was only set if the +rx-during-tx mode was not controlled by a GPIO. Now the flag is set +unconditionally when RS485 is enabled. This results in an incorrect setting +if the rx-during-tx GPIO is not asserted. + +Fix this by setting the flag only if the rx-during-tx mode is not +controlled by a GPIO and thus restore the correct behaviour. + +Cc: stable@vger.kernel.org # 6.6+ +Fixes: 07c30ea5861f ("serial: Do not hold the port lock when setting rx-during-tx GPIO") +Signed-off-by: Lino Sanfilippo +Link: https://lore.kernel.org/r/20240216224709.9928-1-l.sanfilippo@kunbus.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/stm32-usart.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c +index 794b77512740..693e932d6feb 100644 +--- a/drivers/tty/serial/stm32-usart.c ++++ b/drivers/tty/serial/stm32-usart.c +@@ -251,7 +251,9 @@ static int stm32_usart_config_rs485(struct uart_port *port, struct ktermios *ter + writel_relaxed(cr3, port->membase + ofs->cr3); + writel_relaxed(cr1, port->membase + ofs->cr1); + +- rs485conf->flags |= SER_RS485_RX_DURING_TX; ++ if (!port->rs485_rx_during_tx_gpio) ++ rs485conf->flags |= SER_RS485_RX_DURING_TX; ++ + } else { + stm32_usart_clr_bits(port, ofs->cr3, + USART_CR3_DEM | USART_CR3_DEP); +-- +2.44.0 + diff --git a/queue-6.6/series b/queue-6.6/series index 0ee1179648a..ee10463881b 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -170,3 +170,24 @@ kvm-arm64-vgic-its-test-for-valid-irq-in-its_sync_lpi_pending_table.patch accel-ivpu-don-t-enable-any-tiles-by-default-on-vpu40xx.patch gtp-fix-use-after-free-and-null-ptr-deref-in-gtp_genl_dump_pdp.patch crypto-virtio-akcipher-fix-stack-overflow-on-memcpy.patch +irqchip-mbigen-don-t-use-bus_get_dev_root-to-find-the-parent.patch +irqchip-gic-v3-its-do-not-assume-vpe-tables-are-preallocated.patch +irqchip-sifive-plic-enable-interrupt-if-needed-before-eoi.patch +pci-msi-prevent-msi-hardware-interrupt-number-truncation.patch +l2tp-pass-correct-message-length-to-ip6_append_data.patch +arm-ep93xx-add-terminator-to-gpiod_lookup_table.patch +dm-integrity-dm-verity-reduce-stack-usage-for-recheck.patch +erofs-fix-refcount-on-the-metabuf-used-for-inode-lookup.patch +revert-usb-typec-tcpm-reset-counter-when-enter-into-unattached-state-after-try-role.patch +serial-stm32-do-not-always-set-ser_rs485_rx_during_tx-if-rs485-is-enabled.patch +serial-amba-pl011-fix-dma-transmission-in-rs485-mode.patch +usb-dwc3-gadget-don-t-disconnect-if-not-started.patch +usb-cdnsp-blocked-some-cdns3-specific-code.patch +usb-cdnsp-fixed-issue-with-incorrect-detecting-cdnsp-family-controllers.patch +usb-cdns3-fixed-memory-use-after-free-at-cdns3_gadget_ep_disable.patch +usb-cdns3-fix-memory-double-free-when-handle-zero-packet.patch +usb-gadget-ncm-avoid-dropping-datagrams-of-properly-parsed-ntbs.patch +usb-gadget-omap_udc-fix-usb-gadget-regression-on-palm-te.patch +usb-roles-fix-null-pointer-issue-when-put-module-s-reference.patch +usb-roles-don-t-get-set_role-when-usb_role_switch-is-unregistered.patch +mptcp-add-needs_id-for-userspace-appending-addr.patch diff --git a/queue-6.6/usb-cdns3-fix-memory-double-free-when-handle-zero-packet.patch b/queue-6.6/usb-cdns3-fix-memory-double-free-when-handle-zero-packet.patch new file mode 100644 index 00000000000..18556be36ab --- /dev/null +++ b/queue-6.6/usb-cdns3-fix-memory-double-free-when-handle-zero-packet.patch @@ -0,0 +1,62 @@ +From 5fd9e45f1ebcd57181358af28506e8a661a260b3 Mon Sep 17 00:00:00 2001 +From: Frank Li +Date: Fri, 2 Feb 2024 10:42:17 -0500 +Subject: usb: cdns3: fix memory double free when handle zero packet + +From: Frank Li + +commit 5fd9e45f1ebcd57181358af28506e8a661a260b3 upstream. + +829 if (request->complete) { +830 spin_unlock(&priv_dev->lock); +831 usb_gadget_giveback_request(&priv_ep->endpoint, +832 request); +833 spin_lock(&priv_dev->lock); +834 } +835 +836 if (request->buf == priv_dev->zlp_buf) +837 cdns3_gadget_ep_free_request(&priv_ep->endpoint, request); + +Driver append an additional zero packet request when queue a packet, which +length mod max packet size is 0. When transfer complete, run to line 831, +usb_gadget_giveback_request() will free this requestion. 836 condition is +true, so cdns3_gadget_ep_free_request() free this request again. + +Log: + +[ 1920.140696][ T150] BUG: KFENCE: use-after-free read in cdns3_gadget_giveback+0x134/0x2c0 [cdns3] +[ 1920.140696][ T150] +[ 1920.151837][ T150] Use-after-free read at 0x000000003d1cd10b (in kfence-#36): +[ 1920.159082][ T150] cdns3_gadget_giveback+0x134/0x2c0 [cdns3] +[ 1920.164988][ T150] cdns3_transfer_completed+0x438/0x5f8 [cdns3] + +Add check at line 829, skip call usb_gadget_giveback_request() if it is +additional zero length packet request. Needn't call +usb_gadget_giveback_request() because it is allocated in this driver. + +Cc: stable@vger.kernel.org +Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver") +Signed-off-by: Frank Li +Reviewed-by: Roger Quadros +Acked-by: Peter Chen +Link: https://lore.kernel.org/r/20240202154217.661867-2-Frank.Li@nxp.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/cdns3/cdns3-gadget.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/usb/cdns3/cdns3-gadget.c ++++ b/drivers/usb/cdns3/cdns3-gadget.c +@@ -828,7 +828,11 @@ void cdns3_gadget_giveback(struct cdns3_ + return; + } + +- if (request->complete) { ++ /* ++ * zlp request is appended by driver, needn't call usb_gadget_giveback_request() to notify ++ * gadget composite driver. ++ */ ++ if (request->complete && request->buf != priv_dev->zlp_buf) { + spin_unlock(&priv_dev->lock); + usb_gadget_giveback_request(&priv_ep->endpoint, + request); diff --git a/queue-6.6/usb-cdns3-fixed-memory-use-after-free-at-cdns3_gadget_ep_disable.patch b/queue-6.6/usb-cdns3-fixed-memory-use-after-free-at-cdns3_gadget_ep_disable.patch new file mode 100644 index 00000000000..ff6a87a1507 --- /dev/null +++ b/queue-6.6/usb-cdns3-fixed-memory-use-after-free-at-cdns3_gadget_ep_disable.patch @@ -0,0 +1,56 @@ +From cd45f99034b0c8c9cb346dd0d6407a95ca3d36f6 Mon Sep 17 00:00:00 2001 +From: Frank Li +Date: Fri, 2 Feb 2024 10:42:16 -0500 +Subject: usb: cdns3: fixed memory use after free at cdns3_gadget_ep_disable() + +From: Frank Li + +commit cd45f99034b0c8c9cb346dd0d6407a95ca3d36f6 upstream. + + ... + cdns3_gadget_ep_free_request(&priv_ep->endpoint, &priv_req->request); + list_del_init(&priv_req->list); + ... + +'priv_req' actually free at cdns3_gadget_ep_free_request(). But +list_del_init() use priv_req->list after it. + +[ 1542.642868][ T534] BUG: KFENCE: use-after-free read in __list_del_entry_valid+0x10/0xd4 +[ 1542.642868][ T534] +[ 1542.653162][ T534] Use-after-free read at 0x000000009ed0ba99 (in kfence-#3): +[ 1542.660311][ T534] __list_del_entry_valid+0x10/0xd4 +[ 1542.665375][ T534] cdns3_gadget_ep_disable+0x1f8/0x388 [cdns3] +[ 1542.671571][ T534] usb_ep_disable+0x44/0xe4 +[ 1542.675948][ T534] ffs_func_eps_disable+0x64/0xc8 +[ 1542.680839][ T534] ffs_func_set_alt+0x74/0x368 +[ 1542.685478][ T534] ffs_func_disable+0x18/0x28 + +Move list_del_init() before cdns3_gadget_ep_free_request() to resolve this +problem. + +Cc: stable@vger.kernel.org +Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver") +Signed-off-by: Frank Li +Reviewed-by: Roger Quadros +Acked-by: Peter Chen +Link: https://lore.kernel.org/r/20240202154217.661867-1-Frank.Li@nxp.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/cdns3/cdns3-gadget.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/cdns3/cdns3-gadget.c ++++ b/drivers/usb/cdns3/cdns3-gadget.c +@@ -2539,11 +2539,11 @@ static int cdns3_gadget_ep_disable(struc + + while (!list_empty(&priv_ep->wa2_descmiss_req_list)) { + priv_req = cdns3_next_priv_request(&priv_ep->wa2_descmiss_req_list); ++ list_del_init(&priv_req->list); + + kfree(priv_req->request.buf); + cdns3_gadget_ep_free_request(&priv_ep->endpoint, + &priv_req->request); +- list_del_init(&priv_req->list); + --priv_ep->wa2_counter; + } + diff --git a/queue-6.6/usb-cdnsp-blocked-some-cdns3-specific-code.patch b/queue-6.6/usb-cdnsp-blocked-some-cdns3-specific-code.patch new file mode 100644 index 00000000000..4717d822a44 --- /dev/null +++ b/queue-6.6/usb-cdnsp-blocked-some-cdns3-specific-code.patch @@ -0,0 +1,65 @@ +From 18a6be674306c9acb05c08e5c3fd376ef50a917c Mon Sep 17 00:00:00 2001 +From: Pawel Laszczak +Date: Tue, 6 Feb 2024 11:40:18 +0100 +Subject: usb: cdnsp: blocked some cdns3 specific code + +From: Pawel Laszczak + +commit 18a6be674306c9acb05c08e5c3fd376ef50a917c upstream. + +host.c file has some parts of code that were introduced for CDNS3 driver +and should not be used with CDNSP driver. +This patch blocks using these parts of codes by CDNSP driver. +These elements include: +- xhci_plat_cdns3_xhci object +- cdns3 specific XECP_PORT_CAP_REG register +- cdns3 specific XECP_AUX_CTRL_REG1 register + +cc: stable@vger.kernel.org +Fixes: 3d82904559f4 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver") +Signed-off-by: Pawel Laszczak +Link: https://lore.kernel.org/r/20240206104018.48272-1-pawell@cadence.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/cdns3/host.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +--- a/drivers/usb/cdns3/host.c ++++ b/drivers/usb/cdns3/host.c +@@ -18,6 +18,11 @@ + #include "../host/xhci.h" + #include "../host/xhci-plat.h" + ++/* ++ * The XECP_PORT_CAP_REG and XECP_AUX_CTRL_REG1 exist only ++ * in Cadence USB3 dual-role controller, so it can't be used ++ * with Cadence CDNSP dual-role controller. ++ */ + #define XECP_PORT_CAP_REG 0x8000 + #define XECP_AUX_CTRL_REG1 0x8120 + +@@ -57,6 +62,8 @@ static const struct xhci_plat_priv xhci_ + .resume_quirk = xhci_cdns3_resume_quirk, + }; + ++static const struct xhci_plat_priv xhci_plat_cdnsp_xhci; ++ + static int __cdns_host_init(struct cdns *cdns) + { + struct platform_device *xhci; +@@ -81,8 +88,13 @@ static int __cdns_host_init(struct cdns + goto err1; + } + +- cdns->xhci_plat_data = kmemdup(&xhci_plat_cdns3_xhci, +- sizeof(struct xhci_plat_priv), GFP_KERNEL); ++ if (cdns->version < CDNSP_CONTROLLER_V2) ++ cdns->xhci_plat_data = kmemdup(&xhci_plat_cdns3_xhci, ++ sizeof(struct xhci_plat_priv), GFP_KERNEL); ++ else ++ cdns->xhci_plat_data = kmemdup(&xhci_plat_cdnsp_xhci, ++ sizeof(struct xhci_plat_priv), GFP_KERNEL); ++ + if (!cdns->xhci_plat_data) { + ret = -ENOMEM; + goto err1; diff --git a/queue-6.6/usb-cdnsp-fixed-issue-with-incorrect-detecting-cdnsp-family-controllers.patch b/queue-6.6/usb-cdnsp-fixed-issue-with-incorrect-detecting-cdnsp-family-controllers.patch new file mode 100644 index 00000000000..33a7b3e1287 --- /dev/null +++ b/queue-6.6/usb-cdnsp-fixed-issue-with-incorrect-detecting-cdnsp-family-controllers.patch @@ -0,0 +1,94 @@ +From 47625b018c6bc788bc10dd654c82696eb0a5ef11 Mon Sep 17 00:00:00 2001 +From: Pawel Laszczak +Date: Thu, 15 Feb 2024 13:16:09 +0100 +Subject: usb: cdnsp: fixed issue with incorrect detecting CDNSP family controllers + +From: Pawel Laszczak + +commit 47625b018c6bc788bc10dd654c82696eb0a5ef11 upstream. + +Cadence have several controllers from 0x000403xx family but current +driver suuport detecting only one with DID equal 0x0004034E. +It causes that if someone uses different CDNSP controller then driver +will use incorrect version and register space. +Patch fix this issue. + +cc: stable@vger.kernel.org +Fixes: 3d82904559f4 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver") +Signed-off-by: Pawel Laszczak +Link: https://lore.kernel.org/r/20240215121609.259772-1-pawell@cadence.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/cdns3/core.c | 1 - + drivers/usb/cdns3/drd.c | 13 +++++++++---- + drivers/usb/cdns3/drd.h | 6 +++++- + 3 files changed, 14 insertions(+), 6 deletions(-) + +--- a/drivers/usb/cdns3/core.c ++++ b/drivers/usb/cdns3/core.c +@@ -395,7 +395,6 @@ pm_put: + return ret; + } + +- + /** + * cdns_wakeup_irq - interrupt handler for wakeup events + * @irq: irq number for cdns3/cdnsp core device +--- a/drivers/usb/cdns3/drd.c ++++ b/drivers/usb/cdns3/drd.c +@@ -156,7 +156,8 @@ bool cdns_is_device(struct cdns *cdns) + */ + static void cdns_otg_disable_irq(struct cdns *cdns) + { +- writel(0, &cdns->otg_irq_regs->ien); ++ if (cdns->version) ++ writel(0, &cdns->otg_irq_regs->ien); + } + + /** +@@ -422,15 +423,20 @@ int cdns_drd_init(struct cdns *cdns) + + cdns->otg_regs = (void __iomem *)&cdns->otg_v1_regs->cmd; + +- if (readl(&cdns->otg_cdnsp_regs->did) == OTG_CDNSP_DID) { ++ state = readl(&cdns->otg_cdnsp_regs->did); ++ ++ if (OTG_CDNSP_CHECK_DID(state)) { + cdns->otg_irq_regs = (struct cdns_otg_irq_regs __iomem *) + &cdns->otg_cdnsp_regs->ien; + cdns->version = CDNSP_CONTROLLER_V2; +- } else { ++ } else if (OTG_CDNS3_CHECK_DID(state)) { + cdns->otg_irq_regs = (struct cdns_otg_irq_regs __iomem *) + &cdns->otg_v1_regs->ien; + writel(1, &cdns->otg_v1_regs->simulate); + cdns->version = CDNS3_CONTROLLER_V1; ++ } else { ++ dev_err(cdns->dev, "not supporte DID=0x%08x\n", state); ++ return -EINVAL; + } + + dev_dbg(cdns->dev, "DRD version v1 (ID: %08x, rev: %08x)\n", +@@ -483,7 +489,6 @@ int cdns_drd_exit(struct cdns *cdns) + return 0; + } + +- + /* Indicate the cdns3 core was power lost before */ + bool cdns_power_is_lost(struct cdns *cdns) + { +--- a/drivers/usb/cdns3/drd.h ++++ b/drivers/usb/cdns3/drd.h +@@ -79,7 +79,11 @@ struct cdnsp_otg_regs { + __le32 susp_timing_ctrl; + }; + +-#define OTG_CDNSP_DID 0x0004034E ++/* CDNSP driver supports 0x000403xx Cadence USB controller family. */ ++#define OTG_CDNSP_CHECK_DID(did) (((did) & GENMASK(31, 8)) == 0x00040300) ++ ++/* CDNS3 driver supports 0x000402xx Cadence USB controller family. */ ++#define OTG_CDNS3_CHECK_DID(did) (((did) & GENMASK(31, 8)) == 0x00040200) + + /* + * Common registers interface for both CDNS3 and CDNSP version of DRD. diff --git a/queue-6.6/usb-dwc3-gadget-don-t-disconnect-if-not-started.patch b/queue-6.6/usb-dwc3-gadget-don-t-disconnect-if-not-started.patch new file mode 100644 index 00000000000..8b9ec48d240 --- /dev/null +++ b/queue-6.6/usb-dwc3-gadget-don-t-disconnect-if-not-started.patch @@ -0,0 +1,39 @@ +From b191a18cb5c47109ca696370a74a5062a70adfd0 Mon Sep 17 00:00:00 2001 +From: Thinh Nguyen +Date: Fri, 16 Feb 2024 00:41:02 +0000 +Subject: usb: dwc3: gadget: Don't disconnect if not started + +From: Thinh Nguyen + +commit b191a18cb5c47109ca696370a74a5062a70adfd0 upstream. + +Don't go through soft-disconnection sequence if the controller hasn't +started. Otherwise, there will be timeout and warning reports from the +soft-disconnection flow. + +Cc: stable@vger.kernel.org +Fixes: 61a348857e86 ("usb: dwc3: gadget: Fix NULL pointer dereference in dwc3_gadget_suspend") +Reported-by: Marek Szyprowski +Closes: https://lore.kernel.org/linux-usb/20240215233536.7yejlj3zzkl23vjd@synopsys.com/T/#mb0661cd5f9272602af390c18392b9a36da4f96e6 +Tested-by: Marek Szyprowski +Signed-off-by: Thinh Nguyen +Link: https://lore.kernel.org/r/e3be9b929934e0680a6f4b8f6eb11b18ae9c7e07.1708043922.git.Thinh.Nguyen@synopsys.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc3/gadget.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -2650,6 +2650,11 @@ static int dwc3_gadget_soft_disconnect(s + int ret; + + spin_lock_irqsave(&dwc->lock, flags); ++ if (!dwc->pullups_connected) { ++ spin_unlock_irqrestore(&dwc->lock, flags); ++ return 0; ++ } ++ + dwc->connected = false; + + /* diff --git a/queue-6.6/usb-gadget-ncm-avoid-dropping-datagrams-of-properly-parsed-ntbs.patch b/queue-6.6/usb-gadget-ncm-avoid-dropping-datagrams-of-properly-parsed-ntbs.patch new file mode 100644 index 00000000000..5053c5d6bc7 --- /dev/null +++ b/queue-6.6/usb-gadget-ncm-avoid-dropping-datagrams-of-properly-parsed-ntbs.patch @@ -0,0 +1,88 @@ +From 76c51146820c5dac629f21deafab0a7039bc3ccd Mon Sep 17 00:00:00 2001 +From: Krishna Kurapati +Date: Mon, 5 Feb 2024 13:16:50 +0530 +Subject: usb: gadget: ncm: Avoid dropping datagrams of properly parsed NTBs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Krishna Kurapati + +commit 76c51146820c5dac629f21deafab0a7039bc3ccd upstream. + +It is observed sometimes when tethering is used over NCM with Windows 11 +as host, at some instances, the gadget_giveback has one byte appended at +the end of a proper NTB. When the NTB is parsed, unwrap call looks for +any leftover bytes in SKB provided by u_ether and if there are any pending +bytes, it treats them as a separate NTB and parses it. But in case the +second NTB (as per unwrap call) is faulty/corrupt, all the datagrams that +were parsed properly in the first NTB and saved in rx_list are dropped. + +Adding a few custom traces showed the following: +[002] d..1 7828.532866: dwc3_gadget_giveback: ep1out: +req 000000003868811a length 1025/16384 zsI ==> 0 +[002] d..1 7828.532867: ncm_unwrap_ntb: K: ncm_unwrap_ntb toprocess: 1025 +[002] d..1 7828.532867: ncm_unwrap_ntb: K: ncm_unwrap_ntb nth: 1751999342 +[002] d..1 7828.532868: ncm_unwrap_ntb: K: ncm_unwrap_ntb seq: 0xce67 +[002] d..1 7828.532868: ncm_unwrap_ntb: K: ncm_unwrap_ntb blk_len: 0x400 +[002] d..1 7828.532868: ncm_unwrap_ntb: K: ncm_unwrap_ntb ndp_len: 0x10 +[002] d..1 7828.532869: ncm_unwrap_ntb: K: Parsed NTB with 1 frames + +In this case, the giveback is of 1025 bytes and block length is 1024. +The rest 1 byte (which is 0x00) won't be parsed resulting in drop of +all datagrams in rx_list. + +Same is case with packets of size 2048: +[002] d..1 7828.557948: dwc3_gadget_giveback: ep1out: +req 0000000011dfd96e length 2049/16384 zsI ==> 0 +[002] d..1 7828.557949: ncm_unwrap_ntb: K: ncm_unwrap_ntb nth: 1751999342 +[002] d..1 7828.557950: ncm_unwrap_ntb: K: ncm_unwrap_ntb blk_len: 0x800 + +Lecroy shows one byte coming in extra confirming that the byte is coming +in from PC: + + Transfer 2959 - Bytes Transferred(1025) Timestamp((18.524 843 590) + - Transaction 8391 - Data(1025 bytes) Timestamp(18.524 843 590) + --- Packet 4063861 + Data(1024 bytes) + Duration(2.117us) Idle(14.700ns) Timestamp(18.524 843 590) + --- Packet 4063863 + Data(1 byte) + Duration(66.160ns) Time(282.000ns) Timestamp(18.524 845 722) + +According to Windows driver, no ZLP is needed if wBlockLength is non-zero, +because the non-zero wBlockLength has already told the function side the +size of transfer to be expected. However, there are in-market NCM devices +that rely on ZLP as long as the wBlockLength is multiple of wMaxPacketSize. +To deal with such devices, it pads an extra 0 at end so the transfer is no +longer multiple of wMaxPacketSize. + +Cc: +Fixes: 9f6ce4240a2b ("usb: gadget: f_ncm.c added") +Signed-off-by: Krishna Kurapati +Reviewed-by: Maciej Żenczykowski +Link: https://lore.kernel.org/r/20240205074650.200304-1-quic_kriskura@quicinc.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_ncm.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/function/f_ncm.c ++++ b/drivers/usb/gadget/function/f_ncm.c +@@ -1325,7 +1325,15 @@ parse_ntb: + "Parsed NTB with %d frames\n", dgram_counter); + + to_process -= block_len; +- if (to_process != 0) { ++ ++ /* ++ * Windows NCM driver avoids USB ZLPs by adding a 1-byte ++ * zero pad as needed. ++ */ ++ if (to_process == 1 && ++ (*(unsigned char *)(ntb_ptr + block_len) == 0x00)) { ++ to_process--; ++ } else if (to_process > 0) { + ntb_ptr = (unsigned char *)(ntb_ptr + block_len); + goto parse_ntb; + } diff --git a/queue-6.6/usb-gadget-omap_udc-fix-usb-gadget-regression-on-palm-te.patch b/queue-6.6/usb-gadget-omap_udc-fix-usb-gadget-regression-on-palm-te.patch new file mode 100644 index 00000000000..407811cfa36 --- /dev/null +++ b/queue-6.6/usb-gadget-omap_udc-fix-usb-gadget-regression-on-palm-te.patch @@ -0,0 +1,37 @@ +From 858a74cb512833e276d96a72acb560ce8c138bec Mon Sep 17 00:00:00 2001 +From: Aaro Koskinen +Date: Sat, 17 Feb 2024 21:20:42 +0200 +Subject: usb: gadget: omap_udc: fix USB gadget regression on Palm TE + +From: Aaro Koskinen + +commit 858a74cb512833e276d96a72acb560ce8c138bec upstream. + +When upgrading from 6.1 LTS to 6.6 LTS, I noticed the ethernet gadget +stopped working on Palm TE. + +Commit 8825acd7cc8a ("ARM: omap1: remove dead code") deleted Palm TE from +machine_without_vbus_sense(), although the board is still used. Fix that. + +Fixes: 8825acd7cc8a ("ARM: omap1: remove dead code") +Cc: stable +Signed-off-by: Aaro Koskinen +Acked-by: Arnd Bergmann +Link: https://lore.kernel.org/r/20240217192042.GA372205@darkstar.musicnaut.iki.fi +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/udc/omap_udc.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/udc/omap_udc.c ++++ b/drivers/usb/gadget/udc/omap_udc.c +@@ -2036,7 +2036,8 @@ static irqreturn_t omap_udc_iso_irq(int + + static inline int machine_without_vbus_sense(void) + { +- return machine_is_omap_osk() || machine_is_sx1(); ++ return machine_is_omap_osk() || machine_is_omap_palmte() || ++ machine_is_sx1(); + } + + static int omap_udc_start(struct usb_gadget *g, diff --git a/queue-6.6/usb-roles-don-t-get-set_role-when-usb_role_switch-is-unregistered.patch b/queue-6.6/usb-roles-don-t-get-set_role-when-usb_role_switch-is-unregistered.patch new file mode 100644 index 00000000000..e80c98b7859 --- /dev/null +++ b/queue-6.6/usb-roles-don-t-get-set_role-when-usb_role_switch-is-unregistered.patch @@ -0,0 +1,76 @@ +From b787a3e781759026a6212736ef8e52cf83d1821a Mon Sep 17 00:00:00 2001 +From: Xu Yang +Date: Mon, 29 Jan 2024 17:37:39 +0800 +Subject: usb: roles: don't get/set_role() when usb_role_switch is unregistered + +From: Xu Yang + +commit b787a3e781759026a6212736ef8e52cf83d1821a upstream. + +There is a possibility that usb_role_switch device is unregistered before +the user put usb_role_switch. In this case, the user may still want to +get/set_role() since the user can't sense the changes of usb_role_switch. + +This will add a flag to show if usb_role_switch is already registered and +avoid unwanted behaviors. + +Fixes: fde0aa6c175a ("usb: common: Small class for USB role switches") +cc: stable@vger.kernel.org +Signed-off-by: Xu Yang +Acked-by: Heikki Krogerus +Link: https://lore.kernel.org/r/20240129093739.2371530-2-xu.yang_2@nxp.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/roles/class.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +--- a/drivers/usb/roles/class.c ++++ b/drivers/usb/roles/class.c +@@ -23,6 +23,7 @@ struct usb_role_switch { + struct mutex lock; /* device lock*/ + struct module *module; /* the module this device depends on */ + enum usb_role role; ++ bool registered; + + /* From descriptor */ + struct device *usb2_port; +@@ -49,6 +50,9 @@ int usb_role_switch_set_role(struct usb_ + if (IS_ERR_OR_NULL(sw)) + return 0; + ++ if (!sw->registered) ++ return -EOPNOTSUPP; ++ + mutex_lock(&sw->lock); + + ret = sw->set(sw, role); +@@ -74,7 +78,7 @@ enum usb_role usb_role_switch_get_role(s + { + enum usb_role role; + +- if (IS_ERR_OR_NULL(sw)) ++ if (IS_ERR_OR_NULL(sw) || !sw->registered) + return USB_ROLE_NONE; + + mutex_lock(&sw->lock); +@@ -357,6 +361,8 @@ usb_role_switch_register(struct device * + return ERR_PTR(ret); + } + ++ sw->registered = true; ++ + /* TODO: Symlinks for the host port and the device controller. */ + + return sw; +@@ -371,8 +377,10 @@ EXPORT_SYMBOL_GPL(usb_role_switch_regist + */ + void usb_role_switch_unregister(struct usb_role_switch *sw) + { +- if (!IS_ERR_OR_NULL(sw)) ++ if (!IS_ERR_OR_NULL(sw)) { ++ sw->registered = false; + device_unregister(&sw->dev); ++ } + } + EXPORT_SYMBOL_GPL(usb_role_switch_unregister); + diff --git a/queue-6.6/usb-roles-fix-null-pointer-issue-when-put-module-s-reference.patch b/queue-6.6/usb-roles-fix-null-pointer-issue-when-put-module-s-reference.patch new file mode 100644 index 00000000000..cc9225404dc --- /dev/null +++ b/queue-6.6/usb-roles-fix-null-pointer-issue-when-put-module-s-reference.patch @@ -0,0 +1,96 @@ +From 1c9be13846c0b2abc2480602f8ef421360e1ad9e Mon Sep 17 00:00:00 2001 +From: Xu Yang +Date: Mon, 29 Jan 2024 17:37:38 +0800 +Subject: usb: roles: fix NULL pointer issue when put module's reference + +From: Xu Yang + +commit 1c9be13846c0b2abc2480602f8ef421360e1ad9e upstream. + +In current design, usb role class driver will get usb_role_switch parent's +module reference after the user get usb_role_switch device and put the +reference after the user put the usb_role_switch device. However, the +parent device of usb_role_switch may be removed before the user put the +usb_role_switch. If so, then, NULL pointer issue will be met when the user +put the parent module's reference. + +This will save the module pointer in structure of usb_role_switch. Then, +we don't need to find module by iterating long relations. + +Fixes: 5c54fcac9a9d ("usb: roles: Take care of driver module reference counting") +cc: stable@vger.kernel.org +Signed-off-by: Xu Yang +Acked-by: Heikki Krogerus +Link: https://lore.kernel.org/r/20240129093739.2371530-1-xu.yang_2@nxp.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/roles/class.c | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +--- a/drivers/usb/roles/class.c ++++ b/drivers/usb/roles/class.c +@@ -21,6 +21,7 @@ static const struct class role_class = { + struct usb_role_switch { + struct device dev; + struct mutex lock; /* device lock*/ ++ struct module *module; /* the module this device depends on */ + enum usb_role role; + + /* From descriptor */ +@@ -135,7 +136,7 @@ struct usb_role_switch *usb_role_switch_ + usb_role_switch_match); + + if (!IS_ERR_OR_NULL(sw)) +- WARN_ON(!try_module_get(sw->dev.parent->driver->owner)); ++ WARN_ON(!try_module_get(sw->module)); + + return sw; + } +@@ -157,7 +158,7 @@ struct usb_role_switch *fwnode_usb_role_ + sw = fwnode_connection_find_match(fwnode, "usb-role-switch", + NULL, usb_role_switch_match); + if (!IS_ERR_OR_NULL(sw)) +- WARN_ON(!try_module_get(sw->dev.parent->driver->owner)); ++ WARN_ON(!try_module_get(sw->module)); + + return sw; + } +@@ -172,7 +173,7 @@ EXPORT_SYMBOL_GPL(fwnode_usb_role_switch + void usb_role_switch_put(struct usb_role_switch *sw) + { + if (!IS_ERR_OR_NULL(sw)) { +- module_put(sw->dev.parent->driver->owner); ++ module_put(sw->module); + put_device(&sw->dev); + } + } +@@ -189,15 +190,18 @@ struct usb_role_switch * + usb_role_switch_find_by_fwnode(const struct fwnode_handle *fwnode) + { + struct device *dev; ++ struct usb_role_switch *sw = NULL; + + if (!fwnode) + return NULL; + + dev = class_find_device_by_fwnode(&role_class, fwnode); +- if (dev) +- WARN_ON(!try_module_get(dev->parent->driver->owner)); ++ if (dev) { ++ sw = to_role_switch(dev); ++ WARN_ON(!try_module_get(sw->module)); ++ } + +- return dev ? to_role_switch(dev) : NULL; ++ return sw; + } + EXPORT_SYMBOL_GPL(usb_role_switch_find_by_fwnode); + +@@ -338,6 +342,7 @@ usb_role_switch_register(struct device * + sw->set = desc->set; + sw->get = desc->get; + ++ sw->module = parent->driver->owner; + sw->dev.parent = parent; + sw->dev.fwnode = desc->fwnode; + sw->dev.class = &role_class;