From c0f07ff93bffae8c4252e4945ad82bc98f82a60e Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Thu, 6 Sep 2018 10:31:59 +0200 Subject: [PATCH] s390/monwriter: do not use stack buffers for hardware data With CONFIG_VMAP_STACK=y the stack is allocated from the vmalloc space. Data structures passed to a hardware or a hypervisor interface that requires V=R can not be allocated on the stack anymore. Use kmalloc to get memory for the appldata_parameter_list and appldata_product_id structures. Reviewed-by: Gerald Schaefer Signed-off-by: Martin Schwidefsky --- drivers/s390/char/monwriter.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c index 6388f614de4e..fdc0c0b7a6f5 100644 --- a/drivers/s390/char/monwriter.c +++ b/drivers/s390/char/monwriter.c @@ -58,24 +58,31 @@ struct mon_private { static int monwrite_diag(struct monwrite_hdr *myhdr, char *buffer, int fcn) { - struct appldata_parameter_list parm_list; - struct appldata_product_id id; + struct appldata_parameter_list *parm_list; + struct appldata_product_id *id; int rc; - memcpy(id.prod_nr, "LNXAPPL", 7); - id.prod_fn = myhdr->applid; - id.record_nr = myhdr->record_num; - id.version_nr = myhdr->version; - id.release_nr = myhdr->release; - id.mod_lvl = myhdr->mod_level; - rc = appldata_asm(&parm_list, &id, fcn, + id = kmalloc(sizeof(*id), GFP_KERNEL); + parm_list = kmalloc(sizeof(*parm_list), GFP_KERNEL); + rc = -ENOMEM; + if (!id || !parm_list) + goto out; + memcpy(id->prod_nr, "LNXAPPL", 7); + id->prod_fn = myhdr->applid; + id->record_nr = myhdr->record_num; + id->version_nr = myhdr->version; + id->release_nr = myhdr->release; + id->mod_lvl = myhdr->mod_level; + rc = appldata_asm(parm_list, id, fcn, (void *) buffer, myhdr->datalen); if (rc <= 0) - return rc; + goto out; pr_err("Writing monitor data failed with rc=%i\n", rc); - if (rc == 5) - return -EPERM; - return -EINVAL; + rc = (rc == 5) ? -EPERM : -EINVAL; +out: + kfree(id); + kfree(parm_list); + return rc; } static struct mon_buf *monwrite_find_hdr(struct mon_private *monpriv,