Index: share/man/man4/cloudabi.4 =================================================================== --- share/man/man4/cloudabi.4 +++ share/man/man4/cloudabi.4 @@ -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 26, 2017 .Dt CLOUDABI 4 .Os .Sh NAME @@ -84,7 +84,7 @@ .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, Index: sys/arm64/cloudabi32/cloudabi32_sysvec.c =================================================================== --- sys/arm64/cloudabi32/cloudabi32_sysvec.c +++ sys/arm64/cloudabi32/cloudabi32_sysvec.c @@ -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 @@ { 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 @@ 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 @@ 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 @@ 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,12 +159,6 @@ 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 @@ -161,8 +166,11 @@ * 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 @@ .sv_coredump = elf32_coredump, .sv_pagesize = PAGE_SIZE, .sv_minuser = VM_MIN_ADDRESS, - .sv_maxuser = VM_MAXUSER_ADDRESS, + .sv_maxuser = (uintptr_t)1 << 32, .sv_stackprot = VM_PROT_READ | VM_PROT_WRITE, .sv_copyout_strings = cloudabi32_copyout_strings, .sv_setregs = cloudabi32_proc_setregs, Index: sys/conf/files.arm64 =================================================================== --- sys/conf/files.arm64 +++ sys/conf/files.arm64 @@ -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_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" Index: sys/modules/Makefile =================================================================== --- sys/modules/Makefile +++ sys/modules/Makefile @@ -796,8 +796,8 @@ _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"