Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Lasse Collin and committed by
Andrew Morton
4b62813f bdfc0411

+61 -3
+5
lib/xz/Kconfig
··· 30 30 default y 31 31 select XZ_DEC_BCJ 32 32 33 + config XZ_DEC_ARM64 34 + bool "ARM64 BCJ filter decoder" if EXPERT 35 + default y 36 + select XZ_DEC_BCJ 37 + 33 38 config XZ_DEC_SPARC 34 39 bool "SPARC BCJ filter decoder" if EXPERT 35 40 default y
+51 -1
lib/xz/xz_dec_bcj.c
··· 23 23 BCJ_IA64 = 6, /* Big or little endian */ 24 24 BCJ_ARM = 7, /* Little endian only */ 25 25 BCJ_ARMTHUMB = 8, /* Little endian only */ 26 - BCJ_SPARC = 9 /* Big or little endian */ 26 + BCJ_SPARC = 9, /* Big or little endian */ 27 + BCJ_ARM64 = 10 /* AArch64 */ 27 28 } type; 28 29 29 30 /* ··· 347 346 } 348 347 #endif 349 348 349 + #ifdef XZ_DEC_ARM64 350 + static size_t bcj_arm64(struct xz_dec_bcj *s, uint8_t *buf, size_t size) 351 + { 352 + size_t i; 353 + uint32_t instr; 354 + uint32_t addr; 355 + 356 + size &= ~(size_t)3; 357 + 358 + for (i = 0; i < size; i += 4) { 359 + instr = get_unaligned_le32(buf + i); 360 + 361 + if ((instr >> 26) == 0x25) { 362 + /* BL instruction */ 363 + addr = instr - ((s->pos + (uint32_t)i) >> 2); 364 + instr = 0x94000000 | (addr & 0x03FFFFFF); 365 + put_unaligned_le32(instr, buf + i); 366 + 367 + } else if ((instr & 0x9F000000) == 0x90000000) { 368 + /* ADRP instruction */ 369 + addr = ((instr >> 29) & 3) | ((instr >> 3) & 0x1FFFFC); 370 + 371 + /* Only convert values in the range +/-512 MiB. */ 372 + if ((addr + 0x020000) & 0x1C0000) 373 + continue; 374 + 375 + addr -= (s->pos + (uint32_t)i) >> 12; 376 + 377 + instr &= 0x9000001F; 378 + instr |= (addr & 3) << 29; 379 + instr |= (addr & 0x03FFFC) << 3; 380 + instr |= (0U - (addr & 0x020000)) & 0xE00000; 381 + 382 + put_unaligned_le32(instr, buf + i); 383 + } 384 + } 385 + 386 + return i; 387 + } 388 + #endif 389 + 350 390 /* 351 391 * Apply the selected BCJ filter. Update *pos and s->pos to match the amount 352 392 * of data that got filtered. ··· 433 391 #ifdef XZ_DEC_SPARC 434 392 case BCJ_SPARC: 435 393 filtered = bcj_sparc(s, buf, size); 394 + break; 395 + #endif 396 + #ifdef XZ_DEC_ARM64 397 + case BCJ_ARM64: 398 + filtered = bcj_arm64(s, buf, size); 436 399 break; 437 400 #endif 438 401 default: ··· 612 565 #endif 613 566 #ifdef XZ_DEC_SPARC 614 567 case BCJ_SPARC: 568 + #endif 569 + #ifdef XZ_DEC_ARM64 570 + case BCJ_ARM64: 615 571 #endif 616 572 break; 617 573
+5 -2
lib/xz/xz_private.h
··· 36 36 # ifdef CONFIG_XZ_DEC_SPARC 37 37 # define XZ_DEC_SPARC 38 38 # endif 39 + # ifdef CONFIG_XZ_DEC_ARM64 40 + # define XZ_DEC_ARM64 41 + # endif 39 42 # ifdef CONFIG_XZ_DEC_MICROLZMA 40 43 # define XZ_DEC_MICROLZMA 41 44 # endif ··· 100 97 */ 101 98 #ifndef XZ_DEC_BCJ 102 99 # if defined(XZ_DEC_X86) || defined(XZ_DEC_POWERPC) \ 103 - || defined(XZ_DEC_IA64) || defined(XZ_DEC_ARM) \ 100 + || defined(XZ_DEC_IA64) \ 104 101 || defined(XZ_DEC_ARM) || defined(XZ_DEC_ARMTHUMB) \ 105 - || defined(XZ_DEC_SPARC) 102 + || defined(XZ_DEC_SPARC) || defined(XZ_DEC_ARM64) 106 103 # define XZ_DEC_BCJ 107 104 # endif 108 105 #endif