xz: Add ARM64 BCJ filter
Also omit a duplicated check for XZ_DEC_ARM in xz_private.h. A later commit updates lib/decompress_unxz.c to enable this filter for kernel decompression. lib/decompress_unxz.c is already used if CONFIG_EFI_ZBOOT=y && CONFIG_KERNEL_XZ=y. This filter can be used by Squashfs without modifications to the Squashfs kernel code (only needs support in userspace Squashfs-tools). Link: https://lkml.kernel.org/r/20240721133633.47721-12-lasse.collin@tukaani.org Signed-off-by: Lasse Collin <lasse.collin@tukaani.org> Reviewed-by: Sam James <sam@gentoo.org> Cc: Albert Ou <aou@eecs.berkeley.edu> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Emil Renner Berthing <emil.renner.berthing@canonical.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Herbert Xu <herbert@gondor.apana.org.au> Cc: Joel Stanley <joel@jms.id.au> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Jubin Zhong <zhongjubin@huawei.com> Cc: Jules Maselbas <jmaselbas@zdiv.net> Cc: Krzysztof Kozlowski <krzk@kernel.org> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Palmer Dabbelt <palmer@dabbelt.com> Cc: Paul Walmsley <paul.walmsley@sifive.com> Cc: Randy Dunlap <rdunlap@infradead.org> Cc: Rui Li <me@lirui.org> Cc: Simon Glass <sjg@chromium.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Will Deacon <will@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
bdfc041171
commit
4b62813f5e
3 changed files with 61 additions and 3 deletions
|
@ -30,6 +30,11 @@ config XZ_DEC_ARMTHUMB
|
|||
default y
|
||||
select XZ_DEC_BCJ
|
||||
|
||||
config XZ_DEC_ARM64
|
||||
bool "ARM64 BCJ filter decoder" if EXPERT
|
||||
default y
|
||||
select XZ_DEC_BCJ
|
||||
|
||||
config XZ_DEC_SPARC
|
||||
bool "SPARC BCJ filter decoder" if EXPERT
|
||||
default y
|
||||
|
|
|
@ -23,7 +23,8 @@ struct xz_dec_bcj {
|
|||
BCJ_IA64 = 6, /* Big or little endian */
|
||||
BCJ_ARM = 7, /* Little endian only */
|
||||
BCJ_ARMTHUMB = 8, /* Little endian only */
|
||||
BCJ_SPARC = 9 /* Big or little endian */
|
||||
BCJ_SPARC = 9, /* Big or little endian */
|
||||
BCJ_ARM64 = 10 /* AArch64 */
|
||||
} type;
|
||||
|
||||
/*
|
||||
|
@ -346,6 +347,47 @@ static size_t bcj_sparc(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef XZ_DEC_ARM64
|
||||
static size_t bcj_arm64(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
uint32_t instr;
|
||||
uint32_t addr;
|
||||
|
||||
size &= ~(size_t)3;
|
||||
|
||||
for (i = 0; i < size; i += 4) {
|
||||
instr = get_unaligned_le32(buf + i);
|
||||
|
||||
if ((instr >> 26) == 0x25) {
|
||||
/* BL instruction */
|
||||
addr = instr - ((s->pos + (uint32_t)i) >> 2);
|
||||
instr = 0x94000000 | (addr & 0x03FFFFFF);
|
||||
put_unaligned_le32(instr, buf + i);
|
||||
|
||||
} else if ((instr & 0x9F000000) == 0x90000000) {
|
||||
/* ADRP instruction */
|
||||
addr = ((instr >> 29) & 3) | ((instr >> 3) & 0x1FFFFC);
|
||||
|
||||
/* Only convert values in the range +/-512 MiB. */
|
||||
if ((addr + 0x020000) & 0x1C0000)
|
||||
continue;
|
||||
|
||||
addr -= (s->pos + (uint32_t)i) >> 12;
|
||||
|
||||
instr &= 0x9000001F;
|
||||
instr |= (addr & 3) << 29;
|
||||
instr |= (addr & 0x03FFFC) << 3;
|
||||
instr |= (0U - (addr & 0x020000)) & 0xE00000;
|
||||
|
||||
put_unaligned_le32(instr, buf + i);
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Apply the selected BCJ filter. Update *pos and s->pos to match the amount
|
||||
* of data that got filtered.
|
||||
|
@ -392,6 +434,11 @@ static void bcj_apply(struct xz_dec_bcj *s,
|
|||
case BCJ_SPARC:
|
||||
filtered = bcj_sparc(s, buf, size);
|
||||
break;
|
||||
#endif
|
||||
#ifdef XZ_DEC_ARM64
|
||||
case BCJ_ARM64:
|
||||
filtered = bcj_arm64(s, buf, size);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* Never reached but silence compiler warnings. */
|
||||
|
@ -565,6 +612,9 @@ XZ_EXTERN enum xz_ret xz_dec_bcj_reset(struct xz_dec_bcj *s, uint8_t id)
|
|||
#endif
|
||||
#ifdef XZ_DEC_SPARC
|
||||
case BCJ_SPARC:
|
||||
#endif
|
||||
#ifdef XZ_DEC_ARM64
|
||||
case BCJ_ARM64:
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
|
|
@ -36,6 +36,9 @@
|
|||
# ifdef CONFIG_XZ_DEC_SPARC
|
||||
# define XZ_DEC_SPARC
|
||||
# endif
|
||||
# ifdef CONFIG_XZ_DEC_ARM64
|
||||
# define XZ_DEC_ARM64
|
||||
# endif
|
||||
# ifdef CONFIG_XZ_DEC_MICROLZMA
|
||||
# define XZ_DEC_MICROLZMA
|
||||
# endif
|
||||
|
@ -97,9 +100,9 @@
|
|||
*/
|
||||
#ifndef XZ_DEC_BCJ
|
||||
# if defined(XZ_DEC_X86) || defined(XZ_DEC_POWERPC) \
|
||||
|| defined(XZ_DEC_IA64) || defined(XZ_DEC_ARM) \
|
||||
|| defined(XZ_DEC_IA64) \
|
||||
|| defined(XZ_DEC_ARM) || defined(XZ_DEC_ARMTHUMB) \
|
||||
|| defined(XZ_DEC_SPARC)
|
||||
|| defined(XZ_DEC_SPARC) || defined(XZ_DEC_ARM64)
|
||||
# define XZ_DEC_BCJ
|
||||
# endif
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue