Skip site navigation (1)Skip section navigation (2)
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>