From owner-freebsd-arm@freebsd.org Tue Sep 29 13:23:42 2015 Return-Path: Delivered-To: freebsd-arm@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 0A088A0A3AF for ; Tue, 29 Sep 2015 13:23:42 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from kib.kiev.ua (kib.kiev.ua [IPv6:2001:470:d5e7:1::1]) (using TLSv1 with cipher DHE-RSA-CAMELLIA256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 600D113D9 for ; Tue, 29 Sep 2015 13:23:41 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from tom.home (kostik@localhost [127.0.0.1]) by kib.kiev.ua (8.15.2/8.15.2) with ESMTPS id t8TDNXjV074934 (version=TLSv1 cipher=DHE-RSA-CAMELLIA256-SHA bits=256 verify=NO) for ; Tue, 29 Sep 2015 16:23:33 +0300 (EEST) (envelope-from kostikbel@gmail.com) DKIM-Filter: OpenDKIM Filter v2.10.3 kib.kiev.ua t8TDNXjV074934 Received: (from kostik@localhost) by tom.home (8.15.2/8.15.2/Submit) id t8TDNXJL074933 for freebsd-arm@freebsd.org; Tue, 29 Sep 2015 16:23:33 +0300 (EEST) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: tom.home: kostik set sender to kostikbel@gmail.com using -f Date: Tue, 29 Sep 2015 16:23:33 +0300 From: Konstantin Belousov To: freebsd-arm@freebsd.org Subject: Shared page and related goodies for ARMv7 Message-ID: <20150929132332.GH11284@kib.kiev.ua> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.24 (2015-08-30) X-Spam-Status: No, score=-2.0 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FROM,NML_ADSP_CUSTOM_MED autolearn=no autolearn_force=no version=3.4.1 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on tom.home X-BeenThere: freebsd-arm@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "Porting FreeBSD to ARM processors." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 29 Sep 2015 13:23:42 -0000 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#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 #include +#include #include #include @@ -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 #include #include +#include +#include #include #include #include #include +#include #ifdef FDT #include @@ -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 #include #include +#include #include #include @@ -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 #include +#ifdef __arm__ +#include +#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;