diff options
| author | Konstantin Belousov <kib@FreeBSD.org> | 2018-08-01 18:45:51 +0000 |
|---|---|---|
| committer | Konstantin Belousov <kib@FreeBSD.org> | 2018-08-01 18:45:51 +0000 |
| commit | e45b89d23d34f192217b1464b4392f1fb638136c (patch) | |
| tree | d8520ce1716c891b6a24b7be8fdf74e9b27160d0 | |
| parent | 322dacf057fe8850ecaa00eb08d921d058625241 (diff) | |
Notes
| -rw-r--r-- | sys/amd64/amd64/pmap.c | 10 | ||||
| -rw-r--r-- | sys/arm/arm/pmap-v4.c | 5 | ||||
| -rw-r--r-- | sys/arm/arm/pmap-v6.c | 11 | ||||
| -rw-r--r-- | sys/arm64/arm64/pmap.c | 7 | ||||
| -rw-r--r-- | sys/i386/i386/copyout.c | 3 | ||||
| -rw-r--r-- | sys/i386/i386/pmap.c | 53 | ||||
| -rw-r--r-- | sys/i386/i386/vm_machdep.c | 2 | ||||
| -rw-r--r-- | sys/i386/include/pmap.h | 2 | ||||
| -rw-r--r-- | sys/mips/mips/pmap.c | 16 | ||||
| -rw-r--r-- | sys/powerpc/powerpc/pmap_dispatch.c | 18 | ||||
| -rw-r--r-- | sys/riscv/riscv/pmap.c | 7 | ||||
| -rw-r--r-- | sys/sparc64/sparc64/pmap.c | 7 | ||||
| -rw-r--r-- | sys/vm/pmap.h | 1 |
13 files changed, 116 insertions, 26 deletions
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index b8939a5c3c987..572b21974531b 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -1489,6 +1489,14 @@ pmap_swap_pat(pmap_t pmap, pt_entry_t entry) return (entry); } +boolean_t +pmap_is_valid_memattr(pmap_t pmap __unused, vm_memattr_t mode) +{ + + return (mode >= 0 && mode < PAT_INDEX_SIZE && + pat_index[(int)mode] >= 0); +} + /* * Determine the appropriate bits to set in a PTE or PDE for a specified * caching mode. @@ -1498,7 +1506,7 @@ pmap_cache_bits(pmap_t pmap, int mode, boolean_t is_pde) { int cache_bits, pat_flag, pat_idx; - if (mode < 0 || mode >= PAT_INDEX_SIZE || pat_index[mode] < 0) + if (!pmap_is_valid_memattr(pmap, mode)) panic("Unknown caching mode %d\n", mode); switch (pmap->pm_type) { diff --git a/sys/arm/arm/pmap-v4.c b/sys/arm/arm/pmap-v4.c index e7eddadfad91c..6fe5b83427b9f 100644 --- a/sys/arm/arm/pmap-v4.c +++ b/sys/arm/arm/pmap-v4.c @@ -4859,4 +4859,9 @@ pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma) panic("Can't change memattr on page with existing mappings"); } +boolean_t +pmap_is_valid_memattr(pmap_t pmap __unused, vm_memattr_t mode) +{ + return (mode == VM_MEMATTR_DEFAULT || mode == VM_MEMATTR_UNCACHEABLE); +} diff --git a/sys/arm/arm/pmap-v6.c b/sys/arm/arm/pmap-v6.c index 15aee3bb32176..3f8145d0768ce 100644 --- a/sys/arm/arm/pmap-v6.c +++ b/sys/arm/arm/pmap-v6.c @@ -393,12 +393,21 @@ CTASSERT(VM_MEMATTR_NOCACHE == 1); CTASSERT(VM_MEMATTR_DEVICE == 2); CTASSERT(VM_MEMATTR_SO == 3); CTASSERT(VM_MEMATTR_WRITE_THROUGH == 4); +#define VM_MEMATTR_END (VM_MEMATTR_WRITE_THROUGH + 1) + +boolean_t +pmap_is_valid_memattr(pmap_t pmap __unused, vm_memattr_t mode) +{ + + return (mode >= 0 && mode < VM_MEMATTR_END); +} static inline uint32_t vm_memattr_to_pte2(vm_memattr_t ma) { - KASSERT((u_int)ma < 5, ("%s: bad vm_memattr_t %d", __func__, ma)); + KASSERT((u_int)ma < VM_MEMATTR_END, + ("%s: bad vm_memattr_t %d", __func__, ma)); return (pte2_attr_tab[(u_int)ma]); } diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c index eb385b13c9369..b2c7cee18d70b 100644 --- a/sys/arm64/arm64/pmap.c +++ b/sys/arm64/arm64/pmap.c @@ -5361,3 +5361,10 @@ pmap_unmap_io_transient(vm_page_t page[], vm_offset_t vaddr[], int count, } } } + +boolean_t +pmap_is_valid_memattr(pmap_t pmap __unused, vm_memattr_t mode) +{ + + return (mode >= VM_MEMATTR_DEVICE && mode <= VM_MEMATTR_WRITE_THROUGH); +} diff --git a/sys/i386/i386/copyout.c b/sys/i386/i386/copyout.c index 1af4f125cc5cf..a051e8c25a8f9 100644 --- a/sys/i386/i386/copyout.c +++ b/sys/i386/i386/copyout.c @@ -130,7 +130,8 @@ cp_slow0(vm_offset_t uva, size_t len, bool write, } for (i = 0, pte = vtopte(kaddr); i < plen; i++, pte++) { *pte = PG_V | PG_RW | PG_A | PG_M | VM_PAGE_TO_PHYS(m[i]) | - pmap_cache_bits(pmap_page_get_memattr(m[i]), FALSE); + pmap_cache_bits(kernel_pmap, pmap_page_get_memattr(m[i]), + FALSE); invlpg(kaddr + ptoa(i)); } kaddr += uva - trunc_page(uva); diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index 301e352c220c3..76b93bdaca168 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -1059,16 +1059,24 @@ SYSCTL_ULONG(_vm_pmap_pde, OID_AUTO, promotions, CTLFLAG_RD, * Low level helper routines..... ***************************************************/ +boolean_t +pmap_is_valid_memattr(pmap_t pmap __unused, vm_memattr_t mode) +{ + + return (mode >= 0 && mode < PAT_INDEX_SIZE && + pat_index[(int)mode] >= 0); +} + /* * Determine the appropriate bits to set in a PTE or PDE for a specified * caching mode. */ int -pmap_cache_bits(int mode, boolean_t is_pde) +pmap_cache_bits(pmap_t pmap, int mode, boolean_t is_pde) { int cache_bits, pat_flag, pat_idx; - if (mode < 0 || mode >= PAT_INDEX_SIZE || pat_index[mode] < 0) + if (!pmap_is_valid_memattr(pmap, mode)) panic("Unknown caching mode %d\n", mode); /* The PAT bit is different for PTE's and PDE's. */ @@ -1744,7 +1752,8 @@ pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, int mode) pt_entry_t *pte; pte = vtopte(va); - pte_store(pte, pa | PG_RW | PG_V | pmap_cache_bits(mode, 0)); + pte_store(pte, pa | PG_RW | PG_V | pmap_cache_bits(kernel_pmap, + mode, 0)); } /* @@ -1839,7 +1848,8 @@ pmap_qenter(vm_offset_t sva, vm_page_t *ma, int count) endpte = pte + count; while (pte < endpte) { m = *ma++; - pa = VM_PAGE_TO_PHYS(m) | pmap_cache_bits(m->md.pat_mode, 0); + pa = VM_PAGE_TO_PHYS(m) | pmap_cache_bits(kernel_pmap, + m->md.pat_mode, 0); if ((*pte & (PG_FRAME | PG_PTE_CACHE)) != pa) { oldpte |= *pte; #if defined(PAE) || defined(PAE_TABLES) @@ -3654,7 +3664,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, newpte |= PG_W; if (pmap != kernel_pmap) newpte |= PG_U; - newpte |= pmap_cache_bits(m->md.pat_mode, psind > 0); + newpte |= pmap_cache_bits(pmap, m->md.pat_mode, psind > 0); if ((m->oflags & VPO_UNMANAGED) == 0) newpte |= PG_MANAGED; @@ -3877,7 +3887,7 @@ pmap_enter_4mpage(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot) pd_entry_t newpde; PMAP_LOCK_ASSERT(pmap, MA_OWNED); - newpde = VM_PAGE_TO_PHYS(m) | pmap_cache_bits(m->md.pat_mode, 1) | + newpde = VM_PAGE_TO_PHYS(m) | pmap_cache_bits(pmap, m->md.pat_mode, 1) | PG_PS | PG_V; if ((m->oflags & VPO_UNMANAGED) == 0) newpde |= PG_MANAGED; @@ -4135,7 +4145,7 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, */ pmap->pm_stats.resident_count++; - pa = VM_PAGE_TO_PHYS(m) | pmap_cache_bits(m->md.pat_mode, 0); + pa = VM_PAGE_TO_PHYS(m) | pmap_cache_bits(pmap, m->md.pat_mode, 0); #if defined(PAE) || defined(PAE_TABLES) if ((prot & VM_PROT_EXECUTE) == 0) pa |= pg_nx; @@ -4223,8 +4233,8 @@ pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_object_t object, * "pa" will not affect the termination of this loop. */ PMAP_LOCK(pmap); - for (pa = ptepa | pmap_cache_bits(pat_mode, 1); pa < ptepa + - size; pa += NBPDR) { + for (pa = ptepa | pmap_cache_bits(pmap, pat_mode, 1); + pa < ptepa + size; pa += NBPDR) { pde = pmap_pde(pmap, addr); if (*pde == 0) { pde_store(pde, pa | PG_PS | PG_M | PG_A | @@ -4489,7 +4499,7 @@ pmap_zero_page(vm_page_t m) if (*cmap_pte2) panic("pmap_zero_page: CMAP2 busy"); *cmap_pte2 = PG_V | PG_RW | VM_PAGE_TO_PHYS(m) | PG_A | PG_M | - pmap_cache_bits(m->md.pat_mode, 0); + pmap_cache_bits(kernel_pmap, m->md.pat_mode, 0); invlcaddr(pc->pc_cmap_addr2); pagezero(pc->pc_cmap_addr2); *cmap_pte2 = 0; @@ -4520,7 +4530,7 @@ pmap_zero_page_area(vm_page_t m, int off, int size) if (*cmap_pte2) panic("pmap_zero_page_area: CMAP2 busy"); *cmap_pte2 = PG_V | PG_RW | VM_PAGE_TO_PHYS(m) | PG_A | PG_M | - pmap_cache_bits(m->md.pat_mode, 0); + pmap_cache_bits(kernel_pmap, m->md.pat_mode, 0); invlcaddr(pc->pc_cmap_addr2); if (off == 0 && size == PAGE_SIZE) pagezero(pc->pc_cmap_addr2); @@ -4550,10 +4560,10 @@ pmap_copy_page(vm_page_t src, vm_page_t dst) if (*cmap_pte2) panic("pmap_copy_page: CMAP2 busy"); *cmap_pte1 = PG_V | VM_PAGE_TO_PHYS(src) | PG_A | - pmap_cache_bits(src->md.pat_mode, 0); + pmap_cache_bits(kernel_pmap, src->md.pat_mode, 0); invlcaddr(pc->pc_cmap_addr1); *cmap_pte2 = PG_V | PG_RW | VM_PAGE_TO_PHYS(dst) | PG_A | PG_M | - pmap_cache_bits(dst->md.pat_mode, 0); + pmap_cache_bits(kernel_pmap, dst->md.pat_mode, 0); invlcaddr(pc->pc_cmap_addr2); bcopy(pc->pc_cmap_addr1, pc->pc_cmap_addr2, PAGE_SIZE); *cmap_pte1 = 0; @@ -4592,10 +4602,10 @@ pmap_copy_pages(vm_page_t ma[], vm_offset_t a_offset, vm_page_t mb[], b_pg_offset = b_offset & PAGE_MASK; cnt = min(cnt, PAGE_SIZE - b_pg_offset); *cmap_pte1 = PG_V | VM_PAGE_TO_PHYS(a_pg) | PG_A | - pmap_cache_bits(a_pg->md.pat_mode, 0); + pmap_cache_bits(kernel_pmap, a_pg->md.pat_mode, 0); invlcaddr(pc->pc_cmap_addr1); *cmap_pte2 = PG_V | PG_RW | VM_PAGE_TO_PHYS(b_pg) | PG_A | - PG_M | pmap_cache_bits(b_pg->md.pat_mode, 0); + PG_M | pmap_cache_bits(kernel_pmap, b_pg->md.pat_mode, 0); invlcaddr(pc->pc_cmap_addr2); a_cp = pc->pc_cmap_addr1 + a_pg_offset; b_cp = pc->pc_cmap_addr2 + b_pg_offset; @@ -5567,7 +5577,8 @@ pmap_flush_page(vm_page_t m) if (*cmap_pte2) panic("pmap_flush_page: CMAP2 busy"); *cmap_pte2 = PG_V | PG_RW | VM_PAGE_TO_PHYS(m) | - PG_A | PG_M | pmap_cache_bits(m->md.pat_mode, 0); + PG_A | PG_M | pmap_cache_bits(kernel_pmap, m->md.pat_mode, + 0); invlcaddr(pc->pc_cmap_addr2); sva = (vm_offset_t)pc->pc_cmap_addr2; eva = sva + PAGE_SIZE; @@ -5628,8 +5639,8 @@ pmap_change_attr(vm_offset_t va, vm_size_t size, int mode) if (base < VM_MIN_KERNEL_ADDRESS) return (EINVAL); - cache_bits_pde = pmap_cache_bits(mode, 1); - cache_bits_pte = pmap_cache_bits(mode, 0); + cache_bits_pde = pmap_cache_bits(kernel_pmap, mode, 1); + cache_bits_pte = pmap_cache_bits(kernel_pmap, mode, 0); changed = FALSE; /* @@ -5835,7 +5846,7 @@ pmap_quick_enter_page(vm_page_t m) KASSERT(*pte == 0, ("pmap_quick_enter_page: PTE busy")); *pte = PG_V | PG_RW | VM_PAGE_TO_PHYS(m) | PG_A | PG_M | - pmap_cache_bits(pmap_page_get_memattr(m), 0); + pmap_cache_bits(kernel_pmap, pmap_page_get_memattr(m), 0); invlpg(qaddr); return (qaddr); @@ -5886,7 +5897,7 @@ pmap_trm_import(void *unused __unused, vmem_size_t size, int flags, VM_ALLOC_NORMAL | VM_ALLOC_WIRED | VM_ALLOC_WAITOK); pte_store(&trm_pte[atop(af - prev_addr)], VM_PAGE_TO_PHYS(m) | PG_M | PG_A | PG_RW | PG_V | pgeflag | - pmap_cache_bits(VM_MEMATTR_DEFAULT, FALSE)); + pmap_cache_bits(kernel_pmap, VM_MEMATTR_DEFAULT, FALSE)); } *addrp = prev_addr; return (0); @@ -5907,7 +5918,7 @@ void pmap_init_trm(void) if ((pd_m->flags & PG_ZERO) == 0) pmap_zero_page(pd_m); PTD[TRPTDI] = VM_PAGE_TO_PHYS(pd_m) | PG_M | PG_A | PG_RW | PG_V | - pmap_cache_bits(VM_MEMATTR_DEFAULT, TRUE); + pmap_cache_bits(kernel_pmap, VM_MEMATTR_DEFAULT, TRUE); } void * diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c index e997ec6c8658a..c3ed95dd4d023 100644 --- a/sys/i386/i386/vm_machdep.c +++ b/sys/i386/i386/vm_machdep.c @@ -584,7 +584,7 @@ sf_buf_map(struct sf_buf *sf, int flags) ptep = vtopte(sf->kva); opte = *ptep; *ptep = VM_PAGE_TO_PHYS(sf->m) | PG_RW | PG_V | - pmap_cache_bits(sf->m->md.pat_mode, 0); + pmap_cache_bits(kernel_pmap, sf->m->md.pat_mode, 0); /* * Avoid unnecessary TLB invalidations: If the sf_buf's old diff --git a/sys/i386/include/pmap.h b/sys/i386/include/pmap.h index c8f906f15d23f..eea683f5f858c 100644 --- a/sys/i386/include/pmap.h +++ b/sys/i386/include/pmap.h @@ -374,7 +374,7 @@ extern vm_offset_t virtual_end; * vtopte(). */ void pmap_bootstrap(vm_paddr_t); -int pmap_cache_bits(int mode, boolean_t is_pde); +int pmap_cache_bits(pmap_t, int mode, boolean_t is_pde); int pmap_change_attr(vm_offset_t, vm_size_t, int); void pmap_init_pat(void); void pmap_kenter(vm_offset_t va, vm_paddr_t pa); diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index 012362f11f7a3..56afb4a3ca749 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -3645,3 +3645,19 @@ pmap_change_attr(vm_offset_t sva, vm_size_t size, vm_memattr_t ma) mips_dcache_wbinv_range(ova, size); return 0; } + +boolean_t +pmap_is_valid_memattr(pmap_t pmap __unused, vm_memattr_t mode) +{ + + switch (mode) { + case VM_MEMATTR_UNCACHEABLE: + case VM_MEMATTR_WRITE_BACK: +#ifdef MIPS_CCA_WC + case VM_MEMATTR_WRITE_COMBINING: +#endif + return (TRUE); + default: + return (FALSE); + } +} diff --git a/sys/powerpc/powerpc/pmap_dispatch.c b/sys/powerpc/powerpc/pmap_dispatch.c index 709ba3a3e37d2..3cfa741d2ddb5 100644 --- a/sys/powerpc/powerpc/pmap_dispatch.c +++ b/sys/powerpc/powerpc/pmap_dispatch.c @@ -620,3 +620,21 @@ pmap_mmu_install(char *name, int prio) } int unmapped_buf_allowed; + +boolean_t +pmap_is_valid_memattr(pmap_t pmap __unused, vm_memattr_t mode) +{ + + switch (mode) { + case VM_MEMATTR_DEFAULT: + case VM_MEMATTR_UNCACHEABLE: + case VM_MEMATTR_CACHEABLE: + case VM_MEMATTR_WRITE_COMBINING: + case VM_MEMATTR_WRITE_BACK: + case VM_MEMATTR_WRITE_THROUGH: + case VM_MEMATTR_PREFETCHABLE: + return (TRUE); + default: + return (FALSE); + } +} diff --git a/sys/riscv/riscv/pmap.c b/sys/riscv/riscv/pmap.c index 83da411e81a4c..6d5d7cf844d88 100644 --- a/sys/riscv/riscv/pmap.c +++ b/sys/riscv/riscv/pmap.c @@ -3336,3 +3336,10 @@ pmap_unmap_io_transient(vm_page_t page[], vm_offset_t vaddr[], int count, } } } + +boolean_t +pmap_is_valid_memattr(pmap_t pmap __unused, vm_memattr_t mode) +{ + + return (mode >= VM_MEMATTR_DEVICE && mode <= VM_MEMATTR_WRITE_BACK); +} diff --git a/sys/sparc64/sparc64/pmap.c b/sys/sparc64/sparc64/pmap.c index bc70b21e3bcee..a469d6f26c074 100644 --- a/sys/sparc64/sparc64/pmap.c +++ b/sys/sparc64/sparc64/pmap.c @@ -2318,3 +2318,10 @@ pmap_align_superpage(vm_object_t object, vm_ooffset_t offset, { } + +boolean_t +pmap_is_valid_memattr(pmap_t pmap __unused, vm_memattr_t mode) +{ + + return (mode == VM_MEMATTR_DEFAULT); +} diff --git a/sys/vm/pmap.h b/sys/vm/pmap.h index 669fe784b323d..5f16f85b76f4f 100644 --- a/sys/vm/pmap.h +++ b/sys/vm/pmap.h @@ -142,6 +142,7 @@ void pmap_init(void); boolean_t pmap_is_modified(vm_page_t m); boolean_t pmap_is_prefaultable(pmap_t pmap, vm_offset_t va); boolean_t pmap_is_referenced(vm_page_t m); +boolean_t pmap_is_valid_memattr(pmap_t, vm_memattr_t); vm_offset_t pmap_map(vm_offset_t *, vm_paddr_t, vm_paddr_t, int); int pmap_mincore(pmap_t pmap, vm_offset_t addr, vm_paddr_t *locked_pa); |
