Subject: panic in pmap_enter() (Re: PR/31924 CVS commit: src/sys/uvm)
To: None <chs@NetBSD.org>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: port-sh3
Date: 11/08/2005 20:06:31
In article <051107200649.M0114790@mirage.ceres.dti.ne.jp>
I wrote:

> >  Modified Files:
> >  	src/sys/uvm: uvm_amap.c
> >  
> >  Log Message:
> >  in amap_cow_now(), handle the case where we have to sleep and some of the
> >  already-copied pages are paged out.  anons that have already been copied
> >  will have refcount == 1, whereas anons that still need to be copied will
> >  have refcount > 1.  fixes PR 25392, PR 30257, PR 31924.
> 
> Now the problem no longer occurs at least on my dreamcast. Thanks!

I've got another panic after this fix:

---
panic: tlb_handler: invalid user-space access from kernel mode va=0x00000000, ss
r=0x400000f0, spc=0x8c0f4c26  lwp=0x8c8a9220 onfault=0x0
Stopped in pid 1185.1 (amd) at	netbsd:cpu_Debugger+0x6:        mov     r14,r15

db> tr
cpu_Debugger() at netbsd:panic+0x98
panic() at netbsd:tlb_exception+0x3ec
tlb_exception() at 0x8c000484
<EXPEVT 040; SSR=400000f0> at netbsd:__pmap_pte_alloc+0x2e
__pmap_pte_alloc() at netbsd:pmap_enter+0x124
pmap_enter() at netbsd:uvm_fault+0x3ec
uvm_fault() at netbsd:tlb_exception+0x1d8
tlb_exception() at 0x8c000484
<EXPEVT 040; SSR=00000001> at 0x40914e
db>
---

Is this caused by just lacking an error check (patch attached),
or more serious problem?
---
Izumi Tsutsui

---
Index: arch/sh3/sh3/pmap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sh3/sh3/pmap.c,v
retrieving revision 1.50
diff -u -r1.50 pmap.c
--- arch/sh3/sh3/pmap.c	30 Dec 2003 12:33:19 -0000	1.50
+++ arch/sh3/sh3/pmap.c	8 Nov 2005 10:51:58 -0000
@@ -309,7 +309,7 @@
 {
 	struct vm_page *pg;
 	struct vm_page_md *pvh;
-	pt_entry_t entry;
+	pt_entry_t entry, *pte;
 	boolean_t kva = (pmap == pmap_kernel());
 
 	/* "flags" never exceed "prot" */
@@ -367,7 +367,14 @@
 	}
 
 	/* Register to page table */
-	*__pmap_pte_alloc(pmap, va) = entry;
+	pte = __pmap_pte_alloc(pmap, va);
+	if (pte == NULL) {
+		if (flags & PMAP_CANFAIL)
+			return ENOMEM;
+		panic("pmap_enter: cannot allocate pte");
+	}
+
+	*pte = entry;
 
 	if (pmap->pm_asid != -1)
 		sh_tlb_update(pmap->pm_asid, va, entry);
@@ -882,6 +889,8 @@
 
 	/* Allocate page table (not managed page) */
 	pg = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_USERESERVE | UVM_PGA_ZERO);
+	if (pg == NULL)
+		return NULL;
 
 	ptp = (pt_entry_t *)SH3_PHYS_TO_P1SEG(VM_PAGE_TO_PHYS(pg));
 	pmap->pm_ptp[__PMAP_PTP_INDEX(va)] = ptp;