summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2018-09-06 10:31:59 +0200
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2018-10-09 11:20:53 +0200
commitc0f07ff93bffae8c4252e4945ad82bc98f82a60e (patch)
treee367dabb81e425c9594932b0143f4af609735db9
parent8ef9eda0188c2e904ef257f67cefcc3371a0c98e (diff)
downloadlinux-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.c33
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,