From patchwork Mon Oct 1 17:58:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Salyzyn X-Patchwork-Id: 10622521 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DF4FC112B for ; Mon, 1 Oct 2018 18:08:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C9B8A25D9E for ; Mon, 1 Oct 2018 18:08:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BD95F26BE9; Mon, 1 Oct 2018 18:08:36 +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=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.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 0673D25D9E for ; Mon, 1 Oct 2018 18:08:36 +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:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version: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=wR/+65AFqc5mKlJBp0Ck6gC2Ll45Dm2k+1byAfK73jA=; b=trsuWq3pENxUcR dWZPpubugwuX+9/upaBdtm1NJR1ITB+bUimp78ACsliwoeNMN0fM3kDJ7bYkCcevAz4FZrVu3et+9 /PWr15wVKEcy66++e5RIPJF01CLS7/S50St6ILV/TtTm23MF715q6Tvz+DLcxIsXMC6+iCAGlx4HG 4q+Dxd523XBxHiSVOQqy6izlYY+fHHXy8RWlkXdmXRrnbGNXX3cM7y0hnmHpCQ6EOhAA5K5J6RVel MKfQj6HWOZ/5jYSp1vCXDlFVuUVx66HH6Ew+AyMBhpHkNQbKbovzQnyNs45lhTpLoD+n+IMJShRlq iieKWx2uWH8Jp8KXWK1Q==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g72cI-0002d5-EB; Mon, 01 Oct 2018 18:08:22 +0000 Received: from mail-pf1-x441.google.com ([2607:f8b0:4864:20::441]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1g72YQ-0008DV-4B for linux-arm-kernel@lists.infradead.org; Mon, 01 Oct 2018 18:05:48 +0000 Received: by mail-pf1-x441.google.com with SMTP id l9-v6so9778998pff.9 for ; Mon, 01 Oct 2018 11:04:11 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=sOPjKLOAakk2ATxxw5XzVSyruYdNVeZzHr/Hs8pvlVw=; b=hnDPHpV7TRVLm1iFIa+huzuRU52EietdeZtd38RC4mD3lpJ1E56o+dY5ponRV1+tDH CjhttDPBZsCyq+6GWF2H90ZKfgbgPWC+ZMjwyEEzH3O+TCPxB7Lcydfv5iUrElcaletM smKvnJKirX6OAHOoFdP1mdtEnYigBtHyRVCRZ9TRTGSr3oNk5OxVocVvt80FxDzV7LGv QRCmAKg6r5sTNr+gnIQ1R0kAUHaIbqXzm2LO2SOxsPcZ/1swGJc0h/dlapt3mK+gUC7h a2MSWCS/jJSLAf4m+Xr0M75IXW4xtztUiAE4Z2ZLxF7VTaEYZHqN0hAqxSqmVHFNUm0Q lRcQ== 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:mime-version:content-transfer-encoding; bh=sOPjKLOAakk2ATxxw5XzVSyruYdNVeZzHr/Hs8pvlVw=; b=KAu1m/6Z0IwpdTyYCzjw+8xhRb91KbMQgwsWCI6hTOLpUji1YmXUC5q8I0to0eOdu+ R71m27qSxMDP7grDM0e+PJA2wMERBUVvHrFwW5F78I8601ZeAA+oPjZ3zQG1C24o9X0W AA8LU3zzNg8/Q0+budXEhPEz8V63/XSKeO12FE2W/XKj12ce46v9aZzW6QR+GnmRzWku W1GJe/OTLla+Pw3Fa6JwQ+J94ZeQzkFTflnE7by7XDiS01slJi0t6bJQNimqOKfNaYJJ fM1sAdH6IncFxGurzDwu+3Qo/ksciU74Q+JFTJhXHTy0HIan2TltaZUxhDrzaimM0PqT 4jZA== X-Gm-Message-State: ABuFfogShVEIu3xW8B6Y8WtOXnS2hPzn7NtByZkWFg6DuYs6jtkW9neD RUIY0AdKMRrOYwnSGUZoghj7jQ== X-Google-Smtp-Source: ACcGV609gFtSB8A7iVi5SNuJhxzQZ+JwUX0XV2went9IB2rxXdILtfk8FBA6kCYRUlUeYkAeXK8A6A== X-Received: by 2002:a63:1245:: with SMTP id 5-v6mr11167820pgs.299.1538417051064; Mon, 01 Oct 2018 11:04:11 -0700 (PDT) Received: from nebulus.mtv.corp.google.com ([2620:0:1000:1612:b4fb:6752:f21f:3502]) by smtp.gmail.com with ESMTPSA id d186-v6sm24469261pfg.173.2018.10.01.11.04.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 01 Oct 2018 11:04:10 -0700 (PDT) From: Mark Salyzyn To: linux-kernel@vger.kernel.org Subject: RESEND [PATCH 3/6] arm64: Refactor vDSO init/setup Date: Mon, 1 Oct 2018 10:58:40 -0700 Message-Id: <20181001175845.168430-21-salyzyn@android.com> X-Mailer: git-send-email 2.19.0.605.g01d371f741-goog In-Reply-To: <20181001175845.168430-1-salyzyn@android.com> References: <20181001175845.168430-1-salyzyn@android.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181001_110422_302846_40A1F959 X-CRM114-Status: GOOD ( 23.01 ) 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: Mark Rutland , Laura Abbott , Kees Cook , Ard Biesheuvel , Catalin Marinas , Kevin Brodsky , Will Deacon , Russell King , Jeremy Linton , Mark Salyzyn , android-kernel@android.com, James Morse , Andrew Pinski , Dmitry Safonov , Andy Gross , John Stultz , Thomas Gleixner , Andy Lutomirski , linux-arm-kernel@lists.infradead.org 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 Tested-by: Mark Salyzyn Cc: James Morse Cc: Russell King Cc: Catalin Marinas Cc: Will Deacon Cc: Andy Lutomirski Cc: Dmitry Safonov Cc: John Stultz Cc: Mark Rutland Cc: Laura Abbott Cc: Kees Cook Cc: Ard Biesheuvel Cc: Andy Gross Cc: Andrew Pinski Cc: Thomas Gleixner Cc: linux-kernel@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: Jeremy Linton Cc: android-kernel@android.com --- 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 76a94bed4bd5..8529e85a521f 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; } /*