Received: by 2002:a25:f815:0:0:0:0:0 with SMTP id u21csp1864874ybd; Sun, 23 Jun 2019 18:41:46 -0700 (PDT) X-Google-Smtp-Source: APXvYqwDHYNRWsgNH1+zI3l1nTGGRntXHg6/8kaP5vM7TU9jXZ4JW+7dQp5rDrEGP+GKE/mxhFRh X-Received: by 2002:a63:3f48:: with SMTP id m69mr6719518pga.17.1561340506155; Sun, 23 Jun 2019 18:41:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1561340506; cv=none; d=google.com; s=arc-20160816; b=fjBPvpmwS6VI0sLivsjzA/XEo0VZHIdOO6CgPnCiSP3rjxJus6BSGJwsfyGGATt9rB IhsL6XYwUe9ZWOR1k1Aj0SAo3Vjz2vEc+a8Nl8eFAeAZXnboR5lQFlgVB5BsNsdQyYrB Yb4KcxxARZmP2k0DWU58BptN5PLDiAwNuN2gk/0K5FHK2jASpks50IqwTlW9euGQtjkh w18ppjf4eDfMAtNOcWBUHq6GhgdQCqGcg88jCxWt1YXVXNlHw9l/BS3hffac4L25oIlo 0xO43ihUexoe4hx8Zj8ZeWk2xdkse21IWjnHDvzNSrgiTaUbSyxY7+GW1MD2RooJyWUF 6QEw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-disposition :content-transfer-encoding:mime-version:robot-unsubscribe:robot-id :git-commit-id:subject:to:references:in-reply-to:reply-to:cc :message-id:from:date:dkim-signature:dkim-filter; bh=FL9ElRP2NbGlm6mzGfn/VOTynle12eJGugbYHDBNIq4=; b=P9jGwGyvcVhJz3UV0mPY7u3qK2EQZufEIAlCYkTZ//i4sLEThoexZZu73GrodqVpNk 4ukPrAfyJTuMO1ML9lgDcmA278AW/Es8xPAAUcFwUd3qgdfbGEwflOmIsRznw0JXX8sq wp0JrZTEnySilVLjYYyW6ijfWEgEJuD9t6QMY+LLJI9Au6qQLTeAZDiFge1Nletg1FmV v1qoycMG+T7MoMJ2bh7RO7RKSBnMLfzC3AV+vy4TiYnUw+qSssgrpLYLTNvUNZZx7eAi CWp3GMNxMDnyz0MzLLevS89c8qf1Ky8aGCD7UE9ZSJV3I3XyMULa6HxZCZXPZ81pRc9g BChw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@zytor.com header.s=2019061801 header.b="rUg/d3Xk"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=zytor.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p12si8685279plq.331.2019.06.23.18.41.30; Sun, 23 Jun 2019 18:41:46 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@zytor.com header.s=2019061801 header.b="rUg/d3Xk"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=zytor.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726641AbfFXBlE (ORCPT + 99 others); Sun, 23 Jun 2019 21:41:04 -0400 Received: from terminus.zytor.com ([198.137.202.136]:43987 "EHLO mail.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726544AbfFXBlC (ORCPT ); Sun, 23 Jun 2019 21:41:02 -0400 Received: from terminus.zytor.com (localhost [127.0.0.1]) by terminus.zytor.com (8.15.2/8.15.2) with ESMTPS id x5NNpl932859584 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Sun, 23 Jun 2019 16:51:47 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 terminus.zytor.com x5NNpl932859584 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2019061801; t=1561333908; bh=FL9ElRP2NbGlm6mzGfn/VOTynle12eJGugbYHDBNIq4=; h=Date:From:Cc:Reply-To:In-Reply-To:References:To:Subject:From; b=rUg/d3Xk5aGEGkrifgFzZ9rPswCm4tUvVX+c1XDFzPw0WJ6isGkESU96Cf/ooazrz qb/XoC3qxDCa0kxvE7ACmGANIPKQCMluzaDaJL+h7yPQPqRu2uXOXEfkEklYSQjvdJ ob0x9GD+1gi3ug9aYlO53z7kJ9GqqfcweuHfRfJIb2QLcSlL6MnLcRkvfUK6+UhlmE ZqkrjCSQGeQMf5tiD9SSPMZtt/DfRRqOc0a693UBrX4v8/ShdPEQI1mDrV92BrZC21 tA8MewVsLwoX9qxO111D9b2ihqLx+yvJHqwFJLyIdaXP2drtf5c2YJbfygm6OdADTk fKzqsbsYqgrNA== Received: (from tipbot@localhost) by terminus.zytor.com (8.15.2/8.15.2/Submit) id x5NNpk3l2859580; Sun, 23 Jun 2019 16:51:46 -0700 Date: Sun, 23 Jun 2019 16:51:46 -0700 X-Authentication-Warning: terminus.zytor.com: tipbot set sender to tipbot@zytor.com using -f From: tip-bot for Vincenzo Frascino Message-ID: Cc: ralf@linux-mips.org, sthotton@marvell.com, linux-kernel@vger.kernel.org, tglx@linutronix.de, linux@rasmusvillemoes.dk, hpa@zytor.com, pcc@google.com, shuah@kernel.org, linux@armlinux.org.uk, mingo@kernel.org, huw@codeweavers.com, 0x7f454c46@gmail.com, paul.burton@mips.com, daniel.lezcano@linaro.org, arnd@arndb.de, salyzyn@android.com, vincenzo.frascino@arm.com, catalin.marinas@arm.com, will.deacon@arm.com, andre.przywara@arm.com Reply-To: linux@rasmusvillemoes.dk, hpa@zytor.com, pcc@google.com, tglx@linutronix.de, linux-kernel@vger.kernel.org, ralf@linux-mips.org, sthotton@marvell.com, huw@codeweavers.com, 0x7f454c46@gmail.com, mingo@kernel.org, shuah@kernel.org, linux@armlinux.org.uk, arnd@arndb.de, daniel.lezcano@linaro.org, paul.burton@mips.com, will.deacon@arm.com, andre.przywara@arm.com, catalin.marinas@arm.com, vincenzo.frascino@arm.com, salyzyn@android.com In-Reply-To: <20190621095252.32307-12-vincenzo.frascino@arm.com> References: <20190621095252.32307-12-vincenzo.frascino@arm.com> To: linux-tip-commits@vger.kernel.org Subject: [tip:timers/vdso] arm64: vdso: Refactor vDSO code Git-Commit-ID: c7aa2d71020d74d4c673922e295b07f6adafd6e0 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline X-Spam-Status: No, score=2.3 required=5.0 tests=ALL_TRUSTED,BAYES_00, DATE_IN_FUTURE_03_06,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU, DKIM_VALID_EF,FREEMAIL_FORGED_REPLYTO,FREEMAIL_REPLYTO_END_DIGIT autolearn=no autolearn_force=no version=3.4.2 X-Spam-Level: ** X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on terminus.zytor.com Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: c7aa2d71020d74d4c673922e295b07f6adafd6e0 Gitweb: https://git.kernel.org/tip/c7aa2d71020d74d4c673922e295b07f6adafd6e0 Author: Vincenzo Frascino AuthorDate: Fri, 21 Jun 2019 10:52:38 +0100 Committer: Thomas Gleixner CommitDate: Sat, 22 Jun 2019 21:21:08 +0200 arm64: vdso: Refactor vDSO code Most of the code for initializing the vDSOs in arm64 and compat will be shared, hence refactoring of the current code is required to avoid duplication and to simplify maintainability. No functional change. Signed-off-by: Vincenzo Frascino Signed-off-by: Thomas Gleixner Tested-by: Shijith Thotton Tested-by: Andre Przywara Cc: linux-arch@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-mips@vger.kernel.org Cc: linux-kselftest@vger.kernel.org Cc: Catalin Marinas Cc: Will Deacon Cc: Arnd Bergmann Cc: Russell King Cc: Ralf Baechle Cc: Paul Burton Cc: Daniel Lezcano Cc: Mark Salyzyn Cc: Peter Collingbourne Cc: Shuah Khan Cc: Dmitry Safonov <0x7f454c46@gmail.com> Cc: Rasmus Villemoes Cc: Huw Davies Link: https://lkml.kernel.org/r/20190621095252.32307-12-vincenzo.frascino@arm.com --- arch/arm64/kernel/vdso.c | 215 +++++++++++++++++++++++++++++++---------------- 1 file changed, 144 insertions(+), 71 deletions(-) diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 478ec865a413..be23efc3f60d 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -29,7 +29,31 @@ #include extern char vdso_start[], vdso_end[]; -static unsigned long vdso_pages __ro_after_init; + +/* vdso_lookup arch_index */ +enum arch_vdso_type { + ARM64_VDSO = 0, +}; +#define VDSO_TYPES (ARM64_VDSO + 1) + +struct __vdso_abi { + const char *name; + const char *vdso_code_start; + const char *vdso_code_end; + unsigned long vdso_pages; + /* Data Mapping */ + struct vm_special_mapping *dm; + /* Code Mapping */ + struct vm_special_mapping *cm; +}; + +static struct __vdso_abi vdso_lookup[VDSO_TYPES] __ro_after_init = { + { + .name = "vdso", + .vdso_code_start = vdso_start, + .vdso_code_end = vdso_end, + }, +}; /* * The vDSO data page. @@ -40,10 +64,110 @@ static union { } vdso_data_store __page_aligned_data; struct vdso_data *vdso_data = vdso_data_store.data; +static int __vdso_remap(enum arch_vdso_type arch_index, + const struct vm_special_mapping *sm, + struct vm_area_struct *new_vma) +{ + unsigned long new_size = new_vma->vm_end - new_vma->vm_start; + unsigned long vdso_size = vdso_lookup[arch_index].vdso_code_end - + vdso_lookup[arch_index].vdso_code_start; + + if (vdso_size != new_size) + return -EINVAL; + + current->mm->context.vdso = (void *)new_vma->vm_start; + + return 0; +} + +static int __vdso_init(enum arch_vdso_type arch_index) +{ + int i; + struct page **vdso_pagelist; + unsigned long pfn; + + if (memcmp(vdso_lookup[arch_index].vdso_code_start, "\177ELF", 4)) { + pr_err("vDSO is not a valid ELF object!\n"); + return -EINVAL; + } + + vdso_lookup[arch_index].vdso_pages = ( + vdso_lookup[arch_index].vdso_code_end - + vdso_lookup[arch_index].vdso_code_start) >> + PAGE_SHIFT; + + /* Allocate the vDSO pagelist, plus a page for the data. */ + vdso_pagelist = kcalloc(vdso_lookup[arch_index].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_lookup[arch_index].vdso_code_start); + + for (i = 0; i < vdso_lookup[arch_index].vdso_pages; i++) + vdso_pagelist[i + 1] = pfn_to_page(pfn + i); + + vdso_lookup[arch_index].dm->pages = &vdso_pagelist[0]; + vdso_lookup[arch_index].cm->pages = &vdso_pagelist[1]; + + return 0; +} + +static int __setup_additional_pages(enum arch_vdso_type arch_index, + struct mm_struct *mm, + struct linux_binprm *bprm, + int uses_interp) +{ + unsigned long vdso_base, vdso_text_len, vdso_mapping_len; + void *ret; + + vdso_text_len = vdso_lookup[arch_index].vdso_pages << PAGE_SHIFT; + /* Be sure to map the data page */ + vdso_mapping_len = vdso_text_len + PAGE_SIZE; + + 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; + } + + ret = _install_special_mapping(mm, vdso_base, PAGE_SIZE, + VM_READ|VM_MAYREAD, + vdso_lookup[arch_index].dm); + if (IS_ERR(ret)) + goto up_fail; + + 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_lookup[arch_index].cm); + if (IS_ERR(ret)) + goto up_fail; + + return 0; + +up_fail: + mm->context.vdso = NULL; + return PTR_ERR(ret); +} + #ifdef CONFIG_COMPAT /* * Create and map the vectors page for AArch32 tasks. */ +/* + * aarch32_vdso_pages: + * 0 - kuser helpers + * 1 - sigreturn code + */ #define C_VECTORS 0 #define C_SIGPAGE 1 #define C_PAGES (C_SIGPAGE + 1) @@ -172,18 +296,18 @@ out: static int vdso_mremap(const struct vm_special_mapping *sm, struct vm_area_struct *new_vma) { - unsigned long new_size = new_vma->vm_end - new_vma->vm_start; - unsigned long vdso_size = vdso_end - vdso_start; - - if (vdso_size != new_size) - return -EINVAL; - - current->mm->context.vdso = (void *)new_vma->vm_start; - - return 0; + return __vdso_remap(ARM64_VDSO, sm, new_vma); } -static struct vm_special_mapping vdso_spec[2] __ro_after_init = { +/* + * aarch64_vdso_pages: + * 0 - vvar + * 1 - vdso + */ +#define A_VVAR 0 +#define A_VDSO 1 +#define A_PAGES (A_VDSO + 1) +static struct vm_special_mapping vdso_spec[A_PAGES] __ro_after_init = { { .name = "[vvar]", }, @@ -195,37 +319,10 @@ static struct vm_special_mapping vdso_spec[2] __ro_after_init = { static int __init vdso_init(void) { - int i; - struct page **vdso_pagelist; - unsigned long pfn; - - if (memcmp(vdso_start, "\177ELF", 4)) { - pr_err("vDSO is not a valid ELF object!\n"); - return -EINVAL; - } - - vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT; - - /* Allocate the vDSO pagelist, plus a page for the data. */ - vdso_pagelist = kcalloc(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)); - + vdso_lookup[ARM64_VDSO].dm = &vdso_spec[A_VVAR]; + vdso_lookup[ARM64_VDSO].cm = &vdso_spec[A_VDSO]; - /* Grab the vDSO code pages. */ - pfn = sym_to_pfn(vdso_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]; - - return 0; + return __vdso_init(ARM64_VDSO); } arch_initcall(vdso_init); @@ -233,41 +330,17 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) { 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; - /* Be sure to map the data page */ - vdso_mapping_len = vdso_text_len + PAGE_SIZE; + int ret; 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; - } - ret = _install_special_mapping(mm, vdso_base, PAGE_SIZE, - VM_READ|VM_MAYREAD, - &vdso_spec[0]); - if (IS_ERR(ret)) - goto up_fail; - - 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; + ret = __setup_additional_pages(ARM64_VDSO, + mm, + bprm, + uses_interp); up_write(&mm->mmap_sem); - return 0; -up_fail: - mm->context.vdso = NULL; - up_write(&mm->mmap_sem); - return PTR_ERR(ret); + return ret; }