Module Name:    src
Committed By:   thorpej
Date:           Sat Oct 30 19:44:56 UTC 2021

Modified Files:
        src/sys/arch/powerpc/oea: altivec.c
        src/sys/arch/powerpc/powerpc: compat_16_machdep.c

Log Message:
- In vec_restore_from_mcontext() and vec_save_to_mcontext(), allows the
  mcontext argument to be NULL.
- In sendsig_sigcontext(), don't set PSL_VEC in the saved MSR; we can't
  actually round-trip the AltiVec registers.  At least get them saved
  into the PCB by calling vec_save_to_mcontext() (with a NULL mcontext
  argument).
- In compat_16_sys___sigreturn14(), call vec_restore_from_mcontext()
  with a NULL mcontext argument, which will force any subsequent use
  of AltiVec to re-load the AltiVec registers from the PCB.

This isn't ideal, but it's the best we can do with the limited capability
of sigcontext.

Fixes PR port-powerpc/56471.


To generate a diff of this commit:
cvs rdiff -u -r1.33 -r1.34 src/sys/arch/powerpc/oea/altivec.c
cvs rdiff -u -r1.21 -r1.22 src/sys/arch/powerpc/powerpc/compat_16_machdep.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/powerpc/oea/altivec.c
diff -u src/sys/arch/powerpc/oea/altivec.c:1.33 src/sys/arch/powerpc/oea/altivec.c:1.34
--- src/sys/arch/powerpc/oea/altivec.c:1.33	Mon Jul  6 10:52:12 2020
+++ src/sys/arch/powerpc/oea/altivec.c	Sat Oct 30 19:44:56 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: altivec.c,v 1.33 2020/07/06 10:52:12 rin Exp $	*/
+/*	$NetBSD: altivec.c,v 1.34 2021/10/30 19:44:56 thorpej Exp $	*/
 
 /*
  * Copyright (C) 1996 Wolfgang Solfrank.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: altivec.c,v 1.33 2020/07/06 10:52:12 rin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: altivec.c,v 1.34 2021/10/30 19:44:56 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/proc.h>
@@ -166,10 +166,13 @@ vec_restore_from_mcontext(struct lwp *l,
 	/* we don't need to save the state, just drop it */
 	pcu_discard(&vec_ops, l, true);
 
-	memcpy(pcb->pcb_vr.vreg, &mcp->__vrf.__vrs, sizeof (pcb->pcb_vr.vreg));
-	pcb->pcb_vr.vscr = mcp->__vrf.__vscr;
-	pcb->pcb_vr.vrsave = mcp->__vrf.__vrsave;
-	l->l_md.md_utf->tf_vrsave = pcb->pcb_vr.vrsave;
+	if (mcp != NULL) {	/* XXX see compat_16_sys___sigreturn14() */
+		memcpy(pcb->pcb_vr.vreg, &mcp->__vrf.__vrs,
+		    sizeof (pcb->pcb_vr.vreg));
+		pcb->pcb_vr.vscr = mcp->__vrf.__vscr;
+		pcb->pcb_vr.vrsave = mcp->__vrf.__vrsave;
+		l->l_md.md_utf->tf_vrsave = pcb->pcb_vr.vrsave;
+	}
 }
 
 bool
@@ -188,11 +191,14 @@ vec_save_to_mcontext(struct lwp *l, mcon
 	 */
 	pcu_save(&vec_ops, l);
 
-	mcp->__gregs[_REG_MSR] |= PSL_VEC;
-	mcp->__vrf.__vscr = pcb->pcb_vr.vscr;
-	mcp->__vrf.__vrsave = l->l_md.md_utf->tf_vrsave;
-	memcpy(mcp->__vrf.__vrs, pcb->pcb_vr.vreg, sizeof (mcp->__vrf.__vrs));
-	*flagp |= _UC_POWERPC_VEC;
+	if (mcp != NULL) {	/* XXX see sendsig_sigcontext() */
+		mcp->__gregs[_REG_MSR] |= PSL_VEC;
+		mcp->__vrf.__vscr = pcb->pcb_vr.vscr;
+		mcp->__vrf.__vrsave = l->l_md.md_utf->tf_vrsave;
+		memcpy(mcp->__vrf.__vrs, pcb->pcb_vr.vreg,
+		    sizeof (mcp->__vrf.__vrs));
+		*flagp |= _UC_POWERPC_VEC;
+	}
 	return true;
 }
 

Index: src/sys/arch/powerpc/powerpc/compat_16_machdep.c
diff -u src/sys/arch/powerpc/powerpc/compat_16_machdep.c:1.21 src/sys/arch/powerpc/powerpc/compat_16_machdep.c:1.22
--- src/sys/arch/powerpc/powerpc/compat_16_machdep.c:1.21	Wed Oct 27 04:15:00 2021
+++ src/sys/arch/powerpc/powerpc/compat_16_machdep.c	Sat Oct 30 19:44:56 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: compat_16_machdep.c,v 1.21 2021/10/27 04:15:00 thorpej Exp $	*/
+/*	$NetBSD: compat_16_machdep.c,v 1.22 2021/10/30 19:44:56 thorpej Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: compat_16_machdep.c,v 1.21 2021/10/27 04:15:00 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: compat_16_machdep.c,v 1.22 2021/10/30 19:44:56 thorpej Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_altivec.h"
@@ -104,7 +104,12 @@ sendsig_sigcontext(const ksiginfo_t *ksi
 	utf->srr1 |= pcb->pcb_flags & (PCB_FE0|PCB_FE1);
 #endif
 #if defined(ALTIVEC) || defined(PPC_HAVE_SPE)
-	utf->srr1 |= vec_used_p(l) ? PSL_VEC : 0;
+	/*
+	 * We can't round-trip the vector unit registers with a
+	 * sigcontext, so at least get them saved into the PCB.
+	 * XXX vec_save_to_mcontext() has a special hack for this.
+	 */
+	vec_save_to_mcontext(l, NULL, NULL);
 #endif
 #ifdef PPC_OEA
 	utf->vrsave = tf->tf_vrsave;
@@ -221,6 +226,15 @@ compat_16_sys___sigreturn14(struct lwp *
 	pcb->pcb_flags &= ~(PCB_FE0|PCB_FE1);
 	pcb->pcb_flags |= utf->srr1 & (PCB_FE0|PCB_FE1);
 #endif
+#if defined(ALTIVEC) || defined(PPC_HAVE_SPE)
+	/*
+	 * We can't round-trip the vector unit registers with a
+	 * sigcontext, so at least force them to get reloaded from
+	 * the PCB (we saved them into the PCB in sendsig_sigcontext()).
+	 * XXX vec_restore_from_mcontext() has a special hack for this.
+	 */
+	vec_restore_from_mcontext(l, NULL);
+#endif
 #ifdef PPC_OEA
 	tf->tf_vrsave = utf->vrsave;
 	tf->tf_mq = utf->mq;

Reply via email to