Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 1 Aug 2018 18:45:51 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r337051 - in head/sys: amd64/amd64 arm/arm arm64/arm64 i386/i386 i386/include mips/mips powerpc/powerpc riscv/riscv sparc64/sparc64 vm
Message-ID:  <201808011845.w71Ijp9c022303@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Wed Aug  1 18:45:51 2018
New Revision: 337051
URL: https://svnweb.freebsd.org/changeset/base/337051

Log:
  Add pmap_is_valid_memattr(9).
  
  Discussed with:	alc
  Sponsored by:	The FreeBSD Foundation, Mellanox Technologies
  MFC after:	1 week
  Differential revision:	https://reviews.freebsd.org/D15583

Modified:
  head/sys/amd64/amd64/pmap.c
  head/sys/arm/arm/pmap-v4.c
  head/sys/arm/arm/pmap-v6.c
  head/sys/arm64/arm64/pmap.c
  head/sys/i386/i386/copyout.c
  head/sys/i386/i386/pmap.c
  head/sys/i386/i386/vm_machdep.c
  head/sys/i386/include/pmap.h
  head/sys/mips/mips/pmap.c
  head/sys/powerpc/powerpc/pmap_dispatch.c
  head/sys/riscv/riscv/pmap.c
  head/sys/sparc64/sparc64/pmap.c
  head/sys/vm/pmap.h

Modified: head/sys/amd64/amd64/pmap.c
==============================================================================
--- head/sys/amd64/amd64/pmap.c	Wed Aug  1 18:45:33 2018	(r337050)
+++ head/sys/amd64/amd64/pmap.c	Wed Aug  1 18:45:51 2018	(r337051)
@@ -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_pd
 {
 	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) {

Modified: head/sys/arm/arm/pmap-v4.c
==============================================================================
--- head/sys/arm/arm/pmap-v4.c	Wed Aug  1 18:45:33 2018	(r337050)
+++ head/sys/arm/arm/pmap-v4.c	Wed Aug  1 18:45:51 2018	(r337051)
@@ -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);
+}

Modified: head/sys/arm/arm/pmap-v6.c
==============================================================================
--- head/sys/arm/arm/pmap-v6.c	Wed Aug  1 18:45:33 2018	(r337050)
+++ head/sys/arm/arm/pmap-v6.c	Wed Aug  1 18:45:51 2018	(r337051)
@@ -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]);
 }
 

Modified: head/sys/arm64/arm64/pmap.c
==============================================================================
--- head/sys/arm64/arm64/pmap.c	Wed Aug  1 18:45:33 2018	(r337050)
+++ head/sys/arm64/arm64/pmap.c	Wed Aug  1 18:45:51 2018	(r337051)
@@ -5361,3 +5361,10 @@ pmap_unmap_io_transient(vm_page_t page[], vm_offset_t 
 		}
 	}
 }
+
+boolean_t
+pmap_is_valid_memattr(pmap_t pmap __unused, vm_memattr_t mode)
+{
+
+	return (mode >= VM_MEMATTR_DEVICE && mode <= VM_MEMATTR_WRITE_THROUGH);
+}

Modified: head/sys/i386/i386/copyout.c
==============================================================================
--- head/sys/i386/i386/copyout.c	Wed Aug  1 18:45:33 2018	(r337050)
+++ head/sys/i386/i386/copyout.c	Wed Aug  1 18:45:51 2018	(r337051)
@@ -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);

Modified: head/sys/i386/i386/pmap.c
==============================================================================
--- head/sys/i386/i386/pmap.c	Wed Aug  1 18:45:33 2018	(r337050)
+++ head/sys/i386/i386/pmap.c	Wed Aug  1 18:45:51 2018	(r337051)
@@ -1059,16 +1059,24 @@ SYSCTL_ULONG(_vm_pmap_pde, OID_AUTO, promotions, CTLFL
  * 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 mo
 	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, v
 		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
 	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, v
 	 */
 	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_
 		 * "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, 
 		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 m
 	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 siz
 		    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 *

Modified: head/sys/i386/i386/vm_machdep.c
==============================================================================
--- head/sys/i386/i386/vm_machdep.c	Wed Aug  1 18:45:33 2018	(r337050)
+++ head/sys/i386/i386/vm_machdep.c	Wed Aug  1 18:45:51 2018	(r337051)
@@ -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

Modified: head/sys/i386/include/pmap.h
==============================================================================
--- head/sys/i386/include/pmap.h	Wed Aug  1 18:45:33 2018	(r337050)
+++ head/sys/i386/include/pmap.h	Wed Aug  1 18:45:51 2018	(r337051)
@@ -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);

Modified: head/sys/mips/mips/pmap.c
==============================================================================
--- head/sys/mips/mips/pmap.c	Wed Aug  1 18:45:33 2018	(r337050)
+++ head/sys/mips/mips/pmap.c	Wed Aug  1 18:45:51 2018	(r337051)
@@ -3645,3 +3645,19 @@ pmap_change_attr(vm_offset_t sva, vm_size_t size, vm_m
 	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);
+	}
+}

Modified: head/sys/powerpc/powerpc/pmap_dispatch.c
==============================================================================
--- head/sys/powerpc/powerpc/pmap_dispatch.c	Wed Aug  1 18:45:33 2018	(r337050)
+++ head/sys/powerpc/powerpc/pmap_dispatch.c	Wed Aug  1 18:45:51 2018	(r337051)
@@ -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);
+	}
+}

Modified: head/sys/riscv/riscv/pmap.c
==============================================================================
--- head/sys/riscv/riscv/pmap.c	Wed Aug  1 18:45:33 2018	(r337050)
+++ head/sys/riscv/riscv/pmap.c	Wed Aug  1 18:45:51 2018	(r337051)
@@ -3336,3 +3336,10 @@ pmap_unmap_io_transient(vm_page_t page[], vm_offset_t 
 		}
 	}
 }
+
+boolean_t
+pmap_is_valid_memattr(pmap_t pmap __unused, vm_memattr_t mode)
+{
+
+	return (mode >= VM_MEMATTR_DEVICE && mode <= VM_MEMATTR_WRITE_BACK);
+}

Modified: head/sys/sparc64/sparc64/pmap.c
==============================================================================
--- head/sys/sparc64/sparc64/pmap.c	Wed Aug  1 18:45:33 2018	(r337050)
+++ head/sys/sparc64/sparc64/pmap.c	Wed Aug  1 18:45:51 2018	(r337051)
@@ -2318,3 +2318,10 @@ pmap_align_superpage(vm_object_t object, vm_ooffset_t 
 {
 
 }
+
+boolean_t
+pmap_is_valid_memattr(pmap_t pmap __unused, vm_memattr_t mode)
+{
+
+	return (mode == VM_MEMATTR_DEFAULT);
+}

Modified: head/sys/vm/pmap.h
==============================================================================
--- head/sys/vm/pmap.h	Wed Aug  1 18:45:33 2018	(r337050)
+++ head/sys/vm/pmap.h	Wed Aug  1 18:45:51 2018	(r337051)
@@ -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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201808011845.w71Ijp9c022303>