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 <behlendorf1@llnl.gov>
Closes #7642 
Closes #7684
This commit is contained in:
Brian Behlendorf
2018-07-11 13:10:40 -07:00
committed by GitHub
parent 2dca37d8dc
commit 33a19e0fd9
4 changed files with 36 additions and 16 deletions
+20 -15
View File
@@ -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