From 07f2a637fa53bcc8064ce4152dd4d9f6693876fb Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Oct 2025 10:36:31 +0200 Subject: [PATCH] 6.17-stable patches added patches: drm-amd-check-whether-secure-display-ta-loaded-successfully.patch drm-amd-fix-hybrid-sleep.patch media-nxp-imx8-isi-m2m-fix-streaming-cleanup-on-release.patch pm-hibernate-add-pm_hibernation_mode_is_suspend.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 --- ...ecure-display-ta-loaded-successfully.patch | 40 ++ queue-6.17/drm-amd-fix-hybrid-sleep.patch | 54 +++ ...m2m-fix-streaming-cleanup-on-release.patch | 344 ++++++++++++++++++ ...e-add-pm_hibernation_mode_is_suspend.patch | 70 ++++ queue-6.17/series | 7 + ...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 ++++ 8 files changed, 861 insertions(+) create mode 100644 queue-6.17/drm-amd-check-whether-secure-display-ta-loaded-successfully.patch create mode 100644 queue-6.17/drm-amd-fix-hybrid-sleep.patch create mode 100644 queue-6.17/media-nxp-imx8-isi-m2m-fix-streaming-cleanup-on-release.patch create mode 100644 queue-6.17/pm-hibernate-add-pm_hibernation_mode_is_suspend.patch create mode 100644 queue-6.17/usb-gadget-f_rndis-refactor-bind-path-to-use-__free.patch create mode 100644 queue-6.17/usb-gadget-introduce-free_usb_request-helper.patch create mode 100644 queue-6.17/usb-gadget-store-endpoint-pointer-in-usb_request.patch diff --git a/queue-6.17/drm-amd-check-whether-secure-display-ta-loaded-successfully.patch b/queue-6.17/drm-amd-check-whether-secure-display-ta-loaded-successfully.patch new file mode 100644 index 0000000000..b61614d964 --- /dev/null +++ b/queue-6.17/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 +@@ -2350,7 +2350,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.17/drm-amd-fix-hybrid-sleep.patch b/queue-6.17/drm-amd-fix-hybrid-sleep.patch new file mode 100644 index 0000000000..db8fe9e9cc --- /dev/null +++ b/queue-6.17/drm-amd-fix-hybrid-sleep.patch @@ -0,0 +1,54 @@ +From stable+bounces-187838-greg=kroah.com@vger.kernel.org Sat Oct 18 15:51:32 2025 +From: Sasha Levin +Date: Sat, 18 Oct 2025 09:51:02 -0400 +Subject: drm/amd: Fix hybrid sleep +To: stable@vger.kernel.org +Cc: "Mario Limonciello (AMD)" , Ionut Nechita , Alex Deucher , Kenneth Crudup , "Rafael J. Wysocki" , Sasha Levin +Message-ID: <20251018135102.711457-2-sashal@kernel.org> + +From: "Mario Limonciello (AMD)" + +[ Upstream commit 0a6e9e098fcc318fec0f45a05a5c4743a81a60d9 ] + +[Why] +commit 530694f54dd5e ("drm/amdgpu: do not resume device in thaw for +normal hibernation") optimized the flow for systems that are going +into S4 where the power would be turned off. Basically the thaw() +callback wouldn't resume the device if the hibernation image was +successfully created since the system would be powered off. + +This however isn't the correct flow for a system entering into +s0i3 after the hibernation image is created. Some of the amdgpu +callbacks have different behavior depending upon the intended +state of the suspend. + +[How] +Use pm_hibernation_mode_is_suspend() as an input to decide whether +to run resume during thaw() callback. + +Reported-by: Ionut Nechita +Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4573 +Tested-by: Ionut Nechita +Fixes: 530694f54dd5e ("drm/amdgpu: do not resume device in thaw for normal hibernation") +Acked-by: Alex Deucher +Tested-by: Kenneth Crudup +Signed-off-by: Mario Limonciello (AMD) +Cc: 6.17+ # 6.17+: 495c8d35035e: PM: hibernate: Add pm_hibernation_mode_is_suspend() +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +@@ -2665,7 +2665,7 @@ static int amdgpu_pmops_thaw(struct devi + struct drm_device *drm_dev = dev_get_drvdata(dev); + + /* do not resume device if it's normal hibernation */ +- if (!pm_hibernate_is_recovering()) ++ if (!pm_hibernate_is_recovering() && !pm_hibernation_mode_is_suspend()) + return 0; + + return amdgpu_device_resume(drm_dev, true); diff --git a/queue-6.17/media-nxp-imx8-isi-m2m-fix-streaming-cleanup-on-release.patch b/queue-6.17/media-nxp-imx8-isi-m2m-fix-streaming-cleanup-on-release.patch new file mode 100644 index 0000000000..50de9bec26 --- /dev/null +++ b/queue-6.17/media-nxp-imx8-isi-m2m-fix-streaming-cleanup-on-release.patch @@ -0,0 +1,344 @@ +From stable+bounces-187357-greg=kroah.com@vger.kernel.org Fri Oct 17 17:48:54 2025 +From: Sasha Levin +Date: Fri, 17 Oct 2025 11:43:59 -0400 +Subject: media: nxp: imx8-isi: m2m: Fix streaming cleanup on release +To: stable@vger.kernel.org +Cc: Guoniu Zhou , Laurent Pinchart , Frank Li , Hans Verkuil , Sasha Levin +Message-ID: <20251017154359.4039136-1-sashal@kernel.org> + +From: Guoniu Zhou + +[ Upstream commit 178aa3360220231dd91e7dbc2eb984525886c9c1 ] + +If streamon/streamoff calls are imbalanced, such as when exiting an +application with Ctrl+C when streaming, the m2m usage_count will never +reach zero and the ISI channel won't be freed. Besides from that, if the +input line width is more than 2K, it will trigger a WARN_ON(): + +[ 59.222120] ------------[ cut here ]------------ +[ 59.226758] WARNING: drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c:631 at mxc_isi_channel_chain+0xa4/0x120, CPU#4: v4l2-ctl/654 +[ 59.238569] Modules linked in: ap1302 +[ 59.242231] CPU: 4 UID: 0 PID: 654 Comm: v4l2-ctl Not tainted 6.16.0-rc4-next-20250704-06511-gff0e002d480a-dirty #258 PREEMPT +[ 59.253597] Hardware name: NXP i.MX95 15X15 board (DT) +[ 59.258720] pstate: 80400009 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) +[ 59.265669] pc : mxc_isi_channel_chain+0xa4/0x120 +[ 59.270358] lr : mxc_isi_channel_chain+0x44/0x120 +[ 59.275047] sp : ffff8000848c3b40 +[ 59.278348] x29: ffff8000848c3b40 x28: ffff0000859b4c98 x27: ffff800081939f00 +[ 59.285472] x26: 000000000000000a x25: ffff0000859b4cb8 x24: 0000000000000001 +[ 59.292597] x23: ffff0000816f4760 x22: ffff0000816f4258 x21: ffff000084ceb780 +[ 59.299720] x20: ffff000084342ff8 x19: ffff000084340000 x18: 0000000000000000 +[ 59.306845] x17: 0000000000000000 x16: 0000000000000000 x15: 0000ffffdb369e1c +[ 59.313969] x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000 +[ 59.321093] x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000 +[ 59.328217] x8 : ffff8000848c3d48 x7 : ffff800081930b30 x6 : ffff800081930b30 +[ 59.335340] x5 : ffff0000859b6000 x4 : ffff80008193ae80 x3 : ffff800081022420 +[ 59.342464] x2 : ffff0000852f6900 x1 : 0000000000000001 x0 : ffff000084341000 +[ 59.349590] Call trace: +[ 59.352025] mxc_isi_channel_chain+0xa4/0x120 (P) +[ 59.356722] mxc_isi_m2m_streamon+0x160/0x20c +[ 59.361072] v4l_streamon+0x24/0x30 +[ 59.364556] __video_do_ioctl+0x40c/0x4a0 +[ 59.368560] video_usercopy+0x2bc/0x690 +[ 59.372382] video_ioctl2+0x18/0x24 +[ 59.375857] v4l2_ioctl+0x40/0x60 +[ 59.379168] __arm64_sys_ioctl+0xac/0x104 +[ 59.383172] invoke_syscall+0x48/0x104 +[ 59.386916] el0_svc_common.constprop.0+0xc0/0xe0 +[ 59.391613] do_el0_svc+0x1c/0x28 +[ 59.394915] el0_svc+0x34/0xf4 +[ 59.397966] el0t_64_sync_handler+0xa0/0xe4 +[ 59.402143] el0t_64_sync+0x198/0x19c +[ 59.405801] ---[ end trace 0000000000000000 ]--- + +Address this issue by moving the streaming preparation and cleanup to +the vb2 .prepare_streaming() and .unprepare_streaming() operations. This +also simplifies the driver by allowing direct usage of the +v4l2_m2m_ioctl_streamon() and v4l2_m2m_ioctl_streamoff() helpers. + +Fixes: cf21f328fcaf ("media: nxp: Add i.MX8 ISI driver") +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20250821135123.29462-1-laurent.pinchart@ideasonboard.com +Signed-off-by: Guoniu Zhou +Co-developed-by: Laurent Pinchart +Signed-off-by: Laurent Pinchart +Tested-by: Guoniu Zhou +Reviewed-by: Frank Li +Signed-off-by: Hans Verkuil +[ added bypass parameter to mxc_isi_channel_chain() call ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c | 226 ++++++++------------- + 1 file changed, 93 insertions(+), 133 deletions(-) + +--- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c ++++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c +@@ -43,7 +43,6 @@ struct mxc_isi_m2m_ctx_queue_data { + struct v4l2_pix_format_mplane format; + const struct mxc_isi_format_info *info; + u32 sequence; +- bool streaming; + }; + + struct mxc_isi_m2m_ctx { +@@ -236,6 +235,66 @@ static void mxc_isi_m2m_vb2_buffer_queue + v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); + } + ++static int mxc_isi_m2m_vb2_prepare_streaming(struct vb2_queue *q) ++{ ++ struct mxc_isi_m2m_ctx *ctx = vb2_get_drv_priv(q); ++ const struct v4l2_pix_format_mplane *out_pix = &ctx->queues.out.format; ++ const struct v4l2_pix_format_mplane *cap_pix = &ctx->queues.cap.format; ++ const struct mxc_isi_format_info *cap_info = ctx->queues.cap.info; ++ const struct mxc_isi_format_info *out_info = ctx->queues.out.info; ++ struct mxc_isi_m2m *m2m = ctx->m2m; ++ bool bypass; ++ int ret; ++ ++ guard(mutex)(&m2m->lock); ++ ++ if (m2m->usage_count == INT_MAX) ++ return -EOVERFLOW; ++ ++ bypass = cap_pix->width == out_pix->width && ++ cap_pix->height == out_pix->height && ++ cap_info->encoding == out_info->encoding; ++ ++ /* ++ * Acquire the pipe and initialize the channel with the first user of ++ * the M2M device. ++ */ ++ if (m2m->usage_count == 0) { ++ ret = mxc_isi_channel_acquire(m2m->pipe, ++ &mxc_isi_m2m_frame_write_done, ++ bypass); ++ if (ret) ++ return ret; ++ ++ mxc_isi_channel_get(m2m->pipe); ++ } ++ ++ m2m->usage_count++; ++ ++ /* ++ * Allocate resources for the channel, counting how many users require ++ * buffer chaining. ++ */ ++ if (!ctx->chained && out_pix->width > MXC_ISI_MAX_WIDTH_UNCHAINED) { ++ ret = mxc_isi_channel_chain(m2m->pipe, bypass); ++ if (ret) ++ goto err_deinit; ++ ++ m2m->chained_count++; ++ ctx->chained = true; ++ } ++ ++ return 0; ++ ++err_deinit: ++ if (--m2m->usage_count == 0) { ++ mxc_isi_channel_put(m2m->pipe); ++ mxc_isi_channel_release(m2m->pipe); ++ } ++ ++ return ret; ++} ++ + static int mxc_isi_m2m_vb2_start_streaming(struct vb2_queue *q, + unsigned int count) + { +@@ -265,13 +324,44 @@ static void mxc_isi_m2m_vb2_stop_streami + } + } + ++static void mxc_isi_m2m_vb2_unprepare_streaming(struct vb2_queue *q) ++{ ++ struct mxc_isi_m2m_ctx *ctx = vb2_get_drv_priv(q); ++ struct mxc_isi_m2m *m2m = ctx->m2m; ++ ++ guard(mutex)(&m2m->lock); ++ ++ /* ++ * If the last context is this one, reset it to make sure the device ++ * will be reconfigured when streaming is restarted. ++ */ ++ if (m2m->last_ctx == ctx) ++ m2m->last_ctx = NULL; ++ ++ /* Free the channel resources if this is the last chained context. */ ++ if (ctx->chained && --m2m->chained_count == 0) ++ mxc_isi_channel_unchain(m2m->pipe); ++ ctx->chained = false; ++ ++ /* Turn off the light with the last user. */ ++ if (--m2m->usage_count == 0) { ++ mxc_isi_channel_disable(m2m->pipe); ++ mxc_isi_channel_put(m2m->pipe); ++ mxc_isi_channel_release(m2m->pipe); ++ } ++ ++ WARN_ON(m2m->usage_count < 0); ++} ++ + static const struct vb2_ops mxc_isi_m2m_vb2_qops = { + .queue_setup = mxc_isi_m2m_vb2_queue_setup, + .buf_init = mxc_isi_m2m_vb2_buffer_init, + .buf_prepare = mxc_isi_m2m_vb2_buffer_prepare, + .buf_queue = mxc_isi_m2m_vb2_buffer_queue, ++ .prepare_streaming = mxc_isi_m2m_vb2_prepare_streaming, + .start_streaming = mxc_isi_m2m_vb2_start_streaming, + .stop_streaming = mxc_isi_m2m_vb2_stop_streaming, ++ .unprepare_streaming = mxc_isi_m2m_vb2_unprepare_streaming, + }; + + static int mxc_isi_m2m_queue_init(void *priv, struct vb2_queue *src_vq, +@@ -481,136 +571,6 @@ static int mxc_isi_m2m_s_fmt_vid(struct + return 0; + } + +-static int mxc_isi_m2m_streamon(struct file *file, void *fh, +- enum v4l2_buf_type type) +-{ +- struct mxc_isi_m2m_ctx *ctx = to_isi_m2m_ctx(fh); +- struct mxc_isi_m2m_ctx_queue_data *q = mxc_isi_m2m_ctx_qdata(ctx, type); +- const struct v4l2_pix_format_mplane *out_pix = &ctx->queues.out.format; +- const struct v4l2_pix_format_mplane *cap_pix = &ctx->queues.cap.format; +- const struct mxc_isi_format_info *cap_info = ctx->queues.cap.info; +- const struct mxc_isi_format_info *out_info = ctx->queues.out.info; +- struct mxc_isi_m2m *m2m = ctx->m2m; +- bool bypass; +- int ret; +- +- if (q->streaming) +- return 0; +- +- mutex_lock(&m2m->lock); +- +- if (m2m->usage_count == INT_MAX) { +- ret = -EOVERFLOW; +- goto unlock; +- } +- +- bypass = cap_pix->width == out_pix->width && +- cap_pix->height == out_pix->height && +- cap_info->encoding == out_info->encoding; +- +- /* +- * Acquire the pipe and initialize the channel with the first user of +- * the M2M device. +- */ +- if (m2m->usage_count == 0) { +- ret = mxc_isi_channel_acquire(m2m->pipe, +- &mxc_isi_m2m_frame_write_done, +- bypass); +- if (ret) +- goto unlock; +- +- mxc_isi_channel_get(m2m->pipe); +- } +- +- m2m->usage_count++; +- +- /* +- * Allocate resources for the channel, counting how many users require +- * buffer chaining. +- */ +- if (!ctx->chained && out_pix->width > MXC_ISI_MAX_WIDTH_UNCHAINED) { +- ret = mxc_isi_channel_chain(m2m->pipe, bypass); +- if (ret) +- goto deinit; +- +- m2m->chained_count++; +- ctx->chained = true; +- } +- +- /* +- * Drop the lock to start the stream, as the .device_run() operation +- * needs to acquire it. +- */ +- mutex_unlock(&m2m->lock); +- ret = v4l2_m2m_ioctl_streamon(file, fh, type); +- if (ret) { +- /* Reacquire the lock for the cleanup path. */ +- mutex_lock(&m2m->lock); +- goto unchain; +- } +- +- q->streaming = true; +- +- return 0; +- +-unchain: +- if (ctx->chained && --m2m->chained_count == 0) +- mxc_isi_channel_unchain(m2m->pipe); +- ctx->chained = false; +- +-deinit: +- if (--m2m->usage_count == 0) { +- mxc_isi_channel_put(m2m->pipe); +- mxc_isi_channel_release(m2m->pipe); +- } +- +-unlock: +- mutex_unlock(&m2m->lock); +- return ret; +-} +- +-static int mxc_isi_m2m_streamoff(struct file *file, void *fh, +- enum v4l2_buf_type type) +-{ +- struct mxc_isi_m2m_ctx *ctx = to_isi_m2m_ctx(fh); +- struct mxc_isi_m2m_ctx_queue_data *q = mxc_isi_m2m_ctx_qdata(ctx, type); +- struct mxc_isi_m2m *m2m = ctx->m2m; +- +- v4l2_m2m_ioctl_streamoff(file, fh, type); +- +- if (!q->streaming) +- return 0; +- +- mutex_lock(&m2m->lock); +- +- /* +- * If the last context is this one, reset it to make sure the device +- * will be reconfigured when streaming is restarted. +- */ +- if (m2m->last_ctx == ctx) +- m2m->last_ctx = NULL; +- +- /* Free the channel resources if this is the last chained context. */ +- if (ctx->chained && --m2m->chained_count == 0) +- mxc_isi_channel_unchain(m2m->pipe); +- ctx->chained = false; +- +- /* Turn off the light with the last user. */ +- if (--m2m->usage_count == 0) { +- mxc_isi_channel_disable(m2m->pipe); +- mxc_isi_channel_put(m2m->pipe); +- mxc_isi_channel_release(m2m->pipe); +- } +- +- WARN_ON(m2m->usage_count < 0); +- +- mutex_unlock(&m2m->lock); +- +- q->streaming = false; +- +- return 0; +-} +- + static const struct v4l2_ioctl_ops mxc_isi_m2m_ioctl_ops = { + .vidioc_querycap = mxc_isi_m2m_querycap, + +@@ -631,8 +591,8 @@ static const struct v4l2_ioctl_ops mxc_i + .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, + .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, + +- .vidioc_streamon = mxc_isi_m2m_streamon, +- .vidioc_streamoff = mxc_isi_m2m_streamoff, ++ .vidioc_streamon = v4l2_m2m_ioctl_streamon, ++ .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, + + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, diff --git a/queue-6.17/pm-hibernate-add-pm_hibernation_mode_is_suspend.patch b/queue-6.17/pm-hibernate-add-pm_hibernation_mode_is_suspend.patch new file mode 100644 index 0000000000..cbfdc9064d --- /dev/null +++ b/queue-6.17/pm-hibernate-add-pm_hibernation_mode_is_suspend.patch @@ -0,0 +1,70 @@ +From stable+bounces-187839-greg=kroah.com@vger.kernel.org Sat Oct 18 15:51:25 2025 +From: Sasha Levin +Date: Sat, 18 Oct 2025 09:51:01 -0400 +Subject: PM: hibernate: Add pm_hibernation_mode_is_suspend() +To: stable@vger.kernel.org +Cc: "Mario Limonciello (AMD)" , Ionut Nechita , Kenneth Crudup , Alex Deucher , "Rafael J. Wysocki" , Sasha Levin +Message-ID: <20251018135102.711457-1-sashal@kernel.org> + +From: "Mario Limonciello (AMD)" + +[ Upstream commit 495c8d35035edb66e3284113bef01f3b1b843832 ] + +Some drivers have different flows for hibernation and suspend. If +the driver opportunistically will skip thaw() then it needs a hint +to know what is happening after the hibernate. + +Introduce a new symbol pm_hibernation_mode_is_suspend() that drivers +can call to determine if suspending the system for this purpose. + +Tested-by: Ionut Nechita +Tested-by: Kenneth Crudup +Acked-by: Alex Deucher +Signed-off-by: Mario Limonciello (AMD) +Signed-off-by: Rafael J. Wysocki +Stable-dep-of: 0a6e9e098fcc ("drm/amd: Fix hybrid sleep") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/suspend.h | 2 ++ + kernel/power/hibernate.c | 11 +++++++++++ + 2 files changed, 13 insertions(+) + +--- a/include/linux/suspend.h ++++ b/include/linux/suspend.h +@@ -276,6 +276,7 @@ extern void arch_suspend_enable_irqs(voi + + extern int pm_suspend(suspend_state_t state); + extern bool sync_on_suspend_enabled; ++bool pm_hibernation_mode_is_suspend(void); + #else /* !CONFIG_SUSPEND */ + #define suspend_valid_only_mem NULL + +@@ -288,6 +289,7 @@ static inline bool pm_suspend_via_firmwa + static inline bool pm_resume_via_firmware(void) { return false; } + static inline bool pm_suspend_no_platform(void) { return false; } + static inline bool pm_suspend_default_s2idle(void) { return false; } ++static inline bool pm_hibernation_mode_is_suspend(void) { return false; } + + static inline void suspend_set_ops(const struct platform_suspend_ops *ops) {} + static inline int pm_suspend(suspend_state_t state) { return -ENOSYS; } +--- a/kernel/power/hibernate.c ++++ b/kernel/power/hibernate.c +@@ -80,6 +80,17 @@ static const struct platform_hibernation + + static atomic_t hibernate_atomic = ATOMIC_INIT(1); + ++#ifdef CONFIG_SUSPEND ++/** ++ * pm_hibernation_mode_is_suspend - Check if hibernation has been set to suspend ++ */ ++bool pm_hibernation_mode_is_suspend(void) ++{ ++ return hibernation_mode == HIBERNATION_SUSPEND; ++} ++EXPORT_SYMBOL_GPL(pm_hibernation_mode_is_suspend); ++#endif ++ + bool hibernate_acquire(void) + { + return atomic_add_unless(&hibernate_atomic, -1, 0); diff --git a/queue-6.17/series b/queue-6.17/series index 677814aa74..df69ba3bf1 100644 --- a/queue-6.17/series +++ b/queue-6.17/series @@ -44,3 +44,10 @@ drm-xe-increase-global-invalidation-timeout-to-1000us.patch perf-core-fix-address-filter-match-with-backing-files.patch perf-core-fix-mmap-event-path-names-with-backing-files.patch perf-core-fix-mmap2-event-device-with-backing-files.patch +drm-amd-check-whether-secure-display-ta-loaded-successfully.patch +pm-hibernate-add-pm_hibernation_mode_is_suspend.patch +drm-amd-fix-hybrid-sleep.patch +media-nxp-imx8-isi-m2m-fix-streaming-cleanup-on-release.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 diff --git a/queue-6.17/usb-gadget-f_rndis-refactor-bind-path-to-use-__free.patch b/queue-6.17/usb-gadget-f_rndis-refactor-bind-path-to-use-__free.patch new file mode 100644 index 0000000000..ec46ba0e3b --- /dev/null +++ b/queue-6.17/usb-gadget-f_rndis-refactor-bind-path-to-use-__free.patch @@ -0,0 +1,212 @@ +From stable+bounces-187777-greg=kroah.com@vger.kernel.org Sat Oct 18 03:57:47 2025 +From: Sasha Levin +Date: Fri, 17 Oct 2025 21:57:35 -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: <20251018015735.165734-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" +@@ -662,6 +664,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; +@@ -669,12 +673,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; +@@ -692,16 +693,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; +@@ -709,36 +708,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, +@@ -747,21 +740,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 +@@ -778,7 +769,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; +@@ -789,9 +780,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 +@@ -802,21 +802,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.17/usb-gadget-introduce-free_usb_request-helper.patch b/queue-6.17/usb-gadget-introduce-free_usb_request-helper.patch new file mode 100644 index 0000000000..62630b8e02 --- /dev/null +++ b/queue-6.17/usb-gadget-introduce-free_usb_request-helper.patch @@ -0,0 +1,68 @@ +From stable+bounces-187775-greg=kroah.com@vger.kernel.org Sat Oct 18 03:57:44 2025 +From: Sasha Levin +Date: Fri, 17 Oct 2025 21:57:34 -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: <20251018015735.165734-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: 082289414360 ("usb: gadget: f_rndis: 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 +@@ -293,6 +294,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.17/usb-gadget-store-endpoint-pointer-in-usb_request.patch b/queue-6.17/usb-gadget-store-endpoint-pointer-in-usb_request.patch new file mode 100644 index 0000000000..f5252b41c0 --- /dev/null +++ b/queue-6.17/usb-gadget-store-endpoint-pointer-in-usb_request.patch @@ -0,0 +1,66 @@ +From stable+bounces-187776-greg=kroah.com@vger.kernel.org Sat Oct 18 03:57:46 2025 +From: Sasha Levin +Date: Fri, 17 Oct 2025 21:57:33 -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: <20251018015735.165734-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: 082289414360 ("usb: gadget: f_rndis: 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 +@@ -32,6 +32,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 +@@ -98,6 +99,7 @@ struct usb_ep; + */ + + struct usb_request { ++ struct usb_ep *ep; + void *buf; + unsigned length; + dma_addr_t dma; -- 2.47.3