From: luto@amacapital.net (Andy Lutomirski)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization
Date: Mon, 30 Jun 2014 14:37:48 -0700 [thread overview]
Message-ID: <53B1D8AC.7060104@mit.edu> (raw)
In-Reply-To: <1403493118-7597-9-git-send-email-nathan_lynch@mentor.com>
On 06/22/2014 08:11 PM, Nathan Lynch wrote:
> Initialize the vdso page list at boot, install the vdso mapping at
> exec time, and update the data page during timer ticks. This code is
> not built if CONFIG_VDSO is not enabled.
>
> Account for the vdso length when randomizing the offset from the
> stack. The vdso is placed immediately following the sigpage with a
> separate install_special_mapping call in arm_install_vdso.
>
> Signed-off-by: Nathan Lynch <nathan_lynch@mentor.com>
> ---
> arch/arm/kernel/process.c | 13 +++-
> arch/arm/kernel/vdso.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 179 insertions(+), 2 deletions(-)
> create mode 100644 arch/arm/kernel/vdso.c
>
> diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
> index 40445fb71ac9..39b0d68aa068 100644
> --- a/arch/arm/kernel/process.c
> +++ b/arch/arm/kernel/process.c
> @@ -520,6 +520,7 @@ extern struct page *get_signal_page(void);
> int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
> {
> struct mm_struct *mm = current->mm;
> + unsigned long npages;
> unsigned long addr;
> unsigned long hint;
> int ret;
> @@ -529,9 +530,11 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
> if (!signal_page)
> return -ENOMEM;
>
> + npages = (vdso_mapping_len >> PAGE_SHIFT) + 1;
> +
> down_write(&mm->mmap_sem);
> - hint = vdso_addr(mm, 1);
> - addr = get_unmapped_area(NULL, hint, PAGE_SIZE, 0, 0);
> + hint = vdso_addr(mm, npages);
> + addr = get_unmapped_area(NULL, hint, npages, 0, 0);
> if (IS_ERR_VALUE(addr)) {
> ret = addr;
> goto up_fail;
> @@ -544,6 +547,12 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
> if (ret == 0)
> mm->context.sigpage = addr;
>
> + /* Unlike the sigpage, failure to install the vdso is unlikely
> + * to be fatal to the process, so no error check needed
> + * here.
> + */
> + arm_install_vdso(mm, addr + PAGE_SIZE);
> +
> up_fail:
> up_write(&mm->mmap_sem);
> return ret;
> diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c
> new file mode 100644
> index 000000000000..0cfd25f09adf
> --- /dev/null
> +++ b/arch/arm/kernel/vdso.c
> @@ -0,0 +1,168 @@
> +/*
> + * Adapted from arm64 version.
> + *
> + * Copyright (C) 2012 ARM Limited
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <linux/err.h>
> +#include <linux/kernel.h>
> +#include <linux/mm.h>
> +#include <linux/slab.h>
> +#include <linux/timekeeper_internal.h>
> +#include <linux/vmalloc.h>
> +
> +#include <asm/barrier.h>
> +#include <asm/cacheflush.h>
> +#include <asm/page.h>
> +#include <asm/vdso.h>
> +#include <asm/vdso_datapage.h>
> +
> +static struct page **vdso_pagelist;
> +
> +unsigned long vdso_mapping_len __read_mostly;
> +
> +/*
> + * The vDSO data page.
> + */
> +static union vdso_data_store vdso_data_store __page_aligned_data;
> +static struct vdso_data *vdso_data = &vdso_data_store.data;
> +
> +static int __init vdso_init(void)
> +{
> + unsigned long vdso_pages;
> + int i;
> +
> + if (memcmp(&vdso_start, "\177ELF", 4)) {
> + pr_err("vDSO is not a valid ELF object!\n");
> + return -ENOEXEC;
> + }
> +
> + vdso_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT;
> + pr_debug("vdso: %ld code pages at base %p\n", vdso_pages, &vdso_start);
> +
> + /* 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] = virt_to_page(vdso_data);
> +
> + /* Grab the vDSO code pages. */
> + for (i = 0; i < vdso_pages; i++)
> + vdso_pagelist[i + 1] = virt_to_page(&vdso_start + i * PAGE_SIZE);
> +
> + /* Precompute the mapping size */
> + vdso_mapping_len = (vdso_pages + 1) << PAGE_SHIFT;
> +
> + return 0;
> +}
> +arch_initcall(vdso_init);
> +
> +/* assumes mmap_sem is write-locked */
> +void arm_install_vdso(struct mm_struct *mm, unsigned long addr)
> +{
> + int ret;
> +
> + mm->context.vdso = ~0UL;
> +
> + if (vdso_pagelist == NULL)
> + return;
> +
> + /*
> + * Put vDSO base into mm struct before calling
> + * install_special_mapping so the perf counter mmap tracking
> + * code will recognise it as a vDSO.
> + */
> + mm->context.vdso = addr;
> +
> + ret = install_special_mapping(mm, addr, vdso_mapping_len,
> + VM_READ|VM_EXEC|
> + VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
> + vdso_pagelist);
Eek. You're mapping the shared data VM_MAYWRITE. This will cause
bizarre and confusing failures if ptrace pokes at it. You also seem to
be sticking it *before* the vdso in the same vma. This will severely
piss off all the tools that assume that "[vdso]" points to an ELF object.
x86 calls this thing "[vvar]" and sticks it after the vdso. You might
not want to have the complexity of sticking it after the vdso (it's
distinctly nontrivial), but I see nothing wrong with giving it its own
vma just before the vdso. The new _install_special_mapping function
makes it considerably easier to do.
(Don't use any version of x86's code before 3.16-rc3 as a reference.)
--Andy
next prev parent reply other threads:[~2014-06-30 21:37 UTC|newest]
Thread overview: 76+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-23 3:11 [PATCH v7 0/9] ARM: VDSO Nathan Lynch
2014-06-23 3:11 ` [PATCH v7 1/9] clocksource: arm_arch_timer: change clocksource name if CP15 unavailable Nathan Lynch
2014-06-23 3:11 ` [PATCH v7 2/9] clocksource: arm_arch_timer: enable counter access for 32-bit ARM Nathan Lynch
2014-06-23 3:11 ` [PATCH v7 3/9] ARM: arch_timer: remove unused functions Nathan Lynch
2014-06-23 3:11 ` [PATCH v7 4/9] arm64: " Nathan Lynch
2014-06-23 3:11 ` [PATCH v7 5/9] ARM: place sigpage at a random offset above stack Nathan Lynch
2014-06-23 3:11 ` [PATCH v7 6/9] ARM: miscellaneous vdso infrastructure, preparation Nathan Lynch
2014-06-30 10:11 ` Arnd Bergmann
2014-06-30 12:27 ` Nathan Lynch
2014-06-30 13:06 ` Arnd Bergmann
2014-06-23 3:11 ` [PATCH v7 7/9] ARM: add vdso user-space code Nathan Lynch
2014-06-28 9:53 ` Russell King - ARM Linux
2014-06-28 10:03 ` Russell King - ARM Linux
2014-06-30 15:56 ` Andy Lutomirski
2014-06-28 15:19 ` Nathan Lynch
2014-06-28 15:26 ` Russell King - ARM Linux
2014-06-28 16:13 ` Nathan Lynch
2014-06-28 18:12 ` Russell King - ARM Linux
2014-06-28 19:45 ` Nathan Lynch
2014-06-28 20:11 ` Russell King - ARM Linux
2014-06-28 21:35 ` Nathan Lynch
2014-06-29 8:34 ` Russell King - ARM Linux
2014-06-29 15:48 ` Nathan Lynch
2014-06-29 16:07 ` Russell King - ARM Linux
2014-06-29 23:04 ` Nathan Lynch
2014-06-30 21:33 ` Andy Lutomirski
2014-06-30 15:59 ` Andy Lutomirski
2014-06-30 16:50 ` Nathan Lynch
2014-06-30 21:29 ` Andy Lutomirski
2014-07-01 9:00 ` Will Deacon
2014-07-01 13:34 ` Nathan Lynch
2014-07-01 14:11 ` Andy Lutomirski
2014-07-01 13:28 ` Nathan Lynch
2014-07-01 14:56 ` Andy Lutomirski
2014-06-23 3:11 ` [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization Nathan Lynch
2014-06-30 21:37 ` Andy Lutomirski [this message]
2014-07-01 9:03 ` Will Deacon
2014-07-01 14:11 ` Nathan Lynch
2014-07-01 14:15 ` Will Deacon
2014-07-01 14:17 ` Andy Lutomirski
2014-07-01 17:27 ` Christopher Covington
2014-07-02 14:40 ` Will Deacon
2014-07-02 15:54 ` Andy Lutomirski
2014-07-02 16:18 ` Nathan Lynch
2014-07-02 16:27 ` Will Deacon
2014-07-02 16:47 ` Andy Lutomirski
2014-07-02 17:24 ` Will Deacon
2014-07-02 18:34 ` Andy Lutomirski
2014-07-02 18:54 ` Will Deacon
2014-07-22 0:14 ` Andy Lutomirski
2014-07-22 8:13 ` Will Deacon
2014-07-01 14:01 ` Nathan Lynch
2014-07-01 14:09 ` Andy Lutomirski
2014-07-01 14:14 ` Russell King - ARM Linux
2014-06-23 3:11 ` [PATCH v7 9/9] ARM: add CONFIG_VDSO Kconfig and Makefile bits Nathan Lynch
2014-06-27 8:51 ` [PATCH v7 0/9] ARM: VDSO Jan Glauber
2014-06-27 8:57 ` Russell King - ARM Linux
2014-06-27 9:41 ` Ard Biesheuvel
2014-06-27 9:46 ` Russell King - ARM Linux
2014-06-27 17:01 ` Nathan Lynch
2014-06-28 9:42 ` Russell King - ARM Linux
2014-06-28 9:55 ` Russell King - ARM Linux
2014-06-28 14:49 ` Russell King - ARM Linux
2014-06-30 7:27 ` Arnd Bergmann
2014-06-30 7:43 ` Arnd Bergmann
2014-06-30 18:27 ` Nathan Lynch
2014-06-27 16:00 ` Nathan Lynch
2014-06-30 16:03 ` Andy Lutomirski
2014-06-30 8:12 ` Ard Biesheuvel
2014-07-01 16:34 ` Nathan Lynch
2014-07-01 20:08 ` Ard Biesheuvel
2014-07-01 22:44 ` Russell King - ARM Linux
2014-06-30 14:40 ` Will Deacon
2014-06-30 15:42 ` Nathan Lynch
2014-06-30 21:56 ` Andy Lutomirski
2014-07-01 9:04 ` Will Deacon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=53B1D8AC.7060104@mit.edu \
--to=luto@amacapital.net \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.