arm: Fix VFP state corruption during signal delivery
Some checks are pending
Cross-build Kernel / ${{ matrix.target_arch }} ${{ matrix.os }} (${{ matrix.compiler }}) (clang-14, /usr/lib/llvm-14/bin, ubuntu-22.04, bmake libarchive-dev clang-14 lld-14, amd64, amd64) (push) Waiting to run
Cross-build Kernel / ${{ matrix.target_arch }} ${{ matrix.os }} (${{ matrix.compiler }}) (clang-14, /usr/lib/llvm-14/bin, ubuntu-22.04, bmake libarchive-dev clang-14 lld-14, arm64, aarch64) (push) Waiting to run
Cross-build Kernel / ${{ matrix.target_arch }} ${{ matrix.os }} (${{ matrix.compiler }}) (clang-18, /opt/homebrew/opt/llvm@18/bin, macos-latest, bmake libarchive llvm@18, amd64, amd64) (push) Waiting to run
Cross-build Kernel / ${{ matrix.target_arch }} ${{ matrix.os }} (${{ matrix.compiler }}) (clang-18, /opt/homebrew/opt/llvm@18/bin, macos-latest, bmake libarchive llvm@18, arm64, aarch64) (push) Waiting to run
Cross-build Kernel / ${{ matrix.target_arch }} ${{ matrix.os }} (${{ matrix.compiler }}) (clang-18, /usr/lib/llvm-18/bin, ubuntu-24.04, bmake libarchive-dev clang-18 lld-18, amd64, amd64) (push) Waiting to run
Cross-build Kernel / ${{ matrix.target_arch }} ${{ matrix.os }} (${{ matrix.compiler }}) (clang-18, /usr/lib/llvm-18/bin, ubuntu-24.04, bmake libarchive-dev clang-18 lld-18, arm64, aarch64) (push) Waiting to run

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: 6926e2699a
Fixes: 4d2427f2c4
MFC after:	4 weeks
This commit is contained in:
Michal Meloun 2024-11-26 12:08:21 +01:00
parent c0a5ee953f
commit 3abef90c32

View File

@ -101,14 +101,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;
}
/*
@ -127,7 +132,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
@ -163,8 +171,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;
@ -189,19 +195,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);
}
@ -315,6 +311,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;