Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 8 Sep 2008 16:04:05 GMT
From:      Rafal Jaworowski <raj@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 149427 for review
Message-ID:  <200809081604.m88G45u1066348@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=149427

Change 149427 by raj@raj_mimi on 2008/09/08 16:03:33

	Do not use cached page for temporary mapping in	pmap_zero_page_generic()
	
	We can safely use a cached page for the temporary mapping only if
	d-cache write-allocate feature is disabled or not present.
	
	The physical page which we zero here is accessed via *additional*
	kernel mapping for the period of zeroing operation. However with WA
	enabled we can have modified but unflushed content pertaining to this
	physical page still in the d-cache due to its primary mapping. In this
	case when that cached content is flushed it will overwrite [portions
	of] the physical page we want to zero here.
	
	This is a general problem with multiple virtual mappings covering the
	same physical page with write-allocate d-cache: there is inherent
	potential for corruptions of this kind, which are not easily resolved;
	it it best policy that such multiple mappings are not allowed.

Affected files ...

.. //depot/projects/arm/src/sys/arm/arm/pmap.c#40 edit

Differences ...

==== //depot/projects/arm/src/sys/arm/arm/pmap.c#40 (text+ko) ====

@@ -3851,21 +3851,19 @@
 
 	mtx_lock(&cmtx);
 	/*
-	 * Hook in the page, zero it, and purge the cache for that
-	 * zeroed page. Invalidate the TLB as needed.
+	 * Hook in the page, zero it, invalidate the TLB as needed.
+	 *
+	 * Note the temporary zero-page mapping must be a non-cached page in
+	 * ordert to work without corruption when write-allocate is enabled.
 	 */
-	*cdst_pte = L2_S_PROTO | phys |
-	    L2_S_PROT(PTE_KERNEL, VM_PROT_WRITE) | pte_l2_s_cache_mode;
-	PTE_SYNC(cdst_pte);
+	*cdst_pte = L2_S_PROTO | phys | L2_S_PROT(PTE_KERNEL, VM_PROT_WRITE);
 	cpu_tlb_flushD_SE(cdstp);
 	cpu_cpwait();
-	if (off || size != PAGE_SIZE) {
+	if (off || size != PAGE_SIZE)
 		bzero((void *)(cdstp + off), size);
-		cpu_dcache_wbinv_range(cdstp + off, size);
-	} else {
+	else
 		bzero_page(cdstp);
-		cpu_dcache_wbinv_range(cdstp, PAGE_SIZE);
-	}
+
 	mtx_unlock(&cmtx);
 #endif
 }



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