FAILED: patch "[PATCH] s390/vfio_ccw: Free all memory if cp_init() fails" failed to apply to 6.1-stable tree
Subsystems (4)
[email protected]
maintainerThe patch below does not apply to the 6.1-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.1.y
git checkout FETCH_HEAD
git cherry-pick -x 74186c2968f8f756ac3226b545b598457c910c75
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026082002-remember-polar-6782@gregkh' --subject-prefix 'PATCH 6.1.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 74186c2968f8f756ac3226b545b598457c910c75 Mon Sep 17 00:00:00 2001
From: Eric Farman <[email protected]>
Date: Tue, 28 Jul 2026 05:30:13 +0200
Subject: [PATCH] s390/vfio_ccw: Free all memory if cp_init() fails
The routine cp_free() is called to unpin/free any memory once an I/O is completed successfully, or if cp_prefetch() fails. But if cp_init() fails, and cp->initialized is not enabled, the same routine cannot be used to free all the memory.
An attempt to address this exists in ccwchain_handle_ccw(), where a single call to ccwchain_free() is made for the currently-processed CCW segment. But this will leak other segments (created as a result of a Transfer in Channel) that had been allocated as part of the same channel program.
Address this by performing the cleanup outside of the recursive ccwchain_handle_ccw()/ccwchain_loop_tic() logic.
drivers/s390/cio/vfio_ccw_cp.c +18 -4
@@ -455,9 +455,6 @@ static int ccwchain_handle_ccw(dma32_t cda, struct channel_program *cp)/* Loop for tics on this new chain. */ ret =ccwchain_loop_tic (chain, cp); -if (ret) -ccwchain_free (chain); -return ret; }
@@ -486,6 +483,23 @@ static int ccwchain_loop_tic(struct ccwchain *chain, struct channel_program *cp)return 0 ; } +static int ccwchain_build_ccws (dma32_t cda,struct channel_program *cp) +{ +struct ccwchain *chain, *temp; +int ret; + + ret =ccwchain_handle_ccw (cda, cp); + +if (ret) { +/* Cleanup if an error occurred */ +list_for_each_entry_safe (chain, temp, &cp->ccwchain_list, next) { +ccwchain_free (chain); + } + } + +return ret; +} +static int ccwchain_fetch_tic (struct ccw1 *ccw,struct channel_program *cp) {
@@ -735,7 +749,7 @@ int cp_init(struct channel_program *cp, union orb *orb)memcpy (&cp->orb, orb,sizeof (*orb));/* Build a ccwchain for the first CCW segment */ - ret =ccwchain_handle_ccw (orb->cmd.cpa, cp); + ret =ccwchain_build_ccws (orb->cmd.cpa, cp);if (!ret) cp->initialized = true;