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:

NetBSD Home
NetBSD PR Database Search

(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.