Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/x86 Change the format of the pp_attrs field: instea...



details:   https://anonhg.NetBSD.org/src/rev/12e3950276d5
branches:  trunk
changeset: 448385:12e3950276d5
user:      maxv <maxv%NetBSD.org@localhost>
date:      Fri Feb 01 05:44:29 2019 +0000

description:
Change the format of the pp_attrs field: instead of using PTE bits
directly, use abstracted bits that are converted from/to PTE bits when
needed (in pmap_sync_pv).

This allows us to use the same pp_attrs for pmaps that have PTE bits at
different locations.

diffstat:

 sys/arch/x86/include/pmap.h    |  15 +++++----
 sys/arch/x86/include/pmap_pv.h |   7 +++-
 sys/arch/x86/x86/pmap.c        |  67 +++++++++++++++++++++++++++++++----------
 3 files changed, 64 insertions(+), 25 deletions(-)

diffs (264 lines):

diff -r 235b69fb5435 -r 12e3950276d5 sys/arch/x86/include/pmap.h
--- a/sys/arch/x86/include/pmap.h       Fri Feb 01 05:32:08 2019 +0000
+++ b/sys/arch/x86/include/pmap.h       Fri Feb 01 05:44:29 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.h,v 1.93 2018/12/17 06:58:54 maxv Exp $   */
+/*     $NetBSD: pmap.h,v 1.94 2019/02/01 05:44:29 maxv Exp $   */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -111,6 +111,7 @@
 
 #if defined(_KERNEL)
 #include <sys/kcpuset.h>
+#include <x86/pmap_pv.h>
 #include <uvm/pmap/pmap_pvt.h>
 
 #define BTSEG_NONE     0
@@ -306,11 +307,11 @@
 #define        pmap_resident_count(pmap)       ((pmap)->pm_stats.resident_count)
 #define        pmap_wired_count(pmap)          ((pmap)->pm_stats.wired_count)
 
-#define pmap_clear_modify(pg)          pmap_clear_attrs(pg, PG_M)
-#define pmap_clear_reference(pg)       pmap_clear_attrs(pg, PG_U)
+#define pmap_clear_modify(pg)          pmap_clear_attrs(pg, PP_ATTRS_M)
+#define pmap_clear_reference(pg)       pmap_clear_attrs(pg, PP_ATTRS_U)
 #define pmap_copy(DP,SP,D,L,S)         __USE(L)
-#define pmap_is_modified(pg)           pmap_test_attrs(pg, PG_M)
-#define pmap_is_referenced(pg)         pmap_test_attrs(pg, PG_U)
+#define pmap_is_modified(pg)           pmap_test_attrs(pg, PP_ATTRS_M)
+#define pmap_is_referenced(pg)         pmap_test_attrs(pg, PP_ATTRS_U)
 #define pmap_move(DP,SP,D,L,S)
 #define pmap_phys_address(ppn)         (x86_ptob(ppn) & ~X86_MMAP_FLAG_MASK)
 #define pmap_mmap_flags(ppn)           x86_mmap_flags(ppn)
@@ -436,7 +437,7 @@
 {
        if ((prot & VM_PROT_WRITE) == 0) {
                if (prot & (VM_PROT_READ|VM_PROT_EXECUTE)) {
-                       (void) pmap_clear_attrs(pg, PG_RW);
+                       (void)pmap_clear_attrs(pg, PP_ATTRS_W);
                } else {
                        pmap_page_remove(pg);
                }
@@ -453,7 +454,7 @@
 {
        if ((prot & VM_PROT_WRITE) == 0) {
                if (prot & (VM_PROT_READ|VM_PROT_EXECUTE)) {
-                       (void) pmap_pv_clear_attrs(pa, PG_RW);
+                       (void)pmap_pv_clear_attrs(pa, PP_ATTRS_W);
                } else {
                        pmap_pv_remove(pa);
                }
diff -r 235b69fb5435 -r 12e3950276d5 sys/arch/x86/include/pmap_pv.h
--- a/sys/arch/x86/include/pmap_pv.h    Fri Feb 01 05:32:08 2019 +0000
+++ b/sys/arch/x86/include/pmap_pv.h    Fri Feb 01 05:44:29 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap_pv.h,v 1.3 2011/06/12 03:35:50 rmind Exp $        */
+/*     $NetBSD: pmap_pv.h,v 1.4 2019/02/01 05:44:29 maxv Exp $ */
 
 /*-
  * Copyright (c)2008 YAMAMOTO Takashi,
@@ -81,7 +81,10 @@
 #define        pp_head pp_u.u_head
 #define        pp_link pp_u.u_link
        uint8_t pp_flags;
-       uint8_t pp_attrs;       /* saved PG_M and PG_U */
+       uint8_t pp_attrs;
+#define PP_ATTRS_M     0x01    /* saved PG_M */
+#define PP_ATTRS_U     0x02    /* saved PG_U */
+#define PP_ATTRS_W     0x04    /* saved PG_RW */
 };
 
 /* pp_flags */
diff -r 235b69fb5435 -r 12e3950276d5 sys/arch/x86/x86/pmap.c
--- a/sys/arch/x86/x86/pmap.c   Fri Feb 01 05:32:08 2019 +0000
+++ b/sys/arch/x86/x86/pmap.c   Fri Feb 01 05:44:29 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.c,v 1.317 2019/01/31 20:42:31 maxv Exp $  */
+/*     $NetBSD: pmap.c,v 1.318 2019/02/01 05:44:29 maxv Exp $  */
 
 /*
  * Copyright (c) 2008, 2010, 2016, 2017 The NetBSD Foundation, Inc.
@@ -130,7 +130,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.317 2019/01/31 20:42:31 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.318 2019/02/01 05:44:29 maxv Exp $");
 
 #include "opt_user_ldt.h"
 #include "opt_lockdebug.h"
@@ -3388,6 +3388,32 @@
        }
 }
 
+static inline uint8_t
+pmap_pte_to_pp_attrs(pt_entry_t pte)
+{
+       uint8_t ret = 0;
+       if (pte & PG_M)
+               ret |= PP_ATTRS_M;
+       if (pte & PG_U)
+               ret |= PP_ATTRS_U;
+       if (pte & PG_RW)
+               ret |= PP_ATTRS_W;
+       return ret;
+}
+
+static inline pt_entry_t
+pmap_pp_attrs_to_pte(uint8_t attrs)
+{
+       pt_entry_t pte = 0;
+       if (attrs & PP_ATTRS_M)
+               pte |= PG_M;
+       if (attrs & PP_ATTRS_U)
+               pte |= PG_U;
+       if (attrs & PP_ATTRS_W)
+               pte |= PG_RW;
+       return pte;
+}
+
 /*
  * pmap_remove_pte: remove a single PTE from a PTP.
  *
@@ -3461,7 +3487,7 @@
        }
 
        /* Sync R/M bits. */
-       pp->pp_attrs |= opte;
+       pp->pp_attrs |= pmap_pte_to_pp_attrs(opte);
        pve = pmap_remove_pv(pp, ptp, va);
 
        if (pve) {
@@ -3573,13 +3599,15 @@
 }
 
 /*
- * pmap_sync_pv: clear pte bits and return the old value of the pte.
+ * pmap_sync_pv: clear pte bits and return the old value of the pp_attrs.
  *
+ * => The 'clearbits' parameter is either ~0 or PP_ATTRS_...
  * => Caller should disable kernel preemption.
  * => issues tlb shootdowns if necessary.
  */
 static int
-pmap_sync_pv(struct pv_pte *pvpte, paddr_t pa, int clearbits, pt_entry_t *optep)
+pmap_sync_pv(struct pv_pte *pvpte, paddr_t pa, int clearbits, uint8_t *oattrs,
+    pt_entry_t *optep)
 {
        struct pmap *pmap;
        struct vm_page *ptp;
@@ -3597,7 +3625,11 @@
        KASSERT(ptp == NULL || ptp_va2o(va, 1) == ptp->offset);
        pmap = ptp_to_pmap(ptp);
 
-       KASSERT(clearbits == ~0 || (clearbits & ~(PG_M | PG_U | PG_RW)) == 0);
+       if (clearbits != ~0) {
+               KASSERT((clearbits & ~(PP_ATTRS_M|PP_ATTRS_U|PP_ATTRS_W)) == 0);
+               clearbits = pmap_pp_attrs_to_pte(clearbits);
+       }
+
        KASSERT(kpreempt_disabled());
 
        ptep = pmap_map_pte(pmap, ptp, va);
@@ -3658,7 +3690,9 @@
        }
        pmap_unmap_pte();
 
-       *optep = opte;
+       *oattrs = pmap_pte_to_pp_attrs(opte);
+       if (optep != NULL)
+               *optep = opte;
        return 0;
 }
 
@@ -3685,6 +3719,7 @@
        struct pv_pte *pvpte;
        struct pv_entry *killlist = NULL;
        struct vm_page *ptp;
+       uint8_t oattrs;
        int count;
 
        count = SPINLOCK_BACKOFF_MIN;
@@ -3707,7 +3742,7 @@
                        pmap_reference(pmap);
                }
 
-               error = pmap_sync_pv(pvpte, pa, ~0, &opte);
+               error = pmap_sync_pv(pvpte, pa, ~0, &oattrs, &opte);
                if (error == EAGAIN) {
                        int hold_count;
                        KERNEL_UNLOCK_ALL(curlwp, &hold_count);
@@ -3719,7 +3754,7 @@
                        goto startover;
                }
 
-               pp->pp_attrs |= opte;
+               pp->pp_attrs |= oattrs;
                va = pvpte->pte_va;
                pve = pmap_remove_pv(pp, ptp, va);
 
@@ -3794,6 +3829,7 @@
 {
        struct pmap_page *pp;
        struct pv_pte *pvpte;
+       uint8_t oattrs;
        u_int result;
        paddr_t pa;
 
@@ -3806,15 +3842,14 @@
        pa = VM_PAGE_TO_PHYS(pg);
        kpreempt_disable();
        for (pvpte = pv_pte_first(pp); pvpte; pvpte = pv_pte_next(pp, pvpte)) {
-               pt_entry_t opte;
                int error;
 
                if ((pp->pp_attrs & testbits) != 0) {
                        break;
                }
-               error = pmap_sync_pv(pvpte, pa, 0, &opte);
+               error = pmap_sync_pv(pvpte, pa, 0, &oattrs, NULL);
                if (error == 0) {
-                       pp->pp_attrs |= opte;
+                       pp->pp_attrs |= oattrs;
                }
        }
        result = pp->pp_attrs & testbits;
@@ -3832,6 +3867,7 @@
 pmap_pp_clear_attrs(struct pmap_page *pp, paddr_t pa, unsigned clearbits)
 {
        struct pv_pte *pvpte;
+       uint8_t oattrs;
        u_int result;
        int count;
 
@@ -3839,10 +3875,9 @@
        kpreempt_disable();
 startover:
        for (pvpte = pv_pte_first(pp); pvpte; pvpte = pv_pte_next(pp, pvpte)) {
-               pt_entry_t opte;
                int error;
 
-               error = pmap_sync_pv(pvpte, pa, clearbits, &opte);
+               error = pmap_sync_pv(pvpte, pa, clearbits, &oattrs, NULL);
                if (error == EAGAIN) {
                        int hold_count;
                        KERNEL_UNLOCK_ALL(curlwp, &hold_count);
@@ -3850,7 +3885,7 @@
                        KERNEL_LOCK(hold_count, curlwp);
                        goto startover;
                }
-               pp->pp_attrs |= opte;
+               pp->pp_attrs |= oattrs;
        }
        result = pp->pp_attrs & clearbits;
        pp->pp_attrs &= ~clearbits;
@@ -4254,7 +4289,7 @@
                }
 
                old_pve = pmap_remove_pv(old_pp, ptp, va);
-               old_pp->pp_attrs |= opte;
+               old_pp->pp_attrs |= pmap_pte_to_pp_attrs(opte);
        }
 
        /*



Home | Main Index | Thread Index | Old Index