mirror of
https://github.com/opnsense/src.git
synced 2026-06-09 00:32:25 -04:00
arm: Fix VFP state corruption during signal delivery
D37419 corrupts VFP context store on signal delivery and D38696 corrupts PCB because it performs a binary copy between structures with different layouts. Revert the problematic parts of these commits to have signals delivery working. Unfortunately, there are more problems with these revisions and more fixes need to be developed. Fixes:6926e2699aFixes:4d2427f2c4MFC after: 4 weeks (cherry picked from commit3abef90c32)
This commit is contained in:
parent
83ad268f7e
commit
d94ff663b6
1 changed files with 24 additions and 18 deletions
|
|
@ -102,14 +102,19 @@ get_vfpcontext(struct thread *td, mcontext_vfp_t *vfp)
|
|||
P_SHOULDSTOP(td->td_proc));
|
||||
|
||||
pcb = td->td_pcb;
|
||||
if ((pcb->pcb_fpflags & PCB_FP_STARTED) != 0 && td == curthread) {
|
||||
if (td == curthread) {
|
||||
critical_enter();
|
||||
vfp_store(&pcb->pcb_vfpstate, false);
|
||||
critical_exit();
|
||||
}
|
||||
KASSERT(pcb->pcb_vfpsaved == &pcb->pcb_vfpstate,
|
||||
("Called get_vfpcontext while the kernel is using the VFP"));
|
||||
memcpy(vfp, &pcb->pcb_vfpstate, sizeof(*vfp));
|
||||
|
||||
memset(vfp, 0, sizeof(*vfp));
|
||||
memcpy(vfp->mcv_reg, pcb->pcb_vfpstate.reg,
|
||||
sizeof(vfp->mcv_reg));
|
||||
vfp->mcv_fpscr = pcb->pcb_vfpstate.fpscr;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -128,7 +133,10 @@ set_vfpcontext(struct thread *td, mcontext_vfp_t *vfp)
|
|||
}
|
||||
KASSERT(pcb->pcb_vfpsaved == &pcb->pcb_vfpstate,
|
||||
("Called set_vfpcontext while the kernel is using the VFP"));
|
||||
memcpy(&pcb->pcb_vfpstate, vfp, sizeof(*vfp));
|
||||
memcpy(pcb->pcb_vfpstate.reg, vfp->mcv_reg,
|
||||
sizeof(pcb->pcb_vfpstate.reg));
|
||||
pcb->pcb_vfpstate.fpscr = vfp->mcv_fpscr;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -164,8 +172,6 @@ get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret)
|
|||
{
|
||||
struct trapframe *tf = td->td_frame;
|
||||
__greg_t *gr = mcp->__gregs;
|
||||
mcontext_vfp_t mcontext_vfp;
|
||||
int rv;
|
||||
|
||||
if (clear_ret & GET_MC_CLEAR_RET) {
|
||||
gr[_REG_R0] = 0;
|
||||
|
|
@ -190,19 +196,9 @@ get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret)
|
|||
gr[_REG_LR] = tf->tf_usr_lr;
|
||||
gr[_REG_PC] = tf->tf_pc;
|
||||
|
||||
#ifdef VFP
|
||||
if (mcp->mc_vfp_size != sizeof(mcontext_vfp_t))
|
||||
return (EINVAL);
|
||||
get_vfpcontext(td, &mcontext_vfp);
|
||||
#else
|
||||
bzero(&mcontext_vfp, sizeof(mcontext_vfp));
|
||||
#endif
|
||||
|
||||
if (mcp->mc_vfp_ptr != NULL) {
|
||||
rv = copyout(&mcontext_vfp, mcp->mc_vfp_ptr, sizeof(mcontext_vfp));
|
||||
if (rv != 0)
|
||||
return (rv);
|
||||
}
|
||||
mcp->mc_vfp_size = 0;
|
||||
mcp->mc_vfp_ptr = NULL;
|
||||
memset(&mcp->mc_spare, 0, sizeof(mcp->mc_spare));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -316,6 +312,16 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
|
|||
/* Populate the siginfo frame. */
|
||||
bzero(&frame, sizeof(frame));
|
||||
get_mcontext(td, &frame.sf_uc.uc_mcontext, 0);
|
||||
|
||||
#ifdef VFP
|
||||
get_vfpcontext(td, &frame.sf_vfp);
|
||||
frame.sf_uc.uc_mcontext.mc_vfp_size = sizeof(fp->sf_vfp);
|
||||
frame.sf_uc.uc_mcontext.mc_vfp_ptr = &fp->sf_vfp;
|
||||
#else
|
||||
frame.sf_uc.uc_mcontext.mc_vfp_size = 0;
|
||||
frame.sf_uc.uc_mcontext.mc_vfp_ptr = NULL;
|
||||
#endif
|
||||
|
||||
frame.sf_si = ksi->ksi_info;
|
||||
frame.sf_uc.uc_sigmask = *mask;
|
||||
frame.sf_uc.uc_stack = td->td_sigstk;
|
||||
|
|
|
|||
Loading…
Reference in a new issue