Subject: port-sparc/3703: update for PR#3575
To: None <gnats-bugs@gnats.netbsd.org>
From: Erik E. Fair <fair@atomic.clock.org>
List: netbsd-bugs
Date: 06/03/1997 16:45:00
>Number: 3703
>Category: port-sparc
>Synopsis: probable fix to panic: pv_unlink0 on sun4m
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: gnats-admin (GNATS administrator)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Jun 3 16:50:01 1997
>Last-Modified:
>Originator: Erik E. Fair
>Organization:
International Organization of Internet Clock Watchers
>Release: NetBSD-current, June 3, 1997
>Environment:
System: NetBSD atomic.clock.org 1.2E NetBSD 1.2E (ATOMIC) #0: Sun Jun 1 16:40:12 PDT 1997 root@atomic.clock.org:/usr/src/sys/arch/sparc/compile/ATOMIC sparc
>Description:
see PR#3575
The enclosed diff does three things:
1. change pv_va in the pv_list structure from an "int" to
a "vm_offset_t", to be consistent with the other ports;
only one printf format needed to corrected.
2. add a check for pv == NULL to #ifdef DIAGNOSTIC in pv_unlink()
3. (this is the probable fix for panic: pv_unlink0) zero out both
pv_va and pv_flags in pv_unlink().
Testing known crash cases after this patch was applied failed to
crash the affected system. Analysis of mechanism is pending.
>How-To-Repeat:
see PR#3575
>Fix:
*** pmap.c.orig Sun May 25 04:21:49 1997
--- pmap.c.new Sun Jun 1 16:43:26 1997
***************
*** 180,189 ****
* THIS SHOULD BE PART OF THE CORE MAP
*/
struct pvlist {
! struct pvlist *pv_next; /* next pvlist, if any */
! struct pmap *pv_pmap; /* pmap of this va */
! int pv_va; /* virtual address */
! int pv_flags; /* flags (below) */
};
/*
--- 180,189 ----
* THIS SHOULD BE PART OF THE CORE MAP
*/
struct pvlist {
! struct pvlist *pv_next; /* next pvlist, if any */
! struct pmap *pv_pmap; /* pmap of this va */
! vm_offset_t pv_va; /* virtual address */
! int pv_flags; /* flags (below) */
};
/*
***************
*** 2086,2091 ****
--- 2086,2093 ----
register struct pvlist *npv;
#ifdef DIAGNOSTIC
+ if (pv == NULL)
+ panic("pv_unlink: pv == NULL");
if (pv->pv_pmap == NULL)
panic("pv_unlink0");
#endif
***************
*** 2100,2107 ****
pv->pv_pmap = npv->pv_pmap;
pv->pv_va = npv->pv_va;
FREE(npv, M_VMPVENT);
! } else
pv->pv_pmap = NULL;
} else {
register struct pvlist *prev;
--- 2102,2112 ----
pv->pv_pmap = npv->pv_pmap;
pv->pv_va = npv->pv_va;
FREE(npv, M_VMPVENT);
! } else {
pv->pv_pmap = NULL;
+ pv->pv_va = NULL;
+ pv->pv_flags = NULL;
+ }
} else {
register struct pvlist *prev;
***************
*** 2357,2362 ****
--- 2362,2369 ----
register struct pvlist *npv;
#ifdef DIAGNOSTIC
+ if (pv == NULL)
+ panic("pv_unlink: pv == NULL");
if (pv->pv_pmap == NULL)
panic("pv_unlink0");
#endif
***************
*** 2371,2378 ****
pv->pv_pmap = npv->pv_pmap;
pv->pv_va = npv->pv_va;
FREE(npv, M_VMPVENT);
! } else
pv->pv_pmap = NULL;
} else {
register struct pvlist *prev;
--- 2378,2388 ----
pv->pv_pmap = npv->pv_pmap;
pv->pv_va = npv->pv_va;
FREE(npv, M_VMPVENT);
! } else {
pv->pv_pmap = NULL;
+ pv->pv_va = NULL;
+ pv->pv_flags = NULL;
+ }
} else {
register struct pvlist *prev;
***************
*** 2436,2445 ****
for (npv = pv; npv != NULL; npv = npv->pv_next) {
if (BADALIAS(va, npv->pv_va)) {
#ifdef DEBUG
! if (pmapdebug & PDB_CACHESTUFF) printf(
! "pv_link: badalias: pid %d, %lx<=>%x, pa %lx\n",
! curproc?curproc->p_pid:-1, va, npv->pv_va,
! vm_first_phys + (pv-pv_table)*NBPG);
#endif
pv->pv_flags &= ~PV_C4M;
pv_changepte4m(pv, 0, ret = SRMMU_PG_C);
--- 2446,2457 ----
for (npv = pv; npv != NULL; npv = npv->pv_next) {
if (BADALIAS(va, npv->pv_va)) {
#ifdef DEBUG
! if (pmapdebug & PDB_CACHESTUFF)
! printf(
! "pv_link: badalias: pid %d, %lx <=> %lx, pa %lx\n",
! curproc ? curproc->p_pid : -1,
! va, npv->pv_va,
! vm_first_phys + (pv - pv_table) * NBPG);
#endif
pv->pv_flags &= ~PV_C4M;
pv_changepte4m(pv, 0, ret = SRMMU_PG_C);
>Audit-Trail:
>Unformatted: