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/27dce1065bc0
branches: trunk
changeset: 996431:27dce1065bc0
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 f0feea35b809 -r 27dce1065bc0 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 f0feea35b809 -r 27dce1065bc0 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 f0feea35b809 -r 27dce1065bc0 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