From fa2b360f261e31f2a54f997095713f91bac0e503 Mon Sep 17 00:00:00 2001 From: Konstantin Khorenko Date: Mon, 15 Apr 2019 14:17:55 +0300 Subject: 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 Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/consolemap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/tty/vt') diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c index 7c7ada0b3ea0..b28aa0d289f8 100644 --- a/drivers/tty/vt/consolemap.c +++ b/drivers/tty/vt/consolemap.c @@ -542,7 +542,7 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list) if (!ct) return 0; - unilist = memdup_user(list, ct * sizeof(struct unipair)); + unilist = vmemdup_user(list, ct * sizeof(struct unipair)); if (IS_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: console_unlock(); - kfree(unilist); + kvfree(unilist); 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 unipair *unilist; - unilist = kmalloc_array(ct, sizeof(struct unipair), GFP_KERNEL); + unilist = kvmalloc_array(ct, sizeof(struct unipair), GFP_KERNEL); if (!unilist) 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))) ret = -EFAULT; put_user(ect, uct); - kfree(unilist); + kvfree(unilist); return ret ? ret : (ect <= ct) ? 0 : -ENOMEM; } -- cgit v1.2.3