2017-11-15 22:42:56

by Mark Salyzyn

[permalink] [raw]
Subject: [PATCH 0/6] 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

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: [email protected]
Cc: [email protected]

From 1584129774092039858@xxx Wed Nov 15 11:04:39 +0000 2017
X-GM-THRID: 1572917095851905670
X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread


2017-11-15 22:44:42

by Mark Salyzyn

[permalink] [raw]
Subject: [PATCH 2/6] arm64: elf: Set AT_SYSINFO_EHDR in compat processes

From: 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.

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: [email protected]
Cc: [email protected]
---
arch/arm64/include/asm/elf.h | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 33be513ef24c..675fa096d4a4 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -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 \
--
2.15.0.448.gf294e3d99a-goog


From 1584141836758173741@xxx Wed Nov 15 14:16:23 +0000 2017
X-GM-THRID: 1584141836758173741
X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread

2017-11-16 00:39:40

by Mark Salyzyn

[permalink] [raw]
Subject: [PATCH 6/6] arm64: Wire up and expose the new compat vDSO

From: 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).

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: [email protected]
Cc: [email protected]
---
arch/arm64/Kconfig | 24 ++++++++++++++++++++++++
arch/arm64/Makefile | 35 +++++++++++++++++++++++++++++++++--
arch/arm64/kernel/Makefile | 3 +++
3 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index d8a4fda50477..379d0154b363 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -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"
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 939b310913cf..baf36f0a992d 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -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)'
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 6e969f3cde6c..5db2b239cd68 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -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
--
2.15.0.448.gf294e3d99a-goog


From 1583629796307031042@xxx Thu Nov 09 22:37:43 +0000 2017
X-GM-THRID: 1583620593186112586
X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread

2017-11-15 23:37:41

by Mark Salyzyn

[permalink] [raw]
Subject: [PATCH 5/6] arm64: compat: 32-bit vDSO setup

From: 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).

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: [email protected]
Cc: [email protected]
---
arch/arm64/kernel/vdso.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)

diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 48b4111a933f..9d44ce962538 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -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;
--
2.15.0.448.gf294e3d99a-goog


From 1584315875358406242@xxx Fri Nov 17 12:22:39 +0000 2017
X-GM-THRID: 1579584616408089177
X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread