Messages in this thread Patch in this message | | | From | Gao Xiang <> | Subject | [PATCH] lib/lz4: explicitly support in-place decompression | Date | Sun, 22 Nov 2020 03:10:24 +0800 |
| |
LZ4 final literal copy could be overlapped when doing in-place decompression, so it's unsafe to just use memcpy() on an optimized memcpy approach but memmove() instead.
Upstream LZ4 has updated this years ago [1] (and the impact is non-sensible [2]), this commit just synchronizes LZ4 upstream code to the kernel side as well.
It can be observed as EROFS in-place decompression failure on specific files when X86_FEATURE_ERMS is unsupported, memcpy() optimization of commit 59daa706fbec ("x86, mem: Optimize memcpy by avoiding memory false dependece") will be enabled then.
Currently most modern x86-CPUs support ERMS, these CPUs just use "rep movsb" approach so no problem at all. However, it can still be verified with forcely disabling ERMS feature...
arch/x86/lib/memcpy_64.S: ALTERNATIVE_2 "jmp memcpy_orig", "", X86_FEATURE_REP_GOOD, \ - "jmp memcpy_erms", X86_FEATURE_ERMS + "jmp memcpy_orig", X86_FEATURE_ERMS
We didn't observed any strange on arm64/arm platform before, but it really needs an update for sure considering this unsafe overlapping memcpy() behavior for LZ4 in-place decompression.
[1] https://github.com/lz4/lz4/commit/33cb8518ac385835cc17be9a770b27b40cd0e15b [2] https://github.com/lz4/lz4/pull/717#issuecomment-497818921 Cc: Yann Collet <yann.collet.73@gmail.com> Cc: Miao Xie <miaoxie@huawei.com> Cc: Chao Yu <yuchao0@huawei.com> Signed-off-by: Gao Xiang <hsiangkao@redhat.com> --- Hi Andrew,
Could you kindly consider picking this patch up, although the impact is EROFS but it touchs in-kernel lz4 library anyway...
Thanks, Gao Xiang
lib/lz4/lz4_decompress.c | 2 +- lib/lz4/lz4defs.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/lz4/lz4_decompress.c b/lib/lz4/lz4_decompress.c index 00cb0d0b73e1..fa88e13ef00b 100644 --- a/lib/lz4/lz4_decompress.c +++ b/lib/lz4/lz4_decompress.c @@ -263,7 +263,7 @@ static FORCE_INLINE int LZ4_decompress_generic( } } - LZ4_memcpy(op, ip, length); + LZ4_memmove(op, ip, length); ip += length; op += length; diff --git a/lib/lz4/lz4defs.h b/lib/lz4/lz4defs.h index c91dd96ef629..673bd206aa98 100644 --- a/lib/lz4/lz4defs.h +++ b/lib/lz4/lz4defs.h @@ -146,6 +146,7 @@ static FORCE_INLINE void LZ4_writeLE16(void *memPtr, U16 value) * environments. This is needed when decompressing the Linux Kernel, for example. */ #define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size) +#define LZ4_memmove(dst, src, size) __builtin_memmove(dst, src, size) static FORCE_INLINE void LZ4_copy8(void *dst, const void *src) { -- 2.18.4
| |