summaryrefslogtreecommitdiffstats
path: root/sys/arm64
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2015-12-07 12:20:26 +0000
committerkib <kib@FreeBSD.org>2015-12-07 12:20:26 +0000
commit80e8626b434515d16b3576174438526755336810 (patch)
treeee009a15b4f96147d9c165989cac04cfe89b0677 /sys/arm64
parent29c1a1655d214f8a5756afd74f04ccf3006ab7fe (diff)
downloadFreeBSD-src-80e8626b434515d16b3576174438526755336810.zip
FreeBSD-src-80e8626b434515d16b3576174438526755336810.tar.gz
Add support for usermode (vdso-like) gettimeofday(2) and
clock_gettime(2) on ARMv7 and ARMv8 systems which have architectural generic timer hardware. It is similar how the RDTSC timer is used in userspace on x86. Fix a permission problem where generic timer access from EL0 (or userspace on v7) was not properly initialized on APs. For ARMv7, mark the stack non-executable. The shared page is added for all arms (including ARMv8 64bit), and the signal trampoline code is moved to the page. Reviewed by: andrew Discussed with: emaste, mmel Sponsored by: The FreeBSD Foundation Differential revision: https://reviews.freebsd.org/D4209
Diffstat (limited to 'sys/arm64')
-rw-r--r--sys/arm64/arm64/elf_machdep.c5
-rw-r--r--sys/arm64/arm64/machdep.c21
-rw-r--r--sys/arm64/include/md_var.h5
-rw-r--r--sys/arm64/include/vdso.h3
-rw-r--r--sys/arm64/include/vmparam.h3
5 files changed, 33 insertions, 4 deletions
diff --git a/sys/arm64/arm64/elf_machdep.c b/sys/arm64/arm64/elf_machdep.c
index 2506de3..9ba2541 100644
--- a/sys/arm64/arm64/elf_machdep.c
+++ b/sys/arm64/arm64/elf_machdep.c
@@ -80,12 +80,15 @@ static struct sysentvec elf64_freebsd_sysvec = {
.sv_setregs = exec_setregs,
.sv_fixlimit = NULL,
.sv_maxssiz = NULL,
- .sv_flags = SV_ABI_FREEBSD | SV_LP64,
+ .sv_flags = SV_SHP | SV_TIMEKEEP | SV_ABI_FREEBSD | SV_LP64,
.sv_set_syscall_retval = cpu_set_syscall_retval,
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
.sv_syscallnames = syscallnames,
+ .sv_shared_page_base = SHAREDPAGE,
+ .sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = NULL,
};
+INIT_SYSENTVEC(elf64_sysvec, &elf64_freebsd_sysvec);
static Elf64_Brandinfo freebsd_brand_info = {
.brand = ELFOSABI_FREEBSD,
diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c
index e92a99f..f7e1456 100644
--- a/sys/arm64/arm64/machdep.c
+++ b/sys/arm64/arm64/machdep.c
@@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sysent.h>
#include <sys/sysproto.h>
#include <sys/ucontext.h>
+#include <sys/vdso.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
@@ -72,6 +73,7 @@ __FBSDID("$FreeBSD$");
#include <machine/devmap.h>
#include <machine/machdep.h>
#include <machine/metadata.h>
+#include <machine/md_var.h>
#include <machine/pcb.h>
#include <machine/reg.h>
#include <machine/vmparam.h>
@@ -505,6 +507,7 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
struct trapframe *tf;
struct sigframe *fp, frame;
struct sigacts *psp;
+ struct sysentvec *sysent;
int code, onstack, sig;
td = curthread;
@@ -563,7 +566,12 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
tf->tf_elr = (register_t)catcher;
tf->tf_sp = (register_t)fp;
- tf->tf_lr = (register_t)(PS_STRINGS - *(p->p_sysent->sv_szsigcode));
+ sysent = p->p_sysent;
+ if (sysent->sv_sigcode_base != 0)
+ tf->tf_lr = (register_t)sysent->sv_sigcode_base;
+ else
+ tf->tf_lr = (register_t)(sysent->sv_psstrings -
+ *(sysent->sv_szsigcode));
CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td, tf->tf_elr,
tf->tf_sp);
@@ -875,6 +883,17 @@ initarm(struct arm64_bootparams *abp)
early_boot = 0;
}
+uint32_t (*arm_cpu_fill_vdso_timehands)(struct vdso_timehands *,
+ struct timecounter *);
+
+uint32_t
+cpu_fill_vdso_timehands(struct vdso_timehands *vdso_th, struct timecounter *tc)
+{
+
+ return (arm_cpu_fill_vdso_timehands != NULL ?
+ arm_cpu_fill_vdso_timehands(vdso_th, tc) : 0);
+}
+
#ifdef DDB
#include <ddb/ddb.h>
diff --git a/sys/arm64/include/md_var.h b/sys/arm64/include/md_var.h
index 8545591..d6cecfc 100644
--- a/sys/arm64/include/md_var.h
+++ b/sys/arm64/include/md_var.h
@@ -46,4 +46,9 @@ void dump_add_page(vm_paddr_t);
void dump_drop_page(vm_paddr_t);
int minidumpsys(struct dumperinfo *);
+struct vdso_timehands;
+struct timecounter;
+extern uint32_t (*arm_cpu_fill_vdso_timehands)(struct vdso_timehands *,
+ struct timecounter *);
+
#endif /* !_MACHINE_MD_VAR_H_ */
diff --git a/sys/arm64/include/vdso.h b/sys/arm64/include/vdso.h
index 5a8f7f5..285e986 100644
--- a/sys/arm64/include/vdso.h
+++ b/sys/arm64/include/vdso.h
@@ -29,6 +29,7 @@
#define _MACHINE_VDSO_H_
#define VDSO_TIMEHANDS_MD \
- uint32_t th_res[8];
+ uint32_t th_physical; \
+ uint32_t th_res[7];
#endif /* !_MACHINE_VDSO_H_ */
diff --git a/sys/arm64/include/vmparam.h b/sys/arm64/include/vmparam.h
index e3c1d74..2752ee1 100644
--- a/sys/arm64/include/vmparam.h
+++ b/sys/arm64/include/vmparam.h
@@ -194,7 +194,8 @@ extern vm_paddr_t dmap_phys_base;
#define VM_MAXUSER_ADDRESS (VM_MAX_USER_ADDRESS)
#define KERNBASE (VM_MIN_KERNEL_ADDRESS)
-#define USRSTACK (VM_MAX_USER_ADDRESS)
+#define SHAREDPAGE (VM_MAXUSER_ADDRESS - PAGE_SIZE)
+#define USRSTACK SHAREDPAGE
/*
* How many physical pages per kmem arena virtual page.
OpenPOWER on IntegriCloud