diff options
author | kib <kib@FreeBSD.org> | 2015-12-07 12:20:26 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2015-12-07 12:20:26 +0000 |
commit | 80e8626b434515d16b3576174438526755336810 (patch) | |
tree | ee009a15b4f96147d9c165989cac04cfe89b0677 /sys/arm64 | |
parent | 29c1a1655d214f8a5756afd74f04ccf3006ab7fe (diff) | |
download | FreeBSD-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.c | 5 | ||||
-rw-r--r-- | sys/arm64/arm64/machdep.c | 21 | ||||
-rw-r--r-- | sys/arm64/include/md_var.h | 5 | ||||
-rw-r--r-- | sys/arm64/include/vdso.h | 3 | ||||
-rw-r--r-- | sys/arm64/include/vmparam.h | 3 |
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. |