diff --git a/sys/arm64/linux/linux_support.S b/sys/arm64/linux/linux_support.S index 151ede7e1c19..3b16583e9d54 100644 --- a/sys/arm64/linux/linux_support.S +++ b/sys/arm64/linux/linux_support.S @@ -1,174 +1,178 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (C) 2018 Turing Robotic Industries Inc. * Copyright (C) 2022 Dmitry Chagin * * 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 + #include #include #include #include #include "assym.inc" .macro check_user_access user_arg, limit, bad_addr_func ldr x7, =(\limit) cmp x\user_arg, x7 b.cs \bad_addr_func .endm futex_fault: SET_FAULT_HANDLER(xzr, x1) EXIT_USER_ACCESS_CHECK(w0, x1) futex_fault_nopcb: mov x0, #EFAULT ret #define LINUX_FUTEX_MAX_LOOPS 128 /* * int oparg, uint32_t *uaddr, int *oldval * * Return 0 on success, errno on failure, * EAGAIN is returned if LL/SC operation fails. * * XXX. VM_MAXUSER_ADDRESS is not applicable here, should be replaced * by something like LINUX_SHAREDPAGE. */ /* (int *)uaddr2 = oparg */ ENTRY(futex_xchgl) check_user_access 1, (VM_MAXUSER_ADDRESS-3), futex_fault_nopcb adr x9, futex_fault /* Load the fault handler */ SET_FAULT_HANDLER(x9, x4) /* And set it */ ENTER_USER_ACCESS(w9, x4) mov w5, #LINUX_FUTEX_MAX_LOOPS prfm pstl1strm, [x1] mov w6, w0 /* Save oparg */ 1: ldxr w4, [x1] /* Load oldval from uaddr */ stlxr w0, w6, [x1] /* Store oparg to uaddr */ cbz w0, 3f /* Exit on success */ sub w5, w5, w0 /* Dec loop counter, w0 is 1 */ cbnz w5, 1b /* Loop */ mov x0, #EAGAIN /* Store of newval failed */ 3: dmb ish EXIT_USER_ACCESS(w9) SET_FAULT_HANDLER(xzr, x9) /* Reset the fault handler */ str w4, [x2] /* Store oldval */ ret END(futex_xchgl) /* (int *)uaddr2 += oparg */ ENTRY(futex_addl) check_user_access 1, (VM_MAXUSER_ADDRESS-3), futex_fault_nopcb adr x9, futex_fault SET_FAULT_HANDLER(x9, x4) ENTER_USER_ACCESS(w9, x4) mov w5, #LINUX_FUTEX_MAX_LOOPS prfm pstl1strm, [x1] mov w6, w0 1: ldxr w4, [x1] add w3, w4, w6 /* oldval + oparg */ stlxr w0, w3, [x1] cbz w0, 3f sub w5, w5, w0 cbnz w5, 1b mov x0, #EAGAIN 3: dmb ish EXIT_USER_ACCESS(w9) SET_FAULT_HANDLER(xzr, x9) str w4, [x2] ret END(futex_addl) /* (int *)uaddr2 |= oparg */ ENTRY(futex_orl) check_user_access 1, (VM_MAXUSER_ADDRESS-3), futex_fault_nopcb adr x9, futex_fault SET_FAULT_HANDLER(x9, x4) ENTER_USER_ACCESS(w9, x4) mov w5, #LINUX_FUTEX_MAX_LOOPS prfm pstl1strm, [x1] mov w6, w0 1: ldxr w4, [x1] orr w3, w4, w6 /* oldavl |= oparg */ stlxr w0, w3, [x1] cbz w0, 3f sub w5, w5, w0 cbnz w5, 1b mov x0, #EAGAIN 3: dmb ish EXIT_USER_ACCESS(w9) SET_FAULT_HANDLER(xzr, x9) str w4, [x2] ret END(futex_orl) /* (int *)uaddr2 &= oparg */ ENTRY(futex_andl) check_user_access 1, (VM_MAXUSER_ADDRESS-3), futex_fault_nopcb adr x9, futex_fault SET_FAULT_HANDLER(x9, x4) ENTER_USER_ACCESS(w9, x4) mov w5, #LINUX_FUTEX_MAX_LOOPS prfm pstl1strm, [x1] mov w6, w0 1: ldxr w4, [x1] and w3, w4, w6 /* oldval &= oparg */ stlxr w0, w3, [x1] cbz w0, 3f sub w5, w5, w0 cbnz w5, 1b mov x0, #EAGAIN 3: dmb ish EXIT_USER_ACCESS(w9) SET_FAULT_HANDLER(xzr, x9) str w4, [x2] ret END(futex_andl) /* (int *)uaddr2 ^= oparg */ ENTRY(futex_xorl) check_user_access 1, (VM_MAXUSER_ADDRESS-3), futex_fault_nopcb adr x9, futex_fault SET_FAULT_HANDLER(x9, x4) ENTER_USER_ACCESS(w9, x4) mov w5, #LINUX_FUTEX_MAX_LOOPS prfm pstl1strm, [x1] mov w6, w0 1: ldxr w4, [x1] eor w3, w4, w6 /* oldval ^= oparg */ stlxr w0, w3, [x1] cbz w0, 3f sub w5, w5, w0 cbnz w5, 1b mov x0, #EAGAIN 3: dmb ish EXIT_USER_ACCESS(w9) SET_FAULT_HANDLER(xzr, x9) str w4, [x2] ret END(futex_xorl) + +GNU_PROPERTY_AARCH64_FEATURE_1_NOTE(GNU_PROPERTY_AARCH64_FEATURE_1_VAL) diff --git a/sys/compat/linux/linux_vdso_inc.S b/sys/compat/linux/linux_vdso_inc.S new file mode 100644 index 000000000000..44cc357b4a4a --- /dev/null +++ b/sys/compat/linux/linux_vdso_inc.S @@ -0,0 +1,39 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (C) 2020 Arm Ltd + * + * 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. + */ + + .section .data + .globl _binary_linux_vdso_so_o_start +_binary_linux_vdso_so_o_start: + .incbin "linux_vdso.so.o" + .globl _binary_linux_vdso_so_o_end +_binary_linux_vdso_so_o_end: + +#if defined(__aarch64__) +#include +#include +GNU_PROPERTY_AARCH64_FEATURE_1_NOTE(GNU_PROPERTY_AARCH64_FEATURE_1_VAL) +#endif diff --git a/sys/modules/linux64/Makefile b/sys/modules/linux64/Makefile index 05fe76ba6a51..5d0174aa8e9b 100644 --- a/sys/modules/linux64/Makefile +++ b/sys/modules/linux64/Makefile @@ -1,112 +1,101 @@ .PATH: ${SRCTOP}/sys/compat/linux ${SRCTOP}/sys/${MACHINE}/linux .if ${MACHINE_CPUARCH} == "amd64" .PATH: ${SRCTOP}/sys/x86/linux .endif KMOD= linux64 SRCS= linux_dummy_machdep.c \ linux_elf64.c \ linux_event.c \ linux_file.c \ linux_fork.c \ linux_futex.c \ linux_getcwd.c \ linux_ioctl.c \ linux_ipc.c \ linux_machdep.c \ linux_misc.c \ linux_ptrace.c \ linux_rseq.c \ linux_signal.c \ linux_socket.c \ linux_stats.c \ linux_syscalls.c \ linux_sysctl.c \ linux_sysent.c \ linux_sysvec.c \ linux_time.c \ linux_vdso.c \ linux_timer.c \ linux_xattr.c \ opt_ktrace.h \ opt_inet6.h \ opt_posix.h \ bus_if.h \ device_if.h \ vnode_if.h \ - linux_support.S + linux_support.S \ + linux_vdso_inc.S .if ${MACHINE_CPUARCH} == "amd64" SRCS+= linux_dummy_x86.c .endif DPSRCS= assym.inc linux_genassym.c # XXX: for assym.inc SRCS+= opt_kstack_pages.h opt_nfs.h opt_hwpmc_hooks.h CLEANFILES= linux_assym.h linux_genassym.o linux_locore.o \ genassym.o linux_vdso_gtod.o linux_vdso.so.o -OBJS= linux_vdso.so linux_assym.h: linux_genassym.o sh ${SYSDIR}/kern/genassym.sh linux_genassym.o > ${.TARGET} .if ${MACHINE_CPUARCH} == "amd64" VDSOFLAGS=-mcmodel=small -msoft-float VDSODEPS=linux_vdso_gettc_x86.inc .elif ${MACHINE_CPUARCH} == "aarch64" # The Linux uses tiny memory model, but our ld does not know about # some of relocation types which is generated by cc VDSOFLAGS=-mgeneral-regs-only -mcmodel=small -ffixed-x18 .endif linux_locore.o: linux_assym.h assym.inc ${CC} -c -x assembler-with-cpp -DLOCORE \ -fPIC -pipe -O2 -Werror ${VDSOFLAGS} \ -nostdinc -fasynchronous-unwind-tables \ -fno-omit-frame-pointer -foptimize-sibling-calls \ -fno-stack-protector -I. -I${SYSDIR} -I${SRCTOP}/include \ ${.IMPSRC} -o ${.TARGET} linux_vdso_gtod.o: linux_vdso_gtod.inc ${VDSODEPS} ${CC} -c -fPIC -pipe -O2 -Werror ${VDSOFLAGS} \ -nostdinc -fasynchronous-unwind-tables \ -fno-omit-frame-pointer -foptimize-sibling-calls \ -fno-stack-protector -I. -I${SYSDIR} -I${SRCTOP}/include \ ${.IMPSRC} -o ${.TARGET} linux_vdso.so.o: linux_locore.o linux_vdso_gtod.o ${LD} --shared --eh-frame-hdr -soname=linux-vdso.so.1 \ --no-undefined --hash-style=both -warn-common -nostdlib \ --strip-debug -s --build-id=sha1 -Bsymbolic \ -T${SRCTOP}/sys/${MACHINE}/linux/linux_vdso.lds.s \ -o ${.TARGET} ${.ALLSRC:M*.o} -.if ${MACHINE_CPUARCH} == "aarch64" -OBJCOPY_TARGET=--output-target elf64-littleaarch64 --binary-architecture aarch64 -.elif ${MACHINE_CPUARCH} == "amd64" -OBJCOPY_TARGET=--output-target elf64-x86-64 --binary-architecture i386:x86-64 -.else -.error ${MACHINE_CPUARCH} not yet supported by linux64 -.endif - -linux_vdso.so: linux_vdso.so.o - ${OBJCOPY} --input-target binary ${OBJCOPY_TARGET} \ - linux_vdso.so.o ${.TARGET} - ${STRIPBIN} -N _binary_linux_vdso_so_o_size ${.TARGET} +linux_vdso_inc.o: linux_vdso.so.o linux_support.o: linux_support.S assym.inc linux_assym.h ${CC} -c -x assembler-with-cpp -DLOCORE ${CFLAGS} \ ${.ALLSRC:M*.S:u} -o ${.TARGET} linux_genassym.o: offset.inc ${CC} -c ${CFLAGS:N-flto:N-fno-common} -fcommon ${.IMPSRC} .if !defined(KERNBUILDDIR) .warning Building Linuxulator outside of a kernel does not make sense .endif EXPORT_SYMS= YES .include