aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/amd64/cloudabi64/cloudabi64_sysvec.c1
-rw-r--r--sys/arm64/cloudabi64/cloudabi64_sysvec.c1
-rw-r--r--sys/compat/cloudabi/cloudabi_util.h5
-rw-r--r--sys/compat/cloudabi/cloudabi_vdso.c88
-rw-r--r--sys/compat/cloudabi64/cloudabi64_module.c11
-rw-r--r--sys/compat/cloudabi64/cloudabi64_vdso.lds.s51
-rw-r--r--sys/conf/files1
-rw-r--r--sys/conf/files.amd6412
-rw-r--r--sys/conf/files.arm6412
-rw-r--r--sys/modules/cloudabi/Makefile2
-rw-r--r--sys/modules/cloudabi64/Makefile32
11 files changed, 211 insertions, 5 deletions
diff --git a/sys/amd64/cloudabi64/cloudabi64_sysvec.c b/sys/amd64/cloudabi64/cloudabi64_sysvec.c
index 08d85a2d5cb7..cefdef983238 100644
--- a/sys/amd64/cloudabi64/cloudabi64_sysvec.c
+++ b/sys/amd64/cloudabi64/cloudabi64_sysvec.c
@@ -196,7 +196,6 @@ static struct sysentvec cloudabi64_elf_sysvec = {
.sv_pagesize = PAGE_SIZE,
.sv_minuser = VM_MIN_ADDRESS,
.sv_maxuser = VM_MAXUSER_ADDRESS,
- .sv_usrstack = USRSTACK,
.sv_stackprot = VM_PROT_READ | VM_PROT_WRITE,
.sv_copyout_strings = cloudabi64_copyout_strings,
.sv_setregs = cloudabi64_proc_setregs,
diff --git a/sys/arm64/cloudabi64/cloudabi64_sysvec.c b/sys/arm64/cloudabi64/cloudabi64_sysvec.c
index cf3e594244bb..ebcb54e1a867 100644
--- a/sys/arm64/cloudabi64/cloudabi64_sysvec.c
+++ b/sys/arm64/cloudabi64/cloudabi64_sysvec.c
@@ -165,7 +165,6 @@ static struct sysentvec cloudabi64_elf_sysvec = {
.sv_pagesize = PAGE_SIZE,
.sv_minuser = VM_MIN_ADDRESS,
.sv_maxuser = VM_MAXUSER_ADDRESS,
- .sv_usrstack = USRSTACK,
.sv_stackprot = VM_PROT_READ | VM_PROT_WRITE,
.sv_copyout_strings = cloudabi64_copyout_strings,
.sv_setregs = cloudabi64_proc_setregs,
diff --git a/sys/compat/cloudabi/cloudabi_util.h b/sys/compat/cloudabi/cloudabi_util.h
index c0a02aa88dcb..6eb65aa87b32 100644
--- a/sys/compat/cloudabi/cloudabi_util.h
+++ b/sys/compat/cloudabi/cloudabi_util.h
@@ -33,6 +33,7 @@
#include <contrib/cloudabi/cloudabi_types_common.h>
struct file;
+struct sysentvec;
struct thread;
struct timespec;
@@ -76,4 +77,8 @@ int cloudabi_futex_lock_wrlock(struct thread *, cloudabi_lock_t *,
cloudabi_scope_t, cloudabi_clockid_t, cloudabi_timestamp_t,
cloudabi_timestamp_t);
+/* vDSO setup and teardown. */
+void cloudabi_vdso_init(struct sysentvec *, char *, char *);
+void cloudabi_vdso_destroy(struct sysentvec *);
+
#endif
diff --git a/sys/compat/cloudabi/cloudabi_vdso.c b/sys/compat/cloudabi/cloudabi_vdso.c
new file mode 100644
index 000000000000..27c3d365af83
--- /dev/null
+++ b/sys/compat/cloudabi/cloudabi_vdso.c
@@ -0,0 +1,88 @@
+/*-
+ * Copyright (c) 2016 Nuxi, https://nuxi.nl/
+ *
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/lock.h>
+#include <sys/sysent.h>
+#include <sys/rwlock.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pager.h>
+
+#include <compat/cloudabi/cloudabi_util.h>
+
+void
+cloudabi_vdso_init(struct sysentvec *sv, char *begin, char *end)
+{
+ vm_page_t m;
+ vm_object_t obj;
+ vm_offset_t addr;
+ size_t i, pages, pages_length, vdso_length;
+
+ /* Determine the number of pages needed to store the vDSO. */
+ vdso_length = end - begin;
+ pages = howmany(vdso_length, PAGE_SIZE);
+ pages_length = pages * PAGE_SIZE;
+
+ /* Allocate a VM object and fill it with the vDSO. */
+ obj = vm_pager_allocate(OBJT_PHYS, 0, pages_length,
+ VM_PROT_DEFAULT, 0, NULL);
+ addr = kva_alloc(PAGE_SIZE);
+ for (i = 0; i < pages; ++i) {
+ VM_OBJECT_WLOCK(obj);
+ m = vm_page_grab(obj, i, VM_ALLOC_NOBUSY | VM_ALLOC_ZERO);
+ m->valid = VM_PAGE_BITS_ALL;
+ VM_OBJECT_WUNLOCK(obj);
+
+ pmap_qenter(addr, &m, 1);
+ memcpy((void *)addr, begin + i * PAGE_SIZE,
+ MIN(vdso_length - i * PAGE_SIZE, PAGE_SIZE));
+ pmap_qremove(addr, 1);
+ }
+ kva_free(addr, PAGE_SIZE);
+
+ /*
+ * Place the vDSO at the top of the address space. The user
+ * stack can start right below it.
+ */
+ sv->sv_shared_page_base = sv->sv_maxuser - pages_length;
+ sv->sv_shared_page_len = pages_length;
+ sv->sv_shared_page_obj = obj;
+ sv->sv_usrstack = sv->sv_shared_page_base;
+}
+
+void
+cloudabi_vdso_destroy(struct sysentvec *sv)
+{
+
+ vm_object_deallocate(sv->sv_shared_page_obj);
+}
diff --git a/sys/compat/cloudabi64/cloudabi64_module.c b/sys/compat/cloudabi64/cloudabi64_module.c
index 246a887105cb..da1ea1149a4b 100644
--- a/sys/compat/cloudabi64/cloudabi64_module.c
+++ b/sys/compat/cloudabi64/cloudabi64_module.c
@@ -38,8 +38,13 @@ __FBSDID("$FreeBSD$");
#include <contrib/cloudabi/cloudabi64_types.h>
+#include <compat/cloudabi/cloudabi_util.h>
+
#include <compat/cloudabi64/cloudabi64_util.h>
+extern char _binary_cloudabi64_vdso_o_start[];
+extern char _binary_cloudabi64_vdso_o_end[];
+
register_t *
cloudabi64_copyout_strings(struct image_params *imgp)
{
@@ -107,6 +112,8 @@ cloudabi64_fixup(register_t **stack_base, struct image_params *imgp)
PTR(CLOUDABI_AT_PHDR, args->phdr),
VAL(CLOUDABI_AT_PHNUM, args->phnum),
VAL(CLOUDABI_AT_TID, td->td_tid),
+ PTR(CLOUDABI_AT_SYSINFO_EHDR,
+ imgp->proc->p_sysent->sv_shared_page_base),
#undef VAL
#undef PTR
{ .a_type = CLOUDABI_AT_NULL },
@@ -127,6 +134,9 @@ cloudabi64_modevent(module_t mod, int type, void *data)
switch (type) {
case MOD_LOAD:
+ cloudabi_vdso_init(cloudabi64_brand.sysvec,
+ _binary_cloudabi64_vdso_o_start,
+ _binary_cloudabi64_vdso_o_end);
if (elf64_insert_brand_entry(&cloudabi64_brand) < 0) {
printf("Failed to add CloudABI ELF brand handler\n");
return (EINVAL);
@@ -139,6 +149,7 @@ cloudabi64_modevent(module_t mod, int type, void *data)
printf("Failed to remove CloudABI ELF brand handler\n");
return (EINVAL);
}
+ cloudabi_vdso_destroy(cloudabi64_brand.sysvec);
return (0);
default:
return (EOPNOTSUPP);
diff --git a/sys/compat/cloudabi64/cloudabi64_vdso.lds.s b/sys/compat/cloudabi64/cloudabi64_vdso.lds.s
new file mode 100644
index 000000000000..29c94d3cdde8
--- /dev/null
+++ b/sys/compat/cloudabi64/cloudabi64_vdso.lds.s
@@ -0,0 +1,51 @@
+/*
+ * Linker script for 64-bit vDSO for CloudABI.
+ * Based on sys/amd64/linux/linux_vdso.lds.s
+ *
+ * $FreeBSD$
+ */
+
+SECTIONS
+{
+ . = . + SIZEOF_HEADERS;
+
+ .hash : { *(.hash) } :text
+ .gnu.hash : { *(.gnu.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+
+ .note : { *(.note.*) } :text :note
+
+ .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
+ .eh_frame : { KEEP (*(.eh_frame)) } :text
+
+ .dynamic : { *(.dynamic) } :text :dynamic
+
+ .rodata : { *(.rodata*) } :text
+ .data : {
+ *(.data*)
+ *(.sdata*)
+ *(.got.plt) *(.got)
+ *(.gnu.linkonce.d.*)
+ *(.bss*)
+ *(.dynbss*)
+ *(.gnu.linkonce.b.*)
+ }
+
+ .altinstructions : { *(.altinstructions) }
+ .altinstr_replacement : { *(.altinstr_replacement) }
+
+ . = ALIGN(0x100);
+ .text : { *(.test .text*) } :text =0x90909090
+}
+
+PHDRS
+{
+ text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */
+ dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
+ note PT_NOTE FLAGS(4); /* PF_R */
+ eh_frame_hdr PT_GNU_EH_FRAME;
+}
diff --git a/sys/conf/files b/sys/conf/files
index 4f5fa71ee9b8..993f0c3892ab 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -284,6 +284,7 @@ compat/cloudabi/cloudabi_proc.c optional compat_cloudabi64
compat/cloudabi/cloudabi_random.c optional compat_cloudabi64
compat/cloudabi/cloudabi_sock.c optional compat_cloudabi64
compat/cloudabi/cloudabi_thread.c optional compat_cloudabi64
+compat/cloudabi/cloudabi_vdso.c optional compat_cloudabi64
compat/cloudabi64/cloudabi64_fd.c optional compat_cloudabi64
compat/cloudabi64/cloudabi64_module.c optional compat_cloudabi64
compat/cloudabi64/cloudabi64_poll.c optional compat_cloudabi64
diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
index 331b811081f7..df5d1bcfb88e 100644
--- a/sys/conf/files.amd64
+++ b/sys/conf/files.amd64
@@ -8,6 +8,18 @@
# dependency lines other than the first are silently ignored.
#
#
+cloudabi64_vdso.o optional compat_cloudabi64 \
+ dependency "$S/contrib/cloudabi/cloudabi_vdso_x86_64.c" \
+ compile-with "${CC} -shared -nostdinc -nostdlib -Wl,-T$S/compat/cloudabi64/cloudabi64_vdso.lds.s -D_KERNEL -I. -I$S -I$S/contrib/cloudabi -O2 -fomit-frame-pointer $S/contrib/cloudabi/cloudabi_vdso_x86_64.c -o ${.TARGET}" \
+ no-obj no-implicit-rule \
+ clean "cloudabi64_vdso.o"
+#
+cloudabi64_vdso_blob.o optional compat_cloudabi64 \
+ dependency "cloudabi64_vdso.o" \
+ compile-with "${OBJCOPY} --input-target binary --output-target elf64-x86-64-freebsd --binary-architecture i386 cloudabi64_vdso.o ${.TARGET}" \
+ no-implicit-rule \
+ clean "cloudabi64_vdso_blob.o"
+#
linux32_genassym.o optional compat_linux32 \
dependency "$S/amd64/linux32/linux32_genassym.c" \
compile-with "${CC} ${CFLAGS:N-fno-common} -c ${.IMPSRC}" \
diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64
index b4c82085ace0..31acaf9ce32f 100644
--- a/sys/conf/files.arm64
+++ b/sys/conf/files.arm64
@@ -1,4 +1,16 @@
# $FreeBSD$
+cloudabi64_vdso.o optional compat_cloudabi64 \
+ dependency "$S/contrib/cloudabi/cloudabi_vdso_aarch64.c" \
+ compile-with "${CC} -shared -nostdinc -nostdlib -Wl,-T$S/compat/cloudabi64/cloudabi64_vdso.lds.s -D_KERNEL -I. -I$S -I$S/contrib/cloudabi -O2 -fomit-frame-pointer $S/contrib/cloudabi/cloudabi_vdso_aarch64.c -o ${.TARGET}" \
+ no-obj no-implicit-rule \
+ clean "cloudabi64_vdso.o"
+#
+cloudabi64_vdso_blob.o optional compat_cloudabi64 \
+ dependency "cloudabi64_vdso.o" \
+ compile-with "${OBJCOPY} --input-target binary --output-target elf64-littleaarch64 --binary-architecture aarch64 cloudabi64_vdso.o ${.TARGET}" \
+ no-implicit-rule \
+ clean "cloudabi64_vdso_blob.o"
+#
arm/arm/generic_timer.c standard
arm/arm/gic.c standard
arm/arm/gic_fdt.c optional fdt
diff --git a/sys/modules/cloudabi/Makefile b/sys/modules/cloudabi/Makefile
index bba50362eab1..c608580c7f30 100644
--- a/sys/modules/cloudabi/Makefile
+++ b/sys/modules/cloudabi/Makefile
@@ -5,6 +5,6 @@
KMOD= cloudabi
SRCS= cloudabi_clock.c cloudabi_errno.c cloudabi_fd.c cloudabi_file.c \
cloudabi_futex.c cloudabi_mem.c cloudabi_proc.c cloudabi_random.c \
- cloudabi_sock.c cloudabi_thread.c vnode_if.h
+ cloudabi_sock.c cloudabi_thread.c cloudabi_vdso.c vnode_if.h
.include <bsd.kmod.mk>
diff --git a/sys/modules/cloudabi64/Makefile b/sys/modules/cloudabi64/Makefile
index 3aee96d97525..b6fe38057ba8 100644
--- a/sys/modules/cloudabi64/Makefile
+++ b/sys/modules/cloudabi64/Makefile
@@ -1,11 +1,39 @@
# $FreeBSD$
-.PATH: ${.CURDIR}/../../compat/cloudabi64
-.PATH: ${.CURDIR}/../../${MACHINE}/cloudabi64
+SYSDIR?=${.CURDIR}/../..
+
+.PATH: ${SYSDIR}/compat/cloudabi64
+.PATH: ${SYSDIR}/${MACHINE}/cloudabi64
KMOD= cloudabi64
SRCS= cloudabi64_fd.c cloudabi64_module.c cloudabi64_poll.c \
cloudabi64_sock.c cloudabi64_syscalls.c cloudabi64_sysent.c \
cloudabi64_sysvec.c cloudabi64_thread.c
+OBJS= cloudabi64_vdso_blob.o
+CLEANFILES=cloudabi64_vdso.o
+
+.if ${MACHINE_CPUARCH} == "aarch64"
+VDSO_SRCS=${SYSDIR}/contrib/cloudabi/cloudabi_vdso_aarch64.c
+OUTPUT_TARGET=elf64-littleaarch64
+BINARY_ARCHITECTURE=aarch64
+.elif ${MACHINE_CPUARCH} == "amd64"
+VDSO_SRCS=${SYSDIR}/contrib/cloudabi/cloudabi_vdso_x86_64.c
+OUTPUT_TARGET=elf64-x86-64-freebsd
+BINARY_ARCHITECTURE=i386
+.endif
+
+cloudabi64_vdso.o: ${VDSO_SRCS}
+ ${CC} -shared -nostdinc -nostdlib \
+ -Wl,-T${SYSDIR}/compat/cloudabi64/cloudabi64_vdso.lds.s \
+ -D_KERNEL -I. -I${SYSDIR} -I${SYSDIR}/contrib/cloudabi \
+ -O2 -fomit-frame-pointer \
+ ${VDSO_SRCS} -o ${.TARGET}
+
+cloudabi64_vdso_blob.o: cloudabi64_vdso.o
+ ${OBJCOPY} --input-target binary \
+ --output-target ${OUTPUT_TARGET} \
+ --binary-architecture ${BINARY_ARCHITECTURE} \
+ cloudabi64_vdso.o ${.TARGET}
+
.include <bsd.kmod.mk>