Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 17 May 2014 22:50:16 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r266373 - in stable/10/sys/arm: arm include
Message-ID:  <201405172250.s4HMoGKq060042@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Sat May 17 22:50:16 2014
New Revision: 266373
URL: http://svnweb.freebsd.org/changeset/base/266373

Log:
  MFC 264990, 264994, 265020, 265025:
  
    Call cpu_icache_sync_range() rather than sync_all since we know the range
    and flushing the entire icache is needlessly expensive.
  
    Provide a proper armv7 implementation of icache_sync_all rather than
    using armv7_idcache_wbinv_all, because wbinv_all doesn't broadcast the
    operation to other cores.  In elf_cpu_load_file() use icache_sync_all()
    and explain why it's needed (and why other sync operations aren't).
  
    Remove cpu_idcache_wbinv_all() from kdb_cpu_trap(), it's no longer needed.
  
    Explain why wbinv_all is SMP-safe when dumping, and add a missing l2 cache
    flush.  (Either it was missing here, or it isn't needed in the minidump
    case.  Adding it here seems like the safer path to consistancy.)

Modified:
  stable/10/sys/arm/arm/cpufunc.c
  stable/10/sys/arm/arm/cpufunc_asm_armv7.S
  stable/10/sys/arm/arm/dump_machdep.c
  stable/10/sys/arm/arm/elf_machdep.c
  stable/10/sys/arm/include/cpufunc.h
  stable/10/sys/arm/include/kdb.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/arm/arm/cpufunc.c
==============================================================================
--- stable/10/sys/arm/arm/cpufunc.c	Sat May 17 22:31:40 2014	(r266372)
+++ stable/10/sys/arm/arm/cpufunc.c	Sat May 17 22:50:16 2014	(r266373)
@@ -769,7 +769,7 @@ struct cpu_functions cortexa_cpufuncs = 
 	
 	/* Cache operations */
 	
-	armv7_idcache_wbinv_all,         /* icache_sync_all      */
+	armv7_icache_sync_all, 	        /* icache_sync_all      */
 	armv7_icache_sync_range,        /* icache_sync_range    */
 	
 	armv7_dcache_wbinv_all,         /* dcache_wbinv_all     */

Modified: stable/10/sys/arm/arm/cpufunc_asm_armv7.S
==============================================================================
--- stable/10/sys/arm/arm/cpufunc_asm_armv7.S	Sat May 17 22:31:40 2014	(r266372)
+++ stable/10/sys/arm/arm/cpufunc_asm_armv7.S	Sat May 17 22:50:16 2014	(r266373)
@@ -250,6 +250,13 @@ ENTRY(armv7_idcache_wbinv_range)
 	RET
 END(armv7_idcache_wbinv_range)
 
+ENTRY_NP(armv7_icache_sync_all)
+	mcr	p15, 0, r0, c7, c1, 0	/* Invalidate all I cache to PoU Inner Shareable */
+	isb				/* instruction synchronization barrier */
+	dsb				/* data synchronization barrier */
+	RET
+END(armv7_icache_sync_all)
+
 ENTRY_NP(armv7_icache_sync_range)
 	ldr	ip, .Larmv7_line_size
 .Larmv7_sync_next:

Modified: stable/10/sys/arm/arm/dump_machdep.c
==============================================================================
--- stable/10/sys/arm/arm/dump_machdep.c	Sat May 17 22:31:40 2014	(r266372)
+++ stable/10/sys/arm/arm/dump_machdep.c	Sat May 17 22:50:16 2014	(r266373)
@@ -174,8 +174,14 @@ cb_dumpdata(struct md_pa *mdp, int seqnr
 	printf("  chunk %d: %dMB (%d pages)", seqnr, pgs * PAGE_SIZE / (
 	    1024*1024), pgs);
 
-	/* Make sure we write coherent datas. */
+	/*
+	 * Make sure we write coherent data.  Note that in the SMP case this
+	 * only operates on the L1 cache of the current CPU, but all other CPUs
+	 * have already been stopped, and their flush/invalidate was done as
+	 * part of stopping.
+	 */
 	cpu_idcache_wbinv_all();
+	cpu_l2cache_wbinv_all();
 #ifdef __XSCALE__
 	xscale_cache_clean_minidata();
 #endif

Modified: stable/10/sys/arm/arm/elf_machdep.c
==============================================================================
--- stable/10/sys/arm/arm/elf_machdep.c	Sat May 17 22:31:40 2014	(r266372)
+++ stable/10/sys/arm/arm/elf_machdep.c	Sat May 17 22:50:16 2014	(r266373)
@@ -220,9 +220,19 @@ int
 elf_cpu_load_file(linker_file_t lf __unused)
 {
 
-	cpu_idcache_wbinv_all();
-	cpu_l2cache_wbinv_all();
-	cpu_tlb_flushID();
+	/*
+	 * The pmap code does not do an icache sync upon establishing executable
+	 * mappings in the kernel pmap.  It's an optimization based on the fact
+	 * that kernel memory allocations always have EXECUTABLE protection even
+	 * when the memory isn't going to hold executable code.  The only time
+	 * kernel memory holding instructions does need a sync is after loading
+	 * a kernel module, and that's when this function gets called.  Normal
+	 * data cache maintenance has already been done by the IO code, and TLB
+	 * maintenance has been done by the pmap code, so all we have to do here
+	 * is invalidate the instruction cache (which also invalidates the
+	 * branch predictor cache on platforms that have one).
+	 */
+	cpu_icache_sync_all();
 	return (0);
 }
 

Modified: stable/10/sys/arm/include/cpufunc.h
==============================================================================
--- stable/10/sys/arm/include/cpufunc.h	Sat May 17 22:31:40 2014	(r266372)
+++ stable/10/sys/arm/include/cpufunc.h	Sat May 17 22:50:16 2014	(r266373)
@@ -411,6 +411,7 @@ void	armv6_idcache_wbinv_range	(vm_offse
 void	armv7_setttb			(u_int);
 void	armv7_tlb_flushID		(void);
 void	armv7_tlb_flushID_SE		(u_int);
+void	armv7_icache_sync_all		();
 void	armv7_icache_sync_range		(vm_offset_t, vm_size_t);
 void	armv7_idcache_wbinv_range	(vm_offset_t, vm_size_t);
 void	armv7_idcache_inv_all		(void);

Modified: stable/10/sys/arm/include/kdb.h
==============================================================================
--- stable/10/sys/arm/include/kdb.h	Sat May 17 22:31:40 2014	(r266372)
+++ stable/10/sys/arm/include/kdb.h	Sat May 17 22:50:16 2014	(r266373)
@@ -49,14 +49,12 @@ static __inline void
 kdb_cpu_sync_icache(unsigned char *addr, size_t size)
 {
 
-	cpu_icache_sync_all();
+	cpu_icache_sync_range((vm_offset_t)addr, size);
 }
 
 static __inline void
 kdb_cpu_trap(int type, int code)
 {
-
-	cpu_idcache_wbinv_all();
 }
 
 #endif /* _MACHINE_KDB_H_ */



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