summaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2018-07-11 13:10:40 -0700
committerGitHub <[email protected]>2018-07-11 13:10:40 -0700
commit33a19e0fd9b22364d295351ea1bda57b80e39e85 (patch)
tree1a0bf9708376d1a00e64dd5f8e23eb3bbcb739b9 /module
parent2dca37d8dc13e6faf92c5a095d49dffd480c5b2d (diff)
Fix kernel unaligned access on sparc64
Update the SA_COPY_DATA macro to check if architecture supports efficient unaligned memory accesses at compile time. Otherwise fallback to using the sa_copy_data() function. The kernel provided CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is used to determine availability in kernel space. In user space the x86_64, x86, powerpc, and sometimes arm architectures will define the HAVE_EFFICIENT_UNALIGNED_ACCESS macro. Signed-off-by: Brian Behlendorf <[email protected]> Closes #7642 Closes #7684
Diffstat (limited to 'module')
-rw-r--r--module/icp/algs/modes/ccm.c2
-rw-r--r--module/zfs/sa.c35
2 files changed, 21 insertions, 16 deletions
diff --git a/module/icp/algs/modes/ccm.c b/module/icp/algs/modes/ccm.c
index 22aeb0a6a..fb41194f8 100644
--- a/module/icp/algs/modes/ccm.c
+++ b/module/icp/algs/modes/ccm.c
@@ -28,7 +28,7 @@
#include <sys/crypto/common.h>
#include <sys/crypto/impl.h>
-#if defined(__i386) || defined(__amd64)
+#ifdef HAVE_EFFICIENT_UNALIGNED_ACCESS
#include <sys/byteorder.h>
#define UNALIGNED_POINTERS_PERMITTED
#endif
diff --git a/module/zfs/sa.c b/module/zfs/sa.c
index 0ca33e80d..caa91bc4c 100644
--- a/module/zfs/sa.c
+++ b/module/zfs/sa.c
@@ -150,21 +150,26 @@ arc_byteswap_func_t sa_bswap_table[] = {
zfs_acl_byteswap,
};
-#define SA_COPY_DATA(f, s, t, l) \
- { \
- if (f == NULL) { \
- if (l == 8) { \
- *(uint64_t *)t = *(uint64_t *)s; \
- } else if (l == 16) { \
- *(uint64_t *)t = *(uint64_t *)s; \
- *(uint64_t *)((uintptr_t)t + 8) = \
- *(uint64_t *)((uintptr_t)s + 8); \
- } else { \
- bcopy(s, t, l); \
- } \
- } else \
- sa_copy_data(f, s, t, l); \
- }
+#ifdef HAVE_EFFICIENT_UNALIGNED_ACCESS
+#define SA_COPY_DATA(f, s, t, l) \
+do { \
+ if (f == NULL) { \
+ if (l == 8) { \
+ *(uint64_t *)t = *(uint64_t *)s; \
+ } else if (l == 16) { \
+ *(uint64_t *)t = *(uint64_t *)s; \
+ *(uint64_t *)((uintptr_t)t + 8) = \
+ *(uint64_t *)((uintptr_t)s + 8); \
+ } else { \
+ bcopy(s, t, l); \
+ } \
+ } else { \
+ sa_copy_data(f, s, t, l); \
+ } \
+} while (0)
+#else
+#define SA_COPY_DATA(f, s, t, l) sa_copy_data(f, s, t, l)
+#endif
/*
* This table is fixed and cannot be changed. Its purpose is to