diff options
author | Brian Behlendorf <[email protected]> | 2018-07-11 13:10:40 -0700 |
---|---|---|
committer | GitHub <[email protected]> | 2018-07-11 13:10:40 -0700 |
commit | 33a19e0fd9b22364d295351ea1bda57b80e39e85 (patch) | |
tree | 1a0bf9708376d1a00e64dd5f8e23eb3bbcb739b9 /module | |
parent | 2dca37d8dc13e6faf92c5a095d49dffd480c5b2d (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.c | 2 | ||||
-rw-r--r-- | module/zfs/sa.c | 35 |
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 |