vfio-ccw: Fix memory leak and don't call cp_free in cp_init
We don't set cp->initialized to true so calling cp_free
will just return and not do anything.
Also fix a memory leak where we fail to free a ccwchain
on an error.
Fixes: 812271b910 ("s390/cio: Squash cp_free() and cp_unpin_free()")
Signed-off-by: Farhan Ali <alifm@linux.ibm.com>
Message-Id: <3173c4216f4555d9765eb6e4922534982bc820e4.1562854091.git.alifm@linux.ibm.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Eric Farman <farman@linux.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
This commit is contained in:
committed by
Cornelia Huck
parent
c9f597a4d6
commit
8b515be512
@@ -421,7 +421,7 @@ static int ccwchain_loop_tic(struct ccwchain *chain,
|
|||||||
static int ccwchain_handle_ccw(u32 cda, struct channel_program *cp)
|
static int ccwchain_handle_ccw(u32 cda, struct channel_program *cp)
|
||||||
{
|
{
|
||||||
struct ccwchain *chain;
|
struct ccwchain *chain;
|
||||||
int len;
|
int len, ret;
|
||||||
|
|
||||||
/* Copy 2K (the most we support today) of possible CCWs */
|
/* Copy 2K (the most we support today) of possible CCWs */
|
||||||
len = copy_from_iova(cp->mdev, cp->guest_cp, cda,
|
len = copy_from_iova(cp->mdev, cp->guest_cp, cda,
|
||||||
@@ -448,7 +448,12 @@ static int ccwchain_handle_ccw(u32 cda, struct channel_program *cp)
|
|||||||
memcpy(chain->ch_ccw, cp->guest_cp, len * sizeof(struct ccw1));
|
memcpy(chain->ch_ccw, cp->guest_cp, len * sizeof(struct ccw1));
|
||||||
|
|
||||||
/* Loop for tics on this new chain. */
|
/* Loop for tics on this new chain. */
|
||||||
return ccwchain_loop_tic(chain, cp);
|
ret = ccwchain_loop_tic(chain, cp);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
ccwchain_free(chain);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loop for TICs. */
|
/* Loop for TICs. */
|
||||||
@@ -642,8 +647,6 @@ int cp_init(struct channel_program *cp, struct device *mdev, union orb *orb)
|
|||||||
|
|
||||||
/* Build a ccwchain for the first CCW segment */
|
/* Build a ccwchain for the first CCW segment */
|
||||||
ret = ccwchain_handle_ccw(orb->cmd.cpa, cp);
|
ret = ccwchain_handle_ccw(orb->cmd.cpa, cp);
|
||||||
if (ret)
|
|
||||||
cp_free(cp);
|
|
||||||
|
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
cp->initialized = true;
|
cp->initialized = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user