Page MenuHomeFreeBSD

D42360.id129376.diff
No OneTemporary

D42360.id129376.diff

diff --git a/sys/arm64/linux/linux_sigframe.h b/sys/arm64/linux/linux_sigframe.h
--- a/sys/arm64/linux/linux_sigframe.h
+++ b/sys/arm64/linux/linux_sigframe.h
@@ -76,7 +76,6 @@
/* frame_record */
uint64_t fp;
uint64_t lr;
- ucontext_t uc;
};
#define LINUX_MINSIGSTKSZ roundup(sizeof(struct l_sigframe), 16)
diff --git a/sys/arm64/linux/linux_sysvec.c b/sys/arm64/linux/linux_sysvec.c
--- a/sys/arm64/linux/linux_sysvec.c
+++ b/sys/arm64/linux/linux_sysvec.c
@@ -190,25 +190,98 @@
int
linux_rt_sigreturn(struct thread *td, struct linux_rt_sigreturn_args *args)
{
+ struct l_rt_sigframe *sf;
struct l_sigframe *frame;
- ucontext_t uc;
+ struct _l_aarch64_ctx *ctx;
+ struct l_fpsimd_context *fpsimd;
struct trapframe *tf;
- int error;
+ sigset_t bmask;
+ int error, offset;
+
+ sf = malloc(sizeof(*sf), M_LINUX, M_WAITOK | M_ZERO);
tf = td->td_frame;
frame = (struct l_sigframe *)tf->tf_sp;
+ error = copyin((void *)&frame->sf, sf, sizeof(*sf));
+ if (error != 0) {
+ free(sf, M_LINUX);
+ return (error);
+ }
- if (copyin((void *)&frame->uc, &uc, sizeof(uc)))
- return (EFAULT);
+ memcpy(tf->tf_x, sf->sf_uc.uc_sc.regs, sizeof(tf->tf_x));
+ tf->tf_lr = sf->sf_uc.uc_sc.regs[30];
+ tf->tf_sp = sf->sf_uc.uc_sc.sp;
+ tf->tf_elr = sf->sf_uc.uc_sc.pc;
+
+ if ((sf->sf_uc.uc_sc.pstate & PSR_M_MASK) != PSR_M_EL0t ||
+ (sf->sf_uc.uc_sc.pstate & PSR_AARCH32) != 0 ||
+ (sf->sf_uc.uc_sc.pstate & PSR_DAIF) !=
+ (td->td_frame->tf_spsr & PSR_DAIF))
+ return (EINVAL);
+ tf->tf_spsr = sf->sf_uc.uc_sc.pstate;
+
+ offset = 0;
+ while (1) {
+ /* The offset must be 16 byte aligned */
+ if ((offset & 15) != 0)
+ goto einval;
+
+ /* Check for buffer overflow of the ctx */
+ if ((offset + sizeof(*ctx)) >
+ sizeof(sf->sf_uc.uc_sc.__reserved))
+ goto einval;
+
+ ctx =
+ (struct _l_aarch64_ctx *)&sf->sf_uc.uc_sc.__reserved[offset];
+
+ /* Check for buffer overflow of the data */
+ if ((offset + ctx->size) > sizeof(sf->sf_uc.uc_sc.__reserved))
+ goto einval;
+
+ switch(ctx->magic) {
+ case 0:
+ if (ctx->size != 0)
+ goto einval;
+ goto done;
+ case L_ESR_MAGIC:
+ /* Ignore */
+ break;
+#ifdef VFP
+ case L_FPSIMD_MAGIC:
+ fpsimd = (struct l_fpsimd_context *)ctx;
+
+ /*
+ * Discard any vfp state for the current thread, we
+ * are about to override it.
+ */
+ critical_enter();
+ vfp_discard(td);
+ critical_exit();
+
+ td->td_pcb->pcb_fpustate.vfp_fpcr = fpsimd->fpcr;
+ td->td_pcb->pcb_fpustate.vfp_fpsr = fpsimd->fpsr;
+ memcpy(td->td_pcb->pcb_fpustate.vfp_regs,
+ fpsimd->vregs, sizeof(fpsimd->vregs));
- error = set_mcontext(td, &uc.uc_mcontext);
- if (error != 0)
- return (error);
+ break;
+#endif
+ default:
+ goto einval;
+ }
+
+ offset += ctx->size;
+ }
+done:
/* Restore signal mask. */
- kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0);
+ linux_to_bsd_sigset(&sf->sf_uc.uc_sigmask, &bmask);
+ kern_sigprocmask(td, SIG_SETMASK, &bmask, NULL, 0);
+ free(sf, M_LINUX);
return (EJUSTRETURN);
+einval:
+ free(sf, M_LINUX);
+ return (EINVAL);
}
static void
@@ -310,7 +383,6 @@
}
memcpy(&frame->sf.sf_uc.uc_stack, &uc_stack, sizeof(uc_stack));
- memcpy(&frame->uc, &uc, sizeof(uc));
/* Copy the sigframe out to the user's stack. */
if (copyout(frame, fp, sizeof(*fp)) != 0) {
@@ -376,8 +448,8 @@
.sv_schedtail = linux_schedtail,
.sv_thread_detach = linux_thread_detach,
.sv_trap = NULL,
- .sv_hwcap = &elf_hwcap,
- .sv_hwcap2 = &elf_hwcap2,
+ .sv_hwcap = &linux_elf_hwcap,
+ .sv_hwcap2 = &linux_elf_hwcap2,
.sv_onexec = linux_on_exec_vmspace,
.sv_onexit = linux_on_exit,
.sv_ontdexit = linux_thread_dtor,

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 8, 2:24 AM (8 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25022453
Default Alt Text
D42360.id129376.diff (3 KB)

Event Timeline