Commit 8ef9eda0 authored by Martin Schwidefsky's avatar Martin Schwidefsky

s390/hypfs: 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 hypsfs_diag304 structure.
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent d36a9281
...@@ -68,40 +68,44 @@ static int hypfs_sprp_create(void **data_ptr, void **free_ptr, size_t *size) ...@@ -68,40 +68,44 @@ static int hypfs_sprp_create(void **data_ptr, void **free_ptr, size_t *size)
static int __hypfs_sprp_ioctl(void __user *user_area) static int __hypfs_sprp_ioctl(void __user *user_area)
{ {
struct hypfs_diag304 diag304; struct hypfs_diag304 *diag304;
unsigned long cmd; unsigned long cmd;
void __user *udata; void __user *udata;
void *data; void *data;
int rc; int rc;
if (copy_from_user(&diag304, user_area, sizeof(diag304))) rc = -ENOMEM;
return -EFAULT;
if ((diag304.args[0] >> 8) != 0 || diag304.args[1] > DIAG304_CMD_MAX)
return -EINVAL;
data = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); data = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!data) diag304 = kzalloc(sizeof(*diag304), GFP_KERNEL);
return -ENOMEM; if (!data || !diag304)
goto out;
udata = (void __user *)(unsigned long) diag304.data;
if (diag304.args[1] == DIAG304_SET_WEIGHTS ||
diag304.args[1] == DIAG304_SET_CAPPING)
if (copy_from_user(data, udata, PAGE_SIZE)) {
rc = -EFAULT; rc = -EFAULT;
if (copy_from_user(diag304, user_area, sizeof(*diag304)))
goto out;
rc = -EINVAL;
if ((diag304->args[0] >> 8) != 0 || diag304->args[1] > DIAG304_CMD_MAX)
goto out;
rc = -EFAULT;
udata = (void __user *)(unsigned long) diag304->data;
if (diag304->args[1] == DIAG304_SET_WEIGHTS ||
diag304->args[1] == DIAG304_SET_CAPPING)
if (copy_from_user(data, udata, PAGE_SIZE))
goto out; goto out;
}
cmd = *(unsigned long *) &diag304.args[0]; cmd = *(unsigned long *) &diag304->args[0];
diag304.rc = hypfs_sprp_diag304(data, cmd); diag304->rc = hypfs_sprp_diag304(data, cmd);
if (diag304.args[1] == DIAG304_QUERY_PRP) if (diag304->args[1] == DIAG304_QUERY_PRP)
if (copy_to_user(udata, data, PAGE_SIZE)) { if (copy_to_user(udata, data, PAGE_SIZE)) {
rc = -EFAULT; rc = -EFAULT;
goto out; goto out;
} }
rc = copy_to_user(user_area, &diag304, sizeof(diag304)) ? -EFAULT : 0; rc = copy_to_user(user_area, diag304, sizeof(*diag304)) ? -EFAULT : 0;
out: out:
kfree(diag304);
free_page((unsigned long) data); free_page((unsigned long) data);
return rc; return rc;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment