arm64: compat: Add COMPAT_VDSO
Subsystems (2)
cover arm64: compat: Add COMPAT_VDSO
Add compatible vDSO32 support to arm64, provide the files necessary for building a compat (AArch32) vDSO in arch/arm64/kernel/vdso32.
Leverages effort to unify the vgettimeofday.c file as outlined below.
To be applied over top the following pending patches:
[PATCH] arm64: compat: Remove leftover variable declaration
NB: approved, in arch64/for-next/core
[PATCH v3 1/3] arm64: compat: Split the sigreturn trampolines and kuser helpers (C sources) [PATCH v3 2/3] arm64: compat: Split the sigreturn trampolines and kuser helpers (assembler sources) [PATCH v3 3/3] arm64: compat: Add CONFIG_KUSER_HELPERS
[PATCH] arm64: compat: Expose offset to registers in sigframes
[PATCH v5 01/12] arm: vdso: rename vdso_datapage variables
[PATCH v5 02/12] arm: vdso: add include file defining __get_datapage()
[PATCH v5 03/12] arm: vdso: inline assembler operations to compiler.h
[PATCH v5 04/12] arm: vdso: do calculations outside reader loops
[PATCH v6 05/12] arm: vdso: Add support for CLOCK_MONOTONIC_RAW
[PATCH v5 06/12] arm: vdso: add support for clock_getres
[PATCH v5 07/12] arm: vdso: disable profiling
[PATCH v5 08/12] arm: vdso: Add ARCH_CLOCK_FIXED_MASK
[PATCH v5 09/12] arm: vdso: move vgettimeofday.c to lib/vdso/
[PATCH v5 10/12] arm64: vdso: replace gettimeofday.S with global vgettimeofday.C [PATCH v5 11/12] lib: vdso: Add support for CLOCK_BOOTTIME
[PATCH v5 12/12] lib: vdso: do not expose gettimeofday, if no arch supported timer [PATCH] lib: vdso: add support for time
PATCH 1/6 arm64: compat: Use vDSO sigreturn trampolines if available
From: Kevin Brodsky <[email protected]>
If the compat vDSO is enabled, it replaces the sigreturn page. Therefore, we use the sigreturn trampolines the vDSO provides instead.
--- arch/arm64/include/asm/vdso.h | 3 +++ arch/arm64/kernel/signal32.c | 15 +++++++++++++++ 2 files changed, 18 insertions(+)
arch/arm64/include/asm/vdso.h +3 -0
@@ -28,6 +28,9 @@#ifndef __ASSEMBLY__#include <generated/vdso-offsets.h> +#ifdef CONFIG_VDSO32 +#include <generated/vdso32-offsets.h> +#endif #define VDSO_SYMBOL (base, name) \ ({ \
arch/arm64/kernel/signal32.c +15 -0
@@ -28,6 +28,7 @@#include <asm/signal32.h> #include <linux/uaccess.h> #include <asm/unistd.h> +#include <asm/vdso.h> struct compat_vfp_sigframe {compat_ulong_t magic;
@@ -433,6 +434,19 @@ static void compat_setup_return(struct pt_regs *regs, struct k_sigaction *ka, retcode =ptr_to_compat (ka->sa.sa_restorer); }else {/* Set up sigreturn pointer */ +#ifdef CONFIG_VDSO32 +void *vdso_base = current->mm->context.vdso; +void *trampoline = + (ka->sa.sa_flags &SA_SIGINFO + ? (thumb + ?VDSO_SYMBOL (vdso_base, compat_rt_sigreturn_thumb) + :VDSO_SYMBOL (vdso_base, compat_rt_sigreturn_arm)) + : (thumb + ?VDSO_SYMBOL (vdso_base, compat_sigreturn_thumb) + :VDSO_SYMBOL (vdso_base, compat_sigreturn_arm))); + + retcode =ptr_to_compat (trampoline) + thumb; +#else void *sigreturn_base = current->mm->context.vdso;unsigned int idx = thumb <<1 ;
@@ -440,6 +454,7 @@ static void compat_setup_return(struct pt_regs *regs, struct k_sigaction *ka, idx +=3 ; retcode =ptr_to_compat (sigreturn_base) + (idx <<2 ) + thumb; +#endif } regs->regs[0 ] = usig;
Signature · 1 line
2.15.0.448.gf294e3d99a-goog
PATCH 2/6 arm64: elf: Set AT_SYSINFO_EHDR in compat processes
In reply to Mark SalyzynFrom: Kevin Brodsky <[email protected]>
If the compat vDSO is enabled, we need to set AT_SYSINFO_EHDR in the auxiliary vector of compat processes to the address of the vDSO code page, so that the dynamic linker can find it (just like the regular vDSO).
Note that we cast context.vdso to Elf64_Off, instead of elf_addr_t, because elf_addr_t is Elf32_Off in compat_binfmt_elf.c, and casting context.vdso to u32 would trigger a pointer narrowing warning.
--- arch/arm64/include/asm/elf.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
arch/arm64/include/asm/elf.h +7 -2
@@ -144,11 +144,12 @@ typedef struct user_fpsimd_state elf_fpregset_t; })/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */ -#define ARCH_DLINFO \ +#define _SET_AUX_ENT_VDSO \ do { \ NEW_AUX_ENT(AT_SYSINFO_EHDR, \ - (elf_addr_t)current->mm->context.vdso); \ + (Elf64_Off)current->mm->context.vdso); \ } while (0) +#define ARCH_DLINFO _SET_AUX_ENT_VDSO#define ARCH_HAS_SETUP_ADDITIONAL_PAGES struct linux_binprm ;
@@ -196,7 +197,11 @@ typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG]; ({ \set_thread_flag (TIF_32BIT ); \ }) +#ifdef CONFIG_VDSO32 +#define COMPAT_ARCH_DLINFO _SET_AUX_ENT_VDSO +#else #define COMPAT_ARCH_DLINFO +#endif extern int aarch32_setup_vectors_page (struct linux_binprm *bprm,int uses_interp);#define compat_arch_setup_additional_pages \
Signature · 1 line
2.15.0.448.gf294e3d99a-goog
PATCH 3/6 arm64: Refactor vDSO init/setup
In reply to Mark SalyzynFrom: Kevin Brodsky <[email protected]>
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.
--- arch/arm64/kernel/vdso.c | 118 ++++++++++++++++++++++++++++------------------- 1 file changed, 70 insertions(+), 48 deletions(-)
arch/arm64/kernel/vdso.c +70 -48
@@ -39,8 +39,11 @@#include <asm/vdso.h> #include <asm/vdso_datapage.h> -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; }/*
Signature · 1 line
2.15.0.448.gf294e3d99a-goog
PATCH 4/6 arm64: compat: Add a 32-bit vDSO
In reply to Mark SalyzynFrom: Kevin Brodsky <[email protected]>
Provide the files necessary for building a compat (AArch32) vDSO in kernel/vdso32.
This is mostly an adaptation of the arm vDSO. The most significant change in vgettimeofday.c is the use of the arm64 vdso_data struct, allowing the vDSO data page to be shared between the 32 and 64-bit vDSOs. Additionally, a different set of barrier macros is used (see aarch32-barrier.h), as we want to support old 32-bit compilers that may not support ARMv8 and its new barrier arguments (*ld).
In addition to the time functions, sigreturn trampolines are also provided, aiming at replacing those in the sigreturn page as the latter don't provide any unwinding information (and it's easier to have just one "user code" page). arm-specific unwinding directives are used, based on glibc's implementation. Symbol offsets are made available to the kernel using the same method as the 64-bit vDSO.
There is unfortunately an important caveat: we cannot get away with hand-coding 32-bit instructions like in kernel/kuser32.S, this time we really need a 32-bit compiler. The compat vDSO Makefile relies on CROSS_COMPILE_ARM32 to provide a 32-bit compiler, appropriate logic will be added to the arm64 Makefile later on to ensure that an attempt to build the compat vDSO is made only if this variable has been set properly.
Take an effort to recode the arm64 vdso code from assembler to C previously submitted by Andrew Pinski <[email protected]>, rework it for use in both arm and arm64, overlapping any optimizations for each architecture.
--- arch/arm64/kernel/vdso32/.gitignore | 2 + arch/arm64/kernel/vdso32/Makefile | 172 +++++++++++++++++++++++++++++++ arch/arm64/kernel/vdso32/compiler.h | 120 +++++++++++++++++++++ arch/arm64/kernel/vdso32/datapage.h | 1 + arch/arm64/kernel/vdso32/sigreturn.S | 76 ++++++++++++++ arch/arm64/kernel/vdso32/vdso.S | 32 ++++++ arch/arm64/kernel/vdso32/vdso.lds.S | 95 +++++++++++++++++ arch/arm64/kernel/vdso32/vgettimeofday.c | 3 + 8 files changed, 501 insertions(+) create mode 100644 arch/arm64/kernel/vdso32/.gitignore create mode 100644 arch/arm64/kernel/vdso32/Makefile create mode 100644 arch/arm64/kernel/vdso32/compiler.h create mode 100644 arch/arm64/kernel/vdso32/datapage.h create mode 100644 arch/arm64/kernel/vdso32/sigreturn.S create mode 100644 arch/arm64/kernel/vdso32/vdso.S create mode 100644 arch/arm64/kernel/vdso32/vdso.lds.S create mode 100644 arch/arm64/kernel/vdso32/vgettimeofday.c
arch/arm64/kernel/vdso32/.gitignore new file +2 -0
@@ -0,0 +1,2 @@ +vdso.lds +vdso.so.raw
arch/arm64/kernel/vdso32/Makefile new file +172 -0
172 lines not on this page · raw message
arch/arm64/kernel/vdso32/compiler.h new file +120 -0
120 lines not on this page · raw message
arch/arm64/kernel/vdso32/datapage.h new file +1 -0
@@ -0,0 +1 @@ +#include "../vdso/datapage.h"
arch/arm64/kernel/vdso32/sigreturn.S new file +76 -0
76 lines not on this page · raw message
arch/arm64/kernel/vdso32/vdso.S new file +32 -0
@@ -0,0 +1,32 @@ +/* + * 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/>. + * + * Author: Will Deacon <[email protected]> + */ + +#include <linux/init.h> +#include <linux/linkage.h> +#include <linux/const.h> +#include <asm/page.h> + + .globl vdso32_start, vdso32_end + .section .rodata + .balign PAGE_SIZE +vdso32_start: + .incbin "arch/arm64/kernel/vdso32/vdso.so" + .balign PAGE_SIZE +vdso32_end: + + .previous
arch/arm64/kernel/vdso32/vdso.lds.S new file +95 -0
95 lines not on this page · raw message
arch/arm64/kernel/vdso32/vgettimeofday.c new file +3 -0
@@ -0,0 +1,3 @@ +#include "compiler.h" +#include "datapage.h" +#include "../../../../lib/vdso/vgettimeofday.c"
Signature · 1 line
2.15.0.448.gf294e3d99a-goog
PATCH 5/6 arm64: compat: 32-bit vDSO setup
In reply to Mark SalyzynFrom: Kevin Brodsky <[email protected]>
If the compat vDSO is enabled, install it in compat processes. In this case, the compat vDSO replaces the sigreturn page (it provides its own sigreturn trampolines).
--- arch/arm64/kernel/vdso.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+)
arch/arm64/kernel/vdso.c +55 -0
@@ -58,6 +58,7 @@ struct vdso_data *vdso_data = &vdso_data_store.data;/* * Create and map the vectors page for AArch32 tasks. */ +#if !defined(CONFIG_VDSO32) || defined(CONFIG_KUSER_HELPERS) static struct page *vectors_page[] __ro_after_init; static const struct vm_special_mapping compat_vdso_spec[] = { {
@@ -73,6 +74,7 @@ static const struct vm_special_mapping compat_vdso_spec[] = { #endif };static struct page *vectors_page[ARRAY_SIZE (compat_vdso_spec)]__ro_after_init ; +#endif static int __init alloc_vectors_page (void ) {
@@ -82,6 +84,7 @@ static int __init alloc_vectors_page(void)unsigned long kuser_vpage;#endif +#ifndef CONFIG_VDSO32 extern char __aarch32_sigret_code_start[], __aarch32_sigret_code_end[];size_t sigret_sz = __aarch32_sigret_code_end - __aarch32_sigret_code_start;
@@ -90,19 +93,24 @@ static int __init alloc_vectors_page(void) sigret_vpage =get_zeroed_page (GFP_ATOMIC );if (!sigret_vpage)return -ENOMEM ; +#endif #ifdef CONFIG_KUSER_HELPERS kuser_vpage =get_zeroed_page (GFP_ATOMIC );if (!kuser_vpage) { +#ifndef CONFIG_VDSO32 free_page (sigret_vpage); +#endif return -ENOMEM ; }#endif +#ifndef CONFIG_VDSO32 /* sigreturn code */ memcpy ((void *)sigret_vpage, __aarch32_sigret_code_start, sigret_sz);flush_icache_range (sigret_vpage, sigret_vpage +PAGE_SIZE ); vectors_page[0 ] =virt_to_page (sigret_vpage); +#endif #ifdef CONFIG_KUSER_HELPERS /* kuser helpers */
@@ -116,6 +124,7 @@ static int __init alloc_vectors_page(void) }arch_initcall (alloc_vectors_page); +#ifndef CONFIG_VDSO32 int aarch32_setup_vectors_page (struct linux_binprm *bprm,int uses_interp) {struct mm_struct *mm = current->mm;
@@ -151,6 +160,7 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)return PTR_ERR_OR_ZERO (ret); } +#endif /* !CONFIG_VDSO32 */ #endif /* CONFIG_COMPAT */ static int vdso_mremap(const struct vm_special_mapping *sm,
@@ -221,6 +231,23 @@ static int __init vdso_mappings_init(const char *name,return 0 ; } +#ifdef CONFIG_COMPAT +#ifdef CONFIG_VDSO32 + +static struct vdso_mappings vdso32_mappings__ro_after_init ; + +static int __init vdso32_init (void ) +{ +extern char vdso32_start[], vdso32_end[]; + +return vdso_mappings_init ("vdso32" , vdso32_start, vdso32_end, + &vdso32_mappings); +} +arch_initcall (vdso32_init); + +#endif /* CONFIG_VDSO32 */ +#endif /* CONFIG_COMPAT */ +static struct vdso_mappings vdso_mappings__ro_after_init ;static int __init vdso_init (void )
@@ -263,6 +290,34 @@ static int vdso_setup(struct mm_struct *mm,return PTR_ERR_OR_ZERO (ret); } +#ifdef CONFIG_COMPAT +#ifdef CONFIG_VDSO32 +int aarch32_setup_vectors_page (struct linux_binprm *bprm,int uses_interp) +{ +struct mm_struct *mm = current->mm; +void *ret; + +if (down_write_killable (&mm->mmap_sem)) +return -EINTR ; + + ret =ERR_PTR (vdso_setup (mm, &vdso32_mappings)); +#ifdef CONFIG_KUSER_HELPERS +if (!IS_ERR (ret)) +/* Map the kuser helpers at the ABI-defined high address. */ + ret =_install_special_mapping (mm,AARCH32_KUSER_HELPERS_BASE , +PAGE_SIZE , +VM_READ |VM_EXEC | +VM_MAYREAD |VM_MAYEXEC , + &compat_vdso_spec[1 ]); +#endif + +up_write (&mm->mmap_sem); + +return PTR_ERR_OR_ZERO (ret); +} +#endif /* CONFIG_VDSO32 */ +#endif /* CONFIG_COMPAT */ +int arch_setup_additional_pages (struct linux_binprm *bprm,int uses_interp) {struct mm_struct *mm = current->mm;
Signature · 1 line
2.15.0.448.gf294e3d99a-goog
PATCH 6/6 arm64: Wire up and expose the new compat vDSO
In reply to Mark SalyzynFrom: Kevin Brodsky <[email protected]>
Expose the new compat vDSO via the COMPAT_VDSO config option.
The option is not enabled in defconfig because we really need a 32-bit compiler this time, and we rely on the user to provide it themselves by setting CROSS_COMPILE_ARM32. Therefore enabling the option by default would make little sense, since the user must explicitly set a non-standard environment variable anyway.
CONFIG_COMPAT_VDSO is not directly used in the code, because we want to ignore it (build as if it were not set) if the user didn't set CROSS_COMPILE_ARM32. If the variable has been set to a valid prefix, CONFIG_VDSO32 will be set; this is the option that the code and Makefiles test.
For more flexibility, like CROSS_COMPILE, CROSS_COMPILE_ARM32 can also be set via CONFIG_CROSS_COMPILE_ARM32 (the environment variable overrides the config option, as expected).
--- arch/arm64/Kconfig | 24 ++++++++++++++++++++++++ arch/arm64/Makefile | 35 +++++++++++++++++++++++++++++++++-- arch/arm64/kernel/Makefile | 3 +++ 3 files changed, 60 insertions(+), 2 deletions(-)
arch/arm64/Kconfig +24 -0
@@ -1183,6 +1183,30 @@ config SYSVIPC_COMPAT def_bool y depends on COMPAT && SYSVIPC +config COMPAT_VDSO + bool "32-bit vDSO" + depends on COMPAT + default n + help + Warning: a 32-bit toolchain is necessary to build the vDSO. You + must explicitly define which toolchain should be used by setting + CROSS_COMPILE_ARM32 to the prefix of the 32-bit toolchain (same format + as CROSS_COMPILE). If CROSS_COMPILE_ARM32 is empty, a warning will be + printed and the kernel will be built as if COMPAT_VDSO had not been + set. If CROSS_COMPILE_ARM32 is set to an invalid prefix, compilation + will be aborted. + + Provide a vDSO to 32-bit processes. It includes the symbols provided + by the vDSO from the 32-bit kernel, so that a 32-bit libc can use + the compat vDSO without modification. It also provides sigreturn + trampolines, replacing the sigreturn page. + +config CROSS_COMPILE_ARM32 + string "32-bit toolchain prefix" + help + Same as setting CROSS_COMPILE_ARM32 in the environment, but saved for + future builds. The environment variable overrides this config option. + endmenu menu "Power management options"
arch/arm64/Makefile +33 -2
@@ -45,10 +45,39 @@ $(warning Detected assembler with broken .inst; disassembly will be unreliable) endif endif -KBUILD_CFLAGS += -mgeneral-regs-only $(lseinstr) $(brokengasinst) +ifeq ($(CONFIG_COMPAT_VDSO), y) + CROSS_COMPILE_ARM32 ?= $(CONFIG_CROSS_COMPILE_ARM32:"%"=%) + + # Check that the user has provided a valid prefix for the 32-bit toolchain. + # To prevent selecting the system $(cc-name) by default, the prefix is not + # allowed to be empty, unlike CROSS_COMPILE. In the unlikely event that the + # system $(cc-name) is actually the 32-bit ARM compiler to be used, the + # variable can be set to the dirname (e.g. CROSS_COMPILE_ARM32=/usr/bin/). + # Note: this Makefile is read both before and after regenerating the config + # (if needed). Any warning appearing before the config has been regenerated + # should be ignored. If the error is triggered and you set + # CONFIG_CROSS_COMPILE_ARM32, set CROSS_COMPILE_ARM32 to an appropriate value + # when invoking make and fix CONFIG_CROSS_COMPILE_ARM32. + ifeq ($(CROSS_COMPILE_ARM32),) + $(error CROSS_COMPILE_ARM32 not defined or empty, the compat vDSO will not be built) + else ifeq ($(cc-name),clang) + export CLANG_TRIPLE_ARM32 ?= $(CROSS_COMPILE_ARM32) + export CLANG_TARGET_ARM32 := --target=$(notdir $(CLANG_TRIPLE_ARM32:%-=%)) + export CONFIG_VDSO32 := y + vdso32 := -DCONFIG_VDSO32=1 + else ifeq ($(shell which $(CROSS_COMPILE_ARM32)$(cc-name) 2> /dev/null),) + $(error $(CROSS_COMPILE_ARM32)$(cc-name) not found, check CROSS_COMPILE_ARM32) + else + export CROSS_COMPILE_ARM32 + export CONFIG_VDSO32 := y + vdso32 := -DCONFIG_VDSO32=1 + endif +endif + +KBUILD_CFLAGS += -mgeneral-regs-only $(lseinstr) $(brokengasinst) $(vdso32) KBUILD_CFLAGS += -fno-asynchronous-unwind-tables KBUILD_CFLAGS += $(call cc-option, -mpc-relative-literal-loads) -KBUILD_AFLAGS += $(lseinstr) $(brokengasinst) +KBUILD_AFLAGS += $(lseinstr) $(brokengasinst) $(vdso32) KBUILD_CFLAGS += $(call cc-option,-mabi=lp64) KBUILD_AFLAGS += $(call cc-option,-mabi=lp64)
@@ -157,6 +186,8 @@ archclean: prepare: vdso_prepare vdso_prepare: prepare0 $(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso include/generated/vdso-offsets.h + $(if $(CONFIG_VDSO32),$(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso32 \ + include/generated/vdso32-offsets.h) define archhelp echo '* Image.gz - Compressed kernel image (arch/$(ARCH)/boot/Image.gz)'
arch/arm64/kernel/Makefile +3 -0
@@ -30,7 +30,9 @@ $(obj)/%.stub.o: $(obj)/%.o FORCE arm64-obj-$(CONFIG_COMPAT) += sys32.o signal32.o \ sys_compat.o entry32.o +ifneq ($(CONFIG_VDSO32),y) arm64-obj-$(CONFIG_COMPAT) += sigreturn32.o +endif arm64-obj-$(CONFIG_KUSER_HELPERS) += kuser32.o arm64-obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o
@@ -58,6 +60,7 @@ arm64-reloc-test-y := reloc_test_core.o reloc_test_syms.o arm64-obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-y += $(arm64-obj-y) vdso/ probes/ +obj-$(CONFIG_VDSO32) += vdso32/ obj-m += $(arm64-obj-m) head-y := head.o extra-y += $(head-y) vmlinux.lds
Signature · 1 line
2.15.0.448.gf294e3d99a-goog
cover arm64: compat: Add COMPAT_VDSO
In reply to Mark SalyzynQuoted 27 lines · Mark Salyzyn
Add compatible vDSO32 support to arm64, provide the files necessary for building a compat (AArch32) vDSO in
arch/arm64/kernel/vdso32.Leverages effort to unify the
vgettimeofday.cfile as outlined below.To be applied over top the following pending patches:
[PATCH] arm64: compat: Remove leftover variable declaration
NB: approved, in arch64/for-next/core
[PATCH v3 1/3] arm64: compat: Split the sigreturn trampolines and kuser helpers (C sources) [PATCH v3 2/3] arm64: compat: Split the sigreturn trampolines and kuser helpers (assembler sources) [PATCH v3 3/3] arm64: compat: AddCONFIG_KUSER_HELPERS
[PATCH] arm64: compat: Expose offset to registers in sigframes
[PATCH v5 01/12] arm: vdso: renamevdso_datapagevariables
[PATCH v5 02/12] arm: vdso: add include file defining__get_datapage()
[PATCH v5 03/12] arm: vdso: inline assembler operations tocompiler.h
[PATCH v5 04/12] arm: vdso: do calculations outside reader loops
[PATCH v6 05/12] arm: vdso: Add support forCLOCK_MONOTONIC_RAW
[PATCH v5 06/12] arm: vdso: add support forclock_getres
[PATCH v5 07/12] arm: vdso: disable profiling
[PATCH v5 08/12] arm: vdso: AddARCH_CLOCK_FIXED_MASK
[PATCH v5 09/12] arm: vdso: movevgettimeofday.ctolib/vdso/
[PATCH v5 10/12] arm64: vdso: replacegettimeofday.Swith global vgettimeofday.C [PATCH v5 11/12] lib: vdso: Add support forCLOCK_BOOTTIME
[PATCH v5 12/12] lib: vdso: do not expose gettimeofday, if no arch supported timer [PATCH] lib: vdso: add support for time
Quoted 8 lines
Signed-off-by Kevin Brodsky <[email protected]>Signed-off-by Mark Salyzyn <[email protected]>Cc Catalin Marinas <[email protected]>Cc Will Deacon <[email protected]>Cc Dave Martin <[email protected]>Cc "Eric W. Biederman" <[email protected]>Cc linux-arm-kernel at lists.infradead.orgCc linux-kernel at vger.kernel.org
Any action for me to take?
-- Mark