Index: sys/arch/arm/arm32/pmap.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/arm32/pmap.c,v retrieving revision 1.327 diff -u -p -r1.327 pmap.c --- sys/arch/arm/arm32/pmap.c 6 Nov 2015 08:44:35 -0000 1.327 +++ sys/arch/arm/arm32/pmap.c 6 Nov 2015 16:19:01 -0000 @@ -213,6 +213,7 @@ #include #include +#include #include @@ -757,6 +758,7 @@ static void pmap_flush_page(struct vm_p #endif #endif static void pmap_page_remove(struct vm_page_md *, paddr_t); +static void pmap_pv_remove(paddr_t); #ifndef ARM_MMU_EXTENDED static void pmap_init_l1(struct l1_ttable *, pd_entry_t *); @@ -3118,15 +3120,20 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_ * If the physical address is different, lookup the * vm_page. */ - if (l2pte_pa(opte) != pa) + if (l2pte_pa(opte) != pa) { + KASSERT(!pmap_pv_tracked(pa)); opg = PHYS_TO_VM_PAGE(l2pte_pa(opte)); - else + } else opg = pg; } else opg = NULL; - if (pg) { - struct vm_page_md *md = VM_PAGE_TO_MD(pg); + struct pmap_page *pp = pmap_pv_tracked(pa); + + if (pg || pp) { + KASSERT((pg != NULL) != (pp != NULL)); + struct vm_page_md *md = (pg != NULL) ? VM_PAGE_TO_MD(pg) : + PMAP_PAGE_TO_MD(pp); /* * This is to be a managed mapping. @@ -3180,7 +3187,7 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_ } else npte |= pte_l2_s_cache_mode; - if (pg == opg) { + if (pg != NULL && pg == opg) { /* * We're changing the attrs of an existing mapping. */ @@ -3949,6 +3956,34 @@ pmap_extract(pmap_t pm, vaddr_t va, padd return true; } +/* + * pmap_pv_remove: remove an unmanaged pv-tracked page from all pmaps + * that map it + */ + +static void +pmap_pv_remove(paddr_t pa) +{ + struct pmap_page *pp; + + pp = pmap_pv_tracked(pa); + if (pp == NULL) + panic("pmap_pv_protect: page not pv-tracked: 0x%"PRIxPADDR, + pa); + + struct vm_page_md *md = PMAP_PAGE_TO_MD(pp); + pmap_page_remove(md, pa); +} + +void +pmap_pv_protect(paddr_t pa, vm_prot_t prot) +{ + + /* the only case is remove at the moment */ + KASSERT(prot == VM_PROT_NONE); + pmap_pv_remove(pa); +} + void pmap_protect(pmap_t pm, vaddr_t sva, vaddr_t eva, vm_prot_t prot) { Index: sys/arch/arm/conf/files.arm =================================================================== RCS file: /cvsroot/src/sys/arch/arm/conf/files.arm,v retrieving revision 1.130 diff -u -p -r1.130 files.arm --- sys/arch/arm/conf/files.arm 7 Feb 2015 17:14:32 -0000 1.130 +++ sys/arch/arm/conf/files.arm 6 Nov 2015 16:19:03 -0000 @@ -213,6 +213,9 @@ file arch/arm/arm32/cortex_pmc.c cortex file arch/arm/arm32/arm32_tlb.c (cpu_armv7 | cpu_arm11) & (!arm11_compat_mmu & !cpu_pre_armv6) file uvm/pmap/pmap_tlb.c (cpu_armv7 | cpu_arm11) & (!arm11_compat_mmu & !cpu_pre_armv6) +# generic pmap files for arm32 implementations +file uvm/pmap/pmap_pvt.c arm32 + # arm32 library functions file arch/arm/arm32/bcopy_page.S arm32 Index: sys/arch/arm/include/arm32/pmap.h =================================================================== RCS file: /cvsroot/src/sys/arch/arm/include/arm32/pmap.h,v retrieving revision 1.142 diff -u -p -r1.142 pmap.h --- sys/arch/arm/include/arm32/pmap.h 9 Sep 2015 07:37:36 -0000 1.142 +++ sys/arch/arm/include/arm32/pmap.h 6 Nov 2015 16:19:04 -0000 @@ -80,6 +80,7 @@ #include #include #include +#include #endif #ifdef ARM_MMU_EXTENDED @@ -1066,11 +1067,11 @@ paddr_t pmap_unmap_poolpage(vaddr_t); #define PMAP_UNMAP_POOLPAGE(va) pmap_unmap_poolpage(va) #endif -/* - * pmap-specific data store in the vm_page structure. - */ -#define __HAVE_VM_PAGE_MD -struct vm_page_md { +#define __HAVE_PMAP_PV_TRACK 1 + +void pmap_pv_protect(paddr_t, vm_prot_t); + +struct pmap_page { SLIST_HEAD(,pv_entry) pvh_list; /* pv_entry list */ int pvh_attrs; /* page attributes */ u_int uro_mappings; @@ -1079,12 +1080,26 @@ struct vm_page_md { u_short s_mappings[2]; /* Assume kernel count <= 65535 */ u_int i_mappings; } k_u; -#define kro_mappings k_u.s_mappings[0] -#define krw_mappings k_u.s_mappings[1] -#define k_mappings k_u.i_mappings }; /* + * pmap-specific data store in the vm_page structure. + */ +#define __HAVE_VM_PAGE_MD +struct vm_page_md { + struct pmap_page pp; +#define pvh_list pp.pvh_list +#define pvh_attrs pp.pvh_attrs +#define uro_mappings pp.uro_mappings +#define urw_mappings pp.urw_mappings +#define kro_mappings pp.k_u.s_mappings[0] +#define krw_mappings pp.k_u.s_mappings[1] +#define k_mappings pp.k_u.i_mappings +}; + +#define PMAP_PAGE_TO_MD(pp) ((struct vm_page_md *)(pp)) + +/* * Set the default color of each page. */ #if ARM_MMU_V6 > 0 Index: sys/arch/x86/conf/files.x86 =================================================================== RCS file: /cvsroot/src/sys/arch/x86/conf/files.x86,v retrieving revision 1.84 diff -u -p -r1.84 files.x86 --- sys/arch/x86/conf/files.x86 27 Apr 2015 07:03:58 -0000 1.84 +++ sys/arch/x86/conf/files.x86 6 Nov 2015 16:19:09 -0000 @@ -95,6 +95,8 @@ file arch/x86/x86/x86_autoconf.c machdep file arch/x86/x86/x86_userconf.c userconf file arch/x86/x86/x86_machdep.c machdep +file uvm/pmap/pmap_pvt.c machdep + file arch/x86/x86/cpu_ucode.c cpu_ucode needs-flag file arch/x86/x86/cpu_ucode_amd.c cpu_ucode needs-flag file arch/x86/x86/cpu_ucode_intel.c cpu_ucode needs-flag Index: sys/arch/x86/include/pmap.h =================================================================== RCS file: /cvsroot/src/sys/arch/x86/include/pmap.h,v retrieving revision 1.56 diff -u -p -r1.56 pmap.h --- sys/arch/x86/include/pmap.h 3 Apr 2015 01:04:23 -0000 1.56 +++ sys/arch/x86/include/pmap.h 6 Nov 2015 16:19:09 -0000 @@ -109,6 +109,7 @@ #if defined(_KERNEL) #include +#include /* * pmap data structures: see pmap.c for details of locking. Index: sys/arch/x86/x86/pmap.c =================================================================== RCS file: /cvsroot/src/sys/arch/x86/x86/pmap.c,v retrieving revision 1.188 diff -u -p -r1.188 pmap.c --- sys/arch/x86/x86/pmap.c 3 Apr 2015 01:04:24 -0000 1.188 +++ sys/arch/x86/x86/pmap.c 6 Nov 2015 16:19:11 -0000 @@ -191,10 +191,9 @@ __KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.1 #include #include #include -#include -#include #include +#include #include @@ -463,120 +462,6 @@ pvhash_remove(struct pv_hash_head *hh, s } /* - * unmanaged pv-tracked ranges - * - * This is a linear list for now because the only user are the DRM - * graphics drivers, with a single tracked range per device, for the - * graphics aperture, so there are expected to be few of them. - * - * This is used only after the VM system is initialized well enough - * that we can use kmem_alloc. - */ - -struct pv_track { - paddr_t pvt_start; - psize_t pvt_size; - struct pv_track *pvt_next; - struct pmap_page pvt_pages[]; -}; - -static struct { - kmutex_t lock; - pserialize_t psz; - struct pv_track *list; -} pv_unmanaged __cacheline_aligned; - -void -pmap_pv_init(void) -{ - - mutex_init(&pv_unmanaged.lock, MUTEX_DEFAULT, IPL_VM); - pv_unmanaged.psz = pserialize_create(); - pv_unmanaged.list = NULL; -} - -void -pmap_pv_track(paddr_t start, psize_t size) -{ - struct pv_track *pvt; - size_t npages; - - KASSERT(start == trunc_page(start)); - KASSERT(size == trunc_page(size)); - - npages = size >> PAGE_SHIFT; - pvt = kmem_zalloc(offsetof(struct pv_track, pvt_pages[npages]), - KM_SLEEP); - pvt->pvt_start = start; - pvt->pvt_size = size; - - mutex_enter(&pv_unmanaged.lock); - pvt->pvt_next = pv_unmanaged.list; - membar_producer(); - pv_unmanaged.list = pvt; - mutex_exit(&pv_unmanaged.lock); -} - -void -pmap_pv_untrack(paddr_t start, psize_t size) -{ - struct pv_track **pvtp, *pvt; - size_t npages; - - KASSERT(start == trunc_page(start)); - KASSERT(size == trunc_page(size)); - - mutex_enter(&pv_unmanaged.lock); - for (pvtp = &pv_unmanaged.list; - (pvt = *pvtp) != NULL; - pvtp = &pvt->pvt_next) { - if (pvt->pvt_start != start) - continue; - if (pvt->pvt_size != size) - panic("pmap_pv_untrack: pv-tracking at 0x%"PRIxPADDR - ": 0x%"PRIxPSIZE" bytes, not 0x%"PRIxPSIZE" bytes", - pvt->pvt_start, pvt->pvt_size, size); - *pvtp = pvt->pvt_next; - pserialize_perform(pv_unmanaged.psz); - pvt->pvt_next = NULL; - goto out; - } - panic("pmap_pv_untrack: pages not pv-tracked at 0x%"PRIxPADDR - " (0x%"PRIxPSIZE" bytes)", - start, size); -out: mutex_exit(&pv_unmanaged.lock); - - npages = size >> PAGE_SHIFT; - kmem_free(pvt, offsetof(struct pv_track, pvt_pages[npages])); -} - -static struct pmap_page * -pmap_pv_tracked(paddr_t pa) -{ - struct pv_track *pvt; - size_t pgno; - int s; - - KASSERT(pa == trunc_page(pa)); - - s = pserialize_read_enter(); - for (pvt = pv_unmanaged.list; pvt != NULL; pvt = pvt->pvt_next) { - membar_datadep_consumer(); - if ((pvt->pvt_start <= pa) && - ((pa - pvt->pvt_start) < pvt->pvt_size)) - break; - } - pserialize_read_exit(s); - - if (pvt == NULL) - return NULL; - KASSERT(pvt->pvt_start <= pa); - KASSERT((pa - pvt->pvt_start) < pvt->pvt_size); - pgno = (pa - pvt->pvt_start) >> PAGE_SHIFT; - return &pvt->pvt_pages[pgno]; -} - -/* * other data structures */