Page MenuHomeFreeBSD

D29060.id85185.diff
No OneTemporary

D29060.id85185.diff

Index: sys/arm64/arm64/elf32_machdep.c
===================================================================
--- sys/arm64/arm64/elf32_machdep.c
+++ sys/arm64/arm64/elf32_machdep.c
@@ -51,6 +51,7 @@
#include <sys/vnode.h>
#include <machine/elf.h>
+#include <machine/machdep.h>
#include <compat/freebsd32/freebsd32_util.h>
@@ -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
@@ -552,6 +552,7 @@
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 +560,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/vfp.c
===================================================================
--- sys/arm64/arm64/vfp.c
+++ sys/arm64/arm64/vfp.c
@@ -30,14 +30,17 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#ifdef VFP
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/limits.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/pcpu.h>
#include <sys/proc.h>
+#include <machine/machdep.h>
+
+#ifdef VFP
#include <machine/armreg.h>
#include <machine/md_var.h>
#include <machine/pcb.h>
@@ -382,3 +385,25 @@
return ((curpcb->pcb_fpflags & PCB_FP_KERN) != 0);
}
#endif
+
+/*
+ * Reset the FP state to avoid leaking state from the parent process across
+ * execve() (and to ensure that we get a consistent 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;
+#ifdef VFP
+ critical_enter();
+ vfp_discard(td);
+ critical_exit();
+#endif
+}
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 <compat/linux/linux_util.h>
#include <compat/linux/linux_vdso.h>
+#include <machine/machdep.h>
+
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

File Metadata

Mime Type
text/plain
Expires
Fri, Apr 24, 5:53 AM (57 m, 53 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32062610
Default Alt Text
D29060.id85185.diff (3 KB)

Event Timeline