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