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: