diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2018-09-06 10:31:59 +0200 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2018-10-09 11:20:53 +0200 |
commit | c0f07ff93bffae8c4252e4945ad82bc98f82a60e (patch) | |
tree | e367dabb81e425c9594932b0143f4af609735db9 | |
parent | 8ef9eda0188c2e904ef257f67cefcc3371a0c98e (diff) | |
download | linux-c0f07ff93bffae8c4252e4945ad82bc98f82a60e.tar.bz2 |
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 <gerald.schaefer@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r-- | drivers/s390/char/monwriter.c | 33 |
1 files 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, |