summaryrefslogtreecommitdiffstats
path: root/sys/compat/cloudabi
diff options
context:
space:
mode:
Diffstat (limited to 'sys/compat/cloudabi')
-rw-r--r--sys/compat/cloudabi/cloudabi_clock.c4
-rw-r--r--sys/compat/cloudabi/cloudabi_thread.c8
-rw-r--r--sys/compat/cloudabi/cloudabi_util.h5
-rw-r--r--sys/compat/cloudabi/cloudabi_vdso.c88
-rw-r--r--sys/compat/cloudabi/cloudabi_vdso.lds51
5 files changed, 146 insertions, 10 deletions
diff --git a/sys/compat/cloudabi/cloudabi_clock.c b/sys/compat/cloudabi/cloudabi_clock.c
index b26d98e..ce53a11 100644
--- a/sys/compat/cloudabi/cloudabi_clock.c
+++ b/sys/compat/cloudabi/cloudabi_clock.c
@@ -117,7 +117,7 @@ cloudabi_sys_clock_res_get(struct thread *td,
error = cloudabi_convert_timespec(&ts, &cts);
if (error != 0)
return (error);
- td->td_retval[0] = cts;
+ memcpy(td->td_retval, &cts, sizeof(cts));
return (0);
}
@@ -129,6 +129,6 @@ cloudabi_sys_clock_time_get(struct thread *td,
int error;
error = cloudabi_clock_time_get(td, uap->clock_id, &ts);
- td->td_retval[0] = ts;
+ memcpy(td->td_retval, &ts, sizeof(ts));
return (error);
}
diff --git a/sys/compat/cloudabi/cloudabi_thread.c b/sys/compat/cloudabi/cloudabi_thread.c
index dd54e89..e70549b 100644
--- a/sys/compat/cloudabi/cloudabi_thread.c
+++ b/sys/compat/cloudabi/cloudabi_thread.c
@@ -60,14 +60,6 @@ cloudabi_sys_thread_exit(struct thread *td,
}
int
-cloudabi_sys_thread_tcb_set(struct thread *td,
- struct cloudabi_sys_thread_tcb_set_args *uap)
-{
-
- return (cpu_set_user_tls(td, uap->tcb));
-}
-
-int
cloudabi_sys_thread_yield(struct thread *td,
struct cloudabi_sys_thread_yield_args *uap)
{
diff --git a/sys/compat/cloudabi/cloudabi_util.h b/sys/compat/cloudabi/cloudabi_util.h
index c0a02aa..6eb65aa 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 0000000..27c3d36
--- /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/cloudabi/cloudabi_vdso.lds b/sys/compat/cloudabi/cloudabi_vdso.lds
new file mode 100644
index 0000000..807c488
--- /dev/null
+++ b/sys/compat/cloudabi/cloudabi_vdso.lds
@@ -0,0 +1,51 @@
+/*
+ * Linker script for the 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;
+}
OpenPOWER on IntegriCloud