s390/monwriter: do not use stack buffers for hardware data
authorMartin Schwidefsky <schwidefsky@de.ibm.com>
Thu, 6 Sep 2018 08:31:59 +0000 (10:31 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Tue, 9 Oct 2018 09:20:53 +0000 (11:20 +0200)
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>
drivers/s390/char/monwriter.c

index 6388f614de4e580822ded85103655911f1df390b..fdc0c0b7a6f58ec8b62ef131b2530aac162f1fbe 100644 (file)
@@ -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,