Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 29 Sep 2015 16:23:33 +0300
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        freebsd-arm@freebsd.org
Subject:   Shared page and related goodies for ARMv7
Message-ID:  <20150929132332.GH11284@kib.kiev.ua>

next in thread | raw e-mail | index | archive | help
As an exercise to get myself more familiar with the ARM architecture,
I added the shared page for FreeBSD/ARMv7.  This provides the standard
features tied to the shared page, in particular, a non-executable stack
for the compatible binaries, and fast gettimeofday() and clock_gettime()
functions.  For reference, the measurements on my RPI2 done by
tools/tools/syscall_timing, show
for userspace gettimeofday:
% ./syscall_timing gettimeofday
Clock resolution: 0.000000053
test    loop    time    iterations      periteration
gettimeofday    0       1.009965385     2743838 0.000000368
gettimeofday    1       1.009899240     2743629 0.000000368
gettimeofday    2       1.009952833     2538253 0.000000397
gettimeofday    3       1.009918198     2404272 0.000000420
gettimeofday    4       1.009875126     2404567 0.000000419
gettimeofday    5       1.009950700     2405196 0.000000419
gettimeofday    6       1.009859555     2623534 0.000000384
gettimeofday    7       1.009911534     2743249 0.000000368
gettimeofday    8       1.009928618     2743240 0.000000368
gettimeofday    9       1.009920910     2743227 0.000000368
for syscall:
gettimeofday    0       1.009994949     659319  0.000001531
gettimeofday    1       1.009869846     583343  0.000001731
gettimeofday    2       1.009899950     583384  0.000001731
gettimeofday    3       1.009873232     636420  0.000001586
gettimeofday    4       1.009909639     669715  0.000001507
gettimeofday    5       1.009941201     669640  0.000001508
gettimeofday    6       1.009930733     669051  0.000001509
gettimeofday    7       1.009890005     669064  0.000001509
gettimeofday    8       1.009915474     669168  0.000001509
gettimeofday    9       1.009918860     668739  0.000001510

The patch is pretty much straightforward, interesting details are
listed below.

- The shared page is only enabled for ARMv7 kernels.  From my reading of
  VMSA chapters for ARMv6 and ARMv7, only v7 ensures that there is no
  cache aliasing for multiple-times mapped page, while v6 requires coloring.
  Shared page is mapped both at the top of UVA and somewhere in KVA.
- There is a bug in the generic timer setup, it seems.  The CNTKCTL CP15
  register is core-private, which means that the in-tree code only sets access
  permissions on the BSP.  APs CNTKCTL are left in undefined state, possibly
  set up to some value by loader.  This might allow userspace to reprogram
  timers on APs.  I fixed this by using rendezvous after SMP is started.
- I have to add explicit directives to create .note.GNU-stack sections in
  some __eabi files from libcompiler-rt which are linked into libc.
  Upstream refused to do global change adding the stack note for all asms,
  recommending to live with --noexecstack assembler option.  But we cannot
  do this for files linked into libc.
- arm64 would require some additions, I did not tested the build.

It would be useful to test the patch on ARMv6 to ensure that signals and
gettimeofday() work.

diff --git a/contrib/compiler-rt/lib/builtins/arm/aeabi_memcmp.S b/contrib/compiler-rt/lib/builtins/arm/aeabi_memcmp.S
index 051ce43..fa69327 100644
--- a/contrib/compiler-rt/lib/builtins/arm/aeabi_memcmp.S
+++ b/contrib/compiler-rt/lib/builtins/arm/aeabi_memcmp.S
@@ -18,3 +18,5 @@ END_COMPILERRT_FUNCTION(__aeabi_memcmp)
 
 DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcmp4, __aeabi_memcmp)
 DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcmp8, __aeabi_memcmp)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/contrib/compiler-rt/lib/builtins/arm/aeabi_memcpy.S b/contrib/compiler-rt/lib/builtins/arm/aeabi_memcpy.S
index cf02332..35b8558 100644
--- a/contrib/compiler-rt/lib/builtins/arm/aeabi_memcpy.S
+++ b/contrib/compiler-rt/lib/builtins/arm/aeabi_memcpy.S
@@ -18,3 +18,5 @@ END_COMPILERRT_FUNCTION(__aeabi_memcpy)
 
 DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcpy4, __aeabi_memcpy)
 DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcpy8, __aeabi_memcpy)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/contrib/compiler-rt/lib/builtins/arm/aeabi_memmove.S b/contrib/compiler-rt/lib/builtins/arm/aeabi_memmove.S
index 4dda06f..2f9f789 100644
--- a/contrib/compiler-rt/lib/builtins/arm/aeabi_memmove.S
+++ b/contrib/compiler-rt/lib/builtins/arm/aeabi_memmove.S
@@ -18,3 +18,5 @@ END_COMPILERRT_FUNCTION(__aeabi_memmove)
 
 DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memmove4, __aeabi_memmove)
 DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memmove8, __aeabi_memmove)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/contrib/compiler-rt/lib/builtins/arm/aeabi_memset.S b/contrib/compiler-rt/lib/builtins/arm/aeabi_memset.S
index c8b49c7..f2342f0 100644
--- a/contrib/compiler-rt/lib/builtins/arm/aeabi_memset.S
+++ b/contrib/compiler-rt/lib/builtins/arm/aeabi_memset.S
@@ -32,3 +32,4 @@ END_COMPILERRT_FUNCTION(__aeabi_memclr)
 DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr4, __aeabi_memclr)
 DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr8, __aeabi_memclr)
 
+	.section .note.GNU-stack,"",%progbits
diff --git a/contrib/gcc/config/arm/crti.asm b/contrib/gcc/config/arm/crti.asm
index 166a3ce..8df00d2 100644
--- a/contrib/gcc/config/arm/crti.asm
+++ b/contrib/gcc/config/arm/crti.asm
@@ -60,6 +60,8 @@
 		
 	.file		"crti.asm"
 
+	.section .note.GNU-stack,"",%progbits
+
 	.section	".init"
 	.align 2
 	.global	_init
diff --git a/contrib/gcc/config/arm/crtn.asm b/contrib/gcc/config/arm/crtn.asm
index 360afae..1947919 100644
--- a/contrib/gcc/config/arm/crtn.asm
+++ b/contrib/gcc/config/arm/crtn.asm
@@ -68,6 +68,8 @@
 	
 	.file		"crtn.asm"
 
+	.section .note.GNU-stack,"",%progbits
+
 	.section	".init"
 	;;
 	FUNC_END
diff --git a/contrib/gcc/config/arm/lib1funcs.asm b/contrib/gcc/config/arm/lib1funcs.asm
index 73c453d..8a48b25 100644
--- a/contrib/gcc/config/arm/lib1funcs.asm
+++ b/contrib/gcc/config/arm/lib1funcs.asm
@@ -1305,3 +1305,5 @@ LSYM(Lchange_\register):
 #include "ieee754-sf.S"
 #include "bpabi.S"
 #endif /* __symbian__ */
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/csu/arm/crti.S b/lib/csu/arm/crti.S
index 40e83bb..c6c37eb 100644
--- a/lib/csu/arm/crti.S
+++ b/lib/csu/arm/crti.S
@@ -19,3 +19,4 @@ _fini:
 	stmdb	sp!, {fp, ip, lr, pc}
 	sub	fp, ip, #4
 
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/csu/arm/crtn.S b/lib/csu/arm/crtn.S
index 962f0ed..25bbd57 100644
--- a/lib/csu/arm/crtn.S
+++ b/lib/csu/arm/crtn.S
@@ -8,3 +8,5 @@ __FBSDID("$FreeBSD$");
 	.section .fini,"ax",%progbits
 	ldmea	fp, {fp, sp, pc}
 	mov	pc, lr
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/aeabi/aeabi_asm_double.S b/lib/libc/arm/aeabi/aeabi_asm_double.S
index 7a5af82..ced4d78 100644
--- a/lib/libc/arm/aeabi/aeabi_asm_double.S
+++ b/lib/libc/arm/aeabi/aeabi_asm_double.S
@@ -117,3 +117,5 @@ ENTRY(__aeabi_cdcmpeq)
 	msr	cpsr_c, ip
 	RET
 END(__aeabi_cdcmpeq)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/aeabi/aeabi_asm_float.S b/lib/libc/arm/aeabi/aeabi_asm_float.S
index e05daa5..de6b1c8 100644
--- a/lib/libc/arm/aeabi/aeabi_asm_float.S
+++ b/lib/libc/arm/aeabi/aeabi_asm_float.S
@@ -108,3 +108,5 @@ ENTRY(__aeabi_cfcmpeq)
 	msr	cpsr_c, ip
 	RET
 END(__aeabi_cfcmpeq)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/aeabi/aeabi_vfp_double.S b/lib/libc/arm/aeabi/aeabi_vfp_double.S
index aae49f8..be4309d 100644
--- a/lib/libc/arm/aeabi/aeabi_vfp_double.S
+++ b/lib/libc/arm/aeabi/aeabi_vfp_double.S
@@ -201,3 +201,4 @@ AEABI_ENTRY(dsub)
 	RET
 AEABI_END(dsub)
 
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/aeabi/aeabi_vfp_float.S b/lib/libc/arm/aeabi/aeabi_vfp_float.S
index 7de8daf..c9df41c 100644
--- a/lib/libc/arm/aeabi/aeabi_vfp_float.S
+++ b/lib/libc/arm/aeabi/aeabi_vfp_float.S
@@ -188,3 +188,4 @@ AEABI_ENTRY(fsub)
 	RET
 AEABI_END(fsub)
 
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/gen/__aeabi_read_tp.S b/lib/libc/arm/gen/__aeabi_read_tp.S
index 670d0b8..224d6a6 100644
--- a/lib/libc/arm/gen/__aeabi_read_tp.S
+++ b/lib/libc/arm/gen/__aeabi_read_tp.S
@@ -45,3 +45,4 @@ END(__aeabi_read_tp)
 	.word ARM_TP_ADDRESS
 #endif
 
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/gen/_ctx_start.S b/lib/libc/arm/gen/_ctx_start.S
index 41bfff9..faedfb5 100644
--- a/lib/libc/arm/gen/_ctx_start.S
+++ b/lib/libc/arm/gen/_ctx_start.S
@@ -8,3 +8,5 @@ ENTRY(_ctx_start)
 	bl	_C_LABEL(ctx_done)
 	bl	_C_LABEL(abort)
 END(_ctx_start)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/gen/_setjmp.S b/lib/libc/arm/gen/_setjmp.S
index 853f61c..e3c67fa 100644
--- a/lib/libc/arm/gen/_setjmp.S
+++ b/lib/libc/arm/gen/_setjmp.S
@@ -157,3 +157,5 @@ botch:
 	b	.
 #endif
 END(_longjmp)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/gen/alloca.S b/lib/libc/arm/gen/alloca.S
index e4a73d4..2539b7a 100644
--- a/lib/libc/arm/gen/alloca.S
+++ b/lib/libc/arm/gen/alloca.S
@@ -44,3 +44,5 @@ ENTRY(alloca)
 	mov	r0, sp			/* r0 = base of new space */
 	RET
 END(alloca)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/gen/divsi3.S b/lib/libc/arm/gen/divsi3.S
index 82de5de..fac0663 100644
--- a/lib/libc/arm/gen/divsi3.S
+++ b/lib/libc/arm/gen/divsi3.S
@@ -389,3 +389,5 @@ ENTRY(__divsi3)
 	mov	r0, r3
 	RET
 END(__divsi3)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/gen/setjmp.S b/lib/libc/arm/gen/setjmp.S
index c9ae329..4e3850d 100644
--- a/lib/libc/arm/gen/setjmp.S
+++ b/lib/libc/arm/gen/setjmp.S
@@ -158,3 +158,5 @@ ENTRY(__longjmp)
 	bl	PIC_SYM(_C_LABEL(abort), PLT)
 1:	b	1b		/* Cannot get here */
 END(__longjmp)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/gen/sigsetjmp.S b/lib/libc/arm/gen/sigsetjmp.S
index 3743e89..236f531 100644
--- a/lib/libc/arm/gen/sigsetjmp.S
+++ b/lib/libc/arm/gen/sigsetjmp.S
@@ -66,3 +66,5 @@ ENTRY(siglongjmp)
 	beq	PIC_SYM(_C_LABEL(_longjmp), PLT)
 	b	PIC_SYM(_C_LABEL(longjmp), PLT)
 END(siglongjmp)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/string/ffs.S b/lib/libc/arm/string/ffs.S
index cc7f396..0ed8152 100644
--- a/lib/libc/arm/string/ffs.S
+++ b/lib/libc/arm/string/ffs.S
@@ -84,3 +84,5 @@ ENTRY(ffs)
 	RET
 #endif
 END(ffs)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/string/memcmp.S b/lib/libc/arm/string/memcmp.S
index 6fd8130..33a11b7 100644
--- a/lib/libc/arm/string/memcmp.S
+++ b/lib/libc/arm/string/memcmp.S
@@ -181,3 +181,5 @@ ENTRY(memcmp)
 	RET
 #endif
 END(memcmp)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/string/memcpy_arm.S b/lib/libc/arm/string/memcpy_arm.S
index 56fb703..57b0449 100644
--- a/lib/libc/arm/string/memcpy_arm.S
+++ b/lib/libc/arm/string/memcpy_arm.S
@@ -334,3 +334,5 @@ ENTRY(memcpy)
 	sub	r1, r1, #1
 	b	.Lmemcpy_l4
 END(memcpy)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/string/memcpy_xscale.S b/lib/libc/arm/string/memcpy_xscale.S
index a451de4..ab01544 100644
--- a/lib/libc/arm/string/memcpy_xscale.S
+++ b/lib/libc/arm/string/memcpy_xscale.S
@@ -1784,3 +1784,5 @@ ENTRY(memcpy)
 	bx	lr
 #endif	/* !_STANDALONE */
 END(memcpy)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/string/memmove.S b/lib/libc/arm/string/memmove.S
index 2cd5a5e..8f96147 100644
--- a/lib/libc/arm/string/memmove.S
+++ b/lib/libc/arm/string/memmove.S
@@ -609,3 +609,5 @@ END(memmove)
 #else
 END(bcopy)
 #endif
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/string/memset.S b/lib/libc/arm/string/memset.S
index 6d76901..96d2f93 100644
--- a/lib/libc/arm/string/memset.S
+++ b/lib/libc/arm/string/memset.S
@@ -263,3 +263,5 @@ END(bzero)
 #else
 END(memset)
 #endif
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/string/strcmp.S b/lib/libc/arm/string/strcmp.S
index d610fea..1cdce8b 100644
--- a/lib/libc/arm/string/strcmp.S
+++ b/lib/libc/arm/string/strcmp.S
@@ -43,3 +43,5 @@ ENTRY(strcmp)
 	sub	r0, r2, r3
 	RET
 END(strcmp)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/string/strlen.S b/lib/libc/arm/string/strlen.S
index c9334f9..240fa7d 100644
--- a/lib/libc/arm/string/strlen.S
+++ b/lib/libc/arm/string/strlen.S
@@ -83,3 +83,5 @@ ENTRY(strlen)
 	mov	r0, r1
 	RET
 END(strlen)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/string/strncmp.S b/lib/libc/arm/string/strncmp.S
index a5c0320..affcaa0 100644
--- a/lib/libc/arm/string/strncmp.S
+++ b/lib/libc/arm/string/strncmp.S
@@ -56,3 +56,5 @@ ENTRY(strncmp)
 	sub	r0, r2, r3
 	RET
 END(strncmp)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/sys/Makefile.inc b/lib/libc/arm/sys/Makefile.inc
index 60c2dc3..5e89109 100644
--- a/lib/libc/arm/sys/Makefile.inc
+++ b/lib/libc/arm/sys/Makefile.inc
@@ -1,6 +1,6 @@
 # $FreeBSD$
 
-SRCS+=	trivial-vdso_tc.c
+SRCS+=	__vdso_gettc.c
 
 MDASM= Ovfork.S brk.S cerror.S pipe.S ptrace.S sbrk.S shmat.S sigreturn.S syscall.S
 
diff --git a/lib/libc/arm/sys/Ovfork.S b/lib/libc/arm/sys/Ovfork.S
index 4520e02..73c619e 100644
--- a/lib/libc/arm/sys/Ovfork.S
+++ b/lib/libc/arm/sys/Ovfork.S
@@ -53,3 +53,5 @@ ENTRY(vfork)
 	and	r0, r0, r1	/* r0 == 0 if child, else unchanged */
 	mov	r15, r2
 END(vfork)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/sys/__vdso_gettc.c b/lib/libc/arm/sys/__vdso_gettc.c
new file mode 100644
index 0000000..613e8fa
--- /dev/null
+++ b/lib/libc/arm/sys/__vdso_gettc.c
@@ -0,0 +1,80 @@
+/*-
+ * Copyright (c) 2015 The FreeBSD Foundation
+ *
+ * Portions of this software were developed by Konstantin Belousov
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/elf.h>
+#include <sys/time.h>
+#include <sys/vdso.h>
+#include <machine/cpufunc.h>
+#include "libc_private.h"
+
+/*
+ * Userspace gettimeofday() is only enabled on ARMv7 CPUs, but libc is
+ * compiled for ARMv6.  Due to clang issues, .arch armv7-a directive
+ * does not work.
+ */
+
+static inline uint64_t
+cp15_cntvct_get(void)
+{
+	uint64_t reg;
+
+	__asm __volatile("mrrc\tp15, 1, %Q0, %R0, c14" : "=r" (reg));
+	return (reg);
+}
+
+static inline uint64_t
+cp15_cntpct_get(void)
+{
+	uint64_t reg;
+
+	__asm __volatile("mrrc\tp15, 0, %Q0, %R0, c14" : "=r" (reg));
+	return (reg);
+}
+
+#pragma weak __vdso_gettc
+u_int
+__vdso_gettc(const struct vdso_timehands *th)
+{
+	uint64_t val;
+
+	__asm __volatile(".word\t0xf57ff06f" : : : "memory"); /* isb */
+	val = th->th_physical == 0 ? cp15_cntvct_get() : cp15_cntpct_get();
+	return (val);
+}
+
+#pragma weak __vdso_gettimekeep
+int
+__vdso_gettimekeep(struct vdso_timekeep **tk)
+{
+
+	return (_elf_aux_info(AT_TIMEKEEP, tk, sizeof(*tk)));
+}
diff --git a/lib/libc/arm/sys/brk.S b/lib/libc/arm/sys/brk.S
index e5f8336..bf1b4fb 100644
--- a/lib/libc/arm/sys/brk.S
+++ b/lib/libc/arm/sys/brk.S
@@ -91,3 +91,5 @@ ENTRY(_brk)
 .Lcurbrk:
 	.word	PIC_SYM(CURBRK, GOT)
 END(_brk)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/sys/cerror.S b/lib/libc/arm/sys/cerror.S
index 26f5211..5fad698 100644
--- a/lib/libc/arm/sys/cerror.S
+++ b/lib/libc/arm/sys/cerror.S
@@ -47,3 +47,5 @@ ASENTRY(CERROR)
 	mvn	r1, #0x00000000
 	ldmfd	sp!, {r4, pc}
 END(CERROR)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/sys/pipe.S b/lib/libc/arm/sys/pipe.S
index 77ce0fc..778e923 100644
--- a/lib/libc/arm/sys/pipe.S
+++ b/lib/libc/arm/sys/pipe.S
@@ -49,3 +49,5 @@ ENTRY(_pipe)
 	mov	r0, #0x00000000
 	RET
 END(_pipe)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/sys/ptrace.S b/lib/libc/arm/sys/ptrace.S
index 876da32..dade223 100644
--- a/lib/libc/arm/sys/ptrace.S
+++ b/lib/libc/arm/sys/ptrace.S
@@ -47,3 +47,5 @@ ENTRY(ptrace)
 	bcs	PIC_SYM(CERROR, PLT)
 	RET
 END(ptrace)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/sys/sbrk.S b/lib/libc/arm/sys/sbrk.S
index 5cd9a03..25622c4 100644
--- a/lib/libc/arm/sys/sbrk.S
+++ b/lib/libc/arm/sys/sbrk.S
@@ -78,3 +78,5 @@ ENTRY(_sbrk)
 .Lcurbrk:
 	.word	PIC_SYM(CURBRK, GOT)
 END(_sbrk)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/sys/shmat.S b/lib/libc/arm/sys/shmat.S
index 3fc3d02..3574b1d 100644
--- a/lib/libc/arm/sys/shmat.S
+++ b/lib/libc/arm/sys/shmat.S
@@ -5,3 +5,5 @@ __FBSDID("$FreeBSD$");
 #include "SYS.h"
 
 RSYSCALL(shmat)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/sys/sigreturn.S b/lib/libc/arm/sys/sigreturn.S
index 1e0f245..c377e4a 100644
--- a/lib/libc/arm/sys/sigreturn.S
+++ b/lib/libc/arm/sys/sigreturn.S
@@ -40,3 +40,5 @@ __FBSDID("$FreeBSD$");
  */
 
 RSYSCALL(sigreturn)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/arm/sys/syscall.S b/lib/libc/arm/sys/syscall.S
index 73e6b83..c88d1ae 100644
--- a/lib/libc/arm/sys/syscall.S
+++ b/lib/libc/arm/sys/syscall.S
@@ -36,3 +36,5 @@ __FBSDID("$FreeBSD$");
 #include "SYS.h"
 
 RSYSCALL(syscall)
+
+	.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc
index a4414fa..e4fe1b2 100644
--- a/lib/libc/sys/Makefile.inc
+++ b/lib/libc/sys/Makefile.inc
@@ -102,7 +102,7 @@ SYM_MAPS+=	${LIBC_SRCTOP}/sys/Symbol.map
 CLEANFILES+=	${SASM} ${SPSEUDO}
 
 .if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" || \
-    ${MACHINE_CPUARCH} == "powerpc"
+    ${MACHINE_CPUARCH} == "powerpc" || ${MACHINE_ARCH:Marmv6*}
 NOTE_GNU_STACK='\t.section .note.GNU-stack,"",%%progbits\n'
 .else
 NOTE_GNU_STACK=''
diff --git a/lib/libcompiler_rt/Makefile b/lib/libcompiler_rt/Makefile
index 5e21883..22c9f89 100644
--- a/lib/libcompiler_rt/Makefile
+++ b/lib/libcompiler_rt/Makefile
@@ -230,7 +230,7 @@ SYMLINKS+=libcompiler_rt_p.a ${LIBDIR}/libgcc_p.a
 .endif
 
 .if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" || \
-    ${MACHINE_CPUARCH} == "powerpc"
+    ${MACHINE_CPUARCH} == "powerpc" || ${MACHINE_ARCH:Marmv6*}
 AFLAGS+=--noexecstack
 ACFLAGS+=-Wa,--noexecstack
 .endif
diff --git a/libexec/rtld-elf/arm/rtld_start.S b/libexec/rtld-elf/arm/rtld_start.S
index c482808..431ea48 100644
--- a/libexec/rtld-elf/arm/rtld_start.S
+++ b/libexec/rtld-elf/arm/rtld_start.S
@@ -97,3 +97,4 @@ _rtld_bind_start:
 	ldmia	sp!,{r0-r5,sl,fp,lr}	/* restore the stack */
 	mov	pc, ip			/* jump to the new address */
 
+	.section .note.GNU-stack,"",%progbits
diff --git a/sys/arm/arm/elf_machdep.c b/sys/arm/arm/elf_machdep.c
index 34761ff..4322cdd 100644
--- a/sys/arm/arm/elf_machdep.c
+++ b/sys/arm/arm/elf_machdep.c
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
 #include <vm/pmap.h>
 #include <vm/vm_param.h>
 
+#include <machine/acle-compat.h>
 #include <machine/elf.h>
 #include <machine/md_var.h>
 
@@ -76,13 +77,20 @@ struct sysentvec elf32_freebsd_sysvec = {
 	.sv_setregs	= exec_setregs,
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz	= NULL,
-	.sv_flags	= SV_ABI_FREEBSD | SV_ILP32,
+	.sv_flags	=
+#if __ARM_ARCH >= 7
+			  SV_SHP |
+#endif
+			  SV_ABI_FREEBSD | SV_ILP32,
 	.sv_set_syscall_retval = cpu_set_syscall_retval,
 	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
 	.sv_syscallnames = syscallnames,
+	.sv_shared_page_base = SHAREDPAGE,
+	.sv_shared_page_len = PAGE_SIZE,
 	.sv_schedtail	= NULL,
 	.sv_thread_detach = NULL,
 };
+INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec);
 
 static Elf32_Brandinfo freebsd_brand_info = {
 	.brand		= ELFOSABI_FREEBSD,
diff --git a/sys/arm/arm/generic_timer.c b/sys/arm/arm/generic_timer.c
index 636ba75..fd1f029 100644
--- a/sys/arm/arm/generic_timer.c
+++ b/sys/arm/arm/generic_timer.c
@@ -49,10 +49,13 @@ __FBSDID("$FreeBSD$");
 #include <sys/rman.h>
 #include <sys/timeet.h>
 #include <sys/timetc.h>
+#include <sys/smp.h>
+#include <sys/vdso.h>
 #include <sys/watchdog.h>
 #include <machine/bus.h>
 #include <machine/cpu.h>
 #include <machine/intr.h>
+#include <machine/md_var.h>
 
 #ifdef FDT
 #include <dev/fdt/fdt_common.h>
@@ -121,6 +124,9 @@ static struct timecounter arm_tmr_timecount = {
 #define	set_el1(x, val)	WRITE_SPECIALREG(x ##_el1, val)
 #endif
 
+static uint32_t arm_tmr_fill_vdso_timehands(struct vdso_timehands *vdso_th,
+    struct timecounter *tc);
+
 static int
 get_freq(void)
 {
@@ -181,17 +187,32 @@ get_ctrl(bool physical)
 }
 
 static void
-disable_user_access(void)
+setup_user_access(void *arg __unused)
 {
 	uint32_t cntkctl;
 
 	cntkctl = get_el1(cntkctl);
 	cntkctl &= ~(GT_CNTKCTL_PL0PTEN | GT_CNTKCTL_PL0VTEN |
-	    GT_CNTKCTL_EVNTEN | GT_CNTKCTL_PL0VCTEN | GT_CNTKCTL_PL0PCTEN);
+	    GT_CNTKCTL_EVNTEN);
+	if (arm_tmr_sc->physical) {
+		cntkctl |= GT_CNTKCTL_PL0PCTEN;
+		cntkctl &= ~GT_CNTKCTL_PL0VCTEN;
+	} else {
+		cntkctl |= GT_CNTKCTL_PL0VCTEN;
+		cntkctl &= ~GT_CNTKCTL_PL0PCTEN;
+	}
 	set_el1(cntkctl, cntkctl);
 	isb();
 }
 
+static void
+tmr_setup_user_access(void *arg __unused)
+{
+
+	smp_rendezvous(NULL, setup_user_access, NULL, NULL);
+}
+SYSINIT(tmr_ua, SI_SUB_SMP, SI_ORDER_SECOND, tmr_setup_user_access, NULL);
+
 static unsigned
 arm_tmr_get_timecount(struct timecounter *tc)
 {
@@ -381,7 +402,7 @@ arm_tmr_attach(device_t dev)
 		}
 	}
 
-	disable_user_access();
+	arm_cpu_fill_vdso_timehands = arm_tmr_fill_vdso_timehands;
 
 	arm_tmr_timecount.tc_frequency = sc->clkfreq;
 	tc_init(&arm_tmr_timecount);
@@ -485,3 +506,13 @@ DELAY(int usec)
 		first = last;
 	}
 }
+
+static uint32_t
+arm_tmr_fill_vdso_timehands(struct vdso_timehands *vdso_th,
+    struct timecounter *tc)
+{
+
+	vdso_th->th_physical = arm_tmr_sc->physical;
+	bzero(vdso_th->th_res, sizeof(vdso_th->th_res));
+	return (tc == &arm_tmr_timecount);
+}
diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c
index 32bbbc6..0105b33 100644
--- a/sys/arm/arm/machdep.c
+++ b/sys/arm/arm/machdep.c
@@ -82,6 +82,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/sysent.h>
 #include <sys/sysproto.h>
 #include <sys/uio.h>
+#include <sys/vdso.h>
 
 #include <vm/vm.h>
 #include <vm/pmap.h>
@@ -336,7 +337,11 @@ sendsig(catcher, ksi, mask)
 	tf->tf_r5 = (register_t)&fp->sf_uc;
 	tf->tf_pc = (register_t)catcher;
 	tf->tf_usr_sp = (register_t)fp;
-	tf->tf_usr_lr = (register_t)(PS_STRINGS - *(p->p_sysent->sv_szsigcode));
+	if (p->p_sysent->sv_sigcode_base != 0)
+		tf->tf_usr_lr = (register_t)p->p_sysent->sv_sigcode_base;
+	else
+		tf->tf_usr_lr = (register_t)(PS_STRINGS -
+		    *(p->p_sysent->sv_szsigcode));
 	/* Set the mode to enter in the signal handler */
 #if __ARM_ARCH >= 7
 	if ((register_t)catcher & 1)
@@ -1696,3 +1701,14 @@ initarm(struct arm_boot_params *abp)
 
 #endif /* !ARM_NEW_PMAP */
 #endif /* FDT */
+
+uint32_t (*arm_cpu_fill_vdso_timehands)(struct vdso_timehands *,
+    struct timecounter *);
+
+uint32_t
+cpu_fill_vdso_timehands(struct vdso_timehands *vdso_th, struct timecounter *tc)
+{
+
+	return (arm_cpu_fill_vdso_timehands != NULL ?
+	    arm_cpu_fill_vdso_timehands(vdso_th, tc) : 0);
+}
diff --git a/sys/arm/include/md_var.h b/sys/arm/include/md_var.h
index 030b48b..e70dd75 100644
--- a/sys/arm/include/md_var.h
+++ b/sys/arm/include/md_var.h
@@ -45,6 +45,11 @@ extern int (*_arm_bzero)(void *, int, int);
 extern int _min_memcpy_size;
 extern int _min_bzero_size;
 
+struct vdso_timehands;
+struct timecounter;
+extern uint32_t (*arm_cpu_fill_vdso_timehands)(struct vdso_timehands *,
+    struct timecounter *);
+
 #define DST_IS_USER	0x1
 #define SRC_IS_USER	0x2
 #define IS_PHYSICAL	0x4
diff --git a/sys/arm/include/vdso.h b/sys/arm/include/vdso.h
index d6aa162..6a0ec7b 100644
--- a/sys/arm/include/vdso.h
+++ b/sys/arm/include/vdso.h
@@ -29,6 +29,7 @@
 #define	_ARM_VDSO_H
 
 #define	VDSO_TIMEHANDS_MD			\
-	uint32_t	th_res[8];
+	uint32_t	th_physical;		\
+	uint32_t	th_res[7];
 
 #endif
diff --git a/sys/arm/include/vmparam.h b/sys/arm/include/vmparam.h
index b6e76bf..36f19a3 100644
--- a/sys/arm/include/vmparam.h
+++ b/sys/arm/include/vmparam.h
@@ -124,7 +124,8 @@
 #endif
 #define VM_MAX_ADDRESS          VM_MAXUSER_ADDRESS
 
-#define USRSTACK        VM_MAXUSER_ADDRESS
+#define	SHAREDPAGE		(VM_MAXUSER_ADDRESS - PAGE_SIZE)
+#define	USRSTACK		SHAREDPAGE
 
 /* initial pagein size of beginning of executable file */
 #ifndef VM_INITIAL_PAGEIN
diff --git a/sys/conf/files.arm b/sys/conf/files.arm
index 84267a0..a98390a 100644
--- a/sys/conf/files.arm
+++ b/sys/conf/files.arm
@@ -102,7 +102,6 @@ font.h				optional	sc			\
 	no-obj no-implicit-rule before-depend				\
 	clean	"font.h ${SC_DFLT_FONT}-8x14 ${SC_DFLT_FONT}-8x16 ${SC_DFLT_FONT}-8x8"
 kern/subr_busdma_bufalloc.c	standard
-kern/subr_dummy_vdso_tc.c	standard
 kern/subr_sfbuf.c		standard
 libkern/arm/aeabi_unwind.c	standard
 libkern/arm/divsi3.S		standard
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index 8023d55..ecec9cd 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -80,6 +80,9 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/elf.h>
 #include <machine/md_var.h>
+#ifdef __arm__
+#include <machine/acle-compat.h>
+#endif
 
 #define ELF_NOTE_ROUNDSIZE	4
 #define OLD_EI_BRAND	8
@@ -116,7 +119,8 @@ SYSCTL_INT(_debug, OID_AUTO, __elfN(legacy_coredump), CTLFLAG_RW,
     &elf_legacy_coredump, 0, "");
 
 int __elfN(nxstack) =
-#if defined(__amd64__) || defined(__powerpc64__) /* both 64 and 32 bit */
+#if defined(__amd64__) || defined(__powerpc64__) /* both 64 and 32 bit */ || \
+    (defined(__arm__) && __ARM_ARCH >= 7)
 	1;
 #else
 	0;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20150929132332.GH11284>