svn commit: r294727 - head/sys/arm/arm

Svatopluk Kraus skra at FreeBSD.org
Mon Jan 25 14:09:37 UTC 2016


Author: skra
Date: Mon Jan 25 14:09:35 2016
New Revision: 294727
URL: https://svnweb.freebsd.org/changeset/base/294727

Log:
  Fix an occasional undefined instruction abort during module loading.
  
  Even if data cache maintenance was done by IO code, the relocation
  fixup process creates dirty cache entries that we must write back
  before doing icache sync.
  
  Reported by:	Thiagarajan Venkatasubramanian <tvenkata at juniper.net>
  Reviewed by:	ian

Modified:
  head/sys/arm/arm/elf_machdep.c

Modified: head/sys/arm/arm/elf_machdep.c
==============================================================================
--- head/sys/arm/arm/elf_machdep.c	Mon Jan 25 13:35:28 2016	(r294726)
+++ head/sys/arm/arm/elf_machdep.c	Mon Jan 25 14:09:35 2016	(r294727)
@@ -256,7 +256,7 @@ elf_reloc_local(linker_file_t lf, Elf_Ad
 }
 
 int
-elf_cpu_load_file(linker_file_t lf __unused)
+elf_cpu_load_file(linker_file_t lf)
 {
 
 	/*
@@ -265,13 +265,25 @@ elf_cpu_load_file(linker_file_t lf __unu
 	 * 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).
+	 * a kernel module, and that's when this function gets called.
+	 *
+	 * This syncs data and instruction caches after loading a module.  We
+	 * don't worry about the kernel itself (lf->id is 1) as locore.S did
+	 * that on entry.  Even if data cache maintenance was done by IO code,
+	 * the relocation fixup process creates dirty cache entries that we must
+	 * write back before doing icache sync. The instruction cache sync also
+	 * invalidates the branch predictor cache on platforms that have one.
 	 */
+	if (lf->id == 1)
+		return (0);
+#if __ARM_ARCH >= 6
+	dcache_wb_pou((vm_offset_t)lf->address, (vm_size_t)lf->size);
+	icache_inv_all();
+#else
+	cpu_dcache_wb_range((vm_offset_t)lf->address, (vm_size_t)lf->size);
+	cpu_l2cache_wb_range((vm_offset_t)lf->address, (vm_size_t)lf->size);
 	cpu_icache_sync_all();
+#endif
 	return (0);
 }
 


More information about the svn-src-all mailing list