diff --git a/sys/powerpc/powerpc/elf64_machdep.c b/sys/powerpc/powerpc/elf64_machdep.c index 2815fcfcd38..7715de17f84 100644 --- a/sys/powerpc/powerpc/elf64_machdep.c +++ b/sys/powerpc/powerpc/elf64_machdep.c @@ -119,7 +119,7 @@ struct sysentvec elf64_freebsd_sysvec_v2 = { .sv_setregs = exec_setregs, .sv_fixlimit = NULL, .sv_maxssiz = NULL, - .sv_flags = SV_ABI_FREEBSD | SV_LP64 | SV_SHP, + .sv_flags = SV_ABI_FREEBSD | SV_LP64 | SV_SHP | SV_ELFV2, .sv_set_syscall_retval = cpu_set_syscall_retval, .sv_fetch_syscall_args = cpu_fetch_syscall_args, .sv_syscallnames = syscallnames, diff --git a/sys/powerpc/powerpc/exec_machdep.c b/sys/powerpc/powerpc/exec_machdep.c index d2f44a5a373..b9e78524ce4 100644 --- a/sys/powerpc/powerpc/exec_machdep.c +++ b/sys/powerpc/powerpc/exec_machdep.c @@ -1016,11 +1016,16 @@ cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg, #endif } else { #ifdef __powerpc64__ - register_t entry_desc[3]; - (void)copyin((void *)entry, entry_desc, sizeof(entry_desc)); - tf->srr0 = entry_desc[0]; - tf->fixreg[2] = entry_desc[1]; - tf->fixreg[11] = entry_desc[2]; + if (SV_PROC_FLAG(td->td_proc, SV_ELFV2)) { + tf->srr0 = (register_t)entry; + } + else { + register_t entry_desc[3]; + (void)copyin((void *)entry, entry_desc, sizeof(entry_desc)); + tf->srr0 = entry_desc[0]; + tf->fixreg[2] = entry_desc[1]; + tf->fixreg[11] = entry_desc[2]; + } tf->srr1 = psl_userset | PSL_FE_DFLT; #endif } diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h index 3938a8ab0e9..4bdb8389920 100644 --- a/sys/sys/sysent.h +++ b/sys/sys/sysent.h @@ -145,6 +145,7 @@ struct sysentvec { #define SV_SHP 0x010000 /* Shared page. */ #define SV_CAPSICUM 0x020000 /* Force cap_enter() on startup. */ #define SV_TIMEKEEP 0x040000 /* Shared page timehands. */ +#define SV_ELFV2 0x080000 /* OpenPOWER ELF V2 compliant executable. */ #define SV_ABI_MASK 0xff #define SV_ABI_ERRNO(p, e) ((p)->p_sysent->sv_errsize <= 0 ? e : \