From patchwork Wed Nov 15 22:05:13 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Salyzyn X-Patchwork-Id: 10060439 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 6E33D6023A for ; Wed, 15 Nov 2017 22:07:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 65DCF29ED7 for ; Wed, 15 Nov 2017 22:07:45 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5A48F2A327; Wed, 15 Nov 2017 22:07:45 +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=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E149229ED7 for ; Wed, 15 Nov 2017 22:07:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=pEkKaV8H6gfF1on+33OSDwV9JC0JG4kKMXCe4JpAr/w=; b=MfQQZ8uBVb2Qye3p2lxKEyMaCG jmMP5l+5MJmK3rc5ofpO3LnflFagauQJjsadoM4BzMyA8kpa0pUCkH65a+EN2A8oaXt+RWUtJ96iX oPp1VD+mQqF+uEVIl4bSAlp9ax18J+QReok9WpkKoqtr9ecmH9gjFyW1sTo44VNpTkc+F8CyocMyr lzjxSU37ZvWSfJEtcmkBt9+ly9OuyR+7jD4QSXj+PVeMNSw/gvuI6eNYam+U+LDvTwNA+8AdAPCLO pC7LnC8dgRsz8EhqtQEIDmgmc4USB+ODVQjsPR7onc8w0JtiN/6jlHAH0WykvvzhKs5KmpBdwQ2mD t+l2V5EA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1eF5qR-0007hk-Q9; Wed, 15 Nov 2017 22:07:43 +0000 Received: from mail-io0-x242.google.com ([2607:f8b0:4001:c06::242]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1eF5pn-00073A-7a for linux-arm-kernel@lists.infradead.org; Wed, 15 Nov 2017 22:07:08 +0000 Received: by mail-io0-x242.google.com with SMTP id w127so3168428iow.11 for ; Wed, 15 Nov 2017 14:06:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=android.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=bqseDCRjc7puD3+E8SvNOy/B95AsrOUJp+hFduotp54=; b=SXQ+975KH8KZ9/4s3K5m34Y6QmQMFLnfek2N00dlIv8yNUSKX5xxw+2xMZDeMdZvIF Gv9lUCY/5wEcbcWI9iHdT7h6FMcgaZPaETTx/mGwvJr9rkIzS7qRv8mE3wwRVGinwSo/ +HZzqi0zKGhvujGAedWKsbJdNOz/bzupyyffc+qD1dRdo1hVEnsyg1oIdKKpodXzJvkX /cZxBkLNknEkb8udV8c0HiLca+X7Uuuhl5eR2E+Ba9Zlvi96fMcoH2jvTbIw6v8Y02O/ QrvoNZEPp2pT1LZvt3Vlrx68uRFBgWVYUp2OGfhWX9gCEwgD7qFwYoyD+A4pZqya4/Dx eKbQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=bqseDCRjc7puD3+E8SvNOy/B95AsrOUJp+hFduotp54=; b=q6b+KZg5ElZYe4D8U22JlQhbkHUaTyjJ/NdULLAm4KnUht9MILWbxiu48lErMZXCi+ 3zM/gFG3PNqrceg0IkBhfNs5bzcM+cO6HyuMlYzwmTZXHuZrHTz5sSPHxmAjWQtFFMjU 4FeEexkfCMSETKZ1n9sCGntZ8TRs53Se06M+C1iNR0VKSiu8Cjk+LHm3l+h63eVr3LFz KGlCZRxaTOpsg4a6UOqur+GpmyWeukyE+gJA5hLarq9Gtklrcw1ZGWSkO79GCCoesffW Ds81vf1R5MIki3eHGK2f5PFXCDf8G9fsALz5c7TpNGks4yXr870eMKH8ofkQ5WwdsAwj OmQA== X-Gm-Message-State: AJaThX7h3aue3QojCte9YNKF0zHMh9d3vsRFnz/KTXaop8OP4JdEJytd A8O6N4zKVkYNHezuL1XXTdemdA== X-Google-Smtp-Source: AGs4zMZ0kWApW23yBAmw0hlIl2CNQSla00A2XhcjS2MliLRjiirrJCj/jdFjVoMtwkjTT+zVliXaIg== X-Received: by 10.107.142.72 with SMTP id q69mr1816093iod.205.1510783602356; Wed, 15 Nov 2017 14:06:42 -0800 (PST) Received: from nebulus.mtv.corp.google.com ([2620:0:1000:1612:b4fb:6752:f21f:3502]) by smtp.gmail.com with ESMTPSA id 14sm5224751itj.34.2017.11.15.14.06.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 15 Nov 2017 14:06:41 -0800 (PST) From: Mark Salyzyn To: linux-kernel@vger.kernel.org Subject: [PATCH 3/6] arm64: Refactor vDSO init/setup Date: Wed, 15 Nov 2017 14:05:13 -0800 Message-Id: <20171115220529.14458-4-salyzyn@android.com> X-Mailer: git-send-email 2.15.0.448.gf294e3d99a-goog In-Reply-To: <20171115220529.14458-1-salyzyn@android.com> References: <20171115220529.14458-1-salyzyn@android.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20171115_140703_786140_281852D2 X-CRM114-Status: GOOD ( 20.26 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kees Cook , Catalin Marinas , Kevin Brodsky , Will Deacon , Mark Salyzyn , John Stultz , "Eric W. Biederman" , Dmitry Safonov , Dave Martin , linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Kevin Brodsky Move the logic for setting up mappings and pages for the vDSO into static functions. This makes the vDSO setup code more consistent with the compat side and will allow to reuse it for the future compat vDSO. Signed-off-by: Kevin Brodsky Signed-off-by: Mark Salyzyn Cc: Catalin Marinas Cc: Will Deacon Cc: Dave Martin Cc: "Eric W. Biederman" Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org --- arch/arm64/kernel/vdso.c | 118 ++++++++++++++++++++++++++++------------------- 1 file changed, 70 insertions(+), 48 deletions(-) diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 26d510474ffa..48b4111a933f 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -39,8 +39,11 @@ #include #include -extern char vdso_start[], vdso_end[]; -static unsigned long vdso_pages __ro_after_init; +struct vdso_mappings { + unsigned long num_code_pages; + struct vm_special_mapping data_mapping; + struct vm_special_mapping code_mapping; +}; /* * The vDSO data page. @@ -164,95 +167,114 @@ static int vdso_mremap(const struct vm_special_mapping *sm, return 0; } -static struct vm_special_mapping vdso_spec[2] __ro_after_init = { - { - .name = "[vvar]", - }, - { - .name = "[vdso]", - .mremap = vdso_mremap, - }, -}; - -static int __init vdso_init(void) +static int __init vdso_mappings_init(const char *name, + const char *code_start, + const char *code_end, + struct vdso_mappings *mappings) { - int i; + unsigned long i, vdso_page; struct page **vdso_pagelist; unsigned long pfn; - if (memcmp(vdso_start, "\177ELF", 4)) { - pr_err("vDSO is not a valid ELF object!\n"); + if (memcmp(code_start, "\177ELF", 4)) { + pr_err("%s is not a valid ELF object!\n", name); return -EINVAL; } - vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT; - pr_info("vdso: %ld pages (%ld code @ %p, %ld data @ %p)\n", - vdso_pages + 1, vdso_pages, vdso_start, 1L, vdso_data); - - /* Allocate the vDSO pagelist, plus a page for the data. */ - vdso_pagelist = kcalloc(vdso_pages + 1, sizeof(struct page *), - GFP_KERNEL); + vdso_pages = (code_end - code_start) >> PAGE_SHIFT; + pr_info("%s: %ld pages (%ld code @ %p, %ld data @ %p)\n", + name, vdso_pages + 1, vdso_pages, code_start, 1L, + vdso_data); + + /* + * Allocate space for storing pointers to the vDSO code pages + the + * data page. The pointers must have the same lifetime as the mappings, + * which are static, so there is no need to keep track of the pointer + * array to free it. + */ + vdso_pagelist = kmalloc_array(vdso_pages + 1, sizeof(struct page *), + GFP_KERNEL); if (vdso_pagelist == NULL) return -ENOMEM; /* Grab the vDSO data page. */ vdso_pagelist[0] = phys_to_page(__pa_symbol(vdso_data)); - /* Grab the vDSO code pages. */ - pfn = sym_to_pfn(vdso_start); + pfn = sym_to_pfn(code_start); for (i = 0; i < vdso_pages; i++) vdso_pagelist[i + 1] = pfn_to_page(pfn + i); - vdso_spec[0].pages = &vdso_pagelist[0]; - vdso_spec[1].pages = &vdso_pagelist[1]; + /* Populate the special mapping structures */ + mappings->data_mapping = (struct vm_special_mapping) { + .name = "[vvar]", + .pages = &vdso_pagelist[0], + }; + + mappings->code_mapping = (struct vm_special_mapping) { + .name = "[vdso]", + .pages = &vdso_pagelist[1], + }; + mappings->num_code_pages = vdso_pages; return 0; } + +static struct vdso_mappings vdso_mappings __ro_after_init; + +static int __init vdso_init(void) +{ + extern char vdso_start[], vdso_end[]; + + return vdso_mappings_init("vdso", vdso_start, vdso_end, + &vdso_mappings); +} arch_initcall(vdso_init); -int arch_setup_additional_pages(struct linux_binprm *bprm, - int uses_interp) +static int vdso_setup(struct mm_struct *mm, + const struct vdso_mappings *mappings) { - struct mm_struct *mm = current->mm; unsigned long vdso_base, vdso_text_len, vdso_mapping_len; void *ret; - vdso_text_len = vdso_pages << PAGE_SHIFT; + vdso_text_len = mappings->num_code_pages << PAGE_SHIFT; /* Be sure to map the data page */ vdso_mapping_len = vdso_text_len + PAGE_SIZE; - if (down_write_killable(&mm->mmap_sem)) - return -EINTR; vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0); - if (IS_ERR_VALUE(vdso_base)) { - ret = ERR_PTR(vdso_base); - goto up_fail; - } + if (IS_ERR_VALUE(vdso_base)) + ret = PTR_ERR_OR_ZERO(ERR_PTR(vdso_base)); + ret = _install_special_mapping(mm, vdso_base, PAGE_SIZE, VM_READ|VM_MAYREAD, - &vdso_spec[0]); + &mappings->data_mapping); if (IS_ERR(ret)) - goto up_fail; + return PTR_ERR_OR_ZERO(ret); vdso_base += PAGE_SIZE; - mm->context.vdso = (void *)vdso_base; ret = _install_special_mapping(mm, vdso_base, vdso_text_len, VM_READ|VM_EXEC| VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, - &vdso_spec[1]); - if (IS_ERR(ret)) - goto up_fail; + &mappings->code_mapping); + if (!IS_ERR(ret)) + mm->context.vdso = (void *)vdso_base; + + return PTR_ERR_OR_ZERO(ret); +} +int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) +{ + struct mm_struct *mm = current->mm; + int ret; - up_write(&mm->mmap_sem); - return 0; + if (down_write_killable(&mm->mmap_sem)) + return -EINTR; + + ret = vdso_setup(mm, &vdso_mappings); -up_fail: - mm->context.vdso = NULL; up_write(&mm->mmap_sem); - return PTR_ERR(ret); + return ret; } /*