diff options
23 files changed, 1346 insertions, 35 deletions
diff --git a/distrib/sets/lists/modules/ad.arm b/distrib/sets/lists/modules/ad.arm index c7b9ed65a47..390cc52828b 100644 --- a/distrib/sets/lists/modules/ad.arm +++ b/distrib/sets/lists/modules/ad.arm @@ -1,4 +1,4 @@ -# $NetBSD: ad.arm,v 1.12 2019/02/03 08:02:58 pgoyette Exp $ +# $NetBSD: ad.arm,v 1.12.2.1 2019/12/09 15:19:30 martin Exp $ ./@MODULEDIR@/compat_netbsd32 base-kernel-modules kmod ./@MODULEDIR@/compat_netbsd32/compat_netbsd32.kmod base-kernel-modules kmod @@ -44,5 +44,7 @@ ./@MODULEDIR@/compat_netbsd32_sysvipc_14/compat_netbsd32_sysvipc_14.kmod base-kernel-modules kmod ./@MODULEDIR@/compat_netbsd32_sysvipc_50 base-kernel-modules kmod ./@MODULEDIR@/compat_netbsd32_sysvipc_50/compat_netbsd32_sysvipc_50.kmod base-kernel-modules kmod +./@MODULEDIR@/dtrace_syscall_linux base-kernel-modules kmod,dtrace +./@MODULEDIR@/dtrace_syscall_linux/dtrace_syscall_linux.kmod base-kernel-modules kmod,dtrace ./@MODULEDIR@/exec_elf32 base-kernel-modules kmod ./@MODULEDIR@/exec_elf32/exec_elf32.kmod base-kernel-modules kmod diff --git a/distrib/sets/lists/modules/md.amd64 b/distrib/sets/lists/modules/md.amd64 index c61a11d3104..e72dde51d86 100644 --- a/distrib/sets/lists/modules/md.amd64 +++ b/distrib/sets/lists/modules/md.amd64 @@ -1,4 +1,4 @@ -# $NetBSD: md.amd64,v 1.80 2019/02/03 08:02:58 pgoyette Exp $ +# $NetBSD: md.amd64,v 1.80.2.1 2019/12/09 15:19:30 martin Exp $ # # NOTE that there are two sets of files here: # @MODULEDIR@ and amd64-xen @@ -115,6 +115,8 @@ ./@MODULEDIR@/drmkms_agp/drmkms_agp.kmod base-kernel-modules kmod ./@MODULEDIR@/drmkms_pci base-kernel-modules kmod ./@MODULEDIR@/drmkms_pci/drmkms_pci.kmod base-kernel-modules kmod +./@MODULEDIR@/dtrace_syscall_linux base-kernel-modules kmod,dtrace +./@MODULEDIR@/dtrace_syscall_linux/dtrace_syscall_linux.kmod base-kernel-modules kmod,dtrace ./@MODULEDIR@/dtrace_syscall_linux32 base-kernel-modules kmod,dtrace ./@MODULEDIR@/dtrace_syscall_linux32/dtrace_syscall_linux32.kmod base-kernel-modules kmod,dtrace ./@MODULEDIR@/dtrace_syscall_netbsd32 base-kernel-modules kmod,dtrace diff --git a/distrib/sets/lists/modules/md.i386 b/distrib/sets/lists/modules/md.i386 index b1269451d5b..3f0fa9bbae6 100644 --- a/distrib/sets/lists/modules/md.i386 +++ b/distrib/sets/lists/modules/md.i386 @@ -1,4 +1,4 @@ -# $NetBSD: md.i386,v 1.82 2018/09/19 16:11:53 maxv Exp $ +# $NetBSD: md.i386,v 1.82.2.1 2019/12/09 15:19:30 martin Exp $ # # NOTE that there are two sets of files here: @MODULEDIR@ and i386pae-xen # @@ -79,6 +79,8 @@ ./@MODULEDIR@/drmkms_agp/drmkms_agp.kmod base-kernel-modules kmod ./@MODULEDIR@/drmkms_pci base-kernel-modules kmod ./@MODULEDIR@/drmkms_pci/drmkms_pci.kmod base-kernel-modules kmod +./@MODULEDIR@/dtrace_syscall_linux base-kernel-modules kmod,dtrace +./@MODULEDIR@/dtrace_syscall_linux/dtrace_syscall_linux.kmod base-kernel-modules kmod,dtrace ./@MODULEDIR@/emdtv base-kernel-modules kmod ./@MODULEDIR@/emdtv/emdtv.kmod base-kernel-modules kmod ./@MODULEDIR@/est base-kernel-modules kmod diff --git a/distrib/sets/lists/modules/mi b/distrib/sets/lists/modules/mi index 43ad3e6471f..c915fa3c487 100644 --- a/distrib/sets/lists/modules/mi +++ b/distrib/sets/lists/modules/mi @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.122.2.2 2019/10/28 16:37:55 martin Exp $ +# $NetBSD: mi,v 1.122.2.3 2019/12/09 15:19:30 martin Exp $ # # Note: don't delete entries from here - mark them as "obsolete" instead. # @@ -146,8 +146,6 @@ ./@MODULEDIR@/dtrace_sdt/dtrace_sdt.kmod base-kernel-modules kmod,dtrace ./@MODULEDIR@/dtrace_syscall base-kernel-modules kmod,dtrace ./@MODULEDIR@/dtrace_syscall/dtrace_syscall.kmod base-kernel-modules kmod,dtrace -./@MODULEDIR@/dtrace_syscall_linux base-kernel-modules kmod,dtrace -./@MODULEDIR@/dtrace_syscall_linux/dtrace_syscall_linux.kmod base-kernel-modules kmod,dtrace ./@MODULEDIR@/dtv base-kernel-modules kmod ./@MODULEDIR@/dtv/dtv.kmod base-kernel-modules kmod ./@MODULEDIR@/dtv_math base-kernel-modules kmod diff --git a/external/cddl/osnet/dev/dtrace/aarch64/dtrace_asm.S b/external/cddl/osnet/dev/dtrace/aarch64/dtrace_asm.S new file mode 100644 index 00000000000..a706576ad08 --- /dev/null +++ b/external/cddl/osnet/dev/dtrace/aarch64/dtrace_asm.S @@ -0,0 +1,171 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * $FreeBSD$ + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#define _ASM +#define _LOCORE + +#include <sys/cpuvar_defs.h> +#include <sys/dtrace.h> + +#include <machine/asm.h> + +/* +void dtrace_membar_producer(void) +*/ +ENTRY(dtrace_membar_producer) + RET +END(dtrace_membar_producer) + +/* +void dtrace_membar_consumer(void) +*/ +ENTRY(dtrace_membar_consumer) + RET +END(dtrace_membar_consumer) + +/* +dtrace_icookie_t dtrace_interrupt_disable(void) +*/ +ENTRY(dtrace_interrupt_disable) + mrs x0, daif + msr daifset, #2 + RET +END(dtrace_interrupt_disable) + +/* +void dtrace_interrupt_enable(dtrace_icookie_t cookie) +*/ +ENTRY(dtrace_interrupt_enable) + msr daif, x0 + RET +END(dtrace_interrupt_enable) +/* +uint8_t +dtrace_fuword8_nocheck(void *addr) +*/ +ENTRY(dtrace_fuword8_nocheck) + ldrb w0, [x0] + RET +END(dtrace_fuword8_nocheck) + +/* +uint16_t +dtrace_fuword16_nocheck(void *addr) +*/ +ENTRY(dtrace_fuword16_nocheck) + ldrh w0, [x0] + RET +END(dtrace_fuword16_nocheck) + +/* +uint32_t +dtrace_fuword32_nocheck(void *addr) +*/ +ENTRY(dtrace_fuword32_nocheck) + ldr w0, [x0] + RET +END(dtrace_fuword32_nocheck) + +/* +uint64_t +dtrace_fuword64_nocheck(void *addr) +*/ +ENTRY(dtrace_fuword64_nocheck) + ldr x0, [x0] + RET +END(dtrace_fuword64_nocheck) + +/* +void +dtrace_copy(uintptr_t uaddr, uintptr_t kaddr, size_t size) +*/ +ENTRY(dtrace_copy) + cbz x2, 2f /* If len == 0 then skip loop */ +1: + ldrb w4, [x0], #1 /* Load from uaddr */ + strb w4, [x1], #1 /* Store in kaddr */ + sub x2, x2, #1 /* len-- */ + cbnz x2, 1b +2: + RET +END(dtrace_copy) + +/* +void +dtrace_copystr(uintptr_t uaddr, uintptr_t kaddr, size_t size, + volatile uint16_t *flags) +XXX: Check for flags? +*/ +ENTRY(dtrace_copystr) + cbz x2, 2f /* If len == 0 then skip loop */ + +1: ldrb w4, [x0], #1 /* Load from uaddr */ + strb w4, [x1], #1 /* Store in kaddr */ + cbz w4, 2f /* If == 0 then break */ + sub x2, x2, #1 /* len-- */ + cbnz x2, 1b +2: + RET +END(dtrace_copystr) + +/* +uintptr_t +dtrace_caller(int aframes) +*/ +ENTRY(dtrace_caller) + mov x0, #-1 + RET +END(dtrace_caller) + +/* +uint32_t +dtrace_cas32(uint32_t *target, uint32_t cmp, uint32_t new) +*/ +ENTRY(dtrace_cas32) +1: ldxr w3, [x0] /* Load target */ + cmp w3, w1 /* Check if *target == cmp */ + bne 2f /* No, return */ + stxr w12, w2, [x0] /* Store new to target */ + cbnz w12, 1b /* Try again if store not succeed */ +2: mov w0, w3 /* Return the value loaded from target */ + RET +END(dtrace_cas32) + +/* +void * +dtrace_casptr(volatile void *target, volatile void *cmp, volatile void *new) +*/ +ENTRY(dtrace_casptr) +1: ldxr x3, [x0] /* Load target */ + cmp x3, x1 /* Check if *target == cmp */ + bne 2f /* No, return */ + stxr w12, x2, [x0] /* Store new to target */ + cbnz w12, 1b /* Try again if store not succeed */ +2: mov x0, x3 /* Return the value loaded from target */ + RET +END(dtrace_casptr) diff --git a/external/cddl/osnet/dev/dtrace/aarch64/dtrace_isa.c b/external/cddl/osnet/dev/dtrace/aarch64/dtrace_isa.c new file mode 100644 index 00000000000..b237c4f1a8a --- /dev/null +++ b/external/cddl/osnet/dev/dtrace/aarch64/dtrace_isa.c @@ -0,0 +1,430 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * $FreeBSD$ + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ +#include <sys/cdefs.h> + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> + +#include <machine/frame.h> +#include <machine/reg.h> + +#include <machine/db_machdep.h> +#include <machine/vmparam.h> +#include <ddb/db_sym.h> +#include <ddb/ddb.h> + +#include "regset.h" + +#define INKERNEL(va) ((VM_MIN_KERNEL_ADDRESS <= (va)) && ((va) < VM_MAX_KERNEL_ADDRESS)) +#define CURRENT_CPU cpu_index(curcpu()) + +struct unwind_state { + register_t fp; + register_t sp; + register_t pc; +}; + +struct arm64_frame { + struct arm64_frame *f_frame; + uintptr_t f_retaddr; +}; + +static int +unwind_frame(struct unwind_state *frame) +{ + uint64_t fp = frame->fp; + + if (!INKERNEL(fp)) + return (-1); + + frame->sp = fp + 0x10; + /* FP to previous frame (X29) */ + frame->fp = *(uint64_t *)(fp); + /* LR (X30) */ + frame->pc = *(uint64_t *)(fp + 8) - 4; + + return (0); +} + +/* + * Wee need some reasonable default to prevent backtrace code + * from wandering too far + */ +#define MAX_FUNCTION_SIZE 0x10000 +#define MAX_PROLOGUE_SIZE 0x100 +#define MAX_USTACK_DEPTH 2048 + +uint8_t dtrace_fuword8_nocheck(void *); +uint16_t dtrace_fuword16_nocheck(void *); +uint32_t dtrace_fuword32_nocheck(void *); +uint64_t dtrace_fuword64_nocheck(void *); + +void +dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes, + uint32_t *intrpc) +{ + struct unwind_state state; + int scp_offset; + register_t sp, fp; + int depth; + + depth = 0; + + if (intrpc != 0) { + pcstack[depth++] = (pc_t) intrpc; + } + + aframes++; + + __asm __volatile("mov %0, sp" : "=&r" (sp)); + + state.fp = (uint64_t)__builtin_frame_address(0); + state.sp = sp; + state.pc = (uint64_t)dtrace_getpcstack; + + while (depth < pcstack_limit) { + if (!INKERNEL(state.pc) || !INKERNEL(state.fp)) + break; + + fp = state.fp; + state.sp = fp + 0x10; + /* FP to previous frame (X29) */ + state.fp = *(register_t *)(fp); + /* LR (X30) */ + state.pc = *(register_t *)(fp + 8) - 4; + + /* + * NB: Unlike some other architectures, we don't need to + * explicitly insert cpu_dtrace_caller as it appears in the + * normal kernel stack trace rather than a special trap frame. + */ + if (aframes > 0) { + aframes--; + } else { + pcstack[depth++] = state.pc; + } + + } + + for (; depth < pcstack_limit; depth++) { + pcstack[depth] = 0; + } +} + +static int +dtrace_getustack_common(uint64_t *pcstack, int pcstack_limit, uintptr_t pc, + uintptr_t fp) +{ + volatile uint16_t *flags = + (volatile uint16_t *)&cpu_core[CURRENT_CPU].cpuc_dtrace_flags; + int ret = 0; + uintptr_t oldfp = fp; + + ASSERT(pcstack == NULL || pcstack_limit > 0); + + while (pc != 0) { + /* + * We limit the number of times we can go around this + * loop to account for a circular stack. + */ + if (ret++ >= MAX_USTACK_DEPTH) { + *flags |= CPU_DTRACE_BADSTACK; + cpu_core[CURRENT_CPU].cpuc_dtrace_illval = fp; + break; + } + + if (pcstack != NULL) { + *pcstack++ = (uint64_t)pc; + pcstack_limit--; + if (pcstack_limit <= 0) + break; + } + + if (fp == 0) + break; + + pc = dtrace_fuword64((void *)(fp + + offsetof(struct arm64_frame, f_retaddr))); + fp = dtrace_fuword64((void *)fp); + + if (fp == oldfp) { + *flags |= CPU_DTRACE_BADSTACK; + cpu_core[CURRENT_CPU].cpuc_dtrace_illval = fp; + break; + } + + /* + * ARM64TODO: + * This workaround might not be necessary. It needs to be + * revised and removed from all architectures if found + * unwanted. Leaving the original x86 comment for reference. + * + * This is totally bogus: if we faulted, we're going to clear + * the fault and break. This is to deal with the apparently + * broken Java stacks on x86. + */ + if (*flags & CPU_DTRACE_FAULT) { + *flags &= ~CPU_DTRACE_FAULT; + break; + } + + oldfp = fp; + } + + return (ret); +} + +void +dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit) +{ + proc_t *p = curproc; + struct trapframe *tf; + uintptr_t pc, sp, fp; + volatile uint16_t *flags = + (volatile uint16_t *)&cpu_core[CURRENT_CPU].cpuc_dtrace_flags; + int n; + + if (*flags & CPU_DTRACE_FAULT) + return; + + if (pcstack_limit <= 0) + return; + + /* + * If there's no user context we still need to zero the stack. + */ + if (p == NULL || (tf = curlwp->l_md.md_utf) == NULL) + goto zero; + + *pcstack++ = (uint64_t)p->p_pid; + pcstack_limit--; + + if (pcstack_limit <= 0) + return; + + pc = tf->tf_pc; + sp = tf->tf_sp; + fp = tf->tf_regs.r_reg[29]; + + if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) { + /* + * In an entry probe. The frame pointer has not yet been + * pushed (that happens in the function prologue). The + * best approach is to add the current pc as a missing top + * of stack and back the pc up to the caller, which is stored + * at the current stack pointer address since the call + * instruction puts it there right before the branch. + */ + + *pcstack++ = (uint64_t)pc; + pcstack_limit--; + if (pcstack_limit <= 0) + return; + + pc = tf->tf_lr; + } + + n = dtrace_getustack_common(pcstack, pcstack_limit, pc, fp); + ASSERT(n >= 0); + ASSERT(n <= pcstack_limit); + + pcstack += n; + pcstack_limit -= n; + +zero: + while (pcstack_limit-- > 0) + *pcstack++ = 0; +} + +int +dtrace_getustackdepth(void) +{ + + printf("IMPLEMENT ME: %s\n", __func__); + + return (0); +} + +void +dtrace_getufpstack(uint64_t *pcstack, uint64_t *fpstack, int pcstack_limit) +{ + + printf("IMPLEMENT ME: %s\n", __func__); +} + +/*ARGSUSED*/ +uint64_t +dtrace_getarg(int arg, int aframes) +{ + + printf("IMPLEMENT ME: %s\n", __func__); + + return (0); +} + +int +dtrace_getstackdepth(int aframes) +{ + struct unwind_state state; + int scp_offset; + register_t sp; + int depth; + int done; + + depth = 1; + done = 0; + + __asm __volatile("mov %0, sp" : "=&r" (sp)); + + state.fp = (uint64_t)__builtin_frame_address(0); + state.sp = sp; + state.pc = (uint64_t)dtrace_getstackdepth; + + do { + done = unwind_frame(&state); + if (!INKERNEL(state.pc) || !INKERNEL(state.fp)) + break; + depth++; + } while (!done); + + if (depth < aframes) + return (0); + else + return (depth - aframes); +} + +ulong_t +dtrace_getreg(struct trapframe *rp, uint_t reg) +{ + + printf("IMPLEMENT ME: %s\n", __func__); + + return (0); +} + +static int +dtrace_copycheck(uintptr_t uaddr, uintptr_t kaddr, size_t size) +{ + + if (uaddr + size > VM_MAXUSER_ADDRESS || uaddr + size < uaddr) { + DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); + cpu_core[CURRENT_CPU].cpuc_dtrace_illval = uaddr; + return (0); + } + + return (1); +} + +void +dtrace_copyin(uintptr_t uaddr, uintptr_t kaddr, size_t size, + volatile uint16_t *flags) +{ + + if (dtrace_copycheck(uaddr, kaddr, size)) + dtrace_copy(uaddr, kaddr, size); +} + +void +dtrace_copyout(uintptr_t kaddr, uintptr_t uaddr, size_t size, + volatile uint16_t *flags) +{ + + if (dtrace_copycheck(uaddr, kaddr, size)) + dtrace_copy(kaddr, uaddr, size); +} + +void +dtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size, + volatile uint16_t *flags) +{ + + if (dtrace_copycheck(uaddr, kaddr, size)) + dtrace_copystr(uaddr, kaddr, size, flags); +} + +void +dtrace_copyoutstr(uintptr_t kaddr, uintptr_t uaddr, size_t size, + volatile uint16_t *flags) +{ + + if (dtrace_copycheck(uaddr, kaddr, size)) + dtrace_copystr(kaddr, uaddr, size, flags); +} + +uint8_t +dtrace_fuword8(void *uaddr) +{ + + if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { + DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); + cpu_core[CURRENT_CPU].cpuc_dtrace_illval = (uintptr_t)uaddr; + return (0); + } + + return (dtrace_fuword8_nocheck(uaddr)); +} + +uint16_t +dtrace_fuword16(void *uaddr) +{ + + if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { + DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); + cpu_core[CURRENT_CPU].cpuc_dtrace_illval = (uintptr_t)uaddr; + return (0); + } + + return (dtrace_fuword16_nocheck(uaddr)); +} + +uint32_t +dtrace_fuword32(void *uaddr) +{ + + if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { + DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); + cpu_core[CURRENT_CPU].cpuc_dtrace_illval = (uintptr_t)uaddr; + return (0); + } + + return (dtrace_fuword32_nocheck(uaddr)); +} + +uint64_t +dtrace_fuword64(void *uaddr) +{ + + if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { + DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); + cpu_core[CURRENT_CPU].cpuc_dtrace_illval = (uintptr_t)uaddr; + return (0); + } + + return (dtrace_fuword64_nocheck(uaddr)); +} diff --git a/external/cddl/osnet/dev/dtrace/aarch64/dtrace_subr.c b/external/cddl/osnet/dev/dtrace/aarch64/dtrace_subr.c new file mode 100644 index 00000000000..c588c404e21 --- /dev/null +++ b/external/cddl/osnet/dev/dtrace/aarch64/dtrace_subr.c @@ -0,0 +1,332 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * $FreeBSD$ + * + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: dtrace_subr.c,v 1.1.2.2 2019/12/09 15:19:30 martin Exp $"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/types.h> +#include <sys/kernel.h> +#include <sys/malloc.h> +#include <sys/kmem.h> +#include <sys/xcall.h> +#include <sys/cpu.h> +#include <sys/cpuvar.h> +#include <sys/dtrace_impl.h> +#include <sys/dtrace_bsd.h> +#include <machine/cpu.h> +#include <machine/frame.h> +#include <machine/vmparam.h> +#include <uvm/uvm_pglist.h> +#include <uvm/uvm_prot.h> +#include <uvm/uvm_pmap.h> + +#define CURRENT_CPU cpu_index(curcpu()) +#define OFFSET_MASK ((1 << OFFSET_SIZE) - 1) + +extern dtrace_id_t dtrace_probeid_error; +extern int (*dtrace_invop_jump_addr)(struct trapframe *); +extern void dtrace_getnanotime(struct timespec *tsp); + +int dtrace_invop(uintptr_t, struct trapframe *, uintptr_t); +void dtrace_invop_init(void); +void dtrace_invop_uninit(void); + +void dtrace_gethrtime_init(void); + +typedef struct dtrace_invop_hdlr { + int (*dtih_func)(uintptr_t, struct trapframe *, uintptr_t); + struct dtrace_invop_hdlr *dtih_next; +} dtrace_invop_hdlr_t; + +dtrace_invop_hdlr_t *dtrace_invop_hdlr; + +int +dtrace_invop(uintptr_t addr, struct trapframe *frame, uintptr_t eax) +{ + dtrace_invop_hdlr_t *hdlr; + int rval; + + for (hdlr = dtrace_invop_hdlr; hdlr != NULL; hdlr = hdlr->dtih_next) + if ((rval = hdlr->dtih_func(addr, frame, eax)) != 0) + return (rval); + + return (0); +} + + +void +dtrace_invop_add(int (*func)(uintptr_t, struct trapframe *, uintptr_t)) +{ + dtrace_invop_hdlr_t *hdlr; + + hdlr = kmem_alloc(sizeof (dtrace_invop_hdlr_t), KM_SLEEP); + hdlr->dtih_func = func; + hdlr->dtih_next = dtrace_invop_hdlr; + dtrace_invop_hdlr = hdlr; +} + +void +dtrace_invop_remove(int (*func)(uintptr_t, struct trapframe *, uintptr_t)) +{ + dtrace_invop_hdlr_t *hdlr, *prev; + + hdlr = dtrace_invop_hdlr; + prev = NULL; + + for (;;) { + if (hdlr == NULL) + panic("attempt to remove non-existent invop handler"); + + if (hdlr->dtih_func == func) + break; + + prev = hdlr; + hdlr = hdlr->dtih_next; + } + + if (prev == NULL) { + ASSERT(dtrace_invop_hdlr == hdlr); + dtrace_invop_hdlr = hdlr->dtih_next; + } else { + ASSERT(dtrace_invop_hdlr != hdlr); + prev->dtih_next = hdlr->dtih_next; + } + + kmem_free(hdlr, 0); +} + +/*ARGSUSED*/ +void +dtrace_toxic_ranges(void (*func)(uintptr_t base, uintptr_t limit)) +{ + + (*func)(0, (uintptr_t)VM_MIN_KERNEL_ADDRESS); +} + +static void +xcall_func(void *arg0, void *arg1) +{ + dtrace_xcall_t func = arg0; + + (*func)(arg1); +} + +void +dtrace_xcall(processorid_t cpu, dtrace_xcall_t func, void *arg) +{ + uint64_t where; + + if (cpu == DTRACE_CPUALL) { + where = xc_broadcast(0, xcall_func, func, arg); + } else { + struct cpu_info *ci = cpu_lookup(cpu); + + KASSERT(ci != NULL); + where = xc_unicast(0, xcall_func, func, arg, ci); + } + xc_wait(where); +} + +static void +dtrace_sync_func(void) +{ + +} + +void +dtrace_sync(void) +{ + + dtrace_xcall(DTRACE_CPUALL, (dtrace_xcall_t)dtrace_sync_func, NULL); +} + +/* + * DTrace needs a high resolution time function which can + * be called from a probe context and guaranteed not to have + * instrumented with probes itself. + * + * Returns nanoseconds since boot. + */ +uint64_t +dtrace_gethrtime() +{ + struct timespec curtime; + + nanouptime(&curtime); + + return (curtime.tv_sec * 1000000000UL + curtime.tv_nsec); + +} + +void +dtrace_gethrtime_init(void) +{ +} + +uint64_t +dtrace_gethrestime(void) +{ + struct timespec current_time; + + dtrace_getnanotime(¤t_time); + + return (current_time.tv_sec * 1000000000UL + current_time.tv_nsec); +} + +/* Function to handle DTrace traps during probes. See arm64/arm64/trap.c */ +int +dtrace_trap(struct trapframe *frame, u_int type) +{ + /* + * A trap can occur while DTrace executes a probe. Before + * executing the probe, DTrace blocks re-scheduling and sets + * a flag in its per-cpu flags to indicate that it doesn't + * want to fault. On returning from the probe, the no-fault + * flag is cleared and finally re-scheduling is enabled. + * + * Check if DTrace has enabled 'no-fault' mode: + * + */ + + if ((cpu_core[CURRENT_CPU].cpuc_dtrace_flags & CPU_DTRACE_NOFAULT) != 0) { + /* + * There are only a couple of trap types that are expected. + * All the rest will be handled in the usual way. + */ + switch (type) { + case ESR_EC_DATA_ABT_EL1: + /* Flag a bad address. */ + cpu_core[CURRENT_CPU].cpuc_dtrace_flags |= CPU_DTRACE_BADADDR; + cpu_core[CURRENT_CPU].cpuc_dtrace_illval = 0; + + /* + * Offset the instruction pointer to the instruction + * following the one causing the fault. + */ + frame->tf_pc += 4; + return (1); + default: + /* Handle all other traps in the usual way. */ + break; + } + } + + /* Handle the trap in the usual way. */ + return (0); +} + +void +dtrace_probe_error(dtrace_state_t *state, dtrace_epid_t epid, int which, + int fault, int fltoffs, uintptr_t illval) +{ + + dtrace_probe(dtrace_probeid_error, (uint64_t)(uintptr_t)state, + (uintptr_t)epid, + (uintptr_t)which, (uintptr_t)fault, (uintptr_t)fltoffs); +} + +static int +dtrace_invop_start(struct trapframe *frame) +{ + int data, invop, reg, update_sp; + register_t arg1, arg2; + register_t *sp; + int offs; + int tmp; + int i; + + invop = dtrace_invop(frame->tf_pc, frame, frame->tf_pc); + + tmp = (invop & LDP_STP_MASK); + if (tmp == STP_64 || tmp == LDP_64) { + sp = (register_t *)frame->tf_sp; + data = invop; + arg1 = (data >> ARG1_SHIFT) & ARG1_MASK; + arg2 = (data >> ARG2_SHIFT) & ARG2_MASK; + + offs = (data >> OFFSET_SHIFT) & OFFSET_MASK; + + switch (tmp) { + case STP_64: + if (offs >> (OFFSET_SIZE - 1)) + sp -= (~offs & OFFSET_MASK) + 1; + else + sp += (offs); + *(sp + 0) = frame->tf_regs.r_reg[arg1]; + *(sp + 1) = frame->tf_regs.r_reg[arg2]; + break; + case LDP_64: + frame->tf_regs.r_reg[arg1] = *(sp + 0); + frame->tf_regs.r_reg[arg2] = *(sp + 1); + if (offs >> (OFFSET_SIZE - 1)) + sp -= (~offs & OFFSET_MASK) + 1; + else + sp += (offs); + break; + default: + break; + } + + /* Update the stack pointer and program counter to continue */ + frame->tf_sp = (register_t)sp; + frame->tf_pc += INSN_SIZE; + return (0); + } + + if ((invop & B_MASK) == B_INSTR) { + data = (invop & B_DATA_MASK); + /* The data is the number of 4-byte words to change the pc */ + data *= 4; + frame->tf_pc += data; + return (0); + } + + if (invop == RET_INSTR) { + frame->tf_pc = frame->tf_lr; + return (0); + } + + return (-1); +} + +void +dtrace_invop_init(void) +{ + + dtrace_invop_jump_addr = dtrace_invop_start; +} + +void +dtrace_invop_uninit(void) +{ + + dtrace_invop_jump_addr = 0; +} diff --git a/external/cddl/osnet/dev/dtrace/aarch64/regset.h b/external/cddl/osnet/dev/dtrace/aarch64/regset.h new file mode 100644 index 00000000000..f99b48f8354 --- /dev/null +++ b/external/cddl/osnet/dev/dtrace/aarch64/regset.h @@ -0,0 +1,51 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * $FreeBSD$ + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */ + +/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ + +#ifndef _REGSET_H +#define _REGSET_H + +/* + * #pragma ident "@(#)regset.h 1.11 05/06/08 SMI" + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Place here */ + +#ifdef __cplusplus +} +#endif + +#endif /* _REGSET_H */ diff --git a/external/cddl/osnet/dev/fbt/aarch64/fbt_isa.c b/external/cddl/osnet/dev/fbt/aarch64/fbt_isa.c new file mode 100644 index 00000000000..123290616ec --- /dev/null +++ b/external/cddl/osnet/dev/fbt/aarch64/fbt_isa.c @@ -0,0 +1,234 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Portions Copyright 2006-2008 John Birrell jb@freebsd.org + * Portions Copyright 2013 Justin Hibbits jhibbits@freebsd.org + * Portions Copyright 2013 Howard Su howardsu@freebsd.org + * Portions Copyright 2015 Ruslan Bukin <br@bsdpad.com> + * + * $FreeBSD$ + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <sys/cdefs.h> +#include <sys/param.h> +#include <sys/cpu.h> +#include <sys/module.h> +#include <sys/kmem.h> +#include <machine/cpufunc.h> + +#include <sys/dtrace.h> + +#include "fbt.h" + +#define AARCH64_BRK 0xd4200000 +#define AARCH64_BRK_IMM16_SHIFT 5 +#define AARCH64_BRK_IMM16_VAL (0x40d << AARCH64_BRK_IMM16_SHIFT) +#define FBT_PATCHVAL (AARCH64_BRK | AARCH64_BRK_IMM16_VAL) +#define FBT_ENTRY "entry" +#define FBT_RETURN "return" + +int +fbt_invop(uintptr_t addr, struct trapframe *frame, uintptr_t rval) +{ + solaris_cpu_t *cpu; + fbt_probe_t *fbt; + + cpu = &solaris_cpu[cpu_index(curcpu())]; + fbt = fbt_probetab[FBT_ADDR2NDX(addr)]; + + for (; fbt != NULL; fbt = fbt->fbtp_hashnext) { + if ((uintptr_t)fbt->fbtp_patchpoint == addr) { + cpu->cpu_dtrace_caller = addr; + + dtrace_probe(fbt->fbtp_id, frame->tf_regs.r_reg[0], + frame->tf_regs.r_reg[1], frame->tf_regs.r_reg[2], + frame->tf_regs.r_reg[3], frame->tf_regs.r_reg[4]); + + cpu->cpu_dtrace_caller = 0; + return (fbt->fbtp_savedval); + } + } + + return (0); +} + +void +fbt_patch_tracepoint(fbt_probe_t *fbt, fbt_patchval_t val) +{ + + *fbt->fbtp_patchpoint = val; + cpu_icache_sync_range((vm_offset_t)fbt->fbtp_patchpoint, 4); +} + +#if defined(__FreeBSD__) +int +fbt_provide_module_function(linker_file_t lf, int symindx, + linker_symval_t *symval, void *opaque) +#elif defined(__NetBSD__) +int +fbt_provide_module_cb(const char *name, int symindx, void *value, + uint32_t symsize, int type, void *opaque) +#else +#error unsupported platform +#endif +{ + fbt_probe_t *fbt, *retfbt; + uint32_t *target, *start; + uint32_t *instr, *limit; + int offs; + +#ifdef __FreeBSD__ + char *modname = opaque; + const char *name = symval->name; + + instr = (uint32_t *)(symval->value); + limit = (uint32_t *)(symval->value + symval->size); +#endif +#ifdef __NetBSD__ + struct fbt_ksyms_arg *fka = opaque; + modctl_t *mod = fka->fka_mod; + const char *modname = module_name(mod); + + /* got a function? */ + if (ELF_ST_TYPE(type) != STT_FUNC) + return 0; + + instr = (uint32_t *)(value); + limit = (uint32_t *)((uintptr_t)value + symsize); +#endif + + /* Check if function is excluded from instrumentation */ + if (fbt_excluded(name)) + return (0); + + if (strncmp(name, "_spl", 4) == 0 || + strcmp(name, "dosoftints") == 0 || + strcmp(name, "nanouptime") == 0 || + strncmp(name, "gtmr_", 5) == 0) { + return 0; + } + + /* Look for stp (pre-indexed) operation */ + for (; instr < limit; instr++) { + if ((*instr & LDP_STP_MASK) == STP_64) + break; + } + + if (instr >= limit) + return (0); + +#ifdef __FreeBSD__ + fbt = malloc(sizeof (fbt_probe_t), M_FBT, M_WAITOK | M_ZERO); +#else + fbt = kmem_zalloc(sizeof (fbt_probe_t), KM_SLEEP); +#endif + fbt->fbtp_name = name; + fbt->fbtp_id = dtrace_probe_create(fbt_id, modname, + name, FBT_ENTRY, 3, fbt); + fbt->fbtp_patchpoint = instr; +#ifdef __FreeBSD__ + fbt->fbtp_ctl = lf; + fbt->fbtp_loadcnt = lf->loadcnt; +#endif +#ifdef __NetBSD__ + fbt->fbtp_ctl = mod; +#endif + fbt->fbtp_savedval = *instr; + fbt->fbtp_patchval = FBT_PATCHVAL; + fbt->fbtp_rval = DTRACE_INVOP_PUSHM; + fbt->fbtp_symindx = symindx; + + fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)]; + fbt_probetab[FBT_ADDR2NDX(instr)] = fbt; + +#ifdef __FreeBSD__ + lf->fbt_nentries++; +#endif + + retfbt = NULL; +again: + for (; instr < limit; instr++) { + if (*instr == RET_INSTR) + break; + else if ((*instr & B_MASK) == B_INSTR) { + offs = (*instr & B_DATA_MASK); + offs *= 4; + target = (instr + offs); +#ifdef __FreeBSD__ + start = (uint32_t *)symval->value; +#else + start = (uint32_t *)value; +#endif + if (target >= limit || target < start) + break; + } + } + + if (instr >= limit) + return (0); + + /* + * We have a winner! + */ +#ifdef __FreeBSD__ + fbt = malloc(sizeof (fbt_probe_t), M_FBT, M_WAITOK | M_ZERO); +#else + fbt = kmem_zalloc(sizeof (fbt_probe_t), KM_SLEEP); +#endif + fbt->fbtp_name = name; + if (retfbt == NULL) { + fbt->fbtp_id = dtrace_probe_create(fbt_id, modname, + name, FBT_RETURN, 3, fbt); + } else { + retfbt->fbtp_next = fbt; + fbt->fbtp_id = retfbt->fbtp_id; + } + retfbt = fbt; + + fbt->fbtp_patchpoint = instr; +#ifdef __FreeBSD__ + fbt->fbtp_ctl = lf; + fbt->fbtp_loadcnt = lf->loadcnt; +#endif +#ifdef __NetBSD__ + fbt->fbtp_ctl = mod; +#endif + fbt->fbtp_symindx = symindx; + if ((*instr & B_MASK) == B_INSTR) + fbt->fbtp_rval = DTRACE_INVOP_B; + else + fbt->fbtp_rval = DTRACE_INVOP_RET; + fbt->fbtp_savedval = *instr; + fbt->fbtp_patchval = FBT_PATCHVAL; + fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)]; + fbt_probetab[FBT_ADDR2NDX(instr)] = fbt; + +#ifdef __FreeBSD__ + lf->fbt_nentries++; +#endif + + instr++; + goto again; +} diff --git a/external/cddl/osnet/dev/fbt/aarch64/fbt_isa.h b/external/cddl/osnet/dev/fbt/aarch64/fbt_isa.h new file mode 100644 index 00000000000..5552f31a64a --- /dev/null +++ b/external/cddl/osnet/dev/fbt/aarch64/fbt_isa.h @@ -0,0 +1,30 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * $FreeBSD$ + * + */ + +#ifndef _FBT_ISA_H_ +#define _FBT_ISA_H_ + +typedef uint32_t fbt_patchval_t; + +#endif diff --git a/external/cddl/osnet/dist/lib/libdtrace/aarch64/dt_isadep.c b/external/cddl/osnet/dist/lib/libdtrace/aarch64/dt_isadep.c index 9f5af857049..3449e7b9426 100644 --- a/external/cddl/osnet/dist/lib/libdtrace/aarch64/dt_isadep.c +++ b/external/cddl/osnet/dist/lib/libdtrace/aarch64/dt_isadep.c @@ -29,6 +29,8 @@ #pragma ident "%Z%%M% %I% %E% SMI" +#include <sys/ioctl.h> + #include <stdlib.h> #include <assert.h> #include <errno.h> diff --git a/external/cddl/osnet/dist/lib/libdtrace/common/dt_link.c b/external/cddl/osnet/dist/lib/libdtrace/common/dt_link.c index 9559caa0679..52e58bbad9a 100644 --- a/external/cddl/osnet/dist/lib/libdtrace/common/dt_link.c +++ b/external/cddl/osnet/dist/lib/libdtrace/common/dt_link.c @@ -550,7 +550,9 @@ dump_elf32(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd) elf_file.ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD; #endif elf_file.ehdr.e_type = ET_REL; -#if defined(__arm__) +#if defined(__aarch64__) + elf_file.ehdr.e_machine = EM_AARCH64; +#elif defined(__arm__) elf_file.ehdr.e_machine = EM_ARM; #elif defined(__mips__) elf_file.ehdr.e_machine = EM_MIPS; @@ -1262,7 +1264,9 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp) if (dtp->dt_oflags & DTRACE_O_LP64) { eclass = ELFCLASS64; -#if defined(__mips__) +#if defined(__aarch64__) + emachine1 = emachine2 = EM_AARCH64; +#elif defined(__mips__) emachine1 = emachine2 = EM_MIPS; #elif defined(__powerpc__) emachine1 = emachine2 = EM_PPC64; @@ -1274,7 +1278,7 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp) symsize = sizeof (Elf64_Sym); } else { eclass = ELFCLASS32; -#if defined(__arm__) +#if defined(__arm__) || defined(__aarch64__) emachine1 = emachine2 = EM_ARM; #elif defined(__mips__) emachine1 = emachine2 = EM_MIPS; diff --git a/external/cddl/osnet/lib/libdtrace/Makefile b/external/cddl/osnet/lib/libdtrace/Makefile index 912b18ba371..c82a5df9c87 100644 --- a/external/cddl/osnet/lib/libdtrace/Makefile +++ b/external/cddl/osnet/lib/libdtrace/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.21 2019/02/11 17:49:37 tnn Exp $ +# $NetBSD: Makefile,v 1.21.2.1 2019/12/09 15:19:32 martin Exp $ # $FreeBSD: head/cddl/lib/libdtrace/Makefile 314654 2017-03-04 11:30:04Z ngie $ @@ -101,6 +101,9 @@ COPTS.dis_tables.c += -Wno-parentheses COPTS.dis_tables.c += ${${ACTIVE_CC} == "gcc" :? -Wno-maybe-uninitialized :} .elif ${MACHINE_ARCH} == "sparc64" CPPFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/sparc +.elif ${MACHINE_ARCH} == "aarch64" +CPPFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/aarch64 +.PATH: ${.CURDIR}/../../dist/lib/libdtrace/aarch64 .elif ${MACHINE_CPU} == "arm" CPPFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/arm .PATH: ${.CURDIR}/../../dist/lib/libdtrace/arm diff --git a/share/mk/bsd.own.mk b/share/mk/bsd.own.mk index 94eae88196e..1cfa77c2469 100644 --- a/share/mk/bsd.own.mk +++ b/share/mk/bsd.own.mk @@ -1,4 +1,4 @@ -# $NetBSD: bsd.own.mk,v 1.1149.2.2 2019/12/08 15:54:34 martin Exp $ +# $NetBSD: bsd.own.mk,v 1.1149.2.3 2019/12/09 15:19:30 martin Exp $ # This needs to be before bsd.init.mk .if defined(BSD_MK_COMPAT_FILE) @@ -1009,6 +1009,7 @@ MKZFS?= yes # .if ${MACHINE_ARCH} == "i386" || \ ${MACHINE_ARCH} == "x86_64" || \ + ${MACHINE_ARCH} == "aarch64" || \ !empty(MACHINE_ARCH:Mearm*) MKDTRACE?= yes MKCTF?= yes diff --git a/sys/arch/aarch64/aarch64/start.S b/sys/arch/aarch64/aarch64/start.S index 1299bcf826d..fec275d9393 100644 --- a/sys/arch/aarch64/aarch64/start.S +++ b/sys/arch/aarch64/aarch64/start.S @@ -1,4 +1,4 @@ -/* $NetBSD: start.S,v 1.2 2018/10/18 09:01:51 skrll Exp $ */ +/* $NetBSD: start.S,v 1.2.6.1 2019/12/09 15:19:31 martin Exp $ */ /* * Copyright (c) 2017 Ryo Shimizu <ryo@nerv.org> @@ -32,7 +32,7 @@ #include <aarch64/asm.h> -RCSID("$NetBSD: start.S,v 1.2 2018/10/18 09:01:51 skrll Exp $") +RCSID("$NetBSD: start.S,v 1.2.6.1 2019/12/09 15:19:31 martin Exp $") /* load far effective address (pc relative) */ .macro ADDR, reg, addr @@ -41,6 +41,11 @@ RCSID("$NetBSD: start.S,v 1.2 2018/10/18 09:01:51 skrll Exp $") .endm /* + * Padding at start of kernel image to make room for 64-byte header (non-ELF booting) + */ +.space 64, 0x0 + +/* * Kernel start routine for aarch64 boards. */ .global start diff --git a/sys/arch/aarch64/aarch64/trap.c b/sys/arch/aarch64/aarch64/trap.c index 1bc0a13a700..cd49e5e4b07 100644 --- a/sys/arch/aarch64/aarch64/trap.c +++ b/sys/arch/aarch64/aarch64/trap.c @@ -1,4 +1,4 @@ -/* $NetBSD: trap.c,v 1.17.4.1 2019/08/07 10:19:54 martin Exp $ */ +/* $NetBSD: trap.c,v 1.17.4.2 2019/12/09 15:19:31 martin Exp $ */ /*- * Copyright (c) 2014 The NetBSD Foundation, Inc. @@ -31,10 +31,11 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.17.4.1 2019/08/07 10:19:54 martin Exp $"); +__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.17.4.2 2019/12/09 15:19:31 martin Exp $"); #include "opt_arm_intr_impl.h" #include "opt_compat_netbsd32.h" +#include "opt_dtrace.h" #include <sys/param.h> #include <sys/kauth.h> @@ -73,11 +74,20 @@ __KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.17.4.1 2019/08/07 10:19:54 martin Exp $") #include <ddb/db_output.h> #include <machine/db_machdep.h> #endif +#ifdef KDTRACE_HOOKS +#include <sys/dtrace_bsd.h> +#endif #ifdef DDB int sigill_debug = 0; #endif +#ifdef KDTRACE_HOOKS +dtrace_doubletrap_func_t dtrace_doubletrap_func = NULL; +dtrace_trap_func_t dtrace_trap_func = NULL; +int (*dtrace_invop_jump_addr)(struct trapframe *); +#endif + const char * const trap_names[] = { [ESR_EC_UNKNOWN] = "Unknown Reason (Illegal Instruction)", [ESR_EC_SERROR] = "SError Interrupt", @@ -186,16 +196,29 @@ trap_el1h_sync(struct trapframe *tf) else daif_enable(DAIF_D|DAIF_A); +#ifdef KDTRACE_HOOKS + if (dtrace_trap_func != NULL && (*dtrace_trap_func)(tf, eclass)) + return; +#endif + switch (eclass) { case ESR_EC_INSN_ABT_EL1: case ESR_EC_DATA_ABT_EL1: data_abort_handler(tf, eclass); break; + case ESR_EC_BKPT_INSN_A64: +#ifdef KDTRACE_HOOKS + if (__SHIFTOUT(esr, ESR_ISS) == 0x40d && + dtrace_invop_jump_addr != 0) { + (*dtrace_invop_jump_addr)(tf); + break; + } + /* FALLTHROUGH */ +#endif case ESR_EC_BRKPNT_EL1: case ESR_EC_SW_STEP_EL1: case ESR_EC_WTCHPNT_EL1: - case ESR_EC_BKPT_INSN_A64: #ifdef DDB if (eclass == ESR_EC_BRKPNT_EL1) kdb_trap(DB_TRAP_BREAKPOINT, tf); diff --git a/sys/arch/aarch64/conf/Makefile.aarch64 b/sys/arch/aarch64/conf/Makefile.aarch64 index 282f863c7ba..d19aab72a05 100644 --- a/sys/arch/aarch64/conf/Makefile.aarch64 +++ b/sys/arch/aarch64/conf/Makefile.aarch64 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile.aarch64,v 1.15 2019/03/03 07:04:40 maxv Exp $ +# $NetBSD: Makefile.aarch64,v 1.15.4.1 2019/12/09 15:19:31 martin Exp $ # Makefile for NetBSD # @@ -74,7 +74,7 @@ locore.o: ${ARM}/aarch64/locore.S assym.h ## (5) link settings ## KERNLDSCRIPT?= ${ARM}/conf/kern.ldscript -LOADADDRESS?= 0xffffffc000000040 +LOADADDRESS?= 0xffffffc000000000 LINKFLAGS_NORMAL= -X # Strip AArch64 mapping symbols from the kernel image, as they interfere diff --git a/sys/arch/aarch64/include/frame.h b/sys/arch/aarch64/include/frame.h index c01b82e148e..717479d36b1 100644 --- a/sys/arch/aarch64/include/frame.h +++ b/sys/arch/aarch64/include/frame.h @@ -1,4 +1,4 @@ -/* $NetBSD: frame.h,v 1.2 2018/04/01 04:35:03 ryo Exp $ */ +/* $NetBSD: frame.h,v 1.2.6.1 2019/12/09 15:19:31 martin Exp $ */ /*- * Copyright (c) 2014 The NetBSD Foundation, Inc. @@ -72,6 +72,8 @@ struct faultbuf { register_t fb_reg[FB_MAX]; }; +#define lwp_trapframe(l) ((l)->l_md.md_utf) + #elif defined(__arm__) #include <arm/frame.h> diff --git a/sys/arch/evbarm/conf/mk.generic64 b/sys/arch/evbarm/conf/mk.generic64 index a6af068cc09..80fcfe16fc1 100644 --- a/sys/arch/evbarm/conf/mk.generic64 +++ b/sys/arch/evbarm/conf/mk.generic64 @@ -1,4 +1,4 @@ -# $NetBSD: mk.generic64,v 1.3 2018/09/29 17:05:55 jmcneill Exp $ +# $NetBSD: mk.generic64,v 1.3.4.1 2019/12/09 15:19:31 martin Exp $ SYSTEM_FIRST_OBJ= start.o SYSTEM_FIRST_SFILE= ${ARM}/aarch64/start.S @@ -7,15 +7,15 @@ _OSRELEASE!= ${HOST_SH} $S/conf/osrelease.sh BOARDTYPE= evbarm64 -MKUBOOTIMAGEARGS= -f arm64 -a 0x200000 +MKUBOOTIMAGEARGS= -f arm64 -u -a 0x200000 MKKNLIMG= ${THISARM}/compile/rpi-mkknlimg.sh -SYSTEM_LD_TAIL_EXTRA+=; \ - echo ${OBJCOPY} -S -O binary $@ $@.bin; \ - ${OBJCOPY} -S -O binary $@ $@.bin; \ - echo ${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS} $@.bin $@.ub; \ - ${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS} $@.bin $@.ub; \ - echo ${MKKNLIMG} $@.ub $@.img; \ - ${HOST_SH} ${MKKNLIMG} $@.ub $@.img; +SYSTEM_LD_TAIL_EXTRA+= && \ + echo ${OBJCOPY} -S -O binary $@ $@.bin && \ + ${OBJCOPY} -S -O binary $@ $@.bin && \ + echo ${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS} $@.bin $@.ub && \ + ${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS} $@.bin $@.ub && \ + echo ${MKKNLIMG} $@.ub $@.img && \ + ${HOST_SH} ${MKKNLIMG} $@.ub $@.img EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.img@} diff --git a/sys/modules/cyclic/Makefile b/sys/modules/cyclic/Makefile index cc1222c8add..58f8e0deead 100644 --- a/sys/modules/cyclic/Makefile +++ b/sys/modules/cyclic/Makefile @@ -8,6 +8,8 @@ OSNETDIR=${NETBSDSRCDIR}/external/cddl/osnet .if exists(${OSNETDIR}/dev/cyclic/${MACHINE:S/amd64/i386/}) ARCH=${MACHINE:S/amd64/i386/} +.elif exists(${OSNETDIR}/dev/cyclic/${MACHINE_CPU:S/aarch64/arm/}) +ARCH=${MACHINE_CPU:S/aarch64/arm/} .elif exists(${OSNETDIR}/dev/cyclic/${MACHINE_CPU}) ARCH=${MACHINE_CPU} .else diff --git a/sys/modules/dtrace/Makefile b/sys/modules/dtrace/Makefile index b26c6317937..a92117334cb 100644 --- a/sys/modules/dtrace/Makefile +++ b/sys/modules/dtrace/Makefile @@ -1,10 +1,13 @@ -# $NetBSD: Makefile,v 1.6 2015/03/08 17:11:57 christos Exp $ +# $NetBSD: Makefile,v 1.6.22.1 2019/12/09 15:19:31 martin Exp $ # $FreeBSD: src/sys/modules/dtrace/Makefile,v 1.6.2.1 2009/08/03 08:13:06 kensmith Exp $ .include <bsd.own.mk> SUBDIR= dtrace sdt fbt lockstat profile syscall + +.if ${MACHINE_ARCH} != "aarch64" SUBDIR+= linux_syscall +.endif .if ${MACHINE_ARCH} == "x86_64" SUBDIR+= netbsd32_syscall diff --git a/usr.bin/mkubootimage/mkubootimage.1 b/usr.bin/mkubootimage/mkubootimage.1 index 0329095c432..6771e734514 100644 --- a/usr.bin/mkubootimage/mkubootimage.1 +++ b/usr.bin/mkubootimage/mkubootimage.1 @@ -1,4 +1,4 @@ -.\" $NetBSD: mkubootimage.1,v 1.12 2018/02/04 15:44:51 jmcneill Exp $ +.\" $NetBSD: mkubootimage.1,v 1.12.6.1 2019/12/09 15:19:30 martin Exp $ .\" .\" Copyright (c) 2012 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -27,7 +27,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd February 4, 2018 +.Dd December 4, 2019 .Dt MKUBOOTIMAGE 1 .Os .Sh NAME @@ -46,6 +46,7 @@ .Fl n Ar image .Op Fl O Po freebsd Ns | Ns linux Ns | Ns netbsd Ns | Ns openbsd Pc .Fl T No ( fs Ns | Ns kernel Ns | Ns kernel_noload Ns | Ns ramdisk Ns | Ns standalone ) +.Op Fl u .Ar source destination .\" .Sh DESCRIPTION @@ -124,6 +125,8 @@ Defines the image type. This is required for .Qq uimg format images. +.It Fl u +Update the header in an existing file instead of creating a new one. .El .Pp The required diff --git a/usr.bin/mkubootimage/mkubootimage.c b/usr.bin/mkubootimage/mkubootimage.c index 79a0dce79a2..f7419d2a6a3 100644 --- a/usr.bin/mkubootimage/mkubootimage.c +++ b/usr.bin/mkubootimage/mkubootimage.c @@ -1,4 +1,4 @@ -/* $NetBSD: mkubootimage.c,v 1.24 2018/02/04 17:33:34 jmcneill Exp $ */ +/* $NetBSD: mkubootimage.c,v 1.24.6.1 2019/12/09 15:19:30 martin Exp $ */ /*- * Copyright (c) 2010 Jared D. McNeill <jmcneill@invisible.ca> @@ -30,7 +30,7 @@ #endif #include <sys/cdefs.h> -__RCSID("$NetBSD: mkubootimage.c,v 1.24 2018/02/04 17:33:34 jmcneill Exp $"); +__RCSID("$NetBSD: mkubootimage.c,v 1.24.6.1 2019/12/09 15:19:30 martin Exp $"); #include <sys/mman.h> #include <sys/stat.h> @@ -74,6 +74,7 @@ static uint32_t image_entrypoint = 0; static char *image_name; static uint32_t image_magic = IH_MAGIC; static enum image_format image_format = FMT_UIMG; +static int update_image = 0; static const struct uboot_image_format { enum image_format format; @@ -269,7 +270,7 @@ usage(void) fprintf(stderr, " -O <openbsd|netbsd|freebsd|linux>"); fprintf(stderr, " -T <standalone|kernel|kernel_noload|ramdisk|fs|script>"); fprintf(stderr, " -a <addr> [-e <ep>] [-m <magic>] -n <name>"); - fprintf(stderr, " [-f <uimg|arm64>]"); + fprintf(stderr, " [-f <uimg|arm64>] [-u]"); fprintf(stderr, " <srcfile> <dstfile>\n"); exit(EXIT_FAILURE); @@ -431,6 +432,13 @@ write_image(void *hdr, size_t hdrlen, int kernel_fd, int image_fd) } } + if (update_image) { + if (lseek(kernel_fd, hdrlen, SEEK_SET) != (off_t)hdrlen) { + perror("seek failed"); + return errno; + } + } + while ((rlen = read(kernel_fd, buf, sizeof(buf))) > 0) { wlen = write(image_fd, buf, rlen); if (wlen != rlen) { @@ -453,7 +461,7 @@ main(int argc, char *argv[]) int ch; unsigned long long num; - while ((ch = getopt(argc, argv, "A:C:E:O:T:a:e:f:hm:n:")) != -1) { + while ((ch = getopt(argc, argv, "A:C:E:O:T:a:e:f:hm:n:u")) != -1) { switch (ch) { case 'A': /* arch */ image_arch = get_arch(optarg); @@ -504,6 +512,9 @@ main(int argc, char *argv[]) case 'n': /* name */ image_name = strdup(optarg); break; + case 'u': /* update image */ + update_image = 1; + break; case 'h': default: usage(); |
