From: Sebastian Ott <sebott@xxxxxxxxxxxxxxxxxx> [ Upstream commit 0d9bfe9123cfde59bf5c2e375b59d2a7d5061c4c ] Measurement characteristics are allocated during channel path registration but not freed during deregistration. Fix this by embedding these characteristics inside struct channel_path. Signed-off-by: Sebastian Ott <sebott@xxxxxxxxxxxxxxxxxx> Reviewed-by: Peter Oberparleiter <oberpar@xxxxxxxxxxxxxxxxxx> Signed-off-by: Martin Schwidefsky <schwidefsky@xxxxxxxxxx> Signed-off-by: Sasha Levin <alexander.levin@xxxxxxxxxxx> --- drivers/s390/cio/chp.c | 6 +++--- drivers/s390/cio/chp.h | 2 +- drivers/s390/cio/chsc.c | 16 ++-------------- 3 files changed, 6 insertions(+), 18 deletions(-) diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index c692dfe..3d2b6c4 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c @@ -139,11 +139,11 @@ static ssize_t chp_measurement_chars_read(struct file *filp, device = container_of(kobj, struct device, kobj); chp = to_channelpath(device); - if (!chp->cmg_chars) + if (chp->cmg == -1) return 0; - return memory_read_from_buffer(buf, count, &off, - chp->cmg_chars, sizeof(struct cmg_chars)); + return memory_read_from_buffer(buf, count, &off, &chp->cmg_chars, + sizeof(chp->cmg_chars)); } static struct bin_attribute chp_measurement_chars_attr = { diff --git a/drivers/s390/cio/chp.h b/drivers/s390/cio/chp.h index 4efd5b8..af02322 100644 --- a/drivers/s390/cio/chp.h +++ b/drivers/s390/cio/chp.h @@ -48,7 +48,7 @@ struct channel_path { /* Channel-measurement related stuff: */ int cmg; int shared; - void *cmg_chars; + struct cmg_chars cmg_chars; }; /* Return channel_path struct for given chpid. */ diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index a831d18..5df0efe 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -967,22 +967,19 @@ static void chsc_initialize_cmg_chars(struct channel_path *chp, u8 cmcv, struct cmg_chars *chars) { - struct cmg_chars *cmg_chars; int i, mask; - cmg_chars = chp->cmg_chars; for (i = 0; i < NR_MEASUREMENT_CHARS; i++) { mask = 0x80 >> (i + 3); if (cmcv & mask) - cmg_chars->values[i] = chars->values[i]; + chp->cmg_chars.values[i] = chars->values[i]; else - cmg_chars->values[i] = 0; + chp->cmg_chars.values[i] = 0; } } int chsc_get_channel_measurement_chars(struct channel_path *chp) { - struct cmg_chars *cmg_chars; int ccode, ret; struct { @@ -1006,11 +1003,6 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp) u32 data[NR_MEASUREMENT_CHARS]; } __attribute__ ((packed)) *scmc_area; - chp->cmg_chars = NULL; - cmg_chars = kmalloc(sizeof(*cmg_chars), GFP_KERNEL); - if (!cmg_chars) - return -ENOMEM; - spin_lock_irq(&chsc_page_lock); memset(chsc_page, 0, PAGE_SIZE); scmc_area = chsc_page; @@ -1042,14 +1034,10 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp) /* No cmg-dependent data. */ goto out; } - chp->cmg_chars = cmg_chars; chsc_initialize_cmg_chars(chp, scmc_area->cmcv, (struct cmg_chars *) &scmc_area->data); out: spin_unlock_irq(&chsc_page_lock); - if (!chp->cmg_chars) - kfree(cmg_chars); - return ret; } -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html