Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 21 Jun 2016 17:53:42 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r302064 - head/sys/arm/include
Message-ID:  <201606211753.u5LHrg7t082487@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Tue Jun 21 17:53:42 2016
New Revision: 302064
URL: https://svnweb.freebsd.org/changeset/base/302064

Log:
  Revert the recent armv6 changes to ALIGNED_POINTER(), restoring the
  fully-pessimized implementation that requires a type to be aligned to
  its natural size.
  
  On armv6+ the compiler might generate load-/store-multiple instructions
  which require 4-byte alignment even though the source code is only
  accessing individual uint32_t values in a way that doesn't require any
  particular alignment at all.  The compiler apparently feels free to
  combine multiple accesses into a single instruction that requires a
  more-strict alignment, and no set of compiler flags seems to disable
  this behavior (at least in clang 3.8).
  
  This fixes alignment faults on arm systems using wifi adapters.  The
  wifi code uses ALIGNED_POINTER(p, uint32_t) to decide whether it needs
  to copy-align tcp headers.  Because clang is combining several uint32_t
  accesses into a single ldm instruction, we need to say that accessing a
  uint32_t requires 4-byte alignment.
  
  Approved by:	re(gjb)

Modified:
  head/sys/arm/include/param.h

Modified: head/sys/arm/include/param.h
==============================================================================
--- head/sys/arm/include/param.h	Tue Jun 21 17:49:33 2016	(r302063)
+++ head/sys/arm/include/param.h	Tue Jun 21 17:53:42 2016	(r302064)
@@ -91,15 +91,15 @@
  * This does not reflect the optimal alignment, just the possibility
  * (within reasonable limits).
  *
- * armv4 and v5 require alignment to the type's size.  armv6 and later require
- * that an 8-byte type be aligned to at least a 4-byte boundary; access to
- * smaller types can be unaligned.
+ * armv4 and v5 require alignment to the type's size.  armv6 requires 8-byte
+ * alignment for the ldrd/strd instructions, but otherwise follows armv7 rules.
+ * armv7 requires that an 8-byte type be aligned to at least a 4-byte boundary;
+ * access to smaller types can be unaligned, except that the compiler may
+ * optimize access to adjacent uint32_t values into a single load/store-multiple
+ * instruction which requires 4-byte alignment, so we must provide the most-
+ * pessimistic answer possible even on armv7.
  */
-#if __ARM_ARCH >= 6
-#define	ALIGNED_POINTER(p, t)	(((sizeof(t) != 8) || ((unsigned)(p) & 3) == 0))
-#else
 #define	ALIGNED_POINTER(p, t)	((((unsigned)(p)) & (sizeof(t)-1)) == 0)
-#endif
 
 /*
  * CACHE_LINE_SIZE is the compile-time maximum cache line size for an



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