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: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
Родитель
d36a928139
Коммит
8ef9eda018
|
@ -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)
|
||||
{
|
||||
struct hypfs_diag304 diag304;
|
||||
struct hypfs_diag304 *diag304;
|
||||
unsigned long cmd;
|
||||
void __user *udata;
|
||||
void *data;
|
||||
int rc;
|
||||
|
||||
if (copy_from_user(&diag304, user_area, sizeof(diag304)))
|
||||
return -EFAULT;
|
||||
if ((diag304.args[0] >> 8) != 0 || diag304.args[1] > DIAG304_CMD_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
rc = -ENOMEM;
|
||||
data = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
diag304 = kzalloc(sizeof(*diag304), GFP_KERNEL);
|
||||
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;
|
||||
}
|
||||
|
||||
cmd = *(unsigned long *) &diag304.args[0];
|
||||
diag304.rc = hypfs_sprp_diag304(data, cmd);
|
||||
cmd = *(unsigned long *) &diag304->args[0];
|
||||
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)) {
|
||||
rc = -EFAULT;
|
||||
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:
|
||||
kfree(diag304);
|
||||
free_page((unsigned long) data);
|
||||
return rc;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче