Index: sys/arm64/arm64/elf32_machdep.c =================================================================== --- sys/arm64/arm64/elf32_machdep.c +++ sys/arm64/arm64/elf32_machdep.c @@ -51,6 +51,7 @@ #include #include +#include #include @@ -251,6 +252,8 @@ tf->tf_x[14] = imgp->entry_addr; tf->tf_elr = imgp->entry_addr; tf->tf_spsr = PSR_M_32; + + exec_reset_vfp_state(td, td->td_pcb); } void Index: sys/arm64/arm64/machdep.c =================================================================== --- sys/arm64/arm64/machdep.c +++ sys/arm64/arm64/machdep.c @@ -548,10 +548,28 @@ return (0); } +/* + * Reset the FP state to avoid leaking state from the parent process across + * execve() (and to ensure that we get a consitent floating point environment + * in every new process). + */ +void +exec_reset_vfp_state(struct thread *td, struct pcb *pcb) +{ + bzero(&pcb->pcb_fpustate.vfp_regs, sizeof(pcb->pcb_fpustate.vfp_regs)); + KASSERT(pcb->pcb_fpusaved == &pcb->pcb_fpustate, + ("pcb_fpusaved should point to pcb_fpustate.")); + pcb->pcb_fpustate.vfp_fpcr = initial_fpcr; + pcb->pcb_fpustate.vfp_fpsr = 0; + pcb->pcb_vfpcpu = UINT_MAX; + pcb->pcb_fpflags = 0; +} + void exec_setregs(struct thread *td, struct image_params *imgp, uintptr_t stack) { struct trapframe *tf = td->td_frame; + struct pcb *pcb = td->td_pcb; memset(tf, 0, sizeof(struct trapframe)); @@ -559,6 +577,11 @@ tf->tf_sp = STACKALIGN(stack); tf->tf_lr = imgp->entry_addr; tf->tf_elr = imgp->entry_addr; + + exec_reset_vfp_state(td, pcb); + + /* FIXME: Shouldn't we also reset pcb_dbg_regs? */ + /* XXX: should exec clear single-step in pcb_flags? */ } /* Sanity check these are the same size, they will be memcpy'd to and fro */ Index: sys/arm64/arm64/vm_machdep.c =================================================================== --- sys/arm64/arm64/vm_machdep.c +++ sys/arm64/arm64/vm_machdep.c @@ -108,7 +108,6 @@ td2->td_pcb->pcb_sp = (uintptr_t)td2->td_frame; td2->td_pcb->pcb_fpusaved = &td2->td_pcb->pcb_fpustate; td2->td_pcb->pcb_vfpcpu = UINT_MAX; - td2->td_pcb->pcb_fpusaved->vfp_fpcr = initial_fpcr; /* Setup to release spin count in fork_exit(). */ td2->td_md.md_spinlock_count = 1; Index: sys/arm64/include/machdep.h =================================================================== --- sys/arm64/include/machdep.h +++ sys/arm64/include/machdep.h @@ -59,6 +59,7 @@ #endif int memory_mapping_mode(vm_paddr_t pa); extern void (*pagezero)(void *); +void exec_reset_vfp_state(struct thread *, struct pcb *); #ifdef SOCDEV_PA /* Index: sys/arm64/linux/linux_sysvec.c =================================================================== --- sys/arm64/linux/linux_sysvec.c +++ sys/arm64/linux/linux_sysvec.c @@ -57,6 +57,8 @@ #include #include +#include + MODULE_VERSION(linux64elf, 1); const char *linux_kplatform; @@ -360,6 +362,8 @@ regs->tf_lr = 0xffffffffffffffff; #endif regs->tf_elr = imgp->entry_addr; + + exec_reset_vfp_state(td, td->td_pcb); } int