From 4c722b50606a3f569bb97233f8ff8b14ca035858 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 21 Sep 2025 19:19:20 +0200 Subject: [PATCH] 6.6-stable patches added patches: iommu-amd-pgtbl-fix-possible-race-while-increase-page-table-level.patch mptcp-pm-nl-announce-deny-join-id0-flag.patch phy-ti-omap-usb2-fix-device-leak-at-unbind.patch phy-use-device_get_match_data.patch selftests-mptcp-userspace-pm-validate-deny-join-id0-flag.patch xhci-dbc-decouple-endpoint-allocation-from-initialization.patch xhci-dbc-fix-full-dbc-transfer-ring-after-several-reconnects.patch --- ...race-while-increase-page-table-level.patch | 145 ++++++++ ...cp-pm-nl-announce-deny-join-id0-flag.patch | 109 ++++++ ...-omap-usb2-fix-device-leak-at-unbind.patch | 63 ++++ queue-6.6/phy-use-device_get_match_data.patch | 321 ++++++++++++++++++ ...space-pm-validate-deny-join-id0-flag.patch | 100 ++++++ queue-6.6/series | 7 + ...point-allocation-from-initialization.patch | 140 ++++++++ ...ansfer-ring-after-several-reconnects.patch | 91 +++++ 8 files changed, 976 insertions(+) create mode 100644 queue-6.6/iommu-amd-pgtbl-fix-possible-race-while-increase-page-table-level.patch create mode 100644 queue-6.6/mptcp-pm-nl-announce-deny-join-id0-flag.patch create mode 100644 queue-6.6/phy-ti-omap-usb2-fix-device-leak-at-unbind.patch create mode 100644 queue-6.6/phy-use-device_get_match_data.patch create mode 100644 queue-6.6/selftests-mptcp-userspace-pm-validate-deny-join-id0-flag.patch create mode 100644 queue-6.6/xhci-dbc-decouple-endpoint-allocation-from-initialization.patch create mode 100644 queue-6.6/xhci-dbc-fix-full-dbc-transfer-ring-after-several-reconnects.patch diff --git a/queue-6.6/iommu-amd-pgtbl-fix-possible-race-while-increase-page-table-level.patch b/queue-6.6/iommu-amd-pgtbl-fix-possible-race-while-increase-page-table-level.patch new file mode 100644 index 0000000000..94c68bf4d5 --- /dev/null +++ b/queue-6.6/iommu-amd-pgtbl-fix-possible-race-while-increase-page-table-level.patch @@ -0,0 +1,145 @@ +From stable+bounces-180817-greg=kroah.com@vger.kernel.org Sun Sep 21 17:39:25 2025 +From: Sasha Levin +Date: Sun, 21 Sep 2025 11:39:16 -0400 +Subject: iommu/amd/pgtbl: Fix possible race while increase page table level +To: stable@vger.kernel.org +Cc: Vasant Hegde , Alejandro Jimenez , Joao Martins , Suravee Suthikulpanit , Joerg Roedel , Sasha Levin +Message-ID: <20250921153916.2944533-1-sashal@kernel.org> + +From: Vasant Hegde + +[ Upstream commit 1e56310b40fd2e7e0b9493da9ff488af145bdd0c ] + +The AMD IOMMU host page table implementation supports dynamic page table levels +(up to 6 levels), starting with a 3-level configuration that expands based on +IOVA address. The kernel maintains a root pointer and current page table level +to enable proper page table walks in alloc_pte()/fetch_pte() operations. + +The IOMMU IOVA allocator initially starts with 32-bit address and onces its +exhuasted it switches to 64-bit address (max address is determined based +on IOMMU and device DMA capability). To support larger IOVA, AMD IOMMU +driver increases page table level. + +But in unmap path (iommu_v1_unmap_pages()), fetch_pte() reads +pgtable->[root/mode] without lock. So its possible that in exteme corner case, +when increase_address_space() is updating pgtable->[root/mode], fetch_pte() +reads wrong page table level (pgtable->mode). It does compare the value with +level encoded in page table and returns NULL. This will result is +iommu_unmap ops to fail and upper layer may retry/log WARN_ON. + +CPU 0 CPU 1 +------ ------ +map pages unmap pages +alloc_pte() -> increase_address_space() iommu_v1_unmap_pages() -> fetch_pte() + pgtable->root = pte (new root value) + READ pgtable->[mode/root] + Reads new root, old mode + Updates mode (pgtable->mode += 1) + +Since Page table level updates are infrequent and already synchronized with a +spinlock, implement seqcount to enable lock-free read operations on the read path. + +Fixes: 754265bcab7 ("iommu/amd: Fix race in increase_address_space()") +Reported-by: Alejandro Jimenez +Cc: stable@vger.kernel.org +Cc: Joao Martins +Cc: Suravee Suthikulpanit +Signed-off-by: Vasant Hegde +Signed-off-by: Joerg Roedel +[ Adapted pgtable->mode and pgtable->root to use domain->iop.mode and domain->iop.root ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iommu/amd/amd_iommu_types.h | 1 + + drivers/iommu/amd/io_pgtable.c | 26 ++++++++++++++++++++++---- + 2 files changed, 23 insertions(+), 4 deletions(-) + +--- a/drivers/iommu/amd/amd_iommu_types.h ++++ b/drivers/iommu/amd/amd_iommu_types.h +@@ -540,6 +540,7 @@ struct amd_irte_ops; + container_of((x), struct amd_io_pgtable, pgtbl_cfg) + + struct amd_io_pgtable { ++ seqcount_t seqcount; /* Protects root/mode update */ + struct io_pgtable_cfg pgtbl_cfg; + struct io_pgtable iop; + int mode; +--- a/drivers/iommu/amd/io_pgtable.c ++++ b/drivers/iommu/amd/io_pgtable.c +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + + #include + +@@ -171,8 +172,11 @@ static bool increase_address_space(struc + + *pte = PM_LEVEL_PDE(domain->iop.mode, iommu_virt_to_phys(domain->iop.root)); + ++ write_seqcount_begin(&domain->iop.seqcount); + domain->iop.root = pte; + domain->iop.mode += 1; ++ write_seqcount_end(&domain->iop.seqcount); ++ + amd_iommu_update_and_flush_device_table(domain); + amd_iommu_domain_flush_complete(domain); + +@@ -199,6 +203,7 @@ static u64 *alloc_pte(struct protection_ + gfp_t gfp, + bool *updated) + { ++ unsigned int seqcount; + int level, end_lvl; + u64 *pte, *page; + +@@ -214,8 +219,14 @@ static u64 *alloc_pte(struct protection_ + } + + +- level = domain->iop.mode - 1; +- pte = &domain->iop.root[PM_LEVEL_INDEX(level, address)]; ++ do { ++ seqcount = read_seqcount_begin(&domain->iop.seqcount); ++ ++ level = domain->iop.mode - 1; ++ pte = &domain->iop.root[PM_LEVEL_INDEX(level, address)]; ++ } while (read_seqcount_retry(&domain->iop.seqcount, seqcount)); ++ ++ + address = PAGE_SIZE_ALIGN(address, page_size); + end_lvl = PAGE_SIZE_LEVEL(page_size); + +@@ -292,6 +303,7 @@ static u64 *fetch_pte(struct amd_io_pgta + unsigned long *page_size) + { + int level; ++ unsigned int seqcount; + u64 *pte; + + *page_size = 0; +@@ -299,8 +311,12 @@ static u64 *fetch_pte(struct amd_io_pgta + if (address > PM_LEVEL_SIZE(pgtable->mode)) + return NULL; + +- level = pgtable->mode - 1; +- pte = &pgtable->root[PM_LEVEL_INDEX(level, address)]; ++ do { ++ seqcount = read_seqcount_begin(&pgtable->seqcount); ++ level = pgtable->mode - 1; ++ pte = &pgtable->root[PM_LEVEL_INDEX(level, address)]; ++ } while (read_seqcount_retry(&pgtable->seqcount, seqcount)); ++ + *page_size = PTE_LEVEL_PAGE_SIZE(level); + + while (level > 0) { +@@ -524,6 +540,8 @@ static struct io_pgtable *v1_alloc_pgtab + cfg->oas = IOMMU_OUT_ADDR_BIT_SIZE, + cfg->tlb = &v1_flush_ops; + ++ seqcount_init(&pgtable->seqcount); ++ + pgtable->iop.ops.map_pages = iommu_v1_map_pages; + pgtable->iop.ops.unmap_pages = iommu_v1_unmap_pages; + pgtable->iop.ops.iova_to_phys = iommu_v1_iova_to_phys; diff --git a/queue-6.6/mptcp-pm-nl-announce-deny-join-id0-flag.patch b/queue-6.6/mptcp-pm-nl-announce-deny-join-id0-flag.patch new file mode 100644 index 0000000000..c71ecdf6ae --- /dev/null +++ b/queue-6.6/mptcp-pm-nl-announce-deny-join-id0-flag.patch @@ -0,0 +1,109 @@ +From matttbe@kernel.org Sat Sep 20 00:38:37 2025 +From: "Matthieu Baerts (NGI0)" +Date: Sat, 20 Sep 2025 00:38:21 +0200 +Subject: mptcp: pm: nl: announce deny-join-id0 flag +To: mptcp@lists.linux.dev, stable@vger.kernel.org, gregkh@linuxfoundation.org +Cc: "Matthieu Baerts (NGI0)" , sashal@kernel.org, Marek Majkowski , Mat Martineau , Jakub Kicinski +Message-ID: <20250919223819.3679521-5-matttbe@kernel.org> + +From: "Matthieu Baerts (NGI0)" + +commit 2293c57484ae64c9a3c847c8807db8c26a3a4d41 upstream. + +During the connection establishment, a peer can tell the other one that +it cannot establish new subflows to the initial IP address and port by +setting the 'C' flag [1]. Doing so makes sense when the sender is behind +a strict NAT, operating behind a legacy Layer 4 load balancer, or using +anycast IP address for example. + +When this 'C' flag is set, the path-managers must then not try to +establish new subflows to the other peer's initial IP address and port. +The in-kernel PM has access to this info, but the userspace PM didn't. + +The RFC8684 [1] is strict about that: + + (...) therefore the receiver MUST NOT try to open any additional + subflows toward this address and port. + +So it is important to tell the userspace about that as it is responsible +for the respect of this flag. + +When a new connection is created and established, the Netlink events +now contain the existing but not currently used 'flags' attribute. When +MPTCP_PM_EV_FLAG_DENY_JOIN_ID0 is set, it means no other subflows +to the initial IP address and port -- info that are also part of the +event -- can be established. + +Link: https://datatracker.ietf.org/doc/html/rfc8684#section-3.1-20.6 [1] +Fixes: 702c2f646d42 ("mptcp: netlink: allow userspace-driven subflow establishment") +Reported-by: Marek Majkowski +Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/532 +Reviewed-by: Mat Martineau +Signed-off-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20250912-net-mptcp-pm-uspace-deny_join_id0-v1-2-40171884ade8@kernel.org +Signed-off-by: Jakub Kicinski +[ Conflicts in mptcp_pm.yaml, and mptcp_pm.h, because these files have + been added later by commit bc8aeb2045e2 ("Documentation: netlink: add + a YAML spec for mptcp"), and commit 9d1ed17f93ce ("uapi: mptcp: use + header file generated from YAML spec"), which are not in this version. + Applying the same modifications, but only in mptcp.h. + Conflict in pm_netlink.c, because of a difference in the context, + introduced by commit b9f4554356f6 ("mptcp: annotate lockless access + for token"), which is not in this version. ] +Signed-off-by: Matthieu Baerts (NGI0) +Signed-off-by: Greg Kroah-Hartman +--- + include/uapi/linux/mptcp.h | 6 ++++-- + net/mptcp/pm_netlink.c | 7 +++++++ + 2 files changed, 11 insertions(+), 2 deletions(-) + +--- a/include/uapi/linux/mptcp.h ++++ b/include/uapi/linux/mptcp.h +@@ -81,6 +81,8 @@ enum { + + #define MPTCP_PM_ADDR_ATTR_MAX (__MPTCP_PM_ADDR_ATTR_MAX - 1) + ++#define MPTCP_PM_EV_FLAG_DENY_JOIN_ID0 _BITUL(0) ++ + #define MPTCP_PM_ADDR_FLAG_SIGNAL (1 << 0) + #define MPTCP_PM_ADDR_FLAG_SUBFLOW (1 << 1) + #define MPTCP_PM_ADDR_FLAG_BACKUP (1 << 2) +@@ -132,13 +134,13 @@ struct mptcp_info { + + /* + * MPTCP_EVENT_CREATED: token, family, saddr4 | saddr6, daddr4 | daddr6, +- * sport, dport ++ * sport, dport, server-side, [flags] + * A new MPTCP connection has been created. It is the good time to allocate + * memory and send ADD_ADDR if needed. Depending on the traffic-patterns + * it can take a long time until the MPTCP_EVENT_ESTABLISHED is sent. + * + * MPTCP_EVENT_ESTABLISHED: token, family, saddr4 | saddr6, daddr4 | daddr6, +- * sport, dport ++ * sport, dport, server-side, [flags] + * A MPTCP connection is established (can start new subflows). + * + * MPTCP_EVENT_CLOSED: token +--- a/net/mptcp/pm_netlink.c ++++ b/net/mptcp/pm_netlink.c +@@ -2252,6 +2252,7 @@ static int mptcp_event_created(struct sk + const struct sock *ssk) + { + int err = nla_put_u32(skb, MPTCP_ATTR_TOKEN, msk->token); ++ u16 flags = 0; + + if (err) + return err; +@@ -2259,6 +2260,12 @@ static int mptcp_event_created(struct sk + if (nla_put_u8(skb, MPTCP_ATTR_SERVER_SIDE, READ_ONCE(msk->pm.server_side))) + return -EMSGSIZE; + ++ if (READ_ONCE(msk->pm.remote_deny_join_id0)) ++ flags |= MPTCP_PM_EV_FLAG_DENY_JOIN_ID0; ++ ++ if (flags && nla_put_u16(skb, MPTCP_ATTR_FLAGS, flags)) ++ return -EMSGSIZE; ++ + return mptcp_event_add_subflow(skb, ssk); + } + diff --git a/queue-6.6/phy-ti-omap-usb2-fix-device-leak-at-unbind.patch b/queue-6.6/phy-ti-omap-usb2-fix-device-leak-at-unbind.patch new file mode 100644 index 0000000000..d342d3eeb0 --- /dev/null +++ b/queue-6.6/phy-ti-omap-usb2-fix-device-leak-at-unbind.patch @@ -0,0 +1,63 @@ +From stable+bounces-180370-greg=kroah.com@vger.kernel.org Wed Sep 17 15:25:36 2025 +From: Sasha Levin +Date: Wed, 17 Sep 2025 09:18:07 -0400 +Subject: phy: ti: omap-usb2: fix device leak at unbind +To: stable@vger.kernel.org +Cc: Johan Hovold , Roger Quadros , Vinod Koul , Sasha Levin +Message-ID: <20250917131807.543316-2-sashal@kernel.org> + +From: Johan Hovold + +[ Upstream commit 64961557efa1b98f375c0579779e7eeda1a02c42 ] + +Make sure to drop the reference to the control device taken by +of_find_device_by_node() during probe when the driver is unbound. + +Fixes: 478b6c7436c2 ("usb: phy: omap-usb2: Don't use omap_get_control_dev()") +Cc: stable@vger.kernel.org # 3.13 +Cc: Roger Quadros +Signed-off-by: Johan Hovold +Link: https://lore.kernel.org/r/20250724131206.2211-3-johan@kernel.org +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/phy/ti/phy-omap-usb2.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/drivers/phy/ti/phy-omap-usb2.c ++++ b/drivers/phy/ti/phy-omap-usb2.c +@@ -363,6 +363,13 @@ static void omap_usb2_init_errata(struct + phy->flags |= OMAP_USB2_DISABLE_CHRG_DET; + } + ++static void omap_usb2_put_device(void *_dev) ++{ ++ struct device *dev = _dev; ++ ++ put_device(dev); ++} ++ + static int omap_usb2_probe(struct platform_device *pdev) + { + struct omap_usb *phy; +@@ -373,6 +380,7 @@ static int omap_usb2_probe(struct platfo + struct device_node *control_node; + struct platform_device *control_pdev; + const struct usb_phy_data *phy_data; ++ int ret; + + phy_data = device_get_match_data(&pdev->dev); + if (!phy_data) +@@ -423,6 +431,11 @@ static int omap_usb2_probe(struct platfo + return -EINVAL; + } + phy->control_dev = &control_pdev->dev; ++ ++ ret = devm_add_action_or_reset(&pdev->dev, omap_usb2_put_device, ++ phy->control_dev); ++ if (ret) ++ return ret; + } else { + if (of_property_read_u32_index(node, + "syscon-phy-power", 1, diff --git a/queue-6.6/phy-use-device_get_match_data.patch b/queue-6.6/phy-use-device_get_match_data.patch new file mode 100644 index 0000000000..f969bb263a --- /dev/null +++ b/queue-6.6/phy-use-device_get_match_data.patch @@ -0,0 +1,321 @@ +From stable+bounces-180369-greg=kroah.com@vger.kernel.org Wed Sep 17 16:58:50 2025 +From: Sasha Levin +Date: Wed, 17 Sep 2025 09:18:06 -0400 +Subject: phy: Use device_get_match_data() +To: stable@vger.kernel.org +Cc: Rob Herring , Heiko Stuebner , Vinod Koul , Sasha Levin +Message-ID: <20250917131807.543316-1-sashal@kernel.org> + +From: Rob Herring + +[ Upstream commit 21bf6fc47a1e45031ba8a7084343b7cfd09ed1d3 ] + +Use preferred device_get_match_data() instead of of_match_device() to +get the driver match data. With this, adjust the includes to explicitly +include the correct headers. + +Signed-off-by: Rob Herring +Reviewed-by: Heiko Stuebner +Link: https://lore.kernel.org/r/20231009172923.2457844-15-robh@kernel.org +Signed-off-by: Vinod Koul +Stable-dep-of: 64961557efa1 ("phy: ti: omap-usb2: fix device leak at unbind") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/phy/broadcom/phy-bcm-ns-usb3.c | 9 +++------ + drivers/phy/marvell/phy-berlin-usb.c | 7 +++---- + drivers/phy/ralink/phy-ralink-usb.c | 10 +++------- + drivers/phy/rockchip/phy-rockchip-pcie.c | 11 ++++------- + drivers/phy/rockchip/phy-rockchip-usb.c | 10 +++------- + drivers/phy/ti/phy-omap-control.c | 9 ++------- + drivers/phy/ti/phy-omap-usb2.c | 11 ++++------- + drivers/phy/ti/phy-ti-pipe3.c | 14 ++++---------- + 8 files changed, 26 insertions(+), 55 deletions(-) + +--- a/drivers/phy/broadcom/phy-bcm-ns-usb3.c ++++ b/drivers/phy/broadcom/phy-bcm-ns-usb3.c +@@ -16,10 +16,11 @@ + #include + #include + #include ++#include + #include +-#include + #include + #include ++#include + #include + + #define BCM_NS_USB3_PHY_BASE_ADDR_REG 0x1f +@@ -189,7 +190,6 @@ static int bcm_ns_usb3_mdio_phy_write(st + static int bcm_ns_usb3_mdio_probe(struct mdio_device *mdiodev) + { + struct device *dev = &mdiodev->dev; +- const struct of_device_id *of_id; + struct phy_provider *phy_provider; + struct device_node *syscon_np; + struct bcm_ns_usb3 *usb3; +@@ -203,10 +203,7 @@ static int bcm_ns_usb3_mdio_probe(struct + usb3->dev = dev; + usb3->mdiodev = mdiodev; + +- of_id = of_match_device(bcm_ns_usb3_id_table, dev); +- if (!of_id) +- return -EINVAL; +- usb3->family = (uintptr_t)of_id->data; ++ usb3->family = (enum bcm_ns_family)device_get_match_data(dev); + + syscon_np = of_parse_phandle(dev->of_node, "usb3-dmp-syscon", 0); + err = of_address_to_resource(syscon_np, 0, &res); +--- a/drivers/phy/marvell/phy-berlin-usb.c ++++ b/drivers/phy/marvell/phy-berlin-usb.c +@@ -8,9 +8,10 @@ + + #include + #include +-#include ++#include + #include + #include ++#include + #include + + #define USB_PHY_PLL 0x04 +@@ -162,8 +163,6 @@ MODULE_DEVICE_TABLE(of, phy_berlin_usb_o + + static int phy_berlin_usb_probe(struct platform_device *pdev) + { +- const struct of_device_id *match = +- of_match_device(phy_berlin_usb_of_match, &pdev->dev); + struct phy_berlin_usb_priv *priv; + struct phy *phy; + struct phy_provider *phy_provider; +@@ -180,7 +179,7 @@ static int phy_berlin_usb_probe(struct p + if (IS_ERR(priv->rst_ctrl)) + return PTR_ERR(priv->rst_ctrl); + +- priv->pll_divider = *((u32 *)match->data); ++ priv->pll_divider = *((u32 *)device_get_match_data(&pdev->dev)); + + phy = devm_phy_create(&pdev->dev, NULL, &phy_berlin_usb_ops); + if (IS_ERR(phy)) { +--- a/drivers/phy/ralink/phy-ralink-usb.c ++++ b/drivers/phy/ralink/phy-ralink-usb.c +@@ -13,9 +13,10 @@ + #include + #include + #include +-#include ++#include + #include + #include ++#include + #include + #include + +@@ -171,18 +172,13 @@ static int ralink_usb_phy_probe(struct p + { + struct device *dev = &pdev->dev; + struct phy_provider *phy_provider; +- const struct of_device_id *match; + struct ralink_usb_phy *phy; + +- match = of_match_device(ralink_usb_phy_of_match, &pdev->dev); +- if (!match) +- return -ENODEV; +- + phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); + if (!phy) + return -ENOMEM; + +- phy->clk = (uintptr_t)match->data; ++ phy->clk = (uintptr_t)device_get_match_data(&pdev->dev); + phy->base = NULL; + + phy->sysctl = syscon_regmap_lookup_by_phandle(dev->of_node, "ralink,sysctl"); +--- a/drivers/phy/rockchip/phy-rockchip-pcie.c ++++ b/drivers/phy/rockchip/phy-rockchip-pcie.c +@@ -12,10 +12,9 @@ + #include + #include + #include +-#include +-#include + #include + #include ++#include + #include + #include + +@@ -62,7 +61,7 @@ struct rockchip_pcie_data { + }; + + struct rockchip_pcie_phy { +- struct rockchip_pcie_data *phy_data; ++ const struct rockchip_pcie_data *phy_data; + struct regmap *reg_base; + struct phy_pcie_instance { + struct phy *phy; +@@ -349,7 +348,6 @@ static int rockchip_pcie_phy_probe(struc + struct rockchip_pcie_phy *rk_phy; + struct phy_provider *phy_provider; + struct regmap *grf; +- const struct of_device_id *of_id; + int i; + u32 phy_num; + +@@ -363,11 +361,10 @@ static int rockchip_pcie_phy_probe(struc + if (!rk_phy) + return -ENOMEM; + +- of_id = of_match_device(rockchip_pcie_phy_dt_ids, &pdev->dev); +- if (!of_id) ++ rk_phy->phy_data = device_get_match_data(&pdev->dev); ++ if (!rk_phy->phy_data) + return -EINVAL; + +- rk_phy->phy_data = (struct rockchip_pcie_data *)of_id->data; + rk_phy->reg_base = grf; + + mutex_init(&rk_phy->pcie_mutex); +--- a/drivers/phy/rockchip/phy-rockchip-usb.c ++++ b/drivers/phy/rockchip/phy-rockchip-usb.c +@@ -13,10 +13,9 @@ + #include + #include + #include +-#include +-#include + #include + #include ++#include + #include + #include + #include +@@ -458,7 +457,6 @@ static int rockchip_usb_phy_probe(struct + struct device *dev = &pdev->dev; + struct rockchip_usb_phy_base *phy_base; + struct phy_provider *phy_provider; +- const struct of_device_id *match; + struct device_node *child; + int err; + +@@ -466,14 +464,12 @@ static int rockchip_usb_phy_probe(struct + if (!phy_base) + return -ENOMEM; + +- match = of_match_device(dev->driver->of_match_table, dev); +- if (!match || !match->data) { ++ phy_base->pdata = device_get_match_data(dev); ++ if (!phy_base->pdata) { + dev_err(dev, "missing phy data\n"); + return -EINVAL; + } + +- phy_base->pdata = match->data; +- + phy_base->dev = dev; + phy_base->reg_base = ERR_PTR(-ENODEV); + if (dev->parent && dev->parent->of_node) +--- a/drivers/phy/ti/phy-omap-control.c ++++ b/drivers/phy/ti/phy-omap-control.c +@@ -8,9 +8,9 @@ + + #include + #include ++#include + #include + #include +-#include + #include + #include + #include +@@ -268,20 +268,15 @@ MODULE_DEVICE_TABLE(of, omap_control_phy + + static int omap_control_phy_probe(struct platform_device *pdev) + { +- const struct of_device_id *of_id; + struct omap_control_phy *control_phy; + +- of_id = of_match_device(omap_control_phy_id_table, &pdev->dev); +- if (!of_id) +- return -EINVAL; +- + control_phy = devm_kzalloc(&pdev->dev, sizeof(*control_phy), + GFP_KERNEL); + if (!control_phy) + return -ENOMEM; + + control_phy->dev = &pdev->dev; +- control_phy->type = *(enum omap_control_phy_type *)of_id->data; ++ control_phy->type = *(enum omap_control_phy_type *)device_get_match_data(&pdev->dev); + + if (control_phy->type == OMAP_CTRL_TYPE_OTGHS) { + control_phy->otghs_control = +--- a/drivers/phy/ti/phy-omap-usb2.c ++++ b/drivers/phy/ti/phy-omap-usb2.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -371,16 +372,12 @@ static int omap_usb2_probe(struct platfo + struct device_node *node = pdev->dev.of_node; + struct device_node *control_node; + struct platform_device *control_pdev; +- const struct of_device_id *of_id; +- struct usb_phy_data *phy_data; ++ const struct usb_phy_data *phy_data; + +- of_id = of_match_device(omap_usb2_id_table, &pdev->dev); +- +- if (!of_id) ++ phy_data = device_get_match_data(&pdev->dev); ++ if (!phy_data) + return -EINVAL; + +- phy_data = (struct usb_phy_data *)of_id->data; +- + phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); + if (!phy) + return -ENOMEM; +--- a/drivers/phy/ti/phy-ti-pipe3.c ++++ b/drivers/phy/ti/phy-ti-pipe3.c +@@ -8,6 +8,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -791,23 +792,16 @@ static int ti_pipe3_probe(struct platfor + struct phy_provider *phy_provider; + struct device *dev = &pdev->dev; + int ret; +- const struct of_device_id *match; +- struct pipe3_data *data; ++ const struct pipe3_data *data; + + phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); + if (!phy) + return -ENOMEM; + +- match = of_match_device(ti_pipe3_id_table, dev); +- if (!match) ++ data = device_get_match_data(dev); ++ if (!data) + return -EINVAL; + +- data = (struct pipe3_data *)match->data; +- if (!data) { +- dev_err(dev, "no driver data\n"); +- return -EINVAL; +- } +- + phy->dev = dev; + phy->mode = data->mode; + phy->dpll_map = data->dpll_map; diff --git a/queue-6.6/selftests-mptcp-userspace-pm-validate-deny-join-id0-flag.patch b/queue-6.6/selftests-mptcp-userspace-pm-validate-deny-join-id0-flag.patch new file mode 100644 index 0000000000..59147e4f19 --- /dev/null +++ b/queue-6.6/selftests-mptcp-userspace-pm-validate-deny-join-id0-flag.patch @@ -0,0 +1,100 @@ +From matttbe@kernel.org Sat Sep 20 00:38:39 2025 +From: "Matthieu Baerts (NGI0)" +Date: Sat, 20 Sep 2025 00:38:22 +0200 +Subject: selftests: mptcp: userspace pm: validate deny-join-id0 flag +To: mptcp@lists.linux.dev, stable@vger.kernel.org, gregkh@linuxfoundation.org +Cc: "Matthieu Baerts (NGI0)" , sashal@kernel.org, Mat Martineau , Jakub Kicinski +Message-ID: <20250919223819.3679521-6-matttbe@kernel.org> + +From: "Matthieu Baerts (NGI0)" + +commit 24733e193a0d68f20d220e86da0362460c9aa812 upstream. + +The previous commit adds the MPTCP_PM_EV_FLAG_DENY_JOIN_ID0 flag. Make +sure it is correctly announced by the other peer when it has been +received. + +pm_nl_ctl will now display 'deny_join_id0:1' when monitoring the events, +and when this flag was set by the other peer. + +The 'Fixes' tag here below is the same as the one from the previous +commit: this patch here is not fixing anything wrong in the selftests, +but it validates the previous fix for an issue introduced by this commit +ID. + +Fixes: 702c2f646d42 ("mptcp: netlink: allow userspace-driven subflow establishment") +Reviewed-by: Mat Martineau +Signed-off-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20250912-net-mptcp-pm-uspace-deny_join_id0-v1-3-40171884ade8@kernel.org +Signed-off-by: Jakub Kicinski +[ Conflict in userspace_pm.sh, because of a difference in the context, + introduced by commit c66fb480a330 ("selftests: userspace pm: avoid + relaunching pm events"), which is not in this version. The same lines + can still be added at the same place. ] +Signed-off-by: Matthieu Baerts (NGI0) +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/net/mptcp/pm_nl_ctl.c | 7 +++++++ + tools/testing/selftests/net/mptcp/userspace_pm.sh | 14 +++++++++++--- + 2 files changed, 18 insertions(+), 3 deletions(-) + +--- a/tools/testing/selftests/net/mptcp/pm_nl_ctl.c ++++ b/tools/testing/selftests/net/mptcp/pm_nl_ctl.c +@@ -194,6 +194,13 @@ static int capture_events(int fd, int ev + fprintf(stderr, ",error:%u", *(__u8 *)RTA_DATA(attrs)); + else if (attrs->rta_type == MPTCP_ATTR_SERVER_SIDE) + fprintf(stderr, ",server_side:%u", *(__u8 *)RTA_DATA(attrs)); ++ else if (attrs->rta_type == MPTCP_ATTR_FLAGS) { ++ __u16 flags = *(__u16 *)RTA_DATA(attrs); ++ ++ /* only print when present, easier */ ++ if (flags & MPTCP_PM_EV_FLAG_DENY_JOIN_ID0) ++ fprintf(stderr, ",deny_join_id0:1"); ++ } + + attrs = RTA_NEXT(attrs, msg_len); + } +--- a/tools/testing/selftests/net/mptcp/userspace_pm.sh ++++ b/tools/testing/selftests/net/mptcp/userspace_pm.sh +@@ -196,6 +196,9 @@ make_connection() + is_v6="v4" + fi + ++ # set this on the client side only: will not affect the rest ++ ip netns exec "$ns2" sysctl -q net.mptcp.allow_join_initial_addr_port=0 ++ + # Capture netlink events over the two network namespaces running + # the MPTCP client and server + if [ -z "$client_evts" ]; then +@@ -227,23 +230,28 @@ make_connection() + local client_token + local client_port + local client_serverside ++ local client_nojoin + local server_token + local server_serverside ++ local server_nojoin + + client_token=$(mptcp_lib_evts_get_info token "$client_evts") + client_port=$(mptcp_lib_evts_get_info sport "$client_evts") + client_serverside=$(mptcp_lib_evts_get_info server_side "$client_evts") ++ client_nojoin=$(mptcp_lib_evts_get_info deny_join_id0 "$client_evts") + server_token=$(mptcp_lib_evts_get_info token "$server_evts") + server_serverside=$(mptcp_lib_evts_get_info server_side "$server_evts") ++ server_nojoin=$(mptcp_lib_evts_get_info deny_join_id0 "$server_evts") + + print_test "Established IP${is_v6} MPTCP Connection ns2 => ns1" +- if [ "$client_token" != "" ] && [ "$server_token" != "" ] && [ "$client_serverside" = 0 ] && +- [ "$server_serverside" = 1 ] ++ if [ "${client_token}" != "" ] && [ "${server_token}" != "" ] && ++ [ "${client_serverside}" = 0 ] && [ "${server_serverside}" = 1 ] && ++ [ "${client_nojoin:-0}" = 0 ] && [ "${server_nojoin:-0}" = 1 ] + then + test_pass + print_title "Connection info: ${client_addr}:${client_port} -> ${connect_addr}:${app_port}" + else +- test_fail "Expected tokens (c:${client_token} - s:${server_token}) and server (c:${client_serverside} - s:${server_serverside})" ++ test_fail "Expected tokens (c:${client_token} - s:${server_token}), server (c:${client_serverside} - s:${server_serverside}), nojoin (c:${client_nojoin} - s:${server_nojoin})" + mptcp_lib_result_print_all_tap + exit 1 + fi diff --git a/queue-6.6/series b/queue-6.6/series index 51808bb50a..ff2b8437d3 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -55,3 +55,10 @@ drm-bridge-cdns-mhdp8546-fix-missing-mutex-unlock-on.patch crypto-af_alg-set-merge-to-zero-early-in-af_alg_send.patch smb-client-fix-smbdirect_recv_io-leak-in-smbd_negoti.patch vmxnet3-unregister-xdp-rxq-info-in-the-reset-path.patch +mptcp-pm-nl-announce-deny-join-id0-flag.patch +selftests-mptcp-userspace-pm-validate-deny-join-id0-flag.patch +phy-use-device_get_match_data.patch +phy-ti-omap-usb2-fix-device-leak-at-unbind.patch +xhci-dbc-decouple-endpoint-allocation-from-initialization.patch +xhci-dbc-fix-full-dbc-transfer-ring-after-several-reconnects.patch +iommu-amd-pgtbl-fix-possible-race-while-increase-page-table-level.patch diff --git a/queue-6.6/xhci-dbc-decouple-endpoint-allocation-from-initialization.patch b/queue-6.6/xhci-dbc-decouple-endpoint-allocation-from-initialization.patch new file mode 100644 index 0000000000..ee3e01920a --- /dev/null +++ b/queue-6.6/xhci-dbc-decouple-endpoint-allocation-from-initialization.patch @@ -0,0 +1,140 @@ +From sashal@kernel.org Wed Sep 17 15:55:01 2025 +From: Sasha Levin +Date: Wed, 17 Sep 2025 09:54:56 -0400 +Subject: xhci: dbc: decouple endpoint allocation from initialization +To: stable@vger.kernel.org +Cc: Mathias Nyman , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20250917135457.565439-1-sashal@kernel.org> + +From: Mathias Nyman + +[ Upstream commit 220a0ffde02f962c13bc752b01aa570b8c65a37b ] + +Decouple allocation of endpoint ring buffer from initialization +of the buffer, and initialization of endpoint context parts from +from the rest of the contexts. + +It allows driver to clear up and reinitialize endpoint rings +after disconnect without reallocating everything. + +This is a prerequisite for the next patch that prevents the transfer +ring from filling up with cancelled (no-op) TRBs if a debug cable is +reconnected several times without transferring anything. + +Cc: stable@vger.kernel.org +Fixes: dfba2174dc42 ("usb: xhci: Add DbC support in xHCI driver") +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20250902105306.877476-2-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-dbgcap.c | 71 ++++++++++++++++++++++++++--------------- + 1 file changed, 46 insertions(+), 25 deletions(-) + +--- a/drivers/usb/host/xhci-dbgcap.c ++++ b/drivers/usb/host/xhci-dbgcap.c +@@ -86,13 +86,34 @@ static u32 xhci_dbc_populate_strings(str + return string_length; + } + ++static void xhci_dbc_init_ep_contexts(struct xhci_dbc *dbc) ++{ ++ struct xhci_ep_ctx *ep_ctx; ++ unsigned int max_burst; ++ dma_addr_t deq; ++ ++ max_burst = DBC_CTRL_MAXBURST(readl(&dbc->regs->control)); ++ ++ /* Populate bulk out endpoint context: */ ++ ep_ctx = dbc_bulkout_ctx(dbc); ++ deq = dbc_bulkout_enq(dbc); ++ ep_ctx->ep_info = 0; ++ ep_ctx->ep_info2 = dbc_epctx_info2(BULK_OUT_EP, 1024, max_burst); ++ ep_ctx->deq = cpu_to_le64(deq | dbc->ring_out->cycle_state); ++ ++ /* Populate bulk in endpoint context: */ ++ ep_ctx = dbc_bulkin_ctx(dbc); ++ deq = dbc_bulkin_enq(dbc); ++ ep_ctx->ep_info = 0; ++ ep_ctx->ep_info2 = dbc_epctx_info2(BULK_IN_EP, 1024, max_burst); ++ ep_ctx->deq = cpu_to_le64(deq | dbc->ring_in->cycle_state); ++} ++ + static void xhci_dbc_init_contexts(struct xhci_dbc *dbc, u32 string_length) + { + struct dbc_info_context *info; +- struct xhci_ep_ctx *ep_ctx; + u32 dev_info; +- dma_addr_t deq, dma; +- unsigned int max_burst; ++ dma_addr_t dma; + + if (!dbc) + return; +@@ -106,20 +127,8 @@ static void xhci_dbc_init_contexts(struc + info->serial = cpu_to_le64(dma + DBC_MAX_STRING_LENGTH * 3); + info->length = cpu_to_le32(string_length); + +- /* Populate bulk out endpoint context: */ +- ep_ctx = dbc_bulkout_ctx(dbc); +- max_burst = DBC_CTRL_MAXBURST(readl(&dbc->regs->control)); +- deq = dbc_bulkout_enq(dbc); +- ep_ctx->ep_info = 0; +- ep_ctx->ep_info2 = dbc_epctx_info2(BULK_OUT_EP, 1024, max_burst); +- ep_ctx->deq = cpu_to_le64(deq | dbc->ring_out->cycle_state); +- +- /* Populate bulk in endpoint context: */ +- ep_ctx = dbc_bulkin_ctx(dbc); +- deq = dbc_bulkin_enq(dbc); +- ep_ctx->ep_info = 0; +- ep_ctx->ep_info2 = dbc_epctx_info2(BULK_IN_EP, 1024, max_burst); +- ep_ctx->deq = cpu_to_le64(deq | dbc->ring_in->cycle_state); ++ /* Populate bulk in and out endpoint contexts: */ ++ xhci_dbc_init_ep_contexts(dbc); + + /* Set DbC context and info registers: */ + lo_hi_writeq(dbc->ctx->dma, &dbc->regs->dccp); +@@ -421,6 +430,23 @@ dbc_alloc_ctx(struct device *dev, gfp_t + return ctx; + } + ++static void xhci_dbc_ring_init(struct xhci_ring *ring) ++{ ++ struct xhci_segment *seg = ring->first_seg; ++ ++ /* clear all trbs on ring in case of old ring */ ++ memset(seg->trbs, 0, TRB_SEGMENT_SIZE); ++ ++ /* Only event ring does not use link TRB */ ++ if (ring->type != TYPE_EVENT) { ++ union xhci_trb *trb = &seg->trbs[TRBS_PER_SEGMENT - 1]; ++ ++ trb->link.segment_ptr = cpu_to_le64(ring->first_seg->dma); ++ trb->link.control = cpu_to_le32(LINK_TOGGLE | TRB_TYPE(TRB_LINK)); ++ } ++ xhci_initialize_ring_info(ring, 1); ++} ++ + static struct xhci_ring * + xhci_dbc_ring_alloc(struct device *dev, enum xhci_ring_type type, gfp_t flags) + { +@@ -449,15 +475,10 @@ xhci_dbc_ring_alloc(struct device *dev, + + seg->dma = dma; + +- /* Only event ring does not use link TRB */ +- if (type != TYPE_EVENT) { +- union xhci_trb *trb = &seg->trbs[TRBS_PER_SEGMENT - 1]; +- +- trb->link.segment_ptr = cpu_to_le64(dma); +- trb->link.control = cpu_to_le32(LINK_TOGGLE | TRB_TYPE(TRB_LINK)); +- } + INIT_LIST_HEAD(&ring->td_list); +- xhci_initialize_ring_info(ring, 1); ++ ++ xhci_dbc_ring_init(ring); ++ + return ring; + dma_fail: + kfree(seg); diff --git a/queue-6.6/xhci-dbc-fix-full-dbc-transfer-ring-after-several-reconnects.patch b/queue-6.6/xhci-dbc-fix-full-dbc-transfer-ring-after-several-reconnects.patch new file mode 100644 index 0000000000..b2be7de5d0 --- /dev/null +++ b/queue-6.6/xhci-dbc-fix-full-dbc-transfer-ring-after-several-reconnects.patch @@ -0,0 +1,91 @@ +From sashal@kernel.org Wed Sep 17 15:55:02 2025 +From: Sasha Levin +Date: Wed, 17 Sep 2025 09:54:57 -0400 +Subject: xhci: dbc: Fix full DbC transfer ring after several reconnects +To: stable@vger.kernel.org +Cc: Mathias Nyman , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20250917135457.565439-2-sashal@kernel.org> + +From: Mathias Nyman + +[ Upstream commit a5c98e8b1398534ae1feb6e95e2d3ee5215538ed ] + +Pending requests will be flushed on disconnect, and the corresponding +TRBs will be turned into No-op TRBs, which are ignored by the xHC +controller once it starts processing the ring. + +If the USB debug cable repeatedly disconnects before ring is started +then the ring will eventually be filled with No-op TRBs. +No new transfers can be queued when the ring is full, and driver will +print the following error message: + + "xhci_hcd 0000:00:14.0: failed to queue trbs" + +This is a normal case for 'in' transfers where TRBs are always enqueued +in advance, ready to take on incoming data. If no data arrives, and +device is disconnected, then ring dequeue will remain at beginning of +the ring while enqueue points to first free TRB after last cancelled +No-op TRB. +s +Solve this by reinitializing the rings when the debug cable disconnects +and DbC is leaving the configured state. +Clear the whole ring buffer and set enqueue and dequeue to the beginning +of ring, and set cycle bit to its initial state. + +Cc: stable@vger.kernel.org +Fixes: dfba2174dc42 ("usb: xhci: Add DbC support in xHCI driver") +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20250902105306.877476-3-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-dbgcap.c | 23 +++++++++++++++++++++-- + 1 file changed, 21 insertions(+), 2 deletions(-) + +--- a/drivers/usb/host/xhci-dbgcap.c ++++ b/drivers/usb/host/xhci-dbgcap.c +@@ -447,6 +447,25 @@ static void xhci_dbc_ring_init(struct xh + xhci_initialize_ring_info(ring, 1); + } + ++static int xhci_dbc_reinit_ep_rings(struct xhci_dbc *dbc) ++{ ++ struct xhci_ring *in_ring = dbc->eps[BULK_IN].ring; ++ struct xhci_ring *out_ring = dbc->eps[BULK_OUT].ring; ++ ++ if (!in_ring || !out_ring || !dbc->ctx) { ++ dev_warn(dbc->dev, "Can't re-init unallocated endpoints\n"); ++ return -ENODEV; ++ } ++ ++ xhci_dbc_ring_init(in_ring); ++ xhci_dbc_ring_init(out_ring); ++ ++ /* set ep context enqueue, dequeue, and cycle to initial values */ ++ xhci_dbc_init_ep_contexts(dbc); ++ ++ return 0; ++} ++ + static struct xhci_ring * + xhci_dbc_ring_alloc(struct device *dev, enum xhci_ring_type type, gfp_t flags) + { +@@ -871,7 +890,7 @@ static enum evtreturn xhci_dbc_do_handle + dev_info(dbc->dev, "DbC cable unplugged\n"); + dbc->state = DS_ENABLED; + xhci_dbc_flush_requests(dbc); +- ++ xhci_dbc_reinit_ep_rings(dbc); + return EVT_DISC; + } + +@@ -881,7 +900,7 @@ static enum evtreturn xhci_dbc_do_handle + writel(portsc, &dbc->regs->portsc); + dbc->state = DS_ENABLED; + xhci_dbc_flush_requests(dbc); +- ++ xhci_dbc_reinit_ep_rings(dbc); + return EVT_DISC; + } + -- 2.47.3