Module Name:    src
Committed By:   martin
Date:           Tue Jun  1 10:39:48 UTC 2021

Modified Files:
        src/sys/arch/aarch64/aarch64 [netbsd-9]: netbsd32_machdep.c

Log Message:
Pull up following revision(s) (requested by rin in ticket #1277):

        sys/arch/aarch64/aarch64/netbsd32_machdep.c: revision 1.18

Fix conversion between aarch64 and aarch32 fpreg's; in aarch32 mode,
d0-d31 are packed into v0-v15 (== q0-q15).

This fixes crashes in VFP-optimized codes running on COMPAT_NETBSD32.

OK ryo


To generate a diff of this commit:
cvs rdiff -u -r1.7.2.2 -r1.7.2.3 \
    src/sys/arch/aarch64/aarch64/netbsd32_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/aarch64/aarch64/netbsd32_machdep.c
diff -u src/sys/arch/aarch64/aarch64/netbsd32_machdep.c:1.7.2.2 src/sys/arch/aarch64/aarch64/netbsd32_machdep.c:1.7.2.3
--- src/sys/arch/aarch64/aarch64/netbsd32_machdep.c:1.7.2.2	Fri Jan  1 12:58:35 2021
+++ src/sys/arch/aarch64/aarch64/netbsd32_machdep.c	Tue Jun  1 10:39:48 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: netbsd32_machdep.c,v 1.7.2.2 2021/01/01 12:58:35 martin Exp $	*/
+/*	$NetBSD: netbsd32_machdep.c,v 1.7.2.3 2021/06/01 10:39:48 martin Exp $	*/
 
 /*
  * Copyright (c) 2018 Ryo Shimizu <r...@nerv.org>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.7.2.2 2021/01/01 12:58:35 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.7.2.3 2021/06/01 10:39:48 martin Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_compat_netbsd.h"
@@ -156,7 +156,7 @@ netbsd32_process_read_fpregs(struct lwp 
 {
 	struct proc * const p = l->l_proc;
 	struct pcb * const pcb = lwp_getpcb(l);
-	int i;
+	int i, j;
 
 	if ((p->p_flag & PK_32) == 0)
 		return EINVAL;
@@ -178,11 +178,17 @@ netbsd32_process_read_fpregs(struct lwp 
 	fpregs->fpr_vfp.vfp_fpinst = 0;
 	fpregs->fpr_vfp.vfp_fpinst2 = 0;
 
-	for (i = 0; i < 32; i++) {
+	for (i = j = 0; i < 16; i++) {
 #ifdef __AARCH64EB__
-		fpregs->fpr_vfp.vfp_regs[i] = pcb->pcb_fpregs.fp_reg[i].u64[1];
+		fpregs->fpr_vfp.vfp_regs[j++] =
+		    pcb->pcb_fpregs.fp_reg[i].u64[1];
+		fpregs->fpr_vfp.vfp_regs[j++] =
+		    pcb->pcb_fpregs.fp_reg[i].u64[0];
 #else
-		fpregs->fpr_vfp.vfp_regs[i] = pcb->pcb_fpregs.fp_reg[i].u64[0];
+		fpregs->fpr_vfp.vfp_regs[j++] =
+		    pcb->pcb_fpregs.fp_reg[i].u64[0];
+		fpregs->fpr_vfp.vfp_regs[j++] =
+		    pcb->pcb_fpregs.fp_reg[i].u64[1];
 #endif
 	}
 
@@ -224,7 +230,7 @@ netbsd32_process_write_fpregs(struct lwp
 {
 	struct proc * const p = l->l_proc;
 	struct pcb * const pcb = lwp_getpcb(l);
-	int i;
+	int i, j;
 
 	if ((p->p_flag & PK_32) == 0)
 		return EINVAL;
@@ -235,17 +241,18 @@ netbsd32_process_write_fpregs(struct lwp
 	pcb->pcb_fpregs.fpsr = fpregs->fpr_vfp.vfp_fpscr & FPSR_BITS;
 	pcb->pcb_fpregs.fpcr = fpregs->fpr_vfp.vfp_fpscr & FPCR_BITS;
 
-	CTASSERT(__arraycount(fpregs->fpr_vfp.vfp_regs) ==
-	    __arraycount(pcb->pcb_fpregs.fp_reg) + 1);
-	for (i = 0; i < __arraycount(pcb->pcb_fpregs.fp_reg); i++) {
+	for (i = j = 0; i < 16; i++) {
 #ifdef __AARCH64EB__
-		pcb->pcb_fpregs.fp_reg[i].u64[0] = 0;
 		pcb->pcb_fpregs.fp_reg[i].u64[1] =
+		    fpregs->fpr_vfp.vfp_regs[j++];
+		pcb->pcb_fpregs.fp_reg[i].u64[0] =
+		    fpregs->fpr_vfp.vfp_regs[j++];
 #else
-		pcb->pcb_fpregs.fp_reg[i].u64[1] = 0;
 		pcb->pcb_fpregs.fp_reg[i].u64[0] =
+		    fpregs->fpr_vfp.vfp_regs[j++];
+		pcb->pcb_fpregs.fp_reg[i].u64[1] =
+		    fpregs->fpr_vfp.vfp_regs[j++];
 #endif
-		    fpregs->fpr_vfp.vfp_regs[i];
 	}
 
 	return 0;
@@ -456,18 +463,21 @@ cpu_getmcontext32(struct lwp *l, mcontex
 	/* fpu context */
 	if (fpu_used_p(l)) {
 		const struct pcb * const pcb = lwp_getpcb(l);
-		int i;
+		int i, j;
 
 		fpu_save(l);
 
-		CTASSERT(__arraycount(mcp->__vfpregs.__vfp_fstmx) ==
-		    __arraycount(pcb->pcb_fpregs.fp_reg));
-		for (i = 0; i < __arraycount(pcb->pcb_fpregs.fp_reg); i++) {
-			mcp->__vfpregs.__vfp_fstmx[i] =
+		for (i = j = 0; i < 16; i++) {
 #ifdef __AARCH64EB__
+			mcp->__vfpregs.__vfp_fstmx[j++] =
 			    pcb->pcb_fpregs.fp_reg[i].u64[1];
+			mcp->__vfpregs.__vfp_fstmx[j++] =
+			    pcb->pcb_fpregs.fp_reg[i].u64[0];
 #else
+			mcp->__vfpregs.__vfp_fstmx[j++] =
 			    pcb->pcb_fpregs.fp_reg[i].u64[0];
+			mcp->__vfpregs.__vfp_fstmx[j++] =
+			    pcb->pcb_fpregs.fp_reg[i].u64[1];
 #endif
 		}
 
@@ -489,7 +499,7 @@ cpu_setmcontext32(struct lwp *l, const m
 	struct trapframe * const tf = l->l_md.md_utf;
 	const __greg32_t * const gr = mcp->__gregs;
 	struct proc * const p = l->l_proc;
-	int error, i;
+	int error, i, j;
 
 	if (flags & _UC_CPU) {
 		error = cpu_mcontext32_validate(l, mcp);
@@ -519,17 +529,18 @@ cpu_setmcontext32(struct lwp *l, const m
 		struct pcb * const pcb = lwp_getpcb(l);
 		fpu_discard(l, true);
 
-		CTASSERT(__arraycount(mcp->__vfpregs.__vfp_fstmx) ==
-		    __arraycount(pcb->pcb_fpregs.fp_reg));
-		for (i = 0; i < __arraycount(pcb->pcb_fpregs.fp_reg); i++) {
+		for (i = j = 0; i < 16; i++) {
 #ifdef __AARCH64EB__
-			pcb->pcb_fpregs.fp_reg[i].u64[0] = 0;
 			pcb->pcb_fpregs.fp_reg[i].u64[1] =
+			    mcp->__vfpregs.__vfp_fstmx[j++];
+			pcb->pcb_fpregs.fp_reg[i].u64[0] =
+			    mcp->__vfpregs.__vfp_fstmx[j++];
 #else
-			pcb->pcb_fpregs.fp_reg[i].u64[1] = 0;
 			pcb->pcb_fpregs.fp_reg[i].u64[0] =
+			    mcp->__vfpregs.__vfp_fstmx[j++];
+			pcb->pcb_fpregs.fp_reg[i].u64[1] =
+			    mcp->__vfpregs.__vfp_fstmx[j++];
 #endif
-			    mcp->__vfpregs.__vfp_fstmx[i];
 		}
 		pcb->pcb_fpregs.fpsr =
 		    mcp->__vfpregs.__vfp_fpscr & FPSR_BITS;

Reply via email to