From patchwork Mon Aug 15 10:10:32 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Murzin X-Patchwork-Id: 9280759 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 2B9E6607FD for ; Mon, 15 Aug 2016 10:11:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1AEAE28C4C for ; Mon, 15 Aug 2016 10:11:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1000228C4F; Mon, 15 Aug 2016 10:11:04 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A2EB328C4C for ; Mon, 15 Aug 2016 10:11:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752684AbcHOKLD (ORCPT ); Mon, 15 Aug 2016 06:11:03 -0400 Received: from foss.arm.com ([217.140.101.70]:39589 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752423AbcHOKLC (ORCPT ); Mon, 15 Aug 2016 06:11:02 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 04633BA6; Mon, 15 Aug 2016 03:12:34 -0700 (PDT) Received: from login2.euhpc.arm.com (login2.euhpc.arm.com [10.6.26.144]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 538463F32C; Mon, 15 Aug 2016 03:11:01 -0700 (PDT) From: Vladimir Murzin To: linux-fbdev@vger.kernel.org Cc: tomi.valkeinen@ti.com, plagnioj@jcrosoft.com, vladimir.murzin@arm.com Subject: [RESEND PATCH 3/3] fbdev: vfb: simplify memory management Date: Mon, 15 Aug 2016 11:10:32 +0100 Message-Id: <1471255832-44793-4-git-send-email-vladimir.murzin@arm.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1471255832-44793-1-git-send-email-vladimir.murzin@arm.com> References: <1471255832-44793-1-git-send-email-vladimir.murzin@arm.com> Sender: linux-fbdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fbdev@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Substitute home-brewed memory management for framebuffer memory with what core mm provide us: vmalloc_32_user() and remap_vmalloc_range() The former is designed to allocate virtually contiguous area which is 32bit addressable and zeroed so it can be mapped to userspace without leaking data. The latter does the similar job to remap_pfn_range() but additionally validate vmalloc'ed area and it's size. Signed-off-by: Vladimir Murzin --- drivers/video/fbdev/vfb.c | 86 +++------------------------------------------ 1 file changed, 5 insertions(+), 81 deletions(-) diff --git a/drivers/video/fbdev/vfb.c b/drivers/video/fbdev/vfb.c index 2645875..1a9b8af 100644 --- a/drivers/video/fbdev/vfb.c +++ b/drivers/video/fbdev/vfb.c @@ -41,55 +41,6 @@ static char *mode_option = NULL; module_param(mode_option, charp, 0); MODULE_PARM_DESC(mode_option, "Preferred video mode (e.g. 640x480-8@60)"); -/********************************************************************** - * - * Memory management - * - **********************************************************************/ -static void *rvmalloc(unsigned long size) -{ - void *mem; - unsigned long adr; - - size = PAGE_ALIGN(size); - mem = vmalloc_32(size); - if (!mem) - return NULL; - - /* - * VFB must clear memory to prevent kernel info - * leakage into userspace - * VGA-based drivers MUST NOT clear memory if - * they want to be able to take over vgacon - */ - - memset(mem, 0, size); - adr = (unsigned long) mem; - while (size > 0) { - SetPageReserved(vmalloc_to_page((void *)adr)); - adr += PAGE_SIZE; - size -= PAGE_SIZE; - } - - return mem; -} - -static void rvfree(void *mem, unsigned long size) -{ - unsigned long adr; - - if (!mem) - return; - - adr = (unsigned long) mem; - while ((long) size > 0) { - ClearPageReserved(vmalloc_to_page((void *)adr)); - adr += PAGE_SIZE; - size -= PAGE_SIZE; - } - vfree(mem); -} - static struct fb_videomode vfb_default = { .xres = 640, .yres = 480, @@ -418,35 +369,7 @@ static int vfb_pan_display(struct fb_var_screeninfo *var, static int vfb_mmap(struct fb_info *info, struct vm_area_struct *vma) { - unsigned long start = vma->vm_start; - unsigned long size = vma->vm_end - vma->vm_start; - unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; - unsigned long page, pos; - - if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) - return -EINVAL; - if (size > info->fix.smem_len) - return -EINVAL; - if (offset > info->fix.smem_len - size) - return -EINVAL; - - pos = (unsigned long)info->fix.smem_start + offset; - - while (size > 0) { - page = vmalloc_to_pfn((void *)pos); - if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) { - return -EAGAIN; - } - start += PAGE_SIZE; - pos += PAGE_SIZE; - if (size > PAGE_SIZE) - size -= PAGE_SIZE; - else - size = 0; - } - - return 0; - + return remap_vmalloc_range(vma, (void *)info->fix.smem_start, vma->vm_pgoff); } #ifndef MODULE @@ -488,12 +411,13 @@ static int __init vfb_setup(char *options) static int vfb_probe(struct platform_device *dev) { struct fb_info *info; + unsigned int size = PAGE_ALIGN(videomemorysize); int retval = -ENOMEM; /* * For real video cards we use ioremap. */ - if (!(videomemory = rvmalloc(videomemorysize))) + if (!(videomemory = vmalloc_32_user(size))) return retval; info = framebuffer_alloc(sizeof(u32) * 256, &dev->dev); @@ -534,7 +458,7 @@ err2: err1: framebuffer_release(info); err: - rvfree(videomemory, videomemorysize); + vfree(videomemory); return retval; } @@ -544,7 +468,7 @@ static int vfb_remove(struct platform_device *dev) if (info) { unregister_framebuffer(info); - rvfree(videomemory, videomemorysize); + vfree(videomemory); fb_dealloc_cmap(&info->cmap); framebuffer_release(info); }