tty/vt: avoid high order pages allocation on GIO_UNIMAP ioctl
GIO_UNIMAP can easily result in a high order allocation, seen 6th order allocation on radeondrmfb: fbcon: radeondrmfb (fb0) is primary device Console: switching to colour frame buffer device 160x64 radeon 0000:01:05.0: fb0: radeondrmfb frame buffer device WARNING: CPU: 0 PID: 78661 at mm/page_alloc.c:3532 __alloc_pages_nodemask+0x1b1/0x600 order 6 >= 3, gfp 0x40d0 The warning is generated by a debug patch. At the same time it's safe to use kvmalloc() for allocation in con_get_unimap(), so let's do the substitution. And do the same for con_set_unimap(). Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>hifive-unleashed-5.2
parent
f692f7766f
commit
fa2b360f26
|
@ -542,7 +542,7 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
|
||||||
if (!ct)
|
if (!ct)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unilist = memdup_user(list, ct * sizeof(struct unipair));
|
unilist = vmemdup_user(list, ct * sizeof(struct unipair));
|
||||||
if (IS_ERR(unilist))
|
if (IS_ERR(unilist))
|
||||||
return PTR_ERR(unilist);
|
return PTR_ERR(unilist);
|
||||||
|
|
||||||
|
@ -641,7 +641,7 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
console_unlock();
|
console_unlock();
|
||||||
kfree(unilist);
|
kvfree(unilist);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -743,7 +743,7 @@ int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct uni
|
||||||
struct uni_pagedir *p;
|
struct uni_pagedir *p;
|
||||||
struct unipair *unilist;
|
struct unipair *unilist;
|
||||||
|
|
||||||
unilist = kmalloc_array(ct, sizeof(struct unipair), GFP_KERNEL);
|
unilist = kvmalloc_array(ct, sizeof(struct unipair), GFP_KERNEL);
|
||||||
if (!unilist)
|
if (!unilist)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -775,7 +775,7 @@ int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct uni
|
||||||
if (copy_to_user(list, unilist, min(ect, ct) * sizeof(struct unipair)))
|
if (copy_to_user(list, unilist, min(ect, ct) * sizeof(struct unipair)))
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
put_user(ect, uct);
|
put_user(ect, uct);
|
||||||
kfree(unilist);
|
kvfree(unilist);
|
||||||
return ret ? ret : (ect <= ct) ? 0 : -ENOMEM;
|
return ret ? ret : (ect <= ct) ? 0 : -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue