Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/powerpc Set normal memory PTEs with PTE_M (memory c...



details:   https://anonhg.NetBSD.org/src/rev/83e01766da15
branches:  trunk
changeset: 534428:83e01766da15
user:      matt <matt%NetBSD.org@localhost>
date:      Thu Jul 25 23:33:04 2002 +0000

description:
Set normal memory PTEs with PTE_M (memory coherent).  Change how we
remember the "exec"ness of a page.  If a managed page is pmap_enter'ed
with VM_PROT_EXECUTE, remember that it's an "exec"page.  Such that when
additional mapping are performed, no synch'ing of the I-cache is needed.
Revoke "exec"ness when the page is mapped into the kernel with VM_PROT_WRITE
or the pmap_page_protect is called with VM_PROT_NONE.

diffstat:

 sys/arch/powerpc/include/mpc6xx/pte.h |   5 ++-
 sys/arch/powerpc/mpc6xx/pmap.c        |  52 ++++++++++++++++++++++------------
 2 files changed, 36 insertions(+), 21 deletions(-)

diffs (131 lines):

diff -r be3a31e91373 -r 83e01766da15 sys/arch/powerpc/include/mpc6xx/pte.h
--- a/sys/arch/powerpc/include/mpc6xx/pte.h     Thu Jul 25 21:30:34 2002 +0000
+++ b/sys/arch/powerpc/include/mpc6xx/pte.h     Thu Jul 25 23:33:04 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pte.h,v 1.8 2002/04/03 00:12:07 matt Exp $     */
+/*     $NetBSD: pte.h,v 1.9 2002/07/25 23:33:04 matt Exp $     */
 
 /*-
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -55,11 +55,12 @@
 #define        PTE_RPGN_SHFT   12
 #define        PTE_REF         0x00000100
 #define        PTE_CHG         0x00000080
-#define        PTE_WIMG        0x00000078
 #define        PTE_W           0x00000040      /* 1 = write-through, 0 = write-back */
 #define        PTE_I           0x00000020      /* cache inhibit */
 #define        PTE_M           0x00000010      /* memory coherency enable */
 #define        PTE_G           0x00000008      /* guarded region (not on 601) */
+#define        PTE_WIMG        (PTE_W|PTE_I|PTE_M|PTE_G)
+#define        PTE_IG          (PTE_I|PTE_G)
 #define        PTE_PP          0x00000003
 #define        PTE_SO          0x00000000      /* Super. Only       (U: XX, S: RW) */
 #define        PTE_SW          0x00000001      /* Super. Write-Only (U: RO, S: RW) */
diff -r be3a31e91373 -r 83e01766da15 sys/arch/powerpc/mpc6xx/pmap.c
--- a/sys/arch/powerpc/mpc6xx/pmap.c    Thu Jul 25 21:30:34 2002 +0000
+++ b/sys/arch/powerpc/mpc6xx/pmap.c    Thu Jul 25 23:33:04 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.c,v 1.50 2002/07/18 22:51:58 matt Exp $   */
+/*     $NetBSD: pmap.c,v 1.51 2002/07/25 23:33:04 matt Exp $   */
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -1166,11 +1166,11 @@
                        failed = 1;
                }
                if (((pvo->pvo_pte.pte_lo ^ pt->pte_lo) &
-                   (PTE_PP|PTE_W|PTE_I|PTE_G|PTE_RPGN)) != 0) {
+                   (PTE_PP|PTE_WIMG|PTE_RPGN)) != 0) {
                        printf("pmap_pvo_check: pvo %p: pte_lo differ: %#x/%#x\n",
                            pvo,
-                           pvo->pvo_pte.pte_lo & (PTE_PP|PTE_W|PTE_I|PTE_G|PTE_RPGN),
-                           pt->pte_lo & (PTE_PP|PTE_W|PTE_I|PTE_G|PTE_RPGN));
+                           pvo->pvo_pte.pte_lo & (PTE_PP|PTE_WIMG|PTE_RPGN),
+                           pt->pte_lo & (PTE_PP|PTE_WIMG|PTE_RPGN));
                        failed = 1;
                }
                if (pmap_pte_to_va(pt) != PVO_VADDR(pvo)) {
@@ -1408,26 +1408,21 @@
         * If this is a managed page, and it's the first reference to the
         * page clear the execness of the page.  Otherwise fetch the execness.
         */
-       if (pg != NULL) {
-               if (LIST_EMPTY(pvo_head)) {
-                       pmap_attr_clear(pg, PTE_EXEC);
-                       DPRINTFN(ENTER, (" first"));
-               } else {
-                       was_exec = pmap_attr_fetch(pg) & PTE_EXEC;
-               }
-       }
+       if (pg != NULL)
+               was_exec = pmap_attr_fetch(pg) & PTE_EXEC;
 
        DPRINTFN(ENTER, (" was_exec=%d", was_exec));
 
        /*
         * Assume the page is cache inhibited and access is guarded unless
-        * it's in our available memory array.
+        * it's in our available memory array.  If it is in the memory array,
+        * asssume it's in memory coherent memory.
         */
-       pte_lo = PTE_I | PTE_G;
+       pte_lo = PTE_IG;
        if ((flags & PMAP_NC) == 0) {
                for (mp = mem; mp->size; mp++) {
                        if (pa >= mp->start && pa < mp->start + mp->size) {
-                               pte_lo &= ~(PTE_I | PTE_G);
+                               pte_lo = PTE_M;
                                break;
                        }
                }
@@ -1498,10 +1493,15 @@
        DPRINTFN(KENTER,
            ("pmap_kenter_pa(%#lx,%#lx,%#x)\n", va, pa, prot));
 
-       pte_lo = PTE_I | PTE_G;
+       /*
+        * Assume the page is cache inhibited and access is guarded unless
+        * it's in our available memory array.  If it is in the memory array,
+        * asssume it's in memory coherent memory.
+        */
+       pte_lo = PTE_IG;
        for (mp = mem; mp->size; mp++) {
                if (pa >= mp->start && pa < mp->start + mp->size) {
-                       pte_lo &= ~(PTE_I | PTE_G);
+                       pte_lo = PTE_M;
                        break;
                }
        }
@@ -1523,9 +1523,15 @@
 
        /* 
         * Flush the real memory from the instruction cache.
+        * If it's writeable, clear the PTE_EXEC attribute.
         */
-       if ((prot & VM_PROT_EXECUTE) && (pte_lo & (PTE_I|PTE_G)) == 0) {
-               pmap_syncicache(pa, NBPG);
+       if (prot & VM_PROT_EXECUTE) {
+               if ((pte_lo & (PTE_IG)) == 0)
+                       pmap_syncicache(pa, NBPG);
+       } else if (prot & VM_PROT_WRITE) {
+               struct vm_page *pg = PHYS_TO_VM_PAGE(pa);
+               if (pg != NULL)
+                       pmap_attr_clear(pg, PTE_EXEC);
        }
 }
 
@@ -1715,6 +1721,14 @@
        s = splvm();
        msr = pmap_interrupts_off();
 
+       /*
+        * When UVM reuses a page, it does a pmap_page_protect with
+        * VM_PROT_NONE.  At that point, we can clear the exec flag
+        * since we know the page will have different contents.
+        */
+       if ((prot & VM_PROT_READ) == 0)
+               pmap_attr_clear(pg, PTE_EXEC);
+
        pvo_head = vm_page_to_pvoh(pg);
        for (pvo = LIST_FIRST(pvo_head); pvo != NULL; pvo = next_pvo) {
                next_pvo = LIST_NEXT(pvo, pvo_vlink);



Home | Main Index | Thread Index | Old Index