From 0b66b308cfe09d1874f4ff8548b7ba13b496b806 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Oct 2025 11:26:37 +0200 Subject: [PATCH] 6.1-stable patches added patches: cpufreq-cppc-avoid-using-cpufreq_eternal-as-transition-delay.patch crypto-rockchip-fix-dma_unmap_sg-nents-value.patch drm-amd-check-whether-secure-display-ta-loaded-successfully.patch drm-exynos-exynos7_drm_decon-fix-uninitialized-crtc-reference-in-functions.patch drm-exynos-exynos7_drm_decon-properly-clear-channels-during-bind.patch drm-exynos-exynos7_drm_decon-remove-ctx-suspended.patch drm-rcar-du-dsi-fix-1-2-3-lane-support.patch usb-gadget-f_acm-refactor-bind-path-to-use-__free.patch usb-gadget-f_ecm-refactor-bind-path-to-use-__free.patch usb-gadget-f_ncm-refactor-bind-path-to-use-__free.patch usb-gadget-f_rndis-refactor-bind-path-to-use-__free.patch usb-gadget-introduce-free_usb_request-helper.patch usb-gadget-store-endpoint-pointer-in-usb_request.patch --- ...-cpufreq_eternal-as-transition-delay.patch | 83 +++++++ ...ockchip-fix-dma_unmap_sg-nents-value.patch | 40 +++ ...ecure-display-ta-loaded-successfully.patch | 40 +++ ...tialized-crtc-reference-in-functions.patch | 67 +++++ ...-properly-clear-channels-during-bind.patch | 117 +++++++++ ...ynos7_drm_decon-remove-ctx-suspended.patch | 166 +++++++++++++ ...m-rcar-du-dsi-fix-1-2-3-lane-support.patch | 78 ++++++ queue-6.1/series | 13 + ...acm-refactor-bind-path-to-use-__free.patch | 170 +++++++++++++ ...ecm-refactor-bind-path-to-use-__free.patch | 159 ++++++++++++ ...ncm-refactor-bind-path-to-use-__free.patch | 231 ++++++++++++++++++ ...dis-refactor-bind-path-to-use-__free.patch | 212 ++++++++++++++++ ...et-introduce-free_usb_request-helper.patch | 68 ++++++ ...tore-endpoint-pointer-in-usb_request.patch | 66 +++++ 14 files changed, 1510 insertions(+) create mode 100644 queue-6.1/cpufreq-cppc-avoid-using-cpufreq_eternal-as-transition-delay.patch create mode 100644 queue-6.1/crypto-rockchip-fix-dma_unmap_sg-nents-value.patch create mode 100644 queue-6.1/drm-amd-check-whether-secure-display-ta-loaded-successfully.patch create mode 100644 queue-6.1/drm-exynos-exynos7_drm_decon-fix-uninitialized-crtc-reference-in-functions.patch create mode 100644 queue-6.1/drm-exynos-exynos7_drm_decon-properly-clear-channels-during-bind.patch create mode 100644 queue-6.1/drm-exynos-exynos7_drm_decon-remove-ctx-suspended.patch create mode 100644 queue-6.1/drm-rcar-du-dsi-fix-1-2-3-lane-support.patch create mode 100644 queue-6.1/usb-gadget-f_acm-refactor-bind-path-to-use-__free.patch create mode 100644 queue-6.1/usb-gadget-f_ecm-refactor-bind-path-to-use-__free.patch create mode 100644 queue-6.1/usb-gadget-f_ncm-refactor-bind-path-to-use-__free.patch create mode 100644 queue-6.1/usb-gadget-f_rndis-refactor-bind-path-to-use-__free.patch create mode 100644 queue-6.1/usb-gadget-introduce-free_usb_request-helper.patch create mode 100644 queue-6.1/usb-gadget-store-endpoint-pointer-in-usb_request.patch diff --git a/queue-6.1/cpufreq-cppc-avoid-using-cpufreq_eternal-as-transition-delay.patch b/queue-6.1/cpufreq-cppc-avoid-using-cpufreq_eternal-as-transition-delay.patch new file mode 100644 index 0000000000..b531fdb3fa --- /dev/null +++ b/queue-6.1/cpufreq-cppc-avoid-using-cpufreq_eternal-as-transition-delay.patch @@ -0,0 +1,83 @@ +From stable+bounces-187855-greg=kroah.com@vger.kernel.org Sat Oct 18 18:41:05 2025 +From: Sasha Levin +Date: Sat, 18 Oct 2025 12:40:55 -0400 +Subject: cpufreq: CPPC: Avoid using CPUFREQ_ETERNAL as transition delay +To: stable@vger.kernel.org +Cc: "Rafael J. Wysocki" , "Mario Limonciello (AMD)" , Jie Zhan , Viresh Kumar , Qais Yousef , Sasha Levin +Message-ID: <20251018164055.845206-1-sashal@kernel.org> + +From: "Rafael J. Wysocki" + +[ Upstream commit f965d111e68f4a993cc44d487d416e3d954eea11 ] + +If cppc_get_transition_latency() returns CPUFREQ_ETERNAL to indicate a +failure to retrieve the transition latency value from the platform +firmware, the CPPC cpufreq driver will use that value (converted to +microseconds) as the policy transition delay, but it is way too large +for any practical use. + +Address this by making the driver use the cpufreq's default +transition latency value (in microseconds) as the transition delay +if CPUFREQ_ETERNAL is returned by cppc_get_transition_latency(). + +Fixes: d4f3388afd48 ("cpufreq / CPPC: Set platform specific transition_delay_us") +Cc: 5.19+ # 5.19 +Signed-off-by: Rafael J. Wysocki +Reviewed-by: Mario Limonciello (AMD) +Reviewed-by: Jie Zhan +Acked-by: Viresh Kumar +Reviewed-by: Qais Yousef +[ added CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS definition to include/linux/cpufreq.h ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/cpufreq/cppc_cpufreq.c | 14 ++++++++++++-- + include/linux/cpufreq.h | 3 +++ + 2 files changed, 15 insertions(+), 2 deletions(-) + +--- a/drivers/cpufreq/cppc_cpufreq.c ++++ b/drivers/cpufreq/cppc_cpufreq.c +@@ -338,6 +338,16 @@ static int cppc_verify_policy(struct cpu + return 0; + } + ++static unsigned int __cppc_cpufreq_get_transition_delay_us(unsigned int cpu) ++{ ++ unsigned int transition_latency_ns = cppc_get_transition_latency(cpu); ++ ++ if (transition_latency_ns == CPUFREQ_ETERNAL) ++ return CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS / NSEC_PER_USEC; ++ ++ return transition_latency_ns / NSEC_PER_USEC; ++} ++ + /* + * The PCC subspace describes the rate at which platform can accept commands + * on the shared PCC channel (including READs which do not count towards freq +@@ -360,12 +370,12 @@ static unsigned int cppc_cpufreq_get_tra + return 10000; + } + } +- return cppc_get_transition_latency(cpu) / NSEC_PER_USEC; ++ return __cppc_cpufreq_get_transition_delay_us(cpu); + } + #else + static unsigned int cppc_cpufreq_get_transition_delay_us(unsigned int cpu) + { +- return cppc_get_transition_latency(cpu) / NSEC_PER_USEC; ++ return __cppc_cpufreq_get_transition_delay_us(cpu); + } + #endif + +--- a/include/linux/cpufreq.h ++++ b/include/linux/cpufreq.h +@@ -32,6 +32,9 @@ + */ + + #define CPUFREQ_ETERNAL (-1) ++ ++#define CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS NSEC_PER_MSEC ++ + #define CPUFREQ_NAME_LEN 16 + /* Print length for names. Extra 1 space for accommodating '\n' in prints */ + #define CPUFREQ_NAME_PLEN (CPUFREQ_NAME_LEN + 1) diff --git a/queue-6.1/crypto-rockchip-fix-dma_unmap_sg-nents-value.patch b/queue-6.1/crypto-rockchip-fix-dma_unmap_sg-nents-value.patch new file mode 100644 index 0000000000..96bf7d01f0 --- /dev/null +++ b/queue-6.1/crypto-rockchip-fix-dma_unmap_sg-nents-value.patch @@ -0,0 +1,40 @@ +From stable+bounces-187868-greg=kroah.com@vger.kernel.org Sat Oct 18 21:37:12 2025 +From: Sasha Levin +Date: Sat, 18 Oct 2025 15:37:04 -0400 +Subject: crypto: rockchip - Fix dma_unmap_sg() nents value +To: stable@vger.kernel.org +Cc: Thomas Fourier , Herbert Xu , Sasha Levin +Message-ID: <20251018193704.891321-1-sashal@kernel.org> + +From: Thomas Fourier + +[ Upstream commit 21140e5caf019e4a24e1ceabcaaa16bd693b393f ] + +The dma_unmap_sg() functions should be called with the same nents as the +dma_map_sg(), not the value the map function returned. + +Fixes: 57d67c6e8219 ("crypto: rockchip - rework by using crypto_engine") +Cc: +Signed-off-by: Thomas Fourier +Signed-off-by: Herbert Xu +[ removed unused rctx variable declaration since device pointer already came from tctx->dev->dev instead of rctx->dev ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/crypto/rockchip/rk3288_crypto_ahash.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c ++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c +@@ -236,10 +236,9 @@ static int rk_hash_unprepare(struct cryp + { + struct ahash_request *areq = container_of(breq, struct ahash_request, base); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); +- struct rk_ahash_rctx *rctx = ahash_request_ctx(areq); + struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm); + +- dma_unmap_sg(tctx->dev->dev, areq->src, rctx->nrsg, DMA_TO_DEVICE); ++ dma_unmap_sg(tctx->dev->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE); + return 0; + } + diff --git a/queue-6.1/drm-amd-check-whether-secure-display-ta-loaded-successfully.patch b/queue-6.1/drm-amd-check-whether-secure-display-ta-loaded-successfully.patch new file mode 100644 index 0000000000..2ba7153490 --- /dev/null +++ b/queue-6.1/drm-amd-check-whether-secure-display-ta-loaded-successfully.patch @@ -0,0 +1,40 @@ +From c760bcda83571e07b72c10d9da175db5051ed971 Mon Sep 17 00:00:00 2001 +From: Mario Limonciello +Date: Thu, 25 Sep 2025 14:10:57 -0500 +Subject: drm/amd: Check whether secure display TA loaded successfully + +From: Mario Limonciello + +commit c760bcda83571e07b72c10d9da175db5051ed971 upstream. + +[Why] +Not all renoir hardware supports secure display. If the TA is present +but the feature isn't supported it will fail to load or send commands. +This shows ERR messages to the user that make it seems like there is +a problem. + +[How] +Check the resp_status of the context to see if there was an error +before trying to send any secure display commands. + +Reviewed-by: Alex Deucher +Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/1415 +Signed-off-by: Mario Limonciello +Signed-off-by: Alex Deucher +Signed-off-by: Adrian Yip +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +@@ -1959,7 +1959,7 @@ static int psp_securedisplay_initialize( + } + + ret = psp_ta_load(psp, &psp->securedisplay_context.context); +- if (!ret) { ++ if (!ret && !psp->securedisplay_context.context.resp_status) { + psp->securedisplay_context.context.initialized = true; + mutex_init(&psp->securedisplay_context.mutex); + } else diff --git a/queue-6.1/drm-exynos-exynos7_drm_decon-fix-uninitialized-crtc-reference-in-functions.patch b/queue-6.1/drm-exynos-exynos7_drm_decon-fix-uninitialized-crtc-reference-in-functions.patch new file mode 100644 index 0000000000..a69d0e7f17 --- /dev/null +++ b/queue-6.1/drm-exynos-exynos7_drm_decon-fix-uninitialized-crtc-reference-in-functions.patch @@ -0,0 +1,67 @@ +From stable+bounces-187791-greg=kroah.com@vger.kernel.org Sat Oct 18 04:26:50 2025 +From: Sasha Levin +Date: Fri, 17 Oct 2025 22:26:40 -0400 +Subject: drm/exynos: exynos7_drm_decon: fix uninitialized crtc reference in functions +To: stable@vger.kernel.org +Cc: Kaustabh Chakraborty , Inki Dae , Sasha Levin +Message-ID: <20251018022642.218123-1-sashal@kernel.org> + +From: Kaustabh Chakraborty + +[ Upstream commit d31bbacf783daf1e71fbe5c68df93550c446bf44 ] + +Modify the functions to accept a pointer to struct decon_context +instead. + +Signed-off-by: Kaustabh Chakraborty +Signed-off-by: Inki Dae +Stable-dep-of: e1361a4f1be9 ("drm/exynos: exynos7_drm_decon: remove ctx->suspended") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/exynos/exynos7_drm_decon.c | 11 ++++------- + 1 file changed, 4 insertions(+), 7 deletions(-) + +--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c ++++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c +@@ -82,10 +82,8 @@ static const enum drm_plane_type decon_w + DRM_PLANE_TYPE_CURSOR, + }; + +-static void decon_wait_for_vblank(struct exynos_drm_crtc *crtc) ++static void decon_wait_for_vblank(struct decon_context *ctx) + { +- struct decon_context *ctx = crtc->ctx; +- + if (ctx->suspended) + return; + +@@ -101,9 +99,8 @@ static void decon_wait_for_vblank(struct + DRM_DEV_DEBUG_KMS(ctx->dev, "vblank wait timed out.\n"); + } + +-static void decon_clear_channels(struct exynos_drm_crtc *crtc) ++static void decon_clear_channels(struct decon_context *ctx) + { +- struct decon_context *ctx = crtc->ctx; + unsigned int win, ch_enabled = 0; + + /* Check if any channel is enabled. */ +@@ -119,7 +116,7 @@ static void decon_clear_channels(struct + + /* Wait for vsync, as disable channel takes effect at next vsync */ + if (ch_enabled) +- decon_wait_for_vblank(ctx->crtc); ++ decon_wait_for_vblank(ctx); + } + + static int decon_ctx_initialize(struct decon_context *ctx, +@@ -127,7 +124,7 @@ static int decon_ctx_initialize(struct d + { + ctx->drm_dev = drm_dev; + +- decon_clear_channels(ctx->crtc); ++ decon_clear_channels(ctx); + + return exynos_drm_register_dma(drm_dev, ctx->dev, &ctx->dma_priv); + } diff --git a/queue-6.1/drm-exynos-exynos7_drm_decon-properly-clear-channels-during-bind.patch b/queue-6.1/drm-exynos-exynos7_drm_decon-properly-clear-channels-during-bind.patch new file mode 100644 index 0000000000..5edb24b849 --- /dev/null +++ b/queue-6.1/drm-exynos-exynos7_drm_decon-properly-clear-channels-during-bind.patch @@ -0,0 +1,117 @@ +From stable+bounces-187792-greg=kroah.com@vger.kernel.org Sat Oct 18 04:26:51 2025 +From: Sasha Levin +Date: Fri, 17 Oct 2025 22:26:41 -0400 +Subject: drm/exynos: exynos7_drm_decon: properly clear channels during bind +To: stable@vger.kernel.org +Cc: Kaustabh Chakraborty , Inki Dae , Sasha Levin +Message-ID: <20251018022642.218123-2-sashal@kernel.org> + +From: Kaustabh Chakraborty + +[ Upstream commit 5f1a453974204175f20b3788824a0fe23cc36f79 ] + +The DECON channels are not cleared properly as the windows aren't +shadow protected. When accompanied with an IOMMU, it pagefaults, and +the kernel panics. + +Implement shadow protect/unprotect, along with a standalone update, +for channel clearing to properly take effect. + +Signed-off-by: Kaustabh Chakraborty +Signed-off-by: Inki Dae +Stable-dep-of: e1361a4f1be9 ("drm/exynos: exynos7_drm_decon: remove ctx->suspended") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/exynos/exynos7_drm_decon.c | 55 ++++++++++++++++------------- + 1 file changed, 32 insertions(+), 23 deletions(-) + +--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c ++++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c +@@ -82,6 +82,28 @@ static const enum drm_plane_type decon_w + DRM_PLANE_TYPE_CURSOR, + }; + ++/** ++ * decon_shadow_protect_win() - disable updating values from shadow registers at vsync ++ * ++ * @ctx: display and enhancement controller context ++ * @win: window to protect registers for ++ * @protect: 1 to protect (disable updates) ++ */ ++static void decon_shadow_protect_win(struct decon_context *ctx, ++ unsigned int win, bool protect) ++{ ++ u32 bits, val; ++ ++ bits = SHADOWCON_WINx_PROTECT(win); ++ ++ val = readl(ctx->regs + SHADOWCON); ++ if (protect) ++ val |= bits; ++ else ++ val &= ~bits; ++ writel(val, ctx->regs + SHADOWCON); ++} ++ + static void decon_wait_for_vblank(struct decon_context *ctx) + { + if (ctx->suspended) +@@ -102,18 +124,27 @@ static void decon_wait_for_vblank(struct + static void decon_clear_channels(struct decon_context *ctx) + { + unsigned int win, ch_enabled = 0; ++ u32 val; + + /* Check if any channel is enabled. */ + for (win = 0; win < WINDOWS_NR; win++) { +- u32 val = readl(ctx->regs + WINCON(win)); ++ val = readl(ctx->regs + WINCON(win)); + + if (val & WINCONx_ENWIN) { ++ decon_shadow_protect_win(ctx, win, true); ++ + val &= ~WINCONx_ENWIN; + writel(val, ctx->regs + WINCON(win)); + ch_enabled = 1; ++ ++ decon_shadow_protect_win(ctx, win, false); + } + } + ++ val = readl(ctx->regs + DECON_UPDATE); ++ val |= DECON_UPDATE_STANDALONE_F; ++ writel(val, ctx->regs + DECON_UPDATE); ++ + /* Wait for vsync, as disable channel takes effect at next vsync */ + if (ch_enabled) + decon_wait_for_vblank(ctx); +@@ -341,28 +372,6 @@ static void decon_win_set_colkey(struct + writel(keycon1, ctx->regs + WKEYCON1_BASE(win)); + } + +-/** +- * decon_shadow_protect_win() - disable updating values from shadow registers at vsync +- * +- * @ctx: display and enhancement controller context +- * @win: window to protect registers for +- * @protect: 1 to protect (disable updates) +- */ +-static void decon_shadow_protect_win(struct decon_context *ctx, +- unsigned int win, bool protect) +-{ +- u32 bits, val; +- +- bits = SHADOWCON_WINx_PROTECT(win); +- +- val = readl(ctx->regs + SHADOWCON); +- if (protect) +- val |= bits; +- else +- val &= ~bits; +- writel(val, ctx->regs + SHADOWCON); +-} +- + static void decon_atomic_begin(struct exynos_drm_crtc *crtc) + { + struct decon_context *ctx = crtc->ctx; diff --git a/queue-6.1/drm-exynos-exynos7_drm_decon-remove-ctx-suspended.patch b/queue-6.1/drm-exynos-exynos7_drm_decon-remove-ctx-suspended.patch new file mode 100644 index 0000000000..563a16bea1 --- /dev/null +++ b/queue-6.1/drm-exynos-exynos7_drm_decon-remove-ctx-suspended.patch @@ -0,0 +1,166 @@ +From stable+bounces-187793-greg=kroah.com@vger.kernel.org Sat Oct 18 04:26:53 2025 +From: Sasha Levin +Date: Fri, 17 Oct 2025 22:26:42 -0400 +Subject: drm/exynos: exynos7_drm_decon: remove ctx->suspended +To: stable@vger.kernel.org +Cc: Kaustabh Chakraborty , Inki Dae , Sasha Levin +Message-ID: <20251018022642.218123-3-sashal@kernel.org> + +From: Kaustabh Chakraborty + +[ Upstream commit e1361a4f1be9cb69a662c6d7b5ce218007d6e82b ] + +Condition guards are found to be redundant, as the call flow is properly +managed now, as also observed in the Exynos5433 DECON driver. Since +state checking is no longer necessary, remove it. + +This also fixes an issue which prevented decon_commit() from +decon_atomic_enable() due to an incorrect state change setting. + +Fixes: 96976c3d9aff ("drm/exynos: Add DECON driver") +Cc: stable@vger.kernel.org +Suggested-by: Inki Dae +Signed-off-by: Kaustabh Chakraborty +Signed-off-by: Inki Dae +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/exynos/exynos7_drm_decon.c | 36 ----------------------------- + 1 file changed, 36 deletions(-) + +--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c ++++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c +@@ -52,7 +52,6 @@ struct decon_context { + void __iomem *regs; + unsigned long irq_flags; + bool i80_if; +- bool suspended; + wait_queue_head_t wait_vsync_queue; + atomic_t wait_vsync_event; + +@@ -106,9 +105,6 @@ static void decon_shadow_protect_win(str + + static void decon_wait_for_vblank(struct decon_context *ctx) + { +- if (ctx->suspended) +- return; +- + atomic_set(&ctx->wait_vsync_event, 1); + + /* +@@ -184,9 +180,6 @@ static void decon_commit(struct exynos_d + struct drm_display_mode *mode = &crtc->base.state->adjusted_mode; + u32 val, clkdiv; + +- if (ctx->suspended) +- return; +- + /* nothing to do if we haven't set the mode yet */ + if (mode->htotal == 0 || mode->vtotal == 0) + return; +@@ -248,9 +241,6 @@ static int decon_enable_vblank(struct ex + struct decon_context *ctx = crtc->ctx; + u32 val; + +- if (ctx->suspended) +- return -EPERM; +- + if (!test_and_set_bit(0, &ctx->irq_flags)) { + val = readl(ctx->regs + VIDINTCON0); + +@@ -273,9 +263,6 @@ static void decon_disable_vblank(struct + struct decon_context *ctx = crtc->ctx; + u32 val; + +- if (ctx->suspended) +- return; +- + if (test_and_clear_bit(0, &ctx->irq_flags)) { + val = readl(ctx->regs + VIDINTCON0); + +@@ -377,9 +364,6 @@ static void decon_atomic_begin(struct ex + struct decon_context *ctx = crtc->ctx; + int i; + +- if (ctx->suspended) +- return; +- + for (i = 0; i < WINDOWS_NR; i++) + decon_shadow_protect_win(ctx, i, true); + } +@@ -399,9 +383,6 @@ static void decon_update_plane(struct ex + unsigned int cpp = fb->format->cpp[0]; + unsigned int pitch = fb->pitches[0]; + +- if (ctx->suspended) +- return; +- + /* + * SHADOWCON/PRTCON register is used for enabling timing. + * +@@ -489,9 +470,6 @@ static void decon_disable_plane(struct e + unsigned int win = plane->index; + u32 val; + +- if (ctx->suspended) +- return; +- + /* protect windows */ + decon_shadow_protect_win(ctx, win, true); + +@@ -510,9 +488,6 @@ static void decon_atomic_flush(struct ex + struct decon_context *ctx = crtc->ctx; + int i; + +- if (ctx->suspended) +- return; +- + for (i = 0; i < WINDOWS_NR; i++) + decon_shadow_protect_win(ctx, i, false); + exynos_crtc_handle_event(crtc); +@@ -540,9 +515,6 @@ static void decon_atomic_enable(struct e + struct decon_context *ctx = crtc->ctx; + int ret; + +- if (!ctx->suspended) +- return; +- + ret = pm_runtime_resume_and_get(ctx->dev); + if (ret < 0) { + DRM_DEV_ERROR(ctx->dev, "failed to enable DECON device.\n"); +@@ -556,8 +528,6 @@ static void decon_atomic_enable(struct e + decon_enable_vblank(ctx->crtc); + + decon_commit(ctx->crtc); +- +- ctx->suspended = false; + } + + static void decon_atomic_disable(struct exynos_drm_crtc *crtc) +@@ -565,9 +535,6 @@ static void decon_atomic_disable(struct + struct decon_context *ctx = crtc->ctx; + int i; + +- if (ctx->suspended) +- return; +- + /* + * We need to make sure that all windows are disabled before we + * suspend that connector. Otherwise we might try to scan from +@@ -577,8 +544,6 @@ static void decon_atomic_disable(struct + decon_disable_plane(crtc, &ctx->planes[i]); + + pm_runtime_put_sync(ctx->dev); +- +- ctx->suspended = true; + } + + static const struct exynos_drm_crtc_ops decon_crtc_ops = { +@@ -699,7 +664,6 @@ static int decon_probe(struct platform_d + return -ENOMEM; + + ctx->dev = dev; +- ctx->suspended = true; + + i80_if_timings = of_get_child_by_name(dev->of_node, "i80-if-timings"); + if (i80_if_timings) diff --git a/queue-6.1/drm-rcar-du-dsi-fix-1-2-3-lane-support.patch b/queue-6.1/drm-rcar-du-dsi-fix-1-2-3-lane-support.patch new file mode 100644 index 0000000000..eebfa2d776 --- /dev/null +++ b/queue-6.1/drm-rcar-du-dsi-fix-1-2-3-lane-support.patch @@ -0,0 +1,78 @@ +From stable+bounces-187807-greg=kroah.com@vger.kernel.org Sat Oct 18 05:18:34 2025 +From: Sasha Levin +Date: Fri, 17 Oct 2025 23:18:25 -0400 +Subject: drm/rcar-du: dsi: Fix 1/2/3 lane support +To: stable@vger.kernel.org +Cc: Marek Vasut , Tomi Valkeinen , Tomi Valkeinen , Sasha Levin +Message-ID: <20251018031825.247562-1-sashal@kernel.org> + +From: Marek Vasut + +[ Upstream commit d83f1d19c898ac1b54ae64d1c950f5beff801982 ] + +Remove fixed PPI lane count setup. The R-Car DSI host is capable +of operating in 1..4 DSI lane mode. Remove the hard-coded 4-lane +configuration from PPI register settings and instead configure +the PPI lane count according to lane count information already +obtained by this driver instance. + +Configure TXSETR register to match PPI lane count. The R-Car V4H +Reference Manual R19UH0186EJ0121 Rev.1.21 section 67.2.2.3 Tx Set +Register (TXSETR), field LANECNT description indicates that the +TXSETR register LANECNT bitfield lane count must be configured +such, that it matches lane count configuration in PPISETR register +DLEN bitfield. Make sure the LANECNT and DLEN bitfields are +configured to match. + +Fixes: 155358310f01 ("drm: rcar-du: Add R-Car DSI driver") +Cc: stable@vger.kernel.org +Signed-off-by: Marek Vasut +Reviewed-by: Tomi Valkeinen +Link: https://lore.kernel.org/r/20250813210840.97621-1-marek.vasut+renesas@mailbox.org +Signed-off-by: Tomi Valkeinen +[ adjusted file paths to remove renesas/ subdirectory ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c | 5 ++++- + drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h | 8 ++++---- + 2 files changed, 8 insertions(+), 5 deletions(-) + +--- a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c ++++ b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c +@@ -385,7 +385,10 @@ static int rcar_mipi_dsi_startup(struct + udelay(10); + rcar_mipi_dsi_clr(dsi, CLOCKSET1, CLOCKSET1_UPDATEPLL); + +- ppisetr = PPISETR_DLEN_3 | PPISETR_CLEN; ++ rcar_mipi_dsi_clr(dsi, TXSETR, TXSETR_LANECNT_MASK); ++ rcar_mipi_dsi_set(dsi, TXSETR, dsi->lanes - 1); ++ ++ ppisetr = ((BIT(dsi->lanes) - 1) & PPISETR_DLEN_MASK) | PPISETR_CLEN; + rcar_mipi_dsi_write(dsi, PPISETR, ppisetr); + + rcar_mipi_dsi_set(dsi, PHYSETUP, PHYSETUP_SHUTDOWNZ); +--- a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h ++++ b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h +@@ -12,6 +12,9 @@ + #define LINKSR_LPBUSY (1 << 1) + #define LINKSR_HSBUSY (1 << 0) + ++#define TXSETR 0x100 ++#define TXSETR_LANECNT_MASK (0x3 << 0) ++ + /* + * Video Mode Register + */ +@@ -80,10 +83,7 @@ + * PHY-Protocol Interface (PPI) Registers + */ + #define PPISETR 0x700 +-#define PPISETR_DLEN_0 (0x1 << 0) +-#define PPISETR_DLEN_1 (0x3 << 0) +-#define PPISETR_DLEN_2 (0x7 << 0) +-#define PPISETR_DLEN_3 (0xf << 0) ++#define PPISETR_DLEN_MASK (0xf << 0) + #define PPISETR_CLEN (1 << 8) + + #define PPICLCR 0x710 diff --git a/queue-6.1/series b/queue-6.1/series index 17c1a682b5..c883389f6f 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -8,3 +8,16 @@ btrfs-fix-clearing-of-btrfs_fs_reloc_running-if-relocation-already-running.patch btrfs-do-not-assert-we-found-block-group-item-when-creating-free-space-tree.patch cifs-parse_dfs_referrals-prevent-oob-on-malformed-input.patch drm-amdgpu-use-atomic-functions-with-memory-barriers-for-vm-fault-info.patch +drm-amd-check-whether-secure-display-ta-loaded-successfully.patch +crypto-rockchip-fix-dma_unmap_sg-nents-value.patch +cpufreq-cppc-avoid-using-cpufreq_eternal-as-transition-delay.patch +drm-rcar-du-dsi-fix-1-2-3-lane-support.patch +drm-exynos-exynos7_drm_decon-fix-uninitialized-crtc-reference-in-functions.patch +drm-exynos-exynos7_drm_decon-properly-clear-channels-during-bind.patch +drm-exynos-exynos7_drm_decon-remove-ctx-suspended.patch +usb-gadget-store-endpoint-pointer-in-usb_request.patch +usb-gadget-introduce-free_usb_request-helper.patch +usb-gadget-f_rndis-refactor-bind-path-to-use-__free.patch +usb-gadget-f_ecm-refactor-bind-path-to-use-__free.patch +usb-gadget-f_acm-refactor-bind-path-to-use-__free.patch +usb-gadget-f_ncm-refactor-bind-path-to-use-__free.patch diff --git a/queue-6.1/usb-gadget-f_acm-refactor-bind-path-to-use-__free.patch b/queue-6.1/usb-gadget-f_acm-refactor-bind-path-to-use-__free.patch new file mode 100644 index 0000000000..c433ac4617 --- /dev/null +++ b/queue-6.1/usb-gadget-f_acm-refactor-bind-path-to-use-__free.patch @@ -0,0 +1,170 @@ +From stable+bounces-187771-greg=kroah.com@vger.kernel.org Sat Oct 18 03:23:38 2025 +From: Sasha Levin +Date: Fri, 17 Oct 2025 21:23:28 -0400 +Subject: usb: gadget: f_acm: Refactor bind path to use __free() +To: stable@vger.kernel.org +Cc: Kuen-Han Tsai , stable@kernel.org, Greg Kroah-Hartman , Sasha Levin +Message-ID: <20251018012328.141282-3-sashal@kernel.org> + +From: Kuen-Han Tsai + +[ Upstream commit 47b2116e54b4a854600341487e8b55249e926324 ] + +After an bind/unbind cycle, the acm->notify_req is left stale. If a +subsequent bind fails, the unified error label attempts to free this +stale request, leading to a NULL pointer dereference when accessing +ep->ops->free_request. + +Refactor the error handling in the bind path to use the __free() +automatic cleanup mechanism. + +Unable to handle kernel NULL pointer dereference at virtual address 0000000000000020 +Call trace: + usb_ep_free_request+0x2c/0xec + gs_free_req+0x30/0x44 + acm_bind+0x1b8/0x1f4 + usb_add_function+0xcc/0x1f0 + configfs_composite_bind+0x468/0x588 + gadget_bind_driver+0x104/0x270 + really_probe+0x190/0x374 + __driver_probe_device+0xa0/0x12c + driver_probe_device+0x3c/0x218 + __device_attach_driver+0x14c/0x188 + bus_for_each_drv+0x10c/0x168 + __device_attach+0xfc/0x198 + device_initial_probe+0x14/0x24 + bus_probe_device+0x94/0x11c + device_add+0x268/0x48c + usb_add_gadget+0x198/0x28c + dwc3_gadget_init+0x700/0x858 + __dwc3_set_mode+0x3cc/0x664 + process_scheduled_works+0x1d8/0x488 + worker_thread+0x244/0x334 + kthread+0x114/0x1bc + ret_from_fork+0x10/0x20 + +Fixes: 1f1ba11b6494 ("usb gadget: issue notifications from ACM function") +Cc: stable@kernel.org +Signed-off-by: Kuen-Han Tsai +Link: https://lore.kernel.org/r/20250916-ready-v1-4-4997bf277548@google.com +Signed-off-by: Greg Kroah-Hartman +Link: https://lore.kernel.org/r/20250916-ready-v1-4-4997bf277548@google.com +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_acm.c | 42 ++++++++++++++++-------------------- + 1 file changed, 19 insertions(+), 23 deletions(-) + +--- a/drivers/usb/gadget/function/f_acm.c ++++ b/drivers/usb/gadget/function/f_acm.c +@@ -11,12 +11,15 @@ + + /* #define VERBOSE_DEBUG */ + ++#include + #include + #include + #include + #include + #include + ++#include ++ + #include "u_serial.h" + + +@@ -612,6 +615,7 @@ acm_bind(struct usb_configuration *c, st + struct usb_string *us; + int status; + struct usb_ep *ep; ++ struct usb_request *request __free(free_usb_request) = NULL; + + /* REVISIT might want instance-specific strings to help + * distinguish instances ... +@@ -629,7 +633,7 @@ acm_bind(struct usb_configuration *c, st + /* allocate instance-specific interface IDs, and patch descriptors */ + status = usb_interface_id(c, f); + if (status < 0) +- goto fail; ++ return status; + acm->ctrl_id = status; + acm_iad_descriptor.bFirstInterface = status; + +@@ -638,40 +642,38 @@ acm_bind(struct usb_configuration *c, st + + status = usb_interface_id(c, f); + if (status < 0) +- goto fail; ++ return status; + acm->data_id = status; + + acm_data_interface_desc.bInterfaceNumber = status; + acm_union_desc.bSlaveInterface0 = status; + acm_call_mgmt_descriptor.bDataInterface = status; + +- status = -ENODEV; +- + /* allocate instance-specific endpoints */ + ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_in_desc); + if (!ep) +- goto fail; ++ return -ENODEV; + acm->port.in = ep; + + ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_out_desc); + if (!ep) +- goto fail; ++ return -ENODEV; + acm->port.out = ep; + + ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_notify_desc); + if (!ep) +- goto fail; ++ return -ENODEV; + acm->notify = ep; + + /* allocate notification */ +- acm->notify_req = gs_alloc_req(ep, +- sizeof(struct usb_cdc_notification) + 2, +- GFP_KERNEL); +- if (!acm->notify_req) +- goto fail; ++ request = gs_alloc_req(ep, ++ sizeof(struct usb_cdc_notification) + 2, ++ GFP_KERNEL); ++ if (!request) ++ return -ENODEV; + +- acm->notify_req->complete = acm_cdc_notify_complete; +- acm->notify_req->context = acm; ++ request->complete = acm_cdc_notify_complete; ++ request->context = acm; + + /* support all relevant hardware speeds... we expect that when + * hardware is dual speed, all bulk-capable endpoints work at +@@ -688,7 +690,9 @@ acm_bind(struct usb_configuration *c, st + status = usb_assign_descriptors(f, acm_fs_function, acm_hs_function, + acm_ss_function, acm_ss_function); + if (status) +- goto fail; ++ return status; ++ ++ acm->notify_req = no_free_ptr(request); + + dev_dbg(&cdev->gadget->dev, + "acm ttyGS%d: %s speed IN/%s OUT/%s NOTIFY/%s\n", +@@ -698,14 +702,6 @@ acm_bind(struct usb_configuration *c, st + acm->port.in->name, acm->port.out->name, + acm->notify->name); + return 0; +- +-fail: +- if (acm->notify_req) +- gs_free_req(acm->notify, acm->notify_req); +- +- ERROR(cdev, "%s/%p: can't bind, err %d\n", f->name, f, status); +- +- return status; + } + + static void acm_unbind(struct usb_configuration *c, struct usb_function *f) diff --git a/queue-6.1/usb-gadget-f_ecm-refactor-bind-path-to-use-__free.patch b/queue-6.1/usb-gadget-f_ecm-refactor-bind-path-to-use-__free.patch new file mode 100644 index 0000000000..da8c9a351c --- /dev/null +++ b/queue-6.1/usb-gadget-f_ecm-refactor-bind-path-to-use-__free.patch @@ -0,0 +1,159 @@ +From stable+bounces-187774-greg=kroah.com@vger.kernel.org Sat Oct 18 03:49:49 2025 +From: Sasha Levin +Date: Fri, 17 Oct 2025 21:49:37 -0400 +Subject: usb: gadget: f_ecm: Refactor bind path to use __free() +To: stable@vger.kernel.org +Cc: Kuen-Han Tsai , stable@kernel.org, Greg Kroah-Hartman , Sasha Levin +Message-ID: <20251018014938.159273-3-sashal@kernel.org> + +From: Kuen-Han Tsai + +[ Upstream commit 42988380ac67c76bb9dff8f77d7ef3eefd50b7b5 ] + +After an bind/unbind cycle, the ecm->notify_req is left stale. If a +subsequent bind fails, the unified error label attempts to free this +stale request, leading to a NULL pointer dereference when accessing +ep->ops->free_request. + +Refactor the error handling in the bind path to use the __free() +automatic cleanup mechanism. + +Fixes: da741b8c56d6 ("usb ethernet gadget: split CDC Ethernet function") +Cc: stable@kernel.org +Signed-off-by: Kuen-Han Tsai +Link: https://lore.kernel.org/r/20250916-ready-v1-5-4997bf277548@google.com +Signed-off-by: Greg Kroah-Hartman +Link: https://lore.kernel.org/r/20250916-ready-v1-5-4997bf277548@google.com +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_ecm.c | 48 +++++++++++++++--------------------- + 1 file changed, 20 insertions(+), 28 deletions(-) + +--- a/drivers/usb/gadget/function/f_ecm.c ++++ b/drivers/usb/gadget/function/f_ecm.c +@@ -8,12 +8,15 @@ + + /* #define VERBOSE_DEBUG */ + ++#include + #include + #include + #include + #include + #include + ++#include ++ + #include "u_ether.h" + #include "u_ether_configfs.h" + #include "u_ecm.h" +@@ -689,6 +692,7 @@ ecm_bind(struct usb_configuration *c, st + struct usb_ep *ep; + + struct f_ecm_opts *ecm_opts; ++ struct usb_request *request __free(free_usb_request) = NULL; + + if (!can_support_ecm(cdev->gadget)) + return -EINVAL; +@@ -726,7 +730,7 @@ ecm_bind(struct usb_configuration *c, st + /* allocate instance-specific interface IDs */ + status = usb_interface_id(c, f); + if (status < 0) +- goto fail; ++ return status; + ecm->ctrl_id = status; + ecm_iad_descriptor.bFirstInterface = status; + +@@ -735,24 +739,22 @@ ecm_bind(struct usb_configuration *c, st + + status = usb_interface_id(c, f); + if (status < 0) +- goto fail; ++ return status; + ecm->data_id = status; + + ecm_data_nop_intf.bInterfaceNumber = status; + ecm_data_intf.bInterfaceNumber = status; + ecm_union_desc.bSlaveInterface0 = status; + +- status = -ENODEV; +- + /* allocate instance-specific endpoints */ + ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_in_desc); + if (!ep) +- goto fail; ++ return -ENODEV; + ecm->port.in_ep = ep; + + ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_out_desc); + if (!ep) +- goto fail; ++ return -ENODEV; + ecm->port.out_ep = ep; + + /* NOTE: a status/notification endpoint is *OPTIONAL* but we +@@ -761,20 +763,18 @@ ecm_bind(struct usb_configuration *c, st + */ + ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_notify_desc); + if (!ep) +- goto fail; ++ return -ENODEV; + ecm->notify = ep; + +- status = -ENOMEM; +- + /* allocate notification request and buffer */ +- ecm->notify_req = usb_ep_alloc_request(ep, GFP_KERNEL); +- if (!ecm->notify_req) +- goto fail; +- ecm->notify_req->buf = kmalloc(ECM_STATUS_BYTECOUNT, GFP_KERNEL); +- if (!ecm->notify_req->buf) +- goto fail; +- ecm->notify_req->context = ecm; +- ecm->notify_req->complete = ecm_notify_complete; ++ request = usb_ep_alloc_request(ep, GFP_KERNEL); ++ if (!request) ++ return -ENOMEM; ++ request->buf = kmalloc(ECM_STATUS_BYTECOUNT, GFP_KERNEL); ++ if (!request->buf) ++ return -ENOMEM; ++ request->context = ecm; ++ request->complete = ecm_notify_complete; + + /* support all relevant hardware speeds... we expect that when + * hardware is dual speed, all bulk-capable endpoints work at +@@ -793,7 +793,7 @@ ecm_bind(struct usb_configuration *c, st + status = usb_assign_descriptors(f, ecm_fs_function, ecm_hs_function, + ecm_ss_function, ecm_ss_function); + if (status) +- goto fail; ++ return status; + + /* NOTE: all that is done without knowing or caring about + * the network link ... which is unavailable to this code +@@ -803,22 +803,14 @@ ecm_bind(struct usb_configuration *c, st + ecm->port.open = ecm_open; + ecm->port.close = ecm_close; + ++ ecm->notify_req = no_free_ptr(request); ++ + DBG(cdev, "CDC Ethernet: %s speed IN/%s OUT/%s NOTIFY/%s\n", + gadget_is_superspeed(c->cdev->gadget) ? "super" : + gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", + ecm->port.in_ep->name, ecm->port.out_ep->name, + ecm->notify->name); + return 0; +- +-fail: +- if (ecm->notify_req) { +- kfree(ecm->notify_req->buf); +- usb_ep_free_request(ecm->notify, ecm->notify_req); +- } +- +- ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); +- +- return status; + } + + static inline struct f_ecm_opts *to_f_ecm_opts(struct config_item *item) diff --git a/queue-6.1/usb-gadget-f_ncm-refactor-bind-path-to-use-__free.patch b/queue-6.1/usb-gadget-f_ncm-refactor-bind-path-to-use-__free.patch new file mode 100644 index 0000000000..8281a9bc38 --- /dev/null +++ b/queue-6.1/usb-gadget-f_ncm-refactor-bind-path-to-use-__free.patch @@ -0,0 +1,231 @@ +From stable+bounces-187768-greg=kroah.com@vger.kernel.org Sat Oct 18 03:22:30 2025 +From: Sasha Levin +Date: Fri, 17 Oct 2025 21:22:17 -0400 +Subject: usb: gadget: f_ncm: Refactor bind path to use __free() +To: stable@vger.kernel.org +Cc: Kuen-Han Tsai , stable@kernel.org, Greg Kroah-Hartman , Sasha Levin +Message-ID: <20251018012217.128900-3-sashal@kernel.org> + +From: Kuen-Han Tsai + +[ Upstream commit 75a5b8d4ddd4eb6b16cb0b475d14ff4ae64295ef ] + +After an bind/unbind cycle, the ncm->notify_req is left stale. If a +subsequent bind fails, the unified error label attempts to free this +stale request, leading to a NULL pointer dereference when accessing +ep->ops->free_request. + +Refactor the error handling in the bind path to use the __free() +automatic cleanup mechanism. + +Unable to handle kernel NULL pointer dereference at virtual address 0000000000000020 +Call trace: + usb_ep_free_request+0x2c/0xec + ncm_bind+0x39c/0x3dc + usb_add_function+0xcc/0x1f0 + configfs_composite_bind+0x468/0x588 + gadget_bind_driver+0x104/0x270 + really_probe+0x190/0x374 + __driver_probe_device+0xa0/0x12c + driver_probe_device+0x3c/0x218 + __device_attach_driver+0x14c/0x188 + bus_for_each_drv+0x10c/0x168 + __device_attach+0xfc/0x198 + device_initial_probe+0x14/0x24 + bus_probe_device+0x94/0x11c + device_add+0x268/0x48c + usb_add_gadget+0x198/0x28c + dwc3_gadget_init+0x700/0x858 + __dwc3_set_mode+0x3cc/0x664 + process_scheduled_works+0x1d8/0x488 + worker_thread+0x244/0x334 + kthread+0x114/0x1bc + ret_from_fork+0x10/0x20 + +Fixes: 9f6ce4240a2b ("usb: gadget: f_ncm.c added") +Cc: stable@kernel.org +Signed-off-by: Kuen-Han Tsai +Link: https://lore.kernel.org/r/20250916-ready-v1-3-4997bf277548@google.com +Signed-off-by: Greg Kroah-Hartman +Link: https://lore.kernel.org/r/20250916-ready-v1-3-4997bf277548@google.com +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_ncm.c | 78 +++++++++++++++--------------------- + 1 file changed, 33 insertions(+), 45 deletions(-) + +--- a/drivers/usb/gadget/function/f_ncm.c ++++ b/drivers/usb/gadget/function/f_ncm.c +@@ -11,6 +11,7 @@ + * Copyright (C) 2008 Nokia Corporation + */ + ++#include + #include + #include + #include +@@ -19,6 +20,7 @@ + #include + + #include ++#include + + #include "u_ether.h" + #include "u_ether_configfs.h" +@@ -1437,18 +1439,18 @@ static int ncm_bind(struct usb_configura + struct usb_ep *ep; + struct f_ncm_opts *ncm_opts; + ++ struct usb_os_desc_table *os_desc_table __free(kfree) = NULL; ++ struct usb_request *request __free(free_usb_request) = NULL; ++ + if (!can_support_ecm(cdev->gadget)) + return -EINVAL; + + ncm_opts = container_of(f->fi, struct f_ncm_opts, func_inst); + + if (cdev->use_os_string) { +- f->os_desc_table = kzalloc(sizeof(*f->os_desc_table), +- GFP_KERNEL); +- if (!f->os_desc_table) ++ os_desc_table = kzalloc(sizeof(*os_desc_table), GFP_KERNEL); ++ if (!os_desc_table) + return -ENOMEM; +- f->os_desc_n = 1; +- f->os_desc_table[0].os_desc = &ncm_opts->ncm_os_desc; + } + + mutex_lock(&ncm_opts->lock); +@@ -1458,16 +1460,15 @@ static int ncm_bind(struct usb_configura + mutex_unlock(&ncm_opts->lock); + + if (status) +- goto fail; ++ return status; + + ncm_opts->bound = true; + + us = usb_gstrings_attach(cdev, ncm_strings, + ARRAY_SIZE(ncm_string_defs)); +- if (IS_ERR(us)) { +- status = PTR_ERR(us); +- goto fail; +- } ++ if (IS_ERR(us)) ++ return PTR_ERR(us); ++ + ncm_control_intf.iInterface = us[STRING_CTRL_IDX].id; + ncm_data_nop_intf.iInterface = us[STRING_DATA_IDX].id; + ncm_data_intf.iInterface = us[STRING_DATA_IDX].id; +@@ -1477,55 +1478,47 @@ static int ncm_bind(struct usb_configura + /* allocate instance-specific interface IDs */ + status = usb_interface_id(c, f); + if (status < 0) +- goto fail; ++ return status; + ncm->ctrl_id = status; + ncm_iad_desc.bFirstInterface = status; + + ncm_control_intf.bInterfaceNumber = status; + ncm_union_desc.bMasterInterface0 = status; + +- if (cdev->use_os_string) +- f->os_desc_table[0].if_id = +- ncm_iad_desc.bFirstInterface; +- + status = usb_interface_id(c, f); + if (status < 0) +- goto fail; ++ return status; + ncm->data_id = status; + + ncm_data_nop_intf.bInterfaceNumber = status; + ncm_data_intf.bInterfaceNumber = status; + ncm_union_desc.bSlaveInterface0 = status; + +- status = -ENODEV; +- + /* allocate instance-specific endpoints */ + ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_in_desc); + if (!ep) +- goto fail; ++ return -ENODEV; + ncm->port.in_ep = ep; + + ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_out_desc); + if (!ep) +- goto fail; ++ return -ENODEV; + ncm->port.out_ep = ep; + + ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_notify_desc); + if (!ep) +- goto fail; ++ return -ENODEV; + ncm->notify = ep; + +- status = -ENOMEM; +- + /* allocate notification request and buffer */ +- ncm->notify_req = usb_ep_alloc_request(ep, GFP_KERNEL); +- if (!ncm->notify_req) +- goto fail; +- ncm->notify_req->buf = kmalloc(NCM_STATUS_BYTECOUNT, GFP_KERNEL); +- if (!ncm->notify_req->buf) +- goto fail; +- ncm->notify_req->context = ncm; +- ncm->notify_req->complete = ncm_notify_complete; ++ request = usb_ep_alloc_request(ep, GFP_KERNEL); ++ if (!request) ++ return -ENOMEM; ++ request->buf = kmalloc(NCM_STATUS_BYTECOUNT, GFP_KERNEL); ++ if (!request->buf) ++ return -ENOMEM; ++ request->context = ncm; ++ request->complete = ncm_notify_complete; + + /* + * support all relevant hardware speeds... we expect that when +@@ -1545,7 +1538,7 @@ static int ncm_bind(struct usb_configura + status = usb_assign_descriptors(f, ncm_fs_function, ncm_hs_function, + ncm_ss_function, ncm_ss_function); + if (status) +- goto fail; ++ return status; + + /* + * NOTE: all that is done without knowing or caring about +@@ -1559,25 +1552,20 @@ static int ncm_bind(struct usb_configura + hrtimer_init(&ncm->task_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_SOFT); + ncm->task_timer.function = ncm_tx_timeout; + ++ if (cdev->use_os_string) { ++ os_desc_table[0].os_desc = &ncm_opts->ncm_os_desc; ++ os_desc_table[0].if_id = ncm_iad_desc.bFirstInterface; ++ f->os_desc_table = no_free_ptr(os_desc_table); ++ f->os_desc_n = 1; ++ } ++ ncm->notify_req = no_free_ptr(request); ++ + DBG(cdev, "CDC Network: %s speed IN/%s OUT/%s NOTIFY/%s\n", + gadget_is_superspeed(c->cdev->gadget) ? "super" : + gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", + ncm->port.in_ep->name, ncm->port.out_ep->name, + ncm->notify->name); + return 0; +- +-fail: +- kfree(f->os_desc_table); +- f->os_desc_n = 0; +- +- if (ncm->notify_req) { +- kfree(ncm->notify_req->buf); +- usb_ep_free_request(ncm->notify, ncm->notify_req); +- } +- +- ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); +- +- return status; + } + + static inline struct f_ncm_opts *to_f_ncm_opts(struct config_item *item) diff --git a/queue-6.1/usb-gadget-f_rndis-refactor-bind-path-to-use-__free.patch b/queue-6.1/usb-gadget-f_rndis-refactor-bind-path-to-use-__free.patch new file mode 100644 index 0000000000..bb2cbb9bb0 --- /dev/null +++ b/queue-6.1/usb-gadget-f_rndis-refactor-bind-path-to-use-__free.patch @@ -0,0 +1,212 @@ +From stable+bounces-187802-greg=kroah.com@vger.kernel.org Sat Oct 18 04:44:54 2025 +From: Sasha Levin +Date: Fri, 17 Oct 2025 22:44:44 -0400 +Subject: usb: gadget: f_rndis: Refactor bind path to use __free() +To: stable@vger.kernel.org +Cc: Kuen-Han Tsai , stable@kernel.org, Greg Kroah-Hartman , Sasha Levin +Message-ID: <20251018024444.228704-3-sashal@kernel.org> + +From: Kuen-Han Tsai + +[ Upstream commit 08228941436047bdcd35a612c1aec0912a29d8cd ] + +After an bind/unbind cycle, the rndis->notify_req is left stale. If a +subsequent bind fails, the unified error label attempts to free this +stale request, leading to a NULL pointer dereference when accessing +ep->ops->free_request. + +Refactor the error handling in the bind path to use the __free() +automatic cleanup mechanism. + +Fixes: 45fe3b8e5342 ("usb ethernet gadget: split RNDIS function") +Cc: stable@kernel.org +Signed-off-by: Kuen-Han Tsai +Link: https://lore.kernel.org/r/20250916-ready-v1-6-4997bf277548@google.com +Signed-off-by: Greg Kroah-Hartman +Link: https://lore.kernel.org/r/20250916-ready-v1-6-4997bf277548@google.com +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_rndis.c | 85 ++++++++++++++-------------------- + 1 file changed, 35 insertions(+), 50 deletions(-) + +--- a/drivers/usb/gadget/function/f_rndis.c ++++ b/drivers/usb/gadget/function/f_rndis.c +@@ -19,6 +19,8 @@ + + #include + ++#include ++ + #include "u_ether.h" + #include "u_ether_configfs.h" + #include "u_rndis.h" +@@ -675,6 +677,8 @@ rndis_bind(struct usb_configuration *c, + struct usb_ep *ep; + + struct f_rndis_opts *rndis_opts; ++ struct usb_os_desc_table *os_desc_table __free(kfree) = NULL; ++ struct usb_request *request __free(free_usb_request) = NULL; + + if (!can_support_rndis(c)) + return -EINVAL; +@@ -682,12 +686,9 @@ rndis_bind(struct usb_configuration *c, + rndis_opts = container_of(f->fi, struct f_rndis_opts, func_inst); + + if (cdev->use_os_string) { +- f->os_desc_table = kzalloc(sizeof(*f->os_desc_table), +- GFP_KERNEL); +- if (!f->os_desc_table) ++ os_desc_table = kzalloc(sizeof(*os_desc_table), GFP_KERNEL); ++ if (!os_desc_table) + return -ENOMEM; +- f->os_desc_n = 1; +- f->os_desc_table[0].os_desc = &rndis_opts->rndis_os_desc; + } + + rndis_iad_descriptor.bFunctionClass = rndis_opts->class; +@@ -705,16 +706,14 @@ rndis_bind(struct usb_configuration *c, + gether_set_gadget(rndis_opts->net, cdev->gadget); + status = gether_register_netdev(rndis_opts->net); + if (status) +- goto fail; ++ return status; + rndis_opts->bound = true; + } + + us = usb_gstrings_attach(cdev, rndis_strings, + ARRAY_SIZE(rndis_string_defs)); +- if (IS_ERR(us)) { +- status = PTR_ERR(us); +- goto fail; +- } ++ if (IS_ERR(us)) ++ return PTR_ERR(us); + rndis_control_intf.iInterface = us[0].id; + rndis_data_intf.iInterface = us[1].id; + rndis_iad_descriptor.iFunction = us[2].id; +@@ -722,36 +721,30 @@ rndis_bind(struct usb_configuration *c, + /* allocate instance-specific interface IDs */ + status = usb_interface_id(c, f); + if (status < 0) +- goto fail; ++ return status; + rndis->ctrl_id = status; + rndis_iad_descriptor.bFirstInterface = status; + + rndis_control_intf.bInterfaceNumber = status; + rndis_union_desc.bMasterInterface0 = status; + +- if (cdev->use_os_string) +- f->os_desc_table[0].if_id = +- rndis_iad_descriptor.bFirstInterface; +- + status = usb_interface_id(c, f); + if (status < 0) +- goto fail; ++ return status; + rndis->data_id = status; + + rndis_data_intf.bInterfaceNumber = status; + rndis_union_desc.bSlaveInterface0 = status; + +- status = -ENODEV; +- + /* allocate instance-specific endpoints */ + ep = usb_ep_autoconfig(cdev->gadget, &fs_in_desc); + if (!ep) +- goto fail; ++ return -ENODEV; + rndis->port.in_ep = ep; + + ep = usb_ep_autoconfig(cdev->gadget, &fs_out_desc); + if (!ep) +- goto fail; ++ return -ENODEV; + rndis->port.out_ep = ep; + + /* NOTE: a status/notification endpoint is, strictly speaking, +@@ -760,21 +753,19 @@ rndis_bind(struct usb_configuration *c, + */ + ep = usb_ep_autoconfig(cdev->gadget, &fs_notify_desc); + if (!ep) +- goto fail; ++ return -ENODEV; + rndis->notify = ep; + +- status = -ENOMEM; +- + /* allocate notification request and buffer */ +- rndis->notify_req = usb_ep_alloc_request(ep, GFP_KERNEL); +- if (!rndis->notify_req) +- goto fail; +- rndis->notify_req->buf = kmalloc(STATUS_BYTECOUNT, GFP_KERNEL); +- if (!rndis->notify_req->buf) +- goto fail; +- rndis->notify_req->length = STATUS_BYTECOUNT; +- rndis->notify_req->context = rndis; +- rndis->notify_req->complete = rndis_response_complete; ++ request = usb_ep_alloc_request(ep, GFP_KERNEL); ++ if (!request) ++ return -ENOMEM; ++ request->buf = kmalloc(STATUS_BYTECOUNT, GFP_KERNEL); ++ if (!request->buf) ++ return -ENOMEM; ++ request->length = STATUS_BYTECOUNT; ++ request->context = rndis; ++ request->complete = rndis_response_complete; + + /* support all relevant hardware speeds... we expect that when + * hardware is dual speed, all bulk-capable endpoints work at +@@ -791,7 +782,7 @@ rndis_bind(struct usb_configuration *c, + status = usb_assign_descriptors(f, eth_fs_function, eth_hs_function, + eth_ss_function, eth_ss_function); + if (status) +- goto fail; ++ return status; + + rndis->port.open = rndis_open; + rndis->port.close = rndis_close; +@@ -802,9 +793,18 @@ rndis_bind(struct usb_configuration *c, + if (rndis->manufacturer && rndis->vendorID && + rndis_set_param_vendor(rndis->params, rndis->vendorID, + rndis->manufacturer)) { +- status = -EINVAL; +- goto fail_free_descs; ++ usb_free_all_descriptors(f); ++ return -EINVAL; ++ } ++ ++ if (cdev->use_os_string) { ++ os_desc_table[0].os_desc = &rndis_opts->rndis_os_desc; ++ os_desc_table[0].if_id = rndis_iad_descriptor.bFirstInterface; ++ f->os_desc_table = no_free_ptr(os_desc_table); ++ f->os_desc_n = 1; ++ + } ++ rndis->notify_req = no_free_ptr(request); + + /* NOTE: all that is done without knowing or caring about + * the network link ... which is unavailable to this code +@@ -817,21 +817,6 @@ rndis_bind(struct usb_configuration *c, + rndis->port.in_ep->name, rndis->port.out_ep->name, + rndis->notify->name); + return 0; +- +-fail_free_descs: +- usb_free_all_descriptors(f); +-fail: +- kfree(f->os_desc_table); +- f->os_desc_n = 0; +- +- if (rndis->notify_req) { +- kfree(rndis->notify_req->buf); +- usb_ep_free_request(rndis->notify, rndis->notify_req); +- } +- +- ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); +- +- return status; + } + + void rndis_borrow_net(struct usb_function_instance *f, struct net_device *net) diff --git a/queue-6.1/usb-gadget-introduce-free_usb_request-helper.patch b/queue-6.1/usb-gadget-introduce-free_usb_request-helper.patch new file mode 100644 index 0000000000..14d4d3255b --- /dev/null +++ b/queue-6.1/usb-gadget-introduce-free_usb_request-helper.patch @@ -0,0 +1,68 @@ +From stable+bounces-187767-greg=kroah.com@vger.kernel.org Sat Oct 18 03:22:29 2025 +From: Sasha Levin +Date: Fri, 17 Oct 2025 21:22:16 -0400 +Subject: usb: gadget: Introduce free_usb_request helper +To: stable@vger.kernel.org +Cc: Kuen-Han Tsai , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20251018012217.128900-2-sashal@kernel.org> + +From: Kuen-Han Tsai + +[ Upstream commit 201c53c687f2b55a7cc6d9f4000af4797860174b ] + +Introduce the free_usb_request() function that frees both the request's +buffer and the request itself. + +This function serves as the cleanup callback for DEFINE_FREE() to enable +automatic, scope-based cleanup for usb_request pointers. + +Signed-off-by: Kuen-Han Tsai +Link: https://lore.kernel.org/r/20250916-ready-v1-2-4997bf277548@google.com +Signed-off-by: Greg Kroah-Hartman +Link: https://lore.kernel.org/r/20250916-ready-v1-2-4997bf277548@google.com +Stable-dep-of: 75a5b8d4ddd4 ("usb: gadget: f_ncm: Refactor bind path to use __free()") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/usb/gadget.h | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +--- a/include/linux/usb/gadget.h ++++ b/include/linux/usb/gadget.h +@@ -15,6 +15,7 @@ + #ifndef __LINUX_USB_GADGET_H + #define __LINUX_USB_GADGET_H + ++#include + #include + #include + #include +@@ -290,6 +291,28 @@ static inline void usb_ep_fifo_flush(str + + /*-------------------------------------------------------------------------*/ + ++/** ++ * free_usb_request - frees a usb_request object and its buffer ++ * @req: the request being freed ++ * ++ * This helper function frees both the request's buffer and the request object ++ * itself by calling usb_ep_free_request(). Its signature is designed to be used ++ * with DEFINE_FREE() to enable automatic, scope-based cleanup for usb_request ++ * pointers. ++ */ ++static inline void free_usb_request(struct usb_request *req) ++{ ++ if (!req) ++ return; ++ ++ kfree(req->buf); ++ usb_ep_free_request(req->ep, req); ++} ++ ++DEFINE_FREE(free_usb_request, struct usb_request *, free_usb_request(_T)) ++ ++/*-------------------------------------------------------------------------*/ ++ + struct usb_dcd_config_params { + __u8 bU1devExitLat; /* U1 Device exit Latency */ + #define USB_DEFAULT_U1_DEV_EXIT_LAT 0x01 /* Less then 1 microsec */ diff --git a/queue-6.1/usb-gadget-store-endpoint-pointer-in-usb_request.patch b/queue-6.1/usb-gadget-store-endpoint-pointer-in-usb_request.patch new file mode 100644 index 0000000000..4a0319b9f3 --- /dev/null +++ b/queue-6.1/usb-gadget-store-endpoint-pointer-in-usb_request.patch @@ -0,0 +1,66 @@ +From stable+bounces-187766-greg=kroah.com@vger.kernel.org Sat Oct 18 03:22:29 2025 +From: Sasha Levin +Date: Fri, 17 Oct 2025 21:22:15 -0400 +Subject: usb: gadget: Store endpoint pointer in usb_request +To: stable@vger.kernel.org +Cc: Kuen-Han Tsai , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20251018012217.128900-1-sashal@kernel.org> + +From: Kuen-Han Tsai + +[ Upstream commit bfb1d99d969fe3b892db30848aeebfa19d21f57f ] + +Gadget function drivers often have goto-based error handling in their +bind paths, which can be bug-prone. Refactoring these paths to use +__free() scope-based cleanup is desirable, but currently blocked. + +The blocker is that usb_ep_free_request(ep, req) requires two +parameters, while the __free() mechanism can only pass a pointer to the +request itself. + +Store an endpoint pointer in the struct usb_request. The pointer is +populated centrally in usb_ep_alloc_request() on every successful +allocation, making the request object self-contained. + +Signed-off-by: Kuen-Han Tsai +Link: https://lore.kernel.org/r/20250916-ready-v1-1-4997bf277548@google.com +Signed-off-by: Greg Kroah-Hartman +Link: https://lore.kernel.org/r/20250916-ready-v1-1-4997bf277548@google.com +Stable-dep-of: 75a5b8d4ddd4 ("usb: gadget: f_ncm: Refactor bind path to use __free()") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/udc/core.c | 3 +++ + include/linux/usb/gadget.h | 2 ++ + 2 files changed, 5 insertions(+) + +--- a/drivers/usb/gadget/udc/core.c ++++ b/drivers/usb/gadget/udc/core.c +@@ -194,6 +194,9 @@ struct usb_request *usb_ep_alloc_request + + req = ep->ops->alloc_request(ep, gfp_flags); + ++ if (req) ++ req->ep = ep; ++ + trace_usb_ep_alloc_request(ep, req, req ? 0 : -ENOMEM); + + return req; +--- a/include/linux/usb/gadget.h ++++ b/include/linux/usb/gadget.h +@@ -31,6 +31,7 @@ struct usb_ep; + + /** + * struct usb_request - describes one i/o request ++ * @ep: The associated endpoint set by usb_ep_alloc_request(). + * @buf: Buffer used for data. Always provide this; some controllers + * only use PIO, or don't use DMA for some endpoints. + * @dma: DMA address corresponding to 'buf'. If you don't set this +@@ -96,6 +97,7 @@ struct usb_ep; + */ + + struct usb_request { ++ struct usb_ep *ep; + void *buf; + unsigned length; + dma_addr_t dma; -- 2.47.3