Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/sh3/sh3 PR port-sh3/56381



details:   https://anonhg.NetBSD.org/src/rev/8bc557e1796e
branches:  trunk
changeset: 1023297:8bc557e1796e
user:      rin <rin%NetBSD.org@localhost>
date:      Thu Sep 02 07:55:56 2021 +0000

description:
PR port-sh3/56381

pmap_enter() returns ENOMEM if __pmap_pte_alloc() fails and PMAP_CANFAIL
flag is specified. In this case, remove pv via __pmap_pv_remove() if it is
added to p-v map list via __pmap_pv_enter().

Otherwise, pmap becomes an inconsistent state, which results in an infinite
loop in pmap_page_protect(), as reported in the PR.

Also, KASSERT's are added for sure, in order to detect the infinite loops.

Great thanks to chs@ for finding out this bug!!

diffstat:

 sys/arch/sh3/sh3/pmap.c |  19 ++++++++++++++-----
 1 files changed, 14 insertions(+), 5 deletions(-)

diffs (49 lines):

diff -r 31883b32d8c5 -r 8bc557e1796e sys/arch/sh3/sh3/pmap.c
--- a/sys/arch/sh3/sh3/pmap.c   Thu Sep 02 07:04:41 2021 +0000
+++ b/sys/arch/sh3/sh3/pmap.c   Thu Sep 02 07:55:56 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.c,v 1.85 2021/07/26 21:43:11 andvar Exp $ */
+/*     $NetBSD: pmap.c,v 1.86 2021/09/02 07:55:56 rin Exp $    */
 
 /*-
  * Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.85 2021/07/26 21:43:11 andvar Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.86 2021/09/02 07:55:56 rin Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -385,9 +385,12 @@
        else {
                pte = __pmap_pte_alloc(pmap, va);
                if (pte == NULL) {
-                       if (flags & PMAP_CANFAIL)
+                       if (flags & PMAP_CANFAIL) {
+                               if (pg != NULL)
+                                       __pmap_pv_remove(pmap, pg, va);
                                return ENOMEM;
-                       panic("pmap_enter: cannot allocate pte");
+                       }
+                       panic("%s: __pmap_pte_alloc failed", __func__);
                }
        }
 
@@ -724,8 +727,14 @@
                /* Remove all */
                s = splvm();
                while ((pv = SLIST_FIRST(&pvh->pvh_head)) != NULL) {
+                       pmap = pv->pv_pmap;
                        va = pv->pv_va;
-                       pmap_remove(pv->pv_pmap, va, va + PAGE_SIZE);
+#ifdef DIAGNOSTIC
+                       pt_entry_t *pte = __pmap_pte_lookup(pmap, va);
+                       KASSERT(pte != NULL);
+                       KASSERT(*pte != 0);
+#endif
+                       pmap_remove(pmap, va, va + PAGE_SIZE);
                }
                splx(s);
        }



Home | Main Index | Thread Index | Old Index