Date: Thu, 30 Nov 2017 17:58:49 +0000 (UTC) From: Ed Schouten <ed@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r326406 - in head: share/man/man4 sys/arm64/cloudabi32 sys/conf sys/modules Message-ID: <201711301758.vAUHwne0055636@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ed Date: Thu Nov 30 17:58:48 2017 New Revision: 326406 URL: https://svnweb.freebsd.org/changeset/base/326406 Log: Port cloudabi32.ko to FreeBSD/arm64. This change adds an implementation of a sysent for running CloudABI armv6 and armv7 binaries on FreeBSD/arm64. It is a somewhat literal copy of the armv6 version, except that it's been patched up to use the proper registers. Just like for cloudabi32.ko on FreeBSD/amd64, we make use of a vDSO that automatically pads system call parameters to 64-bit value. These are stored in a buffer on the stack, meaning we need to use copyin() and copyout() unconditionally. Added: head/sys/arm64/cloudabi32/ - copied from r326229, head/sys/arm/cloudabi32/ Modified: head/share/man/man4/cloudabi.4 head/sys/arm64/cloudabi32/cloudabi32_sysvec.c head/sys/conf/files.arm64 head/sys/modules/Makefile Modified: head/share/man/man4/cloudabi.4 ============================================================================== --- head/share/man/man4/cloudabi.4 Thu Nov 30 15:58:38 2017 (r326405) +++ head/share/man/man4/cloudabi.4 Thu Nov 30 17:58:48 2017 (r326406) @@ -1,4 +1,4 @@ -.\" Copyright (c) 2015-2016 Nuxi, https://nuxi.nl/ +.\" Copyright (c) 2015-2017 Nuxi, https://nuxi.nl/ .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions @@ -22,7 +22,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd September 22, 2016 +.Dd November 30, 2017 .Dt CLOUDABI 4 .Os .Sh NAME @@ -84,7 +84,7 @@ module can be loaded on any architecture supported by .Fx , the .Nm cloudabi32 -module is only available on amd64, armv6 and i386. +module is only available on amd64, arm64, armv6, armv7 and i386. The same holds for the .Nm cloudabi64 module, Modified: head/sys/arm64/cloudabi32/cloudabi32_sysvec.c ============================================================================== --- head/sys/arm/cloudabi32/cloudabi32_sysvec.c Sun Nov 26 14:53:56 2017 (r326229) +++ head/sys/arm64/cloudabi32/cloudabi32_sysvec.c Thu Nov 30 17:58:48 2017 (r326406) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2015-2016 Nuxi, https://nuxi.nl/ + * Copyright (c) 2015-2017 Nuxi, https://nuxi.nl/ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -53,16 +53,13 @@ cloudabi32_proc_setregs(struct thread *td, struct imag { struct trapframe *regs; - exec_setregs(td, imgp, stack); - - /* - * The stack now contains a pointer to the TCB and the auxiliary - * vector. Let r0 point to the auxiliary vector, and set - * tpidrurw to the TCB. - */ regs = td->td_frame; - regs->tf_r0 = + memset(regs, 0, sizeof(*regs)); + regs->tf_x[0] = stack + roundup(sizeof(cloudabi32_tcb_t), sizeof(register_t)); + regs->tf_x[13] = STACKALIGN(stack); + regs->tf_elr = imgp->entry_addr; + regs->tf_spsr |= PSR_AARCH32; (void)cpu_set_user_tls(td, TO_PTR(stack)); } @@ -77,27 +74,30 @@ cloudabi32_fetch_syscall_args(struct thread *td) sa = &td->td_sa; /* Obtain system call number. */ - sa->code = frame->tf_r12; + sa->code = frame->tf_x[0]; if (sa->code >= CLOUDABI32_SYS_MAXSYSCALL) return (ENOSYS); sa->callp = &cloudabi32_sysent[sa->code]; sa->narg = sa->callp->sy_narg; - /* Fetch system call arguments from registers and the stack. */ - sa->args[0] = frame->tf_r0; - sa->args[1] = frame->tf_r1; - sa->args[2] = frame->tf_r2; - sa->args[3] = frame->tf_r3; - if (sa->narg > 4) { - error = copyin((void *)td->td_frame->tf_usr_sp, &sa->args[4], - (sa->narg - 4) * sizeof(register_t)); - if (error != 0) - return (error); - } + /* + * Fetch system call arguments. + * + * The vDSO has already made sure that the arguments are + * eight-byte aligned. Pointers and size_t parameters are + * zero-extended. This makes it possible to copy in the + * arguments directly. As long as the call doesn't use 32-bit + * data structures, we can just invoke the same system call + * implementation used by 64-bit processes. + */ + error = copyin((void *)frame->tf_x[2], sa->args, + sa->narg * sizeof(sa->args[0])); + if (error != 0) + return (error); /* Default system call return values. */ td->td_retval[0] = 0; - td->td_retval[1] = frame->tf_r1; + td->td_retval[1] = 0; return (0); } @@ -108,20 +108,32 @@ cloudabi32_set_syscall_retval(struct thread *td, int e switch (error) { case 0: - /* System call succeeded. */ - frame->tf_r0 = td->td_retval[0]; - frame->tf_r1 = td->td_retval[1]; - frame->tf_spsr &= ~PSR_C; + /* + * System call succeeded. + * + * Simply copy out the 64-bit return values into the + * same buffer provided for system call arguments. The + * vDSO will copy them to the right spot, truncating + * pointers and size_t values to 32 bits. + */ + if (copyout(td->td_retval, (void *)frame->tf_x[2], + sizeof(td->td_retval)) == 0) { + frame->tf_x[0] = 0; + frame->tf_spsr &= ~PSR_C; + } else { + frame->tf_x[0] = CLOUDABI_EFAULT; + frame->tf_spsr |= PSR_C; + } break; case ERESTART: /* Restart system call. */ - frame->tf_pc -= 4; + frame->tf_elr -= 4; break; case EJUSTRETURN: break; default: /* System call returned an error. */ - frame->tf_r0 = cloudabi_convert_errno(error); + frame->tf_x[0] = cloudabi_convert_errno(error); frame->tf_spsr |= PSR_C; break; } @@ -131,16 +143,15 @@ static void cloudabi32_schedtail(struct thread *td) { struct trapframe *frame = td->td_frame; + register_t retval[2]; - /* - * Initial register values for processes returning from fork. - * Make sure that we only set these values when forking, not - * when creating a new thread. - */ + /* Return values for processes returning from fork. */ if ((td->td_pflags & TDP_FORKING) != 0) { - frame->tf_r0 = CLOUDABI_PROCESS_CHILD; - frame->tf_r1 = td->td_tid; + retval[0] = CLOUDABI_PROCESS_CHILD; + retval[1] = td->td_tid; + copyout(retval, (void *)frame->tf_x[2], sizeof(retval)); } + frame->tf_spsr |= PSR_AARCH32; } int @@ -148,21 +159,18 @@ cloudabi32_thread_setregs(struct thread *td, const cloudabi32_threadattr_t *attr, uint32_t tcb) { struct trapframe *frame; - stack_t stack; - /* Perform standard register initialization. */ - stack.ss_sp = TO_PTR(attr->stack); - stack.ss_size = attr->stack_len; - cpu_set_upcall(td, TO_PTR(attr->entry_point), NULL, &stack); - /* * Pass in the thread ID of the new thread and the argument * pointer provided by the parent thread in as arguments to the * entry point. */ frame = td->td_frame; - frame->tf_r0 = td->td_tid; - frame->tf_r1 = attr->argument; + memset(frame, 0, sizeof(*frame)); + frame->tf_x[0] = td->td_tid; + frame->tf_x[1] = attr->argument; + frame->tf_x[13] = STACKALIGN(attr->stack + attr->stack_len); + frame->tf_elr = attr->entry_point; /* Set up TLS. */ return (cpu_set_user_tls(td, TO_PTR(tcb))); @@ -176,7 +184,7 @@ static struct sysentvec cloudabi32_elf_sysvec = { .sv_coredump = elf32_coredump, .sv_pagesize = PAGE_SIZE, .sv_minuser = VM_MIN_ADDRESS, - .sv_maxuser = VM_MAXUSER_ADDRESS, + .sv_maxuser = (uintmax_t)1 << 32, .sv_stackprot = VM_PROT_READ | VM_PROT_WRITE, .sv_copyout_strings = cloudabi32_copyout_strings, .sv_setregs = cloudabi32_proc_setregs, Modified: head/sys/conf/files.arm64 ============================================================================== --- head/sys/conf/files.arm64 Thu Nov 30 15:58:38 2017 (r326405) +++ head/sys/conf/files.arm64 Thu Nov 30 17:58:48 2017 (r326406) @@ -1,4 +1,16 @@ # $FreeBSD$ +cloudabi32_vdso.o optional compat_cloudabi32 \ + dependency "$S/contrib/cloudabi/cloudabi_vdso_armv6_on_64bit.S" \ + compile-with "${CC} -x assembler-with-cpp -m32 -shared -nostdinc -nostdlib -Wl,-T$S/compat/cloudabi/cloudabi_vdso.lds $S/contrib/cloudabi/cloudabi_vdso_armv6_on_64bit.S -o ${.TARGET}" \ + no-obj no-implicit-rule \ + clean "cloudabi32_vdso.o" +# +cloudabi32_vdso_blob.o optional compat_cloudabi32 \ + dependency "cloudabi32_vdso.o" \ + compile-with "${OBJCOPY} --input-target binary --output-target elf64-littleaarch64 --binary-architecture aarch64 cloudabi32_vdso.o ${.TARGET}" \ + no-implicit-rule \ + clean "cloudabi32_vdso_blob.o" +# cloudabi64_vdso.o optional compat_cloudabi64 \ dependency "$S/contrib/cloudabi/cloudabi_vdso_aarch64.S" \ compile-with "${CC} -x assembler-with-cpp -shared -nostdinc -nostdlib -Wl,-T$S/compat/cloudabi/cloudabi_vdso.lds $S/contrib/cloudabi/cloudabi_vdso_aarch64.S -o ${.TARGET}" \ @@ -130,6 +142,7 @@ arm64/cavium/thunder_pcie_fdt.c optional soc_cavm_thu arm64/cavium/thunder_pcie_pem.c optional soc_cavm_thunderx pci arm64/cavium/thunder_pcie_pem_fdt.c optional soc_cavm_thunderx pci fdt arm64/cavium/thunder_pcie_common.c optional soc_cavm_thunderx pci +arm64/cloudabi32/cloudabi32_sysvec.c optional compat_cloudabi32 arm64/cloudabi64/cloudabi64_sysvec.c optional compat_cloudabi64 contrib/vchiq/interface/compat/vchi_bsd.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" Modified: head/sys/modules/Makefile ============================================================================== --- head/sys/modules/Makefile Thu Nov 30 15:58:38 2017 (r326405) +++ head/sys/modules/Makefile Thu Nov 30 17:58:48 2017 (r326406) @@ -796,8 +796,8 @@ _em= em _epic= epic .endif -.if (${MACHINE_CPUARCH} == "amd64" || ${MACHINE_ARCH:Marmv[67]*} != "" || \ - ${MACHINE_CPUARCH} == "i386") +.if (${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "amd64" || \ + ${MACHINE_ARCH:Marmv[67]*} != "" || ${MACHINE_CPUARCH} == "i386") _cloudabi32= cloudabi32 .endif .if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "amd64"
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201711301758.vAUHwne0055636>