NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: port-arm/52603: arm(v7?) vfp register corruption



The following reply was made to PR port-arm/52603; it has been noted by GNATS.

From: Manuel Bouyer <bouyer%antioche.eu.org@localhost>
To: port-arm-maintainer%NetBSD.org@localhost, gnats-bugs%NetBSD.org@localhost,
        netbsd-bugs%NetBSD.org@localhost
Cc: 
Subject: Re: port-arm/52603: arm(v7?) vfp register corruption
Date: Sun, 15 Oct 2017 20:58:24 +0200

 More KASSERT(), this time in mi_switch():
 
 Index: kern/kern_synch.c
 ===================================================================
 RCS file: /cvsroot/src/sys/kern/kern_synch.c,v
 retrieving revision 1.311
 diff -u -p -u -r1.311 kern_synch.c
 --- kern/kern_synch.c	3 Jul 2016 14:24:58 -0000	1.311
 +++ kern/kern_synch.c	15 Oct 2017 18:54:34 -0000
 @@ -97,6 +97,9 @@ __KERNEL_RCSID(0, "$NetBSD: kern_synch.c
  #include <sys/atomic.h>
  #include <sys/syslog.h>
  
 +#include <arm/pcb.h>
 +#include <arm/vfpreg.h>
 +
  #include <uvm/uvm_extern.h>
  
  #include <dev/lockstat.h>
 @@ -503,6 +506,7 @@ nextlwp(struct cpu_info *ci, struct sche
   *
   * Returns 1 if another LWP was actually run.
   */
 +__asm(".fpu\tvfpv4");
  int
  mi_switch(lwp_t *l)
  {
 @@ -724,13 +728,44 @@ mi_switch(lwp_t *l)
  		KASSERTMSG(l == curlwp, "l %p curlwp %p prevlwp %p",
  		    l, curlwp, prevlwp);
  
 +		KASSERTMSG(l->l_switchto == NULL, "l %p curlwp %p prevlwp %p l->l_switchto %p", l, curlwp, prevlwp, l->l_switchto);
 +		if ((l->l_flag & LW_SYSTEM) == 0) {
 +			KASSERTMSG(((struct pcb *)lwp_getpcb(l))->pcb_vfp.vfp_fpexc == armreg_fpexc_read(),
 +			    "fpexc 0x%x prev 0x%x reg 0x%x l %p/%p", 
 +			    ((struct pcb *)lwp_getpcb(l))->pcb_vfp.vfp_fpexc,
 +			    ((struct pcb *)lwp_getpcb(prevlwp))->pcb_vfp.vfp_fpexc,
 +			    armreg_fpexc_read(),
 +			    l, prevlwp);
 +		} else {
 +			KASSERT((l->l_pcu_valid & (1 << PCU_FPU)) == 0);
 +		}
 +
  		/*
  		 * Switched away - we have new curlwp.
  		 * Restore VM context and IPL.
  		 */
  		pmap_activate(l);
  		uvm_emap_switch(l);
 +		if ((l->l_flag & LW_SYSTEM) == 0) {
 +			KASSERTMSG(((struct pcb *)lwp_getpcb(l))->pcb_vfp.vfp_fpexc == armreg_fpexc_read(),
 +			    "XXX fpexc 0x%x prev 0x%x reg 0x%x l %p/%p", 
 +			    ((struct pcb *)lwp_getpcb(l))->pcb_vfp.vfp_fpexc,
 +			    ((struct pcb *)lwp_getpcb(prevlwp))->pcb_vfp.vfp_fpexc,
 +			    armreg_fpexc_read(),
 +			    l, prevlwp);
 +		} else {
 +			KASSERT((l->l_pcu_valid & (1 << PCU_FPU)) == 0);
 +		}
  		pcu_switchpoint(l);
 +		if ((l->l_flag & LW_SYSTEM) == 0) {
 +			KASSERTMSG(((struct pcb *)lwp_getpcb(l))->pcb_vfp.vfp_fpexc == armreg_fpexc_read(),
 +			    "fpexc 0x%x/0x%x l %p/%p", 
 +			    ((struct pcb *)lwp_getpcb(l))->pcb_vfp.vfp_fpexc,
 +			    armreg_fpexc_read(),
 +			    l, prevlwp);
 +		} else {
 +			KASSERT((l->l_pcu_valid & (1 << PCU_FPU)) == 0);
 +		}
  
  		if (prevlwp != NULL) {
  			/* Normalize the count of the spin-mutexes */
 
 
 note that the KASSERTMSG() before and after pmap_activate() are the same.
 The KASSERTMSG() after pmap_activate() fired twice, this means that
 actually cpu_switchto() works as expected, and the FPU is reenabled
 after, probably by an interrupt.
 
 Another KASSERT proved me that IPIs are allowed in this portion of code,
 but I can't see where we could fail to disable the fpu before exiting the
 handler ...
 
 -- 
 Manuel Bouyer <bouyer%antioche.eu.org@localhost>
      NetBSD: 26 ans d'experience feront toujours la difference
 --
 


Home | Main Index | Thread Index | Old Index