NetBSD Problem Report #3703
Received: (qmail 9145 invoked from network); 3 Jun 1997 23:45:39 -0000
Message-Id: <199706032345.QAA19549@atomic.clock.org>
Date: Tue, 3 Jun 1997 16:45:00 -0700 (PDT)
From: "Erik E. Fair" <fair@atomic.clock.org>
Reply-To: fair@atomic.clock.org
To: gnats-bugs@gnats.netbsd.org
Subject: update for PR#3575
X-Send-Pr-Version: 3.95
>Number: 3703
>Category: port-sparc
>Synopsis: probable fix to panic: pv_unlink0 on sun4m
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: gnats-admin
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Jun 03 16:50:01 +0000 1997
>Closed-Date: Thu Jun 12 21:02:18 +0000 1997
>Last-Modified: Thu Jun 12 21:05:50 +0000 1997
>Originator: Erik E. Fair
>Release: NetBSD-current, June 3, 1997
>Organization:
International Organization of Internet Clock Watchers
>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);
>Release-Note:
>Audit-Trail:
From: "Erik E. Fair" <fair@atomic.clock.org>
To: gnats-bugs@gnats.netbsd.org
Cc: Subject: Re: port-sparc/3703 and port-sparc/3575
Date: Tue, 10 Jun 1997 16:54:44 -0700 (PDT)
>Submitter-Id: net
>Originator: Erik E. Fair
>Organization:
International Organization of Internet Clock Watchers
>Confidential: no
>Synopsis: fix for panic: pv_unlink0 on sun4m
>Severity: serious
>Priority: high
>Category: port-sparc
>Class: sw-bug
>Release: NetBSD-current, June 10, 1997
>Environment:
System: NetBSD atomic.clock.org 1.2F NetBSD 1.2F (GENERIC) #3: Tue Jun 10 11:07:03 PDT 1997 root@atomic.clock.org:/usr/src/sys/arch/sparc/compile/GENERIC sparc
>Description:
Under less-than-well-understood conditions, NetBSD/sparc
will panic: pv_unlink0 on sun4m architectures. The enclosed
fix apparently squashes this bug. See PR#3703 for a
description of the diff - this is a corrected version for
a problem introduced in that previous diff.
>How-To-Repeat:
Most commonly, certain SunOS binaries (with SunOS 4.1.4 libraries)
will tickle the bug in the getdents(2) call. Stripping out
unused parts of the NetBSD kernels (e.g. unused graphics drivers)
accelerated the problem (usually didn't get past the end of
/etc/rc.local on our system).
>Fix:
*** pmap.c.orig Sun May 25 04:21:49 1997
--- pmap.c Tue Jun 10 11:05:18 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;
+ return;
+ }
} else {
register struct pvlist *prev;
***************
*** 2165,2174 ****
for (npv = pv; npv != NULL; npv = npv->pv_next) {
if (BADALIAS(va, npv->pv_va)) {
#ifdef DEBUG
! if (pmapdebug) 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_NC;
pv_changepte4_4c(pv, ret = PG_NC, 0);
--- 2170,2180 ----
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_NC;
pv_changepte4_4c(pv, ret = PG_NC, 0);
***************
*** 2357,2362 ****
--- 2363,2370 ----
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;
--- 2379,2389 ----
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;
+ return;
+ }
} 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);
--- 2447,2458 ----
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);
State-Changed-From-To: open->closed
State-Changed-By: pk
State-Changed-When: Thu Jun 12 14:02:18 PDT 1997
State-Changed-Why:
pv_va changed to `vm_offset_t';
Otherwise this patch does not fix the problem (see PR#3575 for
the proper bug identification). Clearing `pv_va' doesn't hurt,
but I think not doing this might prove beneficial for
future bug-tracking..
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.