code:
diff -urdN linux-4.14.40/Documentation/00-INDEX linux-4.14.40.new/Documentation/00-INDEX
--- linux-4.14.40/Documentation/00-INDEX	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/Documentation/00-INDEX	2018-06-12 11:49:20.000000000 +0200
@@ -260,6 +260,8 @@
 	- info on creator of above logo & site to get additional images from.
 lsm.txt
 	- Linux Security Modules: General Security Hooks for Linux
+lzip.txt
+	- info on lzip compression for the linux kernel.
 lzo.txt
 	- kernel LZO decompressor input formats
 m68k/
diff -urdN linux-4.14.40/Documentation/dontdiff linux-4.14.40.new/Documentation/dontdiff
--- linux-4.14.40/Documentation/dontdiff	2018-05-09 21:29:35.000000000 +0200
+++ linux-4.14.40.new/Documentation/dontdiff	2018-06-12 11:49:20.000000000 +0200
@@ -26,6 +26,7 @@
 *.ll
 *.log
 *.lst
+*.lz
 *.lzma
 *.lzo
 *.mo
diff -urdN linux-4.14.40/Documentation/filesystems/squashfs.txt linux-4.14.40.new/Documentation/filesystems/squashfs.txt
--- linux-4.14.40/Documentation/filesystems/squashfs.txt	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/Documentation/filesystems/squashfs.txt	2018-06-20 19:31:56.000000000 +0200
@@ -2,7 +2,7 @@
 =======================

 Squashfs is a compressed read-only filesystem for Linux.
-It uses zlib, lz4, lzo, or xz compression to compress files, inodes and
+It uses zlib, lz4, lzip, lzo, or xz compression to compress files, inodes and
 directories.  Inodes in the system are very small and all blocks are packed to
 minimise data overhead. Block sizes greater than 4K are supported up to a
 maximum of 1Mbytes (default block size 128K).
diff -urdN linux-4.14.40/Documentation/lzip.txt linux-4.14.40.new/Documentation/lzip.txt
--- linux-4.14.40/Documentation/lzip.txt	1970-01-01 01:00:00.000000000 +0100
+++ linux-4.14.40.new/Documentation/lzip.txt	2018-07-08 14:03:38.000000000 +0200
@@ -0,0 +1,59 @@
+==============================
+Lzip data compression in Linux
+==============================
+
+Introduction
+============
+
+Lzip is a lossless data compressor with a user interface similar to the
+one of gzip or bzip2. Lzip can compress about as fast as gzip (lzip -0),
+or compress most files more than bzip2 (lzip -9). Decompression speed is
+intermediate between gzip and bzip2. Lzip implements the LZMA algorithm.
+
+Lzip has been designed, written and tested with great care to be the
+standard general-purpose compressor for unix-like systems. The lzip
+format is as simple as possible (but not simpler). It provides accurate
+and robust 3 factor integrity checking.
+
+Learn more about lzip at http://www.nongnu.org/lzip/lzip.html
+
+Lzip related components in the kernel
+=====================================
+
+The lzip_decompress module in lib/lzip.c provides a versatile lzip
+decompression function able to do buffer to buffer decompression or
+stream decompression with fill and flush callback functions. The usage
+of the function is documented in include/linux/lzip.h.
+
+For decompressing the kernel image, initramfs, and initrd, there is a
+wrapper function in lib/decompress_lunzip.c providing the same common
+interface as the other decompress_*.c files, which is defined in
+include/linux/decompress/generic.h.
+
+For kernel makefiles, two commands are provided in scripts/Makefile.lib
+for use with $(call if_changed). The kernel image must be compressed
+with $(call if_changed,klzip) which will append a four-byte trailer
+containing the size of the uncompressed data, which is needed by the
+boot code. Other things should be compressed with $(call if_changed,lzip).
+
+Testing
+=======
+
+Lzip-compressed kernel images of multiple linux versions since 2.6.30.10
+have been built and tested, even on machines as modest as an AMD 486-DX2
+at 66 MHz with 64 MiB of RAM. In the worst case (on the slow machine
+above), lzip just increased the boot time a 15% compared with gzip. On
+more modern machines, lzip may boot slightly faster than gzip. It just
+takes 0.2 seconds for lzip to decompress vmlinuz-4.4.16 on my machine.
+
+Decompression time is usually a small fraction of the total boot time.
+For example, using lz4 on a desktop machine in order to save 0.05
+seconds of a total boot time of 20 seconds is probably not worth the
+increased image size.
+
+Xlunzip is a test tool for the lzip_decompress module. It is similar to
+lunzip, but it uses the lzip_decompress module as a backend. The xlunzip
+home page is at http://www.nongnu.org/lzip/xlunzip.html
+
+Author: Antonio Diaz Diaz
+Updated: 2018-07-08
diff -urdN linux-4.14.40/Documentation/x86/boot.txt linux-4.14.40.new/Documentation/x86/boot.txt
--- linux-4.14.40/Documentation/x86/boot.txt	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/Documentation/x86/boot.txt	2018-06-12 11:49:20.000000000 +0200
@@ -665,10 +665,10 @@
   The payload may be compressed. The format of both the compressed and
   uncompressed data should be determined using the standard magic
   numbers.  The currently supported compression formats are gzip
-  (magic numbers 1F 8B or 1F 9E), bzip2 (magic number 42 5A), LZMA
-  (magic number 5D 00), XZ (magic number FD 37), and LZ4 (magic number
-  02 21).  The uncompressed payload is currently always ELF (magic
-  number 7F 45 4C 46).
+  (magic numbers 1F 8B or 1F 9E), bzip2 (magic number 42 5A), lzip
+  (magic number 4C 5A), LZMA (magic number 5D 00), XZ (magic number FD
+  37), and LZ4 (magic number 02 21).  The uncompressed payload is
+  currently always ELF (magic number 7F 45 4C 46).

 Field name:	payload_length
 Type:		read
diff -urdN linux-4.14.40/Makefile linux-4.14.40.new/Makefile
--- linux-4.14.40/Makefile	2018-05-09 21:27:55.000000000 +0200
+++ linux-4.14.40.new/Makefile	2018-06-12 11:49:20.000000000 +0200
@@ -908,14 +908,17 @@
 export mod_strip_cmd

 # CONFIG_MODULE_COMPRESS, if defined, will cause module to be compressed
-# after they are installed in agreement with CONFIG_MODULE_COMPRESS_GZIP
-# or CONFIG_MODULE_COMPRESS_XZ.
+# after they are installed in agreement with CONFIG_MODULE_COMPRESS_GZIP,
+# CONFIG_MODULE_COMPRESS_LZIP or CONFIG_MODULE_COMPRESS_XZ.

 mod_compress_cmd = true
 ifdef CONFIG_MODULE_COMPRESS
   ifdef CONFIG_MODULE_COMPRESS_GZIP
     mod_compress_cmd = gzip -n -f
   endif # CONFIG_MODULE_COMPRESS_GZIP
+  ifdef CONFIG_MODULE_COMPRESS_LZIP
+    mod_compress_cmd = lzip -f
+  endif # CONFIG_MODULE_COMPRESS_LZIP
   ifdef CONFIG_MODULE_COMPRESS_XZ
     mod_compress_cmd = xz -f
   endif # CONFIG_MODULE_COMPRESS_XZ
@@ -927,6 +930,7 @@
 #
 INITRD_COMPRESS-y                  := gzip
 INITRD_COMPRESS-$(CONFIG_RD_BZIP2) := bzip2
+INITRD_COMPRESS-$(CONFIG_RD_LZIP)  := lzip
 INITRD_COMPRESS-$(CONFIG_RD_LZMA)  := lzma
 INITRD_COMPRESS-$(CONFIG_RD_XZ)    := xz
 INITRD_COMPRESS-$(CONFIG_RD_LZO)   := lzo
diff -urdN linux-4.14.40/arch/arm/Kconfig linux-4.14.40.new/arch/arm/Kconfig
--- linux-4.14.40/arch/arm/Kconfig	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/arm/Kconfig	2018-06-12 11:49:20.000000000 +0200
@@ -72,6 +72,7 @@
 	select HAVE_IRQ_TIME_ACCOUNTING
 	select HAVE_KERNEL_GZIP
 	select HAVE_KERNEL_LZ4
+	select HAVE_KERNEL_LZIP
 	select HAVE_KERNEL_LZMA
 	select HAVE_KERNEL_LZO
 	select HAVE_KERNEL_XZ
diff -urdN linux-4.14.40/arch/arm/boot/compressed/Makefile linux-4.14.40.new/arch/arm/boot/compressed/Makefile
--- linux-4.14.40/arch/arm/boot/compressed/Makefile	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/arm/boot/compressed/Makefile	2018-06-12 11:49:20.000000000 +0200
@@ -68,6 +68,7 @@
 CPPFLAGS_vmlinux.lds := -DTEXT_START="$(ZTEXTADDR)" -DBSS_START="$(ZBSSADDR)"

 compress-$(CONFIG_KERNEL_GZIP) = gzip
+compress-$(CONFIG_KERNEL_LZIP) = klzip
 compress-$(CONFIG_KERNEL_LZO)  = lzo
 compress-$(CONFIG_KERNEL_LZMA) = lzma
 compress-$(CONFIG_KERNEL_XZ)   = xzkern
diff -urdN linux-4.14.40/arch/arm/boot/compressed/decompress.c linux-4.14.40.new/arch/arm/boot/compressed/decompress.c
--- linux-4.14.40/arch/arm/boot/compressed/decompress.c	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/arm/boot/compressed/decompress.c	2018-06-12 11:49:20.000000000 +0200
@@ -40,6 +40,10 @@
 #include "../../../../lib/decompress_inflate.c"
 #endif

+#ifdef CONFIG_KERNEL_LZIP
+#include "../../../../lib/decompress_lunzip.c"
+#endif
+
 #ifdef CONFIG_KERNEL_LZO
 #include "../../../../lib/decompress_unlzo.c"
 #endif
diff -urdN linux-4.14.40/arch/blackfin/Kconfig linux-4.14.40.new/arch/blackfin/Kconfig
--- linux-4.14.40/arch/blackfin/Kconfig	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/blackfin/Kconfig	2018-06-12 11:49:20.000000000 +0200
@@ -22,6 +22,7 @@
 	select HAVE_IDE
 	select HAVE_KERNEL_GZIP if RAMKERNEL
 	select HAVE_KERNEL_BZIP2 if RAMKERNEL
+	select HAVE_KERNEL_LZIP if RAMKERNEL
 	select HAVE_KERNEL_LZMA if RAMKERNEL
 	select HAVE_KERNEL_LZO if RAMKERNEL
 	select HAVE_OPROFILE
diff -urdN linux-4.14.40/arch/blackfin/Makefile linux-4.14.40.new/arch/blackfin/Makefile
--- linux-4.14.40/arch/blackfin/Makefile	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/blackfin/Makefile	2018-06-12 11:49:20.000000000 +0200
@@ -141,7 +141,8 @@

 INSTALL_PATH ?= /tftpboot
 boot := arch/$(ARCH)/boot
-BOOT_TARGETS = uImage uImage.bin uImage.bz2 uImage.gz uImage.lzma uImage.lzo uImage.xip
+BOOT_TARGETS = uImage uImage.bin uImage.bz2 uImage.gz uImage.lz uImage.lzma \
+	       uImage.lzo uImage.xip
 PHONY += $(BOOT_TARGETS) install
 KBUILD_IMAGE := $(boot)/uImage

@@ -158,6 +159,7 @@
   echo  '  vmImage.bin     - Uncompressed Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.bin)'
   echo  '  vmImage.bz2     - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.bz2)'
   echo  '* vmImage.gz      - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.gz)'
+  echo  '  vmImage.lz      - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.lz)'
   echo  '  vmImage.lzma    - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.lzma)'
   echo  '  vmImage.lzo     - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.lzo)'
   echo  '  vmImage.xip     - XIP Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.xip)'
diff -urdN linux-4.14.40/arch/blackfin/boot/Makefile linux-4.14.40.new/arch/blackfin/boot/Makefile
--- linux-4.14.40/arch/blackfin/boot/Makefile	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/blackfin/boot/Makefile	2018-06-12 11:49:20.000000000 +0200
@@ -6,8 +6,10 @@
 # for more details.
 #

-targets := uImage uImage.bin uImage.bz2 uImage.gz uImage.lzma uImage.lzo uImage.xip
-extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.lzo vmlinux.bin.xip
+targets := uImage uImage.bin uImage.bz2 uImage.gz uImage.lz uImage.lzma \
+	   uImage.lzo uImage.xip
+extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lz \
+	   vmlinux.bin.lzma vmlinux.bin.lzo vmlinux.bin.xip

 ifeq ($(CONFIG_RAMKERNEL),y)
 UIMAGE_LOADADDR = $(CONFIG_BOOT_LOAD)
@@ -27,6 +29,9 @@
 $(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
 	$(call if_changed,bzip2)

+$(obj)/vmlinux.bin.lz: $(obj)/vmlinux.bin FORCE
+	$(call if_changed,klzip)
+
 $(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
 	$(call if_changed,lzma)

@@ -48,6 +53,9 @@
 $(obj)/uImage.gz: $(obj)/vmlinux.bin.gz
 	$(call if_changed,uimage,gzip)

+$(obj)/uImage.lz: $(obj)/vmlinux.bin.lz
+	$(call if_changed,uimage,lzip)
+
 $(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma
 	$(call if_changed,uimage,lzma)

@@ -60,6 +68,7 @@
 suffix-y                      := bin
 suffix-$(CONFIG_KERNEL_GZIP)  := gz
 suffix-$(CONFIG_KERNEL_BZIP2) := bz2
+suffix-$(CONFIG_KERNEL_LZIP)  := lz
 suffix-$(CONFIG_KERNEL_LZMA)  := lzma
 suffix-$(CONFIG_KERNEL_LZO)   := lzo
 suffix-$(CONFIG_ROMKERNEL)    := xip
diff -urdN linux-4.14.40/arch/m32r/Kconfig linux-4.14.40.new/arch/m32r/Kconfig
--- linux-4.14.40/arch/m32r/Kconfig	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/m32r/Kconfig	2018-06-12 11:49:20.000000000 +0200
@@ -7,6 +7,7 @@
 	select INIT_ALL_POSSIBLE
 	select HAVE_KERNEL_GZIP
 	select HAVE_KERNEL_BZIP2
+	select HAVE_KERNEL_LZIP
 	select HAVE_KERNEL_LZMA
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select HAVE_DEBUG_BUGVERBOSE
diff -urdN linux-4.14.40/arch/m32r/boot/compressed/Makefile linux-4.14.40.new/arch/m32r/boot/compressed/Makefile
--- linux-4.14.40/arch/m32r/boot/compressed/Makefile	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/m32r/boot/compressed/Makefile	2018-06-12 11:49:20.000000000 +0200
@@ -5,8 +5,8 @@
 # create a compressed vmlinux image from the original vmlinux
 #

-targets		:= vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 \
-		   vmlinux.bin.lzma head.o misc.o piggy.o vmlinux.lds
+targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 \
+	   vmlinux.bin.lz vmlinux.bin.lzma head.o misc.o piggy.o vmlinux.lds

 OBJECTS = $(obj)/head.o $(obj)/misc.o

@@ -30,6 +30,9 @@
 $(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
 	$(call if_changed,bzip2)

+$(obj)/vmlinux.bin.lz: $(obj)/vmlinux.bin FORCE
+	$(call if_changed,klzip)
+
 $(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
 	$(call if_changed,lzma)

@@ -45,6 +48,7 @@

 suffix-$(CONFIG_KERNEL_GZIP)	= gz
 suffix-$(CONFIG_KERNEL_BZIP2)	= bz2
+suffix-$(CONFIG_KERNEL_LZIP)	= lz
 suffix-$(CONFIG_KERNEL_LZMA)	= lzma

 $(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) FORCE
diff -urdN linux-4.14.40/arch/m32r/boot/compressed/misc.c linux-4.14.40.new/arch/m32r/boot/compressed/misc.c
--- linux-4.14.40/arch/m32r/boot/compressed/misc.c	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/m32r/boot/compressed/misc.c	2018-06-12 11:49:20.000000000 +0200
@@ -39,7 +39,7 @@
 }
 #endif

-#ifdef CONFIG_KERNEL_GZIP
+#if defined(CONFIG_KERNEL_GZIP) || defined(CONFIG_KERNEL_LZIP)
 void *memcpy(void *dest, const void *src, size_t n)
 {
 	char *d = dest;
@@ -49,7 +49,9 @@

 	return dest;
 }
+#endif

+#ifdef CONFIG_KERNEL_GZIP
 #define BOOT_HEAP_SIZE             0x10000
 #include "../../../../lib/decompress_inflate.c"
 #endif
@@ -59,6 +61,11 @@
 #include "../../../../lib/decompress_bunzip2.c"
 #endif

+#ifdef CONFIG_KERNEL_LZIP
+#define BOOT_HEAP_SIZE             0x10000
+#include "../../../../lib/decompress_lunzip.c"
+#endif
+
 #ifdef CONFIG_KERNEL_LZMA
 #define BOOT_HEAP_SIZE             0x10000
 #include "../../../../lib/decompress_unlzma.c"
diff -urdN linux-4.14.40/arch/metag/Kconfig linux-4.14.40.new/arch/metag/Kconfig
--- linux-4.14.40/arch/metag/Kconfig	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/metag/Kconfig	2018-06-12 11:49:20.000000000 +0200
@@ -17,6 +17,7 @@
 	select HAVE_FUNCTION_TRACER
 	select HAVE_KERNEL_BZIP2
 	select HAVE_KERNEL_GZIP
+	select HAVE_KERNEL_LZIP
 	select HAVE_KERNEL_LZO
 	select HAVE_KERNEL_XZ
 	select HAVE_MEMBLOCK
diff -urdN linux-4.14.40/arch/metag/Makefile linux-4.14.40.new/arch/metag/Makefile
--- linux-4.14.40/arch/metag/Makefile	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/metag/Makefile	2018-06-12 11:49:20.000000000 +0200
@@ -56,6 +56,7 @@
 boot_targets				+= uImage
 boot_targets				+= uImage.gz
 boot_targets				+= uImage.bz2
+boot_targets				+= uImage.lz
 boot_targets				+= uImage.xz
 boot_targets				+= uImage.lzo
 boot_targets				+= uImage.bin
@@ -83,6 +84,7 @@
   @echo '  uImage.bin	- Kernel-only image for U-Boot (bin)'
   @echo '  uImage.gz	- Kernel-only image for U-Boot (gzip)'
   @echo '  uImage.bz2	- Kernel-only image for U-Boot (bzip2)'
+  @echo '  uImage.lz	- Kernel-only image for U-Boot (lzip)'
   @echo '  uImage.xz	- Kernel-only image for U-Boot (xz)'
   @echo '  uImage.lzo	- Kernel-only image for U-Boot (lzo)'
   @echo '  dtbs		- Build device tree blobs for enabled boards'
diff -urdN linux-4.14.40/arch/metag/boot/Makefile linux-4.14.40.new/arch/metag/boot/Makefile
--- linux-4.14.40/arch/metag/boot/Makefile	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/metag/boot/Makefile	2018-06-12 11:49:20.000000000 +0200
@@ -9,6 +9,7 @@
 suffix-y := bin
 suffix-$(CONFIG_KERNEL_GZIP)	:= gz
 suffix-$(CONFIG_KERNEL_BZIP2)	:= bz2
+suffix-$(CONFIG_KERNEL_LZIP)	:= lz
 suffix-$(CONFIG_KERNEL_XZ)	:= xz
 suffix-$(CONFIG_KERNEL_LZO)	:= lzo

@@ -16,6 +17,7 @@
 targets += uImage
 targets += uImage.gz
 targets += uImage.bz2
+targets += uImage.lz
 targets += uImage.xz
 targets += uImage.lzo
 targets += uImage.bin
@@ -23,6 +25,7 @@
 extra-y += vmlinux.bin
 extra-y += vmlinux.bin.gz
 extra-y += vmlinux.bin.bz2
+extra-y += vmlinux.bin.lz
 extra-y += vmlinux.bin.xz
 extra-y += vmlinux.bin.lzo

@@ -42,6 +45,9 @@
 $(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
 	$(call if_changed,bzip2)

+$(obj)/vmlinux.bin.lz: $(obj)/vmlinux.bin FORCE
+	$(call if_changed,klzip)
+
 $(obj)/vmlinux.bin.xz: $(obj)/vmlinux.bin FORCE
 	$(call if_changed,xzkern)

@@ -54,6 +60,9 @@
 $(obj)/uImage.bz2: $(obj)/vmlinux.bin.bz2 FORCE
 	$(call if_changed,uimage,bzip2)

+$(obj)/uImage.lz: $(obj)/vmlinux.bin.lz FORCE
+	$(call if_changed,uimage,lzip)
+
 $(obj)/uImage.xz: $(obj)/vmlinux.bin.xz FORCE
 	$(call if_changed,uimage,xz)

diff -urdN linux-4.14.40/arch/mips/Kconfig linux-4.14.40.new/arch/mips/Kconfig
--- linux-4.14.40/arch/mips/Kconfig	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/mips/Kconfig	2018-06-12 11:49:20.000000000 +0200
@@ -1820,6 +1820,7 @@
 	select HAVE_KERNEL_GZIP
 	select HAVE_KERNEL_BZIP2
 	select HAVE_KERNEL_LZ4
+	select HAVE_KERNEL_LZIP
 	select HAVE_KERNEL_LZMA
 	select HAVE_KERNEL_LZO
 	select HAVE_KERNEL_XZ
diff -urdN linux-4.14.40/arch/mips/Makefile linux-4.14.40.new/arch/mips/Makefile
--- linux-4.14.40/arch/mips/Makefile	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/mips/Makefile	2018-06-12 11:49:20.000000000 +0200
@@ -338,12 +338,14 @@
 boot-y			+= uImage.bin
 boot-y			+= uImage.bz2
 boot-y			+= uImage.gz
+boot-y			+= uImage.lz
 boot-y			+= uImage.lzma
 boot-y			+= uImage.lzo
 endif
 boot-y			+= vmlinux.itb
 boot-y			+= vmlinux.gz.itb
 boot-y			+= vmlinux.bz2.itb
+boot-y			+= vmlinux.lz.itb
 boot-y			+= vmlinux.lzma.itb
 boot-y			+= vmlinux.lzo.itb

@@ -454,6 +456,7 @@
 	echo '  uImage.bin           - U-Boot image (uncompressed)'
 	echo '  uImage.bz2           - U-Boot image (bz2)'
 	echo '  uImage.gz            - U-Boot image (gzip)'
+	echo '  uImage.lz            - U-Boot image (lzip)'
 	echo '  uImage.lzma          - U-Boot image (lzma)'
 	echo '  uImage.lzo           - U-Boot image (lzo)'
 	echo '  uzImage.bin          - U-Boot image (self-extracting)'
diff -urdN linux-4.14.40/arch/mips/boot/Makefile linux-4.14.40.new/arch/mips/boot/Makefile
--- linux-4.14.40/arch/mips/boot/Makefile	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/mips/boot/Makefile	2018-06-12 11:49:20.000000000 +0200
@@ -26,6 +26,7 @@
 suffix-y			:= bin
 suffix-$(CONFIG_KERNEL_BZIP2)	:= bz2
 suffix-$(CONFIG_KERNEL_GZIP)	:= gz
+suffix-$(CONFIG_KERNEL_LZIP)	:= lz
 suffix-$(CONFIG_KERNEL_LZMA)	:= lzma
 suffix-$(CONFIG_KERNEL_LZO)	:= lzo

@@ -56,6 +57,7 @@

 extra-y += vmlinux.bin.bz2
 extra-y += vmlinux.bin.gz
+extra-y += vmlinux.bin.lz
 extra-y += vmlinux.bin.lzma
 extra-y += vmlinux.bin.lzo

@@ -65,6 +67,9 @@
 $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
 	$(call if_changed,gzip)

+$(obj)/vmlinux.bin.lz: $(obj)/vmlinux.bin FORCE
+	$(call if_changed,klzip)
+
 $(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
 	$(call if_changed,lzma)

@@ -79,6 +84,7 @@
 targets += uImage.bin
 targets += uImage.bz2
 targets += uImage.gz
+targets += uImage.lz
 targets += uImage.lzma
 targets += uImage.lzo

@@ -91,6 +97,9 @@
 $(obj)/uImage.gz: $(obj)/vmlinux.bin.gz FORCE
 	$(call if_changed,uimage,gzip)

+$(obj)/uImage.lz: $(obj)/vmlinux.bin.lz FORCE
+	$(call if_changed,uimage,lzip)
+
 $(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma FORCE
 	$(call if_changed,uimage,lzma)

@@ -108,6 +117,7 @@
 targets += vmlinux.itb
 targets += vmlinux.gz.itb
 targets += vmlinux.bz2.itb
+targets += vmlinux.lz.itb
 targets += vmlinux.lzma.itb
 targets += vmlinux.lzo.itb

@@ -144,6 +154,9 @@
 $(obj)/vmlinux.bz2.its: $(obj)/vmlinux.its.S $(VMLINUX)  FORCE
 	$(call if_changed_dep,cpp_its_S,bzip2,vmlinux.bin.bz2)

+$(obj)/vmlinux.lz.its: $(obj)/vmlinux.its.S $(VMLINUX) FORCE
+	$(call if_changed_dep,cpp_its_S,lzip,vmlinux.bin.lz)
+
 $(obj)/vmlinux.lzma.its: $(obj)/vmlinux.its.S $(VMLINUX) FORCE
 	$(call if_changed_dep,cpp_its_S,lzma,vmlinux.bin.lzma)

@@ -168,6 +181,9 @@
 $(obj)/vmlinux.bz2.itb: $(obj)/vmlinux.bz2.its $(obj)/vmlinux.bin.bz2 FORCE
 	$(call if_changed,itb-image,$<)

+$(obj)/vmlinux.lz.itb: $(obj)/vmlinux.lz.its $(obj)/vmlinux.bin.lz FORCE
+	$(call if_changed,itb-image,$<)
+
 $(obj)/vmlinux.lzma.itb: $(obj)/vmlinux.lzma.its $(obj)/vmlinux.bin.lzma FORCE
 	$(call if_changed,itb-image,$<)

diff -urdN linux-4.14.40/arch/mips/boot/compressed/Makefile linux-4.14.40.new/arch/mips/boot/compressed/Makefile
--- linux-4.14.40/arch/mips/boot/compressed/Makefile	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/mips/boot/compressed/Makefile	2018-06-12 11:49:20.000000000 +0200
@@ -61,6 +61,7 @@
 tool_$(CONFIG_KERNEL_GZIP)    = gzip
 tool_$(CONFIG_KERNEL_BZIP2)   = bzip2
 tool_$(CONFIG_KERNEL_LZ4)     = lz4
+tool_$(CONFIG_KERNEL_LZIP)    = klzip
 tool_$(CONFIG_KERNEL_LZMA)    = lzma
 tool_$(CONFIG_KERNEL_LZO)     = lzo
 tool_$(CONFIG_KERNEL_XZ)      = xzkern
diff -urdN linux-4.14.40/arch/mips/boot/compressed/decompress.c linux-4.14.40.new/arch/mips/boot/compressed/decompress.c
--- linux-4.14.40/arch/mips/boot/compressed/decompress.c	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/mips/boot/compressed/decompress.c	2018-06-12 11:49:20.000000000 +0200
@@ -64,6 +64,10 @@
 #include "../../../../lib/decompress_unlz4.c"
 #endif

+#ifdef CONFIG_KERNEL_LZIP
+#include "../../../../lib/decompress_lunzip.c"
+#endif
+
 #ifdef CONFIG_KERNEL_LZMA
 #include "../../../../lib/decompress_unlzma.c"
 #endif
diff -urdN linux-4.14.40/arch/s390/Kconfig linux-4.14.40.new/arch/s390/Kconfig
--- linux-4.14.40/arch/s390/Kconfig	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/s390/Kconfig	2018-06-12 11:49:20.000000000 +0200
@@ -152,6 +152,7 @@
 	select HAVE_KERNEL_BZIP2
 	select HAVE_KERNEL_GZIP
 	select HAVE_KERNEL_LZ4
+	select HAVE_KERNEL_LZIP
 	select HAVE_KERNEL_LZMA
 	select HAVE_KERNEL_LZO
 	select HAVE_KERNEL_XZ
diff -urdN linux-4.14.40/arch/s390/boot/compressed/Makefile linux-4.14.40.new/arch/s390/boot/compressed/Makefile
--- linux-4.14.40/arch/s390/boot/compressed/Makefile	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/s390/boot/compressed/Makefile	2018-06-12 11:49:20.000000000 +0200
@@ -7,9 +7,9 @@

 KCOV_INSTRUMENT := n

-targets	:= vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2
-targets += vmlinux.bin.xz vmlinux.bin.lzma vmlinux.bin.lzo vmlinux.bin.lz4
-targets += misc.o piggy.o sizes.h head.o
+targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2
+targets += vmlinux.bin.lz vmlinux.bin.xz vmlinux.bin.lzma vmlinux.bin.lzo
+targets += vmlinux.bin.lz4 misc.o piggy.o sizes.h head.o

 KBUILD_CFLAGS := -m64 -D__KERNEL__ -O2
 KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
@@ -51,6 +51,7 @@
 suffix-$(CONFIG_KERNEL_GZIP)  := gz
 suffix-$(CONFIG_KERNEL_BZIP2) := bz2
 suffix-$(CONFIG_KERNEL_LZ4)  := lz4
+suffix-$(CONFIG_KERNEL_LZIP)  := lz
 suffix-$(CONFIG_KERNEL_LZMA)  := lzma
 suffix-$(CONFIG_KERNEL_LZO)  := lzo
 suffix-$(CONFIG_KERNEL_XZ)  := xz
@@ -61,6 +62,8 @@
 	$(call if_changed,bzip2)
 $(obj)/vmlinux.bin.lz4: $(vmlinux.bin.all-y)
 	$(call if_changed,lz4)
+$(obj)/vmlinux.bin.lz: $(vmlinux.bin.all-y)
+	$(call if_changed,klzip)
 $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y)
 	$(call if_changed,lzma)
 $(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y)
diff -urdN linux-4.14.40/arch/s390/boot/compressed/misc.c linux-4.14.40.new/arch/s390/boot/compressed/misc.c
--- linux-4.14.40/arch/s390/boot/compressed/misc.c	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/s390/boot/compressed/misc.c	2018-06-12 11:49:20.000000000 +0200
@@ -53,6 +53,10 @@
 #include "../../../../lib/decompress_unlz4.c"
 #endif

+#ifdef CONFIG_KERNEL_LZIP
+#include "../../../../lib/decompress_lunzip.c"
+#endif
+
 #ifdef CONFIG_KERNEL_LZMA
 #include "../../../../lib/decompress_unlzma.c"
 #endif
diff -urdN linux-4.14.40/arch/sh/Kconfig linux-4.14.40.new/arch/sh/Kconfig
--- linux-4.14.40/arch/sh/Kconfig	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/sh/Kconfig	2018-06-12 11:49:20.000000000 +0200
@@ -24,6 +24,7 @@
 	select HAVE_KERNEL_GZIP
 	select CPU_NO_EFFICIENT_FFS
 	select HAVE_KERNEL_BZIP2
+	select HAVE_KERNEL_LZIP
 	select HAVE_KERNEL_LZMA
 	select HAVE_KERNEL_XZ
 	select HAVE_KERNEL_LZO
diff -urdN linux-4.14.40/arch/sh/Makefile linux-4.14.40.new/arch/sh/Makefile
--- linux-4.14.40/arch/sh/Makefile	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/sh/Makefile	2018-06-12 11:49:20.000000000 +0200
@@ -205,9 +205,9 @@
 libs-$(CONFIG_SUPERH32)		:= arch/sh/lib/	$(libs-y)
 libs-$(CONFIG_SUPERH64)		:= arch/sh/lib64/ $(libs-y)

-BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.xz uImage.lzo \
-	       uImage.srec uImage.bin zImage vmlinux.bin vmlinux.srec \
-	       romImage
+BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lz uImage.lzma uImage.xz \
+	       uImage.lzo uImage.srec uImage.bin zImage vmlinux.bin \
+	       vmlinux.srec romImage
 PHONY += $(BOOT_TARGETS)

 all: $(notdir $(KBUILD_IMAGE))
@@ -234,6 +234,7 @@
 	@echo '  uImage.bin	           - Kernel-only image for U-Boot (bin)'
 	@echo '* uImage.gz	           - Kernel-only image for U-Boot (gzip)'
 	@echo '  uImage.bz2	           - Kernel-only image for U-Boot (bzip2)'
+	@echo '  uImage.lz	           - Kernel-only image for U-Boot (lzip)'
 	@echo '  uImage.lzma	           - Kernel-only image for U-Boot (lzma)'
 	@echo '  uImage.xz	           - Kernel-only image for U-Boot (xz)'
 	@echo '  uImage.lzo	           - Kernel-only image for U-Boot (lzo)'
diff -urdN linux-4.14.40/arch/sh/boot/Makefile linux-4.14.40.new/arch/sh/boot/Makefile
--- linux-4.14.40/arch/sh/boot/Makefile	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/sh/boot/Makefile	2018-06-12 11:49:20.000000000 +0200
@@ -22,14 +22,15 @@
 suffix-y := bin
 suffix-$(CONFIG_KERNEL_GZIP)	:= gz
 suffix-$(CONFIG_KERNEL_BZIP2)	:= bz2
+suffix-$(CONFIG_KERNEL_LZIP)	:= lz
 suffix-$(CONFIG_KERNEL_LZMA)	:= lzma
 suffix-$(CONFIG_KERNEL_XZ)	:= xz
 suffix-$(CONFIG_KERNEL_LZO)	:= lzo

 targets := zImage vmlinux.srec romImage uImage uImage.srec uImage.gz \
-	   uImage.bz2 uImage.lzma uImage.xz uImage.lzo uImage.bin
-extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \
-	   vmlinux.bin.xz vmlinux.bin.lzo
+	   uImage.bz2 uImage.lz uImage.lzma uImage.xz uImage.lzo uImage.bin
+extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lz \
+	   vmlinux.bin.lzma vmlinux.bin.xz vmlinux.bin.lzo
 subdir- := compressed romimage

 $(obj)/zImage: $(obj)/compressed/vmlinux FORCE
@@ -71,6 +72,9 @@
 $(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
 	$(call if_changed,bzip2)

+$(obj)/vmlinux.bin.lz: $(obj)/vmlinux.bin FORCE
+	$(call if_changed,klzip)
+
 $(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
 	$(call if_changed,lzma)

@@ -86,6 +90,9 @@
 $(obj)/uImage.gz: $(obj)/vmlinux.bin.gz
 	$(call if_changed,uimage,gzip)

+$(obj)/uImage.lz: $(obj)/vmlinux.bin.lz
+	$(call if_changed,uimage,lzip)
+
 $(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma
 	$(call if_changed,uimage,lzma)

diff -urdN linux-4.14.40/arch/sh/boot/compressed/Makefile linux-4.14.40.new/arch/sh/boot/compressed/Makefile
--- linux-4.14.40/arch/sh/boot/compressed/Makefile	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/sh/boot/compressed/Makefile	2018-06-12 11:49:20.000000000 +0200
@@ -5,10 +5,9 @@
 # create a compressed vmlinux image from the original vmlinux
 #

-targets		:= vmlinux vmlinux.bin vmlinux.bin.gz \
-		   vmlinux.bin.bz2 vmlinux.bin.lzma \
-		   vmlinux.bin.xz vmlinux.bin.lzo \
-		   head_$(BITS).o misc.o piggy.o
+targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 \
+	   vmlinux.bin.lz vmlinux.bin.lzma vmlinux.bin.xz vmlinux.bin.lzo \
+	   head_$(BITS).o misc.o piggy.o

 OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/cache.o

@@ -66,6 +65,8 @@
 	$(call if_changed,gzip)
 $(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE
 	$(call if_changed,bzip2)
+$(obj)/vmlinux.bin.lz: $(vmlinux.bin.all-y) FORCE
+	$(call if_changed,klzip)
 $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE
 	$(call if_changed,lzma)
 $(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y) FORCE
diff -urdN linux-4.14.40/arch/sh/boot/compressed/misc.c linux-4.14.40.new/arch/sh/boot/compressed/misc.c
--- linux-4.14.40/arch/sh/boot/compressed/misc.c	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/sh/boot/compressed/misc.c	2018-06-12 11:49:20.000000000 +0200
@@ -58,6 +58,10 @@
 #include "../../../../lib/decompress_bunzip2.c"
 #endif

+#ifdef CONFIG_KERNEL_LZIP
+#include "../../../../lib/decompress_lunzip.c"
+#endif
+
 #ifdef CONFIG_KERNEL_LZMA
 #include "../../../../lib/decompress_unlzma.c"
 #endif
diff -urdN linux-4.14.40/arch/unicore32/.gitignore linux-4.14.40.new/arch/unicore32/.gitignore
--- linux-4.14.40/arch/unicore32/.gitignore	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/unicore32/.gitignore	2018-06-12 11:49:20.000000000 +0200
@@ -17,5 +17,9 @@
 #
 boot/compressed/piggy.S
 boot/compressed/piggy.gzip
+boot/compressed/piggy.bz2
+boot/compressed/piggy.lzip
+boot/compressed/piggy.lzma
+boot/compressed/piggy.lzo
 boot/compressed/vmlinux
 boot/compressed/vmlinux.lds
diff -urdN linux-4.14.40/arch/unicore32/Kconfig linux-4.14.40.new/arch/unicore32/Kconfig
--- linux-4.14.40/arch/unicore32/Kconfig	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/unicore32/Kconfig	2018-06-12 11:49:20.000000000 +0200
@@ -8,6 +8,7 @@
 	select HAVE_GENERIC_DMA_COHERENT
 	select HAVE_KERNEL_GZIP
 	select HAVE_KERNEL_BZIP2
+	select HAVE_KERNEL_LZIP
 	select GENERIC_ATOMIC64
 	select HAVE_KERNEL_LZO
 	select HAVE_KERNEL_LZMA
diff -urdN linux-4.14.40/arch/unicore32/boot/compressed/Makefile linux-4.14.40.new/arch/unicore32/boot/compressed/Makefile
--- linux-4.14.40/arch/unicore32/boot/compressed/Makefile	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/unicore32/boot/compressed/Makefile	2018-06-12 11:49:20.000000000 +0200
@@ -23,6 +23,7 @@
 # piggy.S and piggy.o
 suffix_$(CONFIG_KERNEL_GZIP)	:= gzip
 suffix_$(CONFIG_KERNEL_BZIP2)	:= bz2
+suffix_$(CONFIG_KERNEL_LZIP)	:= lzip
 suffix_$(CONFIG_KERNEL_LZO)	:= lzo
 suffix_$(CONFIG_KERNEL_LZMA)	:= lzma

@@ -36,10 +37,10 @@
 $(obj)/piggy.o:  $(obj)/piggy.$(suffix_y) $(obj)/piggy.S FORCE

 targets		:= vmlinux vmlinux.lds font.o font.c head.o misc.o \
-			piggy.$(suffix_y) piggy.o piggy.S \
+			piggy.$(suffix_y) piggy.o piggy.S

 # Make sure files are removed during clean
-extra-y		+= piggy.gzip piggy.bz2 piggy.lzo piggy.lzma
+extra-y		+= piggy.gzip piggy.bz2 piggy.lzip piggy.lzo piggy.lzma

 # ?
 LDFLAGS_vmlinux += -p
diff -urdN linux-4.14.40/arch/unicore32/boot/compressed/misc.c linux-4.14.40.new/arch/unicore32/boot/compressed/misc.c
--- linux-4.14.40/arch/unicore32/boot/compressed/misc.c	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/unicore32/boot/compressed/misc.c	2018-06-12 11:49:20.000000000 +0200
@@ -95,6 +95,10 @@
 #include "../../../../lib/decompress_bunzip2.c"
 #endif

+#ifdef CONFIG_KERNEL_LZIP
+#include "../../../../lib/decompress_lunzip.c"
+#endif
+
 #ifdef CONFIG_KERNEL_LZO
 #include "../../../../lib/decompress_unlzo.c"
 #endif
diff -urdN linux-4.14.40/arch/x86/Kconfig linux-4.14.40.new/arch/x86/Kconfig
--- linux-4.14.40/arch/x86/Kconfig	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/x86/Kconfig	2018-06-12 11:49:20.000000000 +0200
@@ -148,6 +148,7 @@
 	select HAVE_KERNEL_BZIP2
 	select HAVE_KERNEL_GZIP
 	select HAVE_KERNEL_LZ4
+	select HAVE_KERNEL_LZIP
 	select HAVE_KERNEL_LZMA
 	select HAVE_KERNEL_LZO
 	select HAVE_KERNEL_XZ
diff -urdN linux-4.14.40/arch/x86/boot/compressed/Makefile linux-4.14.40.new/arch/x86/boot/compressed/Makefile
--- linux-4.14.40/arch/x86/boot/compressed/Makefile	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/x86/boot/compressed/Makefile	2018-06-12 11:49:20.000000000 +0200
@@ -23,8 +23,8 @@
 # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
 KCOV_INSTRUMENT		:= n

-targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \
-	vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4
+targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lz \
+	   vmlinux.bin.lzma vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4

 KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ -O2
 KBUILD_CFLAGS += -fno-strict-aliasing $(call cc-option, -fPIE, -fPIC)
@@ -127,6 +127,8 @@
 	$(call if_changed,gzip)
 $(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE
 	$(call if_changed,bzip2)
+$(obj)/vmlinux.bin.lz: $(vmlinux.bin.all-y) FORCE
+	$(call if_changed,klzip)
 $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE
 	$(call if_changed,lzma)
 $(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y) FORCE
@@ -138,6 +140,7 @@

 suffix-$(CONFIG_KERNEL_GZIP)	:= gz
 suffix-$(CONFIG_KERNEL_BZIP2)	:= bz2
+suffix-$(CONFIG_KERNEL_LZIP)	:= lz
 suffix-$(CONFIG_KERNEL_LZMA)	:= lzma
 suffix-$(CONFIG_KERNEL_XZ)	:= xz
 suffix-$(CONFIG_KERNEL_LZO) 	:= lzo
diff -urdN linux-4.14.40/arch/x86/boot/compressed/misc.c linux-4.14.40.new/arch/x86/boot/compressed/misc.c
--- linux-4.14.40/arch/x86/boot/compressed/misc.c	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/arch/x86/boot/compressed/misc.c	2018-06-12 11:49:20.000000000 +0200
@@ -60,6 +60,10 @@
 #include "../../../../lib/decompress_bunzip2.c"
 #endif

+#ifdef CONFIG_KERNEL_LZIP
+#include "../../../../lib/decompress_lunzip.c"
+#endif
+
 #ifdef CONFIG_KERNEL_LZMA
 #include "../../../../lib/decompress_unlzma.c"
 #endif
diff -urdN linux-4.14.40/fs/squashfs/Kconfig linux-4.14.40.new/fs/squashfs/Kconfig
--- linux-4.14.40/fs/squashfs/Kconfig	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/fs/squashfs/Kconfig	2018-06-23 02:28:50.000000000 +0200
@@ -4,7 +4,7 @@
 	help
 	  Saying Y here includes support for SquashFS 4.0 (a Compressed
 	  Read-Only File System).  Squashfs is a highly compressed read-only
-	  filesystem for Linux.  It uses zlib, lzo or xz compression to
+	  filesystem for Linux.  It uses zlib, lzip, lzo or xz compression to
 	  compress both files, inodes and directories.  Inodes in the system
 	  are very small and all blocks are packed to minimise data overhead.
 	  Block sizes greater than 4K are supported up to a maximum of 1 Mbytes
@@ -134,6 +134,21 @@
 	  file systems will be readable without selecting this option.

 	  If unsure, say N.
+
+config SQUASHFS_LZIP
+	bool "Include support for LZIP compressed file systems"
+	depends on SQUASHFS
+	select LZIP_DECOMPRESS
+	help
+	  Saying Y here includes support for reading Squashfs file systems
+	  compressed with LZIP compression.  LZIP gives better compression
+	  than the default zlib compression, at the expense of greater CPU
+	  and memory overhead.
+
+	  LZIP is not the standard compression used in Squashfs and so most
+	  file systems will be readable without selecting this option.
+
+	  If unsure, say N.

 config SQUASHFS_LZO
 	bool "Include support for LZO compressed file systems"
diff -urdN linux-4.14.40/fs/squashfs/Makefile linux-4.14.40.new/fs/squashfs/Makefile
--- linux-4.14.40/fs/squashfs/Makefile	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/fs/squashfs/Makefile	2018-06-20 19:31:56.000000000 +0200
@@ -13,6 +13,7 @@
 squashfs-$(CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU) += decompressor_multi_percpu.o
 squashfs-$(CONFIG_SQUASHFS_XATTR) += xattr.o xattr_id.o
 squashfs-$(CONFIG_SQUASHFS_LZ4) += lz4_wrapper.o
+squashfs-$(CONFIG_SQUASHFS_LZIP) += lzip_wrapper.o
 squashfs-$(CONFIG_SQUASHFS_LZO) += lzo_wrapper.o
 squashfs-$(CONFIG_SQUASHFS_XZ) += xz_wrapper.o
 squashfs-$(CONFIG_SQUASHFS_ZLIB) += zlib_wrapper.o
diff -urdN linux-4.14.40/fs/squashfs/decompressor.c linux-4.14.40.new/fs/squashfs/decompressor.c
--- linux-4.14.40/fs/squashfs/decompressor.c	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/fs/squashfs/decompressor.c	2018-06-20 19:31:56.000000000 +0200
@@ -47,6 +47,12 @@
 };
 #endif

+#ifndef CONFIG_SQUASHFS_LZIP
+static const struct squashfs_decompressor squashfs_lzip_comp_ops = {
+	NULL, NULL, NULL, NULL, LZIP_COMPRESSION, "lzip", 0
+};
+#endif
+
 #ifndef CONFIG_SQUASHFS_LZO
 static const struct squashfs_decompressor squashfs_lzo_comp_ops = {
 	NULL, NULL, NULL, NULL, LZO_COMPRESSION, "lzo", 0
@@ -78,6 +84,7 @@
 static const struct squashfs_decompressor *decompressor[] = {
 	&squashfs_zlib_comp_ops,
 	&squashfs_lz4_comp_ops,
+	&squashfs_lzip_comp_ops,
 	&squashfs_lzo_comp_ops,
 	&squashfs_xz_comp_ops,
 	&squashfs_lzma_unsupported_comp_ops,
diff -urdN linux-4.14.40/fs/squashfs/decompressor.h linux-4.14.40.new/fs/squashfs/decompressor.h
--- linux-4.14.40/fs/squashfs/decompressor.h	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/fs/squashfs/decompressor.h	2018-06-20 19:31:56.000000000 +0200
@@ -50,6 +50,10 @@
 extern const struct squashfs_decompressor squashfs_lz4_comp_ops;
 #endif

+#ifdef CONFIG_SQUASHFS_LZIP
+extern const struct squashfs_decompressor squashfs_lzip_comp_ops;
+#endif
+
 #ifdef CONFIG_SQUASHFS_LZO
 extern const struct squashfs_decompressor squashfs_lzo_comp_ops;
 #endif
diff -urdN linux-4.14.40/fs/squashfs/lzip_wrapper.c linux-4.14.40.new/fs/squashfs/lzip_wrapper.c
--- linux-4.14.40/fs/squashfs/lzip_wrapper.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-4.14.40.new/fs/squashfs/lzip_wrapper.c	2018-06-27 19:06:03.000000000 +0200
@@ -0,0 +1,129 @@
+/*
+ * Squashfs - a compressed read only filesystem for Linux
+ *
+ * Copyright (c) 2014
+ * Phillip Lougher <phillip@squashfs.org.uk>
+ * Copyright (C) 2018 Antonio Diaz Diaz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * lzip_wrapper.c
+ */
+
+#include <linux/buffer_head.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/lzip.h>
+
+#include "squashfs_fs.h"
+#include "squashfs_fs_sb.h"
+#include "squashfs.h"
+#include "decompressor.h"
+#include "page_actor.h"
+
+struct squashfs_lzip {
+	void *input;
+	void *output;
+};
+
+
+static void *lzip_init(struct squashfs_sb_info *msblk, void *buff)
+{
+	int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE);
+	struct squashfs_lzip *stream = kzalloc(sizeof(*stream), GFP_KERNEL);
+	if (stream == NULL)
+		goto failed;
+	stream->input = vmalloc(block_size);
+	if (stream->input == NULL)
+		goto failed2;
+	stream->output = vmalloc(block_size);
+	if (stream->output == NULL)
+		goto failed3;
+
+	return stream;
+
+failed3:
+	vfree(stream->input);
+failed2:
+	kfree(stream);
+failed:
+	ERROR("Failed to initialise LZIP decompressor\n");
+	return ERR_PTR(-ENOMEM);
+}
+
+
+static void lzip_free(void *strm)
+{
+	struct squashfs_lzip *stream = strm;
+
+	if (stream) {
+		vfree(stream->input);
+		vfree(stream->output);
+	}
+	kfree(stream);
+}
+
+
+static int lzip_uncompress(struct squashfs_sb_info *msblk, void *strm,
+	struct buffer_head **bh, int b, int offset, int length,
+	struct squashfs_page_actor *output)
+{
+	struct squashfs_lzip *stream = strm;
+	void *buff = stream->input, *data;
+	long out_pos;
+	int avail, i, bytes = length, res;
+
+	for (i = 0; i < b; i++) {
+		avail = min(bytes, msblk->devblksize - offset);
+		memcpy(buff, bh[i]->b_data + offset, avail);
+		buff += avail;
+		bytes -= avail;
+		offset = 0;
+		put_bh(bh[i]);
+	}
+
+	res = lzip_decompress(stream->input, length, 0, 0, stream->output,
+				output->length, 0, &out_pos);
+	if (res < 0) {
+		ERROR("LZIP error code %d\n", res);
+		return -EIO;
+	}
+	bytes = out_pos;
+	data = squashfs_first_page(output);
+	buff = stream->output;
+	while (data) {
+		if (bytes <= PAGE_SIZE) {
+			memcpy(data, buff, bytes);
+			break;
+		}
+		memcpy(data, buff, PAGE_SIZE);
+		buff += PAGE_SIZE;
+		bytes -= PAGE_SIZE;
+		data = squashfs_next_page(output);
+	}
+	squashfs_finish_page(output);
+
+	return out_pos;
+}
+
+
+const struct squashfs_decompressor squashfs_lzip_comp_ops = {
+	.init = lzip_init,
+	.free = lzip_free,
+	.decompress = lzip_uncompress,
+	.id = LZIP_COMPRESSION,
+	.name = "lzip",
+	.supported = 1
+};
diff -urdN linux-4.14.40/fs/squashfs/squashfs_fs.h linux-4.14.40.new/fs/squashfs/squashfs_fs.h
--- linux-4.14.40/fs/squashfs/squashfs_fs.h	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/fs/squashfs/squashfs_fs.h	2018-06-20 19:31:56.000000000 +0200
@@ -242,6 +242,7 @@
 #define XZ_COMPRESSION		4
 #define LZ4_COMPRESSION		5
 #define ZSTD_COMPRESSION	6
+#define LZIP_COMPRESSION	7

 struct squashfs_super_block {
 	__le32			s_magic;
diff -urdN linux-4.14.40/include/linux/decompress/lunzip.h linux-4.14.40.new/include/linux/decompress/lunzip.h
--- linux-4.14.40/include/linux/decompress/lunzip.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-4.14.40.new/include/linux/decompress/lunzip.h	2018-06-21 00:24:11.000000000 +0200
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef LINUX_DECOMPRESS_LUNZIP_H
+#define LINUX_DECOMPRESS_LUNZIP_H
+
+int lunzip(unsigned char *inbuf, long in_len,
+	   long (*fill)(void*, unsigned long),
+	   long (*flush)(void*, unsigned long),
+	   unsigned char *outbuf,
+	   long *in_posp,
+	   void (*error)(char *x));
+#endif
diff -urdN linux-4.14.40/include/linux/lzip.h linux-4.14.40.new/include/linux/lzip.h
--- linux-4.14.40/include/linux/lzip.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-4.14.40.new/include/linux/lzip.h	2018-07-02 14:06:03.000000000 +0200
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LZIP_H__
+#define __LZIP_H__
+/*
+ * LZIP decompressor
+ *
+ * Copyright (C) 2016-2018 Antonio Diaz Diaz.
+ */
+
+/* Return values (< 0 = Error) */
+enum {
+	LZIP_OOM_INBUF     = -1,
+	LZIP_HEADER1_EOF   = -2,
+	LZIP_HEADER2_EOF   = -3,
+	LZIP_BAD_MAGIC1    = -4,
+	LZIP_BAD_MAGIC2    = -5,
+	LZIP_BAD_VERSION   = -6,
+	LZIP_BAD_DICT_SIZE = -7,
+	LZIP_OOM_OUTBUF    = -8,
+	LZIP_WRITE_ERROR   = -9,
+	LZIP_BAD_DATA      = -10,
+	LZIP_DATA_EOF      = -11,
+	LZIP_BAD_CRC       = -12
+};
+
+int lzip_decompress(unsigned char *inbuf, long in_len,
+			long (*fill)(void*, unsigned long),
+			long (*flush)(void*, unsigned long),
+			unsigned char *outbuf, long out_size,
+			long *in_posp, long *out_posp);
+
+/* inbuf    - input buffer. If null or in_len <= 0, fill must be non-null
+ * in_len   - len of pre-read data in inbuf if inbuf is non-null
+ * fill     - if non-null, function to fill inbuf when empty
+ * flush    - if non-null, function to write out outbuf when full
+ * outbuf   - output buffer. If null or out_size <= 0, flush must be non-null
+ * out_size - size of outbuf if outbuf is non-null
+ * in_posp  - if non-null, the number of bytes consumed will be returned here
+ * out_posp - if non-null, the number of bytes produced will be returned here
+ *
+ * fill will be called (repeatedly) to read data. in_len bytes will be read
+ * per call (or 16384 bytes per call if inbuf is null or in_len <= 0).
+ *
+ * If flush is null, outbuf must be large enough to buffer all the expected
+ * output. Else the flush function will be called to flush the output buffer
+ * at the appropriate time (stream dependent).
+ * If out_size > 0 but is not large enough to buffer all the expected output,
+ * it must be at least as large as the dictionary size of the data.
+ *
+ * inbuf and outbuf may overlap (in-place decompression).
+ */
+
+#endif
diff -urdN linux-4.14.40/init/Kconfig linux-4.14.40.new/init/Kconfig
--- linux-4.14.40/init/Kconfig	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/init/Kconfig	2018-06-12 11:49:20.000000000 +0200
@@ -115,6 +115,9 @@
 config HAVE_KERNEL_BZIP2
 	bool

+config HAVE_KERNEL_LZIP
+	bool
+
 config HAVE_KERNEL_LZMA
 	bool

@@ -130,7 +133,7 @@
 choice
 	prompt "Kernel compression mode"
 	default KERNEL_GZIP
-	depends on HAVE_KERNEL_GZIP || HAVE_KERNEL_BZIP2 || HAVE_KERNEL_LZMA || HAVE_KERNEL_XZ || HAVE_KERNEL_LZO || HAVE_KERNEL_LZ4
+	depends on HAVE_KERNEL_GZIP || HAVE_KERNEL_BZIP2 || HAVE_KERNEL_LZIP || HAVE_KERNEL_LZMA || HAVE_KERNEL_XZ || HAVE_KERNEL_LZO || HAVE_KERNEL_LZ4
 	help
 	  The linux kernel is a kind of self-extracting executable.
 	  Several compression algorithms are available, which differ
@@ -166,6 +169,15 @@
 	  Bzip2 uses a large amount of memory. For modern kernels you
 	  will need at least 8MB RAM or more for booting.

+config KERNEL_LZIP
+	bool "Lzip"
+	depends on HAVE_KERNEL_LZIP
+	help
+	  Lzip's compression ratio is better than that of gzip and bzip2.
+	  Decompression speed is between gzip and bzip2.  Compression can
+	  be as fast as gzip or slower than bzip2 depending on compression
+	  level.  Lzip can produce a kernel about a 16% smaller than gzip.
+
 config KERNEL_LZMA
 	bool "LZMA"
 	depends on HAVE_KERNEL_LZMA
@@ -1834,8 +1846,8 @@
 	depends on MODULES
 	help

-	  Compresses kernel modules when 'make modules_install' is run; gzip or
-	  xz depending on "Compression algorithm" below.
+	  Compresses kernel modules when 'make modules_install' is run; gzip,
+	  lzip or xz are used depending on "Compression algorithm" below.

 	  module-init-tools MAY support gzip, and kmod MAY support gzip and xz.

@@ -1857,11 +1869,14 @@
 	  This determines which sort of compression will be used during
 	  'make modules_install'.

-	  GZIP (default) and XZ are supported.
+	  GZIP (default), LZIP and XZ are supported.

 config MODULE_COMPRESS_GZIP
 	bool "GZIP"

+config MODULE_COMPRESS_LZIP
+	bool "LZIP"
+
 config MODULE_COMPRESS_XZ
 	bool "XZ"

diff -urdN linux-4.14.40/init/do_mounts_rd.c linux-4.14.40.new/init/do_mounts_rd.c
--- linux-4.14.40/init/do_mounts_rd.c	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/init/do_mounts_rd.c	2018-06-12 11:49:20.000000000 +0200
@@ -59,6 +59,7 @@
  *	squashfs
  *	gzip
  *	bzip2
+ *	lzip
  *	lzma
  *	xz
  *	lzo
diff -urdN linux-4.14.40/lib/Kconfig linux-4.14.40.new/lib/Kconfig
--- linux-4.14.40/lib/Kconfig	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/lib/Kconfig	2018-06-23 14:05:29.000000000 +0200
@@ -234,6 +234,12 @@
 	tristate
 	select BITREVERSE

+config LZIP_DECOMPRESS
+	tristate "LZIP decompression support"
+	help
+	  LZMA compression algorithm is supported using the .lz file format.
+	  See Documentation/lzip.txt for more information.
+
 config LZO_COMPRESS
 	tristate

@@ -270,6 +276,10 @@
 config DECOMPRESS_BZIP2
 	tristate

+config DECOMPRESS_LZIP
+	select LZIP_DECOMPRESS
+	tristate
+
 config DECOMPRESS_LZMA
 	tristate

diff -urdN linux-4.14.40/lib/Makefile linux-4.14.40.new/lib/Makefile
--- linux-4.14.40/lib/Makefile	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/lib/Makefile	2018-06-23 02:28:50.000000000 +0200
@@ -113,6 +113,7 @@
 obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/
 obj-$(CONFIG_REED_SOLOMON) += reed_solomon/
 obj-$(CONFIG_BCH) += bch.o
+obj-$(CONFIG_LZIP_DECOMPRESS) += lzip.o
 obj-$(CONFIG_LZO_COMPRESS) += lzo/
 obj-$(CONFIG_LZO_DECOMPRESS) += lzo/
 obj-$(CONFIG_LZ4_COMPRESS) += lz4/
@@ -125,6 +126,7 @@

 lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o
 lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o
+lib-$(CONFIG_DECOMPRESS_LZIP) += decompress_lunzip.o
 lib-$(CONFIG_DECOMPRESS_LZMA) += decompress_unlzma.o
 lib-$(CONFIG_DECOMPRESS_XZ) += decompress_unxz.o
 lib-$(CONFIG_DECOMPRESS_LZO) += decompress_unlzo.o
diff -urdN linux-4.14.40/lib/decompress.c linux-4.14.40.new/lib/decompress.c
--- linux-4.14.40/lib/decompress.c	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/lib/decompress.c	2018-06-12 11:49:20.000000000 +0200
@@ -8,6 +8,7 @@
 #include <linux/decompress/generic.h>

 #include <linux/decompress/bunzip2.h>
+#include <linux/decompress/lunzip.h>
 #include <linux/decompress/unlzma.h>
 #include <linux/decompress/unxz.h>
 #include <linux/decompress/inflate.h>
@@ -25,6 +26,9 @@
 #ifndef CONFIG_DECOMPRESS_BZIP2
 # define bunzip2 NULL
 #endif
+#ifndef CONFIG_DECOMPRESS_LZIP
+# define lunzip NULL
+#endif
 #ifndef CONFIG_DECOMPRESS_LZMA
 # define unlzma NULL
 #endif
@@ -48,6 +52,7 @@
 	{ {0x1f, 0x8b}, "gzip", gunzip },
 	{ {0x1f, 0x9e}, "gzip", gunzip },
 	{ {0x42, 0x5a}, "bzip2", bunzip2 },
+	{ {0x4c, 0x5a}, "lzip", lunzip },
 	{ {0x5d, 0x00}, "lzma", unlzma },
 	{ {0xfd, 0x37}, "xz", unxz },
 	{ {0x89, 0x4c}, "lzo", unlzo },
diff -urdN linux-4.14.40/lib/decompress_lunzip.c linux-4.14.40.new/lib/decompress_lunzip.c
--- linux-4.14.40/lib/decompress_lunzip.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-4.14.40.new/lib/decompress_lunzip.c	2018-07-07 20:59:46.000000000 +0200
@@ -0,0 +1,100 @@
+/*
+ * Wrapper for decompressing LZIP-compressed kernel, initramfs, and initrd
+ *
+ * Copyright (C) 2016-2018 Antonio Diaz Diaz.
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
+
+#ifdef STATIC
+#define PREBOOT
+#include "lzip.c"
+#else
+#include <linux/lzip.h>
+#include <linux/decompress/lunzip.h>
+#include <linux/decompress/mm.h>
+#endif
+
+STATIC int INIT __lunzip(unsigned char *inbuf, long in_len,
+			long (*fill)(void*, unsigned long),
+			long (*flush)(void*, unsigned long),
+			unsigned char *outbuf, long out_size,
+			long *in_posp, long *out_posp,
+			void (*error)(char *x))
+{
+	const int retval = lzip_decompress(inbuf, in_len, fill, flush,
+					outbuf, out_size, in_posp, out_posp);
+	switch (retval) {
+	case 0: break;
+	case LZIP_OOM_INBUF:
+		error("Out of memory while allocating input buffer.");
+		break;
+	case LZIP_HEADER1_EOF:
+		error("File ends unexpectedly at member header.");
+		break;
+	case LZIP_HEADER2_EOF:
+		error("Truncated header in multimember file.");
+		break;
+	case LZIP_BAD_MAGIC1:
+		error("Bad magic number (file not in lzip format).");
+		break;
+	case LZIP_BAD_MAGIC2:
+		error("Corrupt header in multimember file.");
+		break;
+	case LZIP_BAD_VERSION:
+		error("Version of lzip member format not supported.");
+		break;
+	case LZIP_BAD_DICT_SIZE:
+		error("Invalid dictionary size in member header.");
+		break;
+	case LZIP_OOM_OUTBUF:
+		error("Out of memory while allocating output buffer.");
+		break;
+	case LZIP_WRITE_ERROR:
+		error("Write error.");
+		break;
+	case LZIP_BAD_DATA:
+		error("LZIP-compressed data is corrupt.");
+		break;
+	case LZIP_DATA_EOF:
+		error("LZIP-compressed data ends unexpectedly.");
+		break;
+	case LZIP_BAD_CRC:
+		error("CRC mismatch in LZIP-compressed data.");
+		break;
+	default:
+		error("Bug in the LZIP decompressor.");
+	}
+	return retval;
+}
+
+#ifndef PREBOOT
+/* decompress_fn (see linux/decompress/generic.h) should have an out_size
+ * argument to prevent overrunning outbuf in case of corruption of the
+ * compressed data.
+ */
+STATIC int INIT lunzip(unsigned char *inbuf, long in_len,
+			long (*fill)(void*, unsigned long),
+			long (*flush)(void*, unsigned long),
+			unsigned char *outbuf,
+			long *in_posp,
+			void (*error)(char *x))
+{
+	return __lunzip(inbuf, in_len, fill, flush, outbuf, LONG_MAX,
+			in_posp, 0, error);
+}
+#else
+STATIC int INIT __decompress(unsigned char *inbuf, long in_len,
+			long (*fill)(void*, unsigned long),
+			long (*flush)(void*, unsigned long),
+			unsigned char *outbuf, long out_size,
+			long *in_posp,
+			void (*error)(char *x))
+{
+/* Some archs pass out_size = 0 (to mean unlimited size), which is unsafe
+ * in case of corruption of the compressed data.
+ */
+	return __lunzip(inbuf, in_len - 4, fill, flush, outbuf,
+			out_size ? out_size : LONG_MAX, in_posp, 0, error);
+}
+#endif
diff -urdN linux-4.14.40/lib/lzip.c linux-4.14.40.new/lib/lzip.c
--- linux-4.14.40/lib/lzip.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-4.14.40.new/lib/lzip.c	2018-07-10 11:40:02.000000000 +0200
@@ -0,0 +1,881 @@
+/*
+ * LZIP decompressor
+ *
+ * Copyright (C) 2016-2018 Antonio Diaz Diaz.
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
+
+#include <linux/lzip.h>
+#include <linux/decompress/mm.h>
+
+/*
+ * STATIC_RW_DATA is used in the pre-boot environment on some architectures.
+ * See <linux/decompress/mm.h> for details.
+ */
+#ifndef STATIC_RW_DATA
+#define STATIC_RW_DATA static
+#endif
+
+typedef int State;
+
+enum { states = 12 };
+
+static inline bool St_is_char(const State st) { return st < 7; }
+
+static inline State St_set_char(const State st)
+{
+	STATIC_RW_DATA const State next[states] = { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 };
+	return next[st];
+}
+
+static inline State St_set_match(const State st)
+{
+	return ((st < 7) ? 7 : 10);
+}
+
+static inline State St_set_rep(const State st)
+{
+	return ((st < 7) ? 8 : 11);
+}
+
+static inline State St_set_short_rep(const State st)
+{
+	return ((st < 7) ? 9 : 11);
+}
+
+
+enum {
+	min_dictionary_bits = 12,
+	min_dictionary_size = 1 << min_dictionary_bits,
+	max_dictionary_bits = 29,
+	max_dictionary_size = 1 << max_dictionary_bits,
+	literal_context_bits = 3,
+	pos_state_bits = 2,
+	pos_states = 1 << pos_state_bits,
+	pos_state_mask = pos_states - 1,
+
+	len_states = 4,
+	dis_slot_bits = 6,
+	start_dis_model = 4,
+	end_dis_model = 14,
+	modeled_distances = 1 << (end_dis_model / 2),	/* 128 */
+	dis_align_bits = 4,
+	dis_align_size = 1 << dis_align_bits,
+
+	len_low_bits = 3,
+	len_mid_bits = 3,
+	len_high_bits = 8,
+	len_low_symbols = 1 << len_low_bits,
+	len_mid_symbols = 1 << len_mid_bits,
+	len_high_symbols = 1 << len_high_bits,
+	max_len_symbols = len_low_symbols + len_mid_symbols + len_high_symbols,
+
+	min_match_len = 2,					/* must be 2 */
+	max_match_len = min_match_len + max_len_symbols - 1,	/* 273 */
+	min_match_len_limit = 5
+};
+
+static inline int get_len_state(const int len)
+{
+	return min(len - min_match_len, len_states - 1);
+}
+
+static inline int get_lit_state(const uint8_t prev_byte)
+{
+	return (prev_byte >> (8 - literal_context_bits));
+}
+
+
+enum { bit_model_move_bits = 5,
+	bit_model_total_bits = 11,
+	bit_model_total = 1 << bit_model_total_bits
+};
+
+typedef int Bit_model;
+
+static inline void Bm_init(Bit_model * const probability)
+{
+	*probability = bit_model_total / 2;
+}
+
+static inline void Bm_array_init(Bit_model bm[], const int size)
+{
+	int i;
+
+	for (i = 0; i < size; ++i)
+		Bm_init(&bm[i]);
+}
+
+struct Len_model {
+	Bit_model choice1;
+	Bit_model choice2;
+	Bit_model bm_low[pos_states][len_low_symbols];
+	Bit_model bm_mid[pos_states][len_mid_symbols];
+	Bit_model bm_high[len_high_symbols];
+};
+
+static inline void Lm_init(struct Len_model * const lm)
+{
+	Bm_init(&lm->choice1);
+	Bm_init(&lm->choice2);
+	Bm_array_init(lm->bm_low[0], pos_states * len_low_symbols);
+	Bm_array_init(lm->bm_mid[0], pos_states * len_mid_symbols);
+	Bm_array_init(lm->bm_high, len_high_symbols);
+}
+
+
+/* Table of CRCs of all 8-bit messages. */
+STATIC_RW_DATA const uint32_t crc32[256] =
+  {
+  0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
+  0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
+  0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
+  0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
+  0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
+  0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
+  0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
+  0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
+  0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
+  0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
+  0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
+  0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
+  0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
+  0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
+  0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
+  0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
+  0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
+  0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
+  0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
+  0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
+  0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
+  0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
+  0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
+  0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
+  0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
+  0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
+  0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
+  0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
+  0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
+  0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
+  0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
+  0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
+  0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
+  0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
+  0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
+  0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
+  0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
+  0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
+  0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
+  0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
+  0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
+  0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
+  0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D };
+
+
+static inline void CRC32_update_buf(uint32_t * const crc,
+					const uint8_t * const buffer,
+					const long size)
+{
+	long i;
+	uint32_t c = *crc;
+
+	for (i = 0; i < size; ++i)
+		c = crc32[(c^buffer[i])&0xFF] ^ (c >> 8);
+	*crc = c;
+}
+
+
+STATIC_RW_DATA const uint8_t lzip_magic[4] = { 0x4C, 0x5A, 0x49, 0x50 }; /* "LZIP" */
+
+typedef uint8_t Lzip_header[6];		/* 0-3 magic bytes */
+					/*   4 version */
+					/*   5 coded_dict_size */
+enum { Lh_size = 6 };
+
+static inline bool Lh_verify_magic(const Lzip_header data)
+{
+	int i;
+
+	for (i = 0; i < 4; ++i)
+		if (data[i] != lzip_magic[i])
+			return false;
+	return true;
+}
+
+/* detect (truncated) header */
+static inline bool Lh_verify_prefix(const Lzip_header data, const int sz)
+{
+	int i;
+	for (i = 0; i < sz && i < 4; ++i)
+		if (data[i] != lzip_magic[i])
+			return false;
+	return (sz > 0);
+}
+
+/* detect corrupt header */
+static inline bool Lh_verify_corrupt(const Lzip_header data)
+{
+	int matches = 0;
+	int i;
+	for (i = 0; i < 4; ++i)
+		if (data[i] == lzip_magic[i])
+			++matches;
+	return (matches > 1 && matches < 4);
+}
+
+static inline bool Lh_verify_version(const Lzip_header data)
+{
+	return (data[4] == 1);
+}
+
+static inline unsigned Lh_get_dictionary_size(const Lzip_header data)
+{
+	unsigned sz = (1 << (data[5] & 0x1F));
+
+	if (sz > min_dictionary_size)
+		sz -= (sz / 16) * ((data[5] >> 5) & 7);
+	return sz;
+}
+
+
+typedef uint8_t Lzip_trailer[20];
+			/*  0-3  CRC32 of the uncompressed data */
+			/*  4-11 size of the uncompressed data */
+			/* 12-19 member size including header and trailer */
+enum { Lt_size = 20 };
+
+static inline unsigned Lt_get_data_crc(const Lzip_trailer data)
+{
+	unsigned tmp = 0;
+	int i;
+
+	for (i = 3; i >= 0; --i) {
+		tmp <<= 8;
+		tmp += data[i];
+	}
+	return tmp;
+}
+
+static inline unsigned long long Lt_get_data_size(const Lzip_trailer data)
+{
+	unsigned long long tmp = 0;
+	int i;
+
+	for (i = 11; i >= 4; --i) {
+		tmp <<= 8;
+		tmp += data[i];
+	}
+	return tmp;
+}
+
+static inline unsigned long long Lt_get_member_size(const Lzip_trailer data)
+{
+	unsigned long long tmp = 0;
+	int i;
+
+	for (i = 19; i >= 12; --i) {
+		tmp <<= 8;
+		tmp += data[i];
+	}
+	return tmp;
+}
+
+
+struct Range_decoder {
+	unsigned long long partial_member_pos;
+	uint8_t *buffer;	/* input buffer */
+	long buffer_size;
+	long pos;		/* current pos in buffer */
+	long stream_pos;	/* when reached, a new block must be read */
+	uint32_t code;
+	uint32_t range;
+	long (*fill)(void*, unsigned long);
+	bool at_stream_end;
+	bool buffer_given;
+};
+
+
+static bool Rd_read_block(struct Range_decoder * const rdec)
+{
+	if (!rdec->at_stream_end) {
+		rdec->stream_pos = rdec->fill ?
+			rdec->fill(rdec->buffer, rdec->buffer_size) : 0;
+		rdec->at_stream_end = (rdec->stream_pos < rdec->buffer_size);
+		rdec->partial_member_pos += rdec->pos;
+		rdec->pos = 0;
+	}
+	return rdec->pos < rdec->stream_pos;
+}
+
+
+static inline bool Rd_init(struct Range_decoder * const rdec,
+				uint8_t * const inbuf, const long in_len,
+				long (*fill)(void*, unsigned long))
+{
+	rdec->partial_member_pos = 0;
+	rdec->buffer_given = (inbuf && in_len > 0);
+	rdec->buffer_size = rdec->buffer_given ? in_len : 16384;
+	rdec->buffer = rdec->buffer_given ? inbuf : malloc(rdec->buffer_size);
+	if (!rdec->buffer)
+		return false;
+	rdec->pos = 0;
+	rdec->stream_pos = rdec->buffer_given ? in_len : 0;
+	rdec->code = 0;
+	rdec->range = 0xFFFFFFFFU;
+	rdec->fill = fill;
+	rdec->at_stream_end = false;
+	return true;
+}
+
+static inline void Rd_free(struct Range_decoder * const rdec)
+{
+	if (!rdec->buffer_given)
+		free(rdec->buffer);
+}
+
+static inline bool Rd_finished(struct Range_decoder * const rdec)
+{
+	return rdec->pos >= rdec->stream_pos && !Rd_read_block(rdec);
+}
+
+static inline unsigned long long
+Rd_member_position(const struct Range_decoder * const rdec)
+{
+	return rdec->partial_member_pos + rdec->pos;
+}
+
+static inline void Rd_reset_member_position(struct Range_decoder * const rdec)
+{
+	rdec->partial_member_pos = 0; rdec->partial_member_pos -= rdec->pos;
+}
+
+static inline uint8_t Rd_get_byte(struct Range_decoder * const rdec)
+{
+	/* 0xFF avoids decoder error if member is truncated at EOS marker */
+	if (Rd_finished(rdec))
+		return 0xFF;
+	return rdec->buffer[rdec->pos++];
+}
+
+static inline void Rd_load(struct Range_decoder * const rdec)
+{
+	int i;
+
+	rdec->code = 0;
+	for (i = 0; i < 5; ++i)
+		rdec->code = (rdec->code << 8) | Rd_get_byte(rdec);
+	rdec->range = 0xFFFFFFFFU;
+}
+
+static inline void Rd_normalize(struct Range_decoder * const rdec)
+{
+	if (rdec->range <= 0x00FFFFFFU) {
+		rdec->range <<= 8;
+		rdec->code = (rdec->code << 8) | Rd_get_byte(rdec);
+	}
+}
+
+static inline unsigned Rd_decode(struct Range_decoder * const rdec,
+				const int num_bits)
+{
+	unsigned symbol = 0;
+	int i;
+
+	for (i = num_bits; i > 0; --i) {
+		bool bit;
+
+		Rd_normalize(rdec);
+		rdec->range >>= 1;
+		/* symbol <<= 1; */
+		/* if(rdec->code >= rdec->range) { rdec->code -= rdec->range; symbol |= 1; } */
+		bit = (rdec->code >= rdec->range);
+		symbol = (symbol << 1) + bit;
+		rdec->code -= rdec->range & (0U - bit);
+	}
+	return symbol;
+}
+
+static inline unsigned Rd_decode_bit(struct Range_decoder * const rdec,
+					Bit_model * const probability)
+{
+	uint32_t bound;
+
+	Rd_normalize(rdec);
+	bound = (rdec->range >> bit_model_total_bits) * *probability;
+	if (rdec->code < bound) {
+		rdec->range = bound;
+		*probability += (bit_model_total - *probability) >> bit_model_move_bits;
+		return 0;
+	} else {
+		rdec->range -= bound;
+		rdec->code -= bound;
+		*probability -= *probability >> bit_model_move_bits;
+		return 1;
+	}
+}
+
+static inline unsigned Rd_decode_tree3(struct Range_decoder * const rdec,
+					Bit_model bm[])
+{
+	unsigned symbol = 1;
+
+	symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
+	symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
+	symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
+	return symbol & 7;
+}
+
+static inline unsigned Rd_decode_tree6(struct Range_decoder * const rdec,
+					Bit_model bm[])
+{
+	unsigned symbol = 1;
+
+	symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
+	symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
+	symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
+	symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
+	symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
+	symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
+	return symbol & 0x3F;
+}
+
+static inline unsigned Rd_decode_tree8(struct Range_decoder * const rdec,
+					Bit_model bm[])
+{
+	unsigned symbol = 1;
+	int i;
+
+	for (i = 0; i < 8; ++i)
+		symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
+	return symbol & 0xFF;
+}
+
+static inline unsigned
+Rd_decode_tree_reversed(struct Range_decoder * const rdec,
+			Bit_model bm[], const int num_bits)
+{
+	unsigned model = 1;
+	unsigned symbol = 0;
+	int i;
+
+	for (i = 0; i < num_bits; ++i) {
+		const unsigned bit = Rd_decode_bit(rdec, &bm[model]);
+
+		model = (model << 1) + bit;
+		symbol |= (bit << i);
+	}
+	return symbol;
+}
+
+static inline unsigned
+Rd_decode_tree_reversed4(struct Range_decoder * const rdec, Bit_model bm[])
+{
+	unsigned symbol = Rd_decode_bit(rdec, &bm[1]);
+	unsigned model = 2 + symbol;
+	unsigned bit = Rd_decode_bit(rdec, &bm[model]);
+
+	model = (model << 1) + bit; symbol |= (bit << 1);
+	bit = Rd_decode_bit(rdec, &bm[model]);
+	model = (model << 1) + bit; symbol |= (bit << 2);
+	symbol |= (Rd_decode_bit(rdec, &bm[model]) << 3);
+	return symbol;
+}
+
+static inline unsigned Rd_decode_matched(struct Range_decoder * const rdec,
+					Bit_model bm[], unsigned match_byte)
+{
+	unsigned symbol = 1;
+	unsigned mask = 0x100;
+
+	while (true) {
+		const unsigned match_bit = (match_byte <<= 1) & mask;
+		const unsigned bit = Rd_decode_bit(rdec, &bm[symbol+match_bit+mask]);
+
+		symbol = (symbol << 1) + bit;
+		if (symbol > 0xFF)
+			return symbol & 0xFF;
+		mask &= ~(match_bit ^ (bit << 8));	/* if( match_bit != bit ) mask = 0; */
+	}
+}
+
+static inline unsigned Rd_decode_len(struct Range_decoder * const rdec,
+						struct Len_model * const lm,
+						const int pos_state)
+{
+	if (Rd_decode_bit(rdec, &lm->choice1) == 0)
+		return Rd_decode_tree3(rdec, lm->bm_low[pos_state]);
+	if (Rd_decode_bit(rdec, &lm->choice2) == 0)
+		return len_low_symbols +
+			Rd_decode_tree3(rdec, lm->bm_mid[pos_state]);
+	return len_low_symbols + len_mid_symbols +
+		Rd_decode_tree8(rdec, lm->bm_high);
+}
+
+
+struct LZ_decoder {
+	unsigned long long partial_data_pos;
+	struct Range_decoder *rdec;
+	/* Don't move bm_* to LZd_decode_member; makes frame too large. */
+	Bit_model bm_literal[1 << literal_context_bits][0x300];
+	Bit_model bm_match[states][pos_states];
+	Bit_model bm_rep[states];
+	Bit_model bm_rep0[states];
+	Bit_model bm_rep1[states];
+	Bit_model bm_rep2[states];
+	Bit_model bm_len[states][pos_states];
+	Bit_model bm_dis_slot[len_states][1 << dis_slot_bits];
+	Bit_model bm_dis[modeled_distances-end_dis_model+1];
+	Bit_model bm_align[dis_align_size];
+	struct Len_model match_len_model;
+	struct Len_model rep_len_model;
+
+	unsigned long buffer_size;
+	unsigned dictionary_size;
+	uint8_t *buffer;	/* output buffer */
+	unsigned long pos;	/* current pos in buffer */
+	unsigned long stream_pos;	/* first byte not yet written to file */
+	uint32_t crc;
+	long (*flush)(void*, unsigned long);
+	bool pos_wrapped;
+	bool buffer_given;
+	bool write_error;
+};
+
+static void LZd_flush_data(struct LZ_decoder * const d)
+{
+	if (d->pos > d->stream_pos) {
+		const long size = d->pos - d->stream_pos;
+
+		CRC32_update_buf(&d->crc, d->buffer + d->stream_pos, size);
+		if ((d->flush &&
+		     d->flush(d->buffer + d->stream_pos, size) != size) ||
+		    (!d->flush && d->pos_wrapped))
+			d->write_error = true;
+		if (d->pos >= d->buffer_size) {
+			d->partial_data_pos += d->pos;
+			d->pos = 0;
+			d->pos_wrapped = true;
+		}
+		d->stream_pos = d->pos;
+	}
+}
+
+static inline uint8_t LZd_peek_prev(const struct LZ_decoder * const d)
+{
+	if (d->pos > 0)
+		return d->buffer[d->pos-1];
+	if (d->pos_wrapped)
+		return d->buffer[d->buffer_size-1];
+	return 0;			/* prev_byte of first byte */
+}
+
+static inline uint8_t LZd_peek(const struct LZ_decoder * const d,
+				const unsigned distance)
+{
+	const unsigned long i = ((d->pos > distance) ? 0 : d->buffer_size) +
+				d->pos - distance - 1;
+	return d->buffer[i];
+}
+
+static inline void LZd_put_byte(struct LZ_decoder * const d, const uint8_t b)
+{
+	d->buffer[d->pos] = b;
+	if (++d->pos >= d->buffer_size)
+		LZd_flush_data(d);
+}
+
+static inline void LZd_copy_block(struct LZ_decoder * const d,
+				const unsigned distance, unsigned len)
+{
+	unsigned long lpos = d->pos, i = lpos - distance - 1;
+	bool fast, fast2;
+
+	if (lpos > distance) {
+		fast = (len < d->buffer_size - lpos);
+		fast2 = (fast && len <= lpos - i);
+	} else {
+		i += d->buffer_size;
+		fast = (len < d->buffer_size - i);	/* (i == pos) may happen */
+		fast2 = (fast && len <= i - lpos);
+	}
+	if (fast) {				/* no wrap */
+		d->pos += len;
+		if (fast2)			/* no wrap, no overlap */
+			memcpy(d->buffer + lpos, d->buffer + i, len);
+		else
+			for (; len > 0; --len)
+				d->buffer[lpos++] = d->buffer[i++];
+	} else
+		for (; len > 0; --len) {
+			d->buffer[d->pos] = d->buffer[i];
+			if (++d->pos >= d->buffer_size)
+				LZd_flush_data(d);
+			if (++i >= d->buffer_size)
+				i = 0;
+		}
+}
+
+static inline bool LZd_init(struct LZ_decoder * const d,
+			struct Range_decoder * const rde,
+			const unsigned dict_size, uint8_t * const outbuf,
+			long out_size, long (*flush)(void*, unsigned long))
+{
+	d->partial_data_pos = 0;
+	d->rdec = rde;
+	Bm_array_init(d->bm_literal[0], (1 << literal_context_bits) * 0x300);
+	Bm_array_init(d->bm_match[0], states * pos_states);
+	Bm_array_init(d->bm_rep, states);
+	Bm_array_init(d->bm_rep0, states);
+	Bm_array_init(d->bm_rep1, states);
+	Bm_array_init(d->bm_rep2, states);
+	Bm_array_init(d->bm_len[0], states * pos_states);
+	Bm_array_init(d->bm_dis_slot[0], len_states * (1 << dis_slot_bits));
+	Bm_array_init(d->bm_dis, modeled_distances - end_dis_model + 1);
+	Bm_array_init(d->bm_align, dis_align_size);
+	Lm_init(&d->match_len_model);
+	Lm_init(&d->rep_len_model);
+
+	d->buffer_given = (outbuf && out_size > 0);
+	d->buffer_size = d->buffer_given ? out_size : dict_size;
+	d->dictionary_size = min_t(unsigned long, d->buffer_size, dict_size);
+	d->buffer = d->buffer_given ? outbuf : large_malloc(d->buffer_size);
+	if (!d->buffer)
+		return false;
+	d->pos = 0;
+	d->stream_pos = 0;
+	d->crc = 0xFFFFFFFFU;
+	d->flush = flush;
+	d->pos_wrapped = false;
+	d->write_error = false;
+	/* prev_byte of first byte; also for LZd_peek( 0 ) on corrupt file */
+	if (!d->buffer_given)		/* inbuf and outbuf may overlap */
+		d->buffer[d->buffer_size-1] = 0;
+	return true;
+}
+
+static inline void LZd_free(struct LZ_decoder * const d)
+{
+	if (!d->buffer_given)
+		large_free(d->buffer);
+}
+
+static inline unsigned LZd_crc(const struct LZ_decoder * const d)
+{
+	return d->crc ^ 0xFFFFFFFFU;
+}
+
+static inline unsigned long long
+LZd_data_position(const struct LZ_decoder * const d)
+{
+	return d->partial_data_pos + d->pos;
+}
+
+
+static bool LZd_verify_trailer(struct LZ_decoder * const d)
+{
+	Lzip_trailer trailer;
+	int i = 0;
+
+	while (i < Lt_size)
+		trailer[i++] = Rd_get_byte(d->rdec);
+
+	return (Lt_get_data_crc(trailer) == LZd_crc(d) &&
+		Lt_get_data_size(trailer) == LZd_data_position(d) &&
+		Lt_get_member_size(trailer) == Rd_member_position(d->rdec));
+}
+
+
+/* Return value: 0 = OK, < 0 = error (see <linux/lzip.h>). */
+static int LZd_decode_member(struct LZ_decoder * const d)
+{
+	struct Range_decoder * const rdec = d->rdec;
+	unsigned rep0 = 0;	/* rep[0-3] latest four distances */
+	unsigned rep1 = 0;	/* used for efficient coding of */
+	unsigned rep2 = 0;	/* repeated distances */
+	unsigned rep3 = 0;
+	State state = 0;
+
+	Rd_load(rdec);
+	while (!Rd_finished(rdec)) {
+		int len;
+		const int pos_state = LZd_data_position(d) & pos_state_mask;
+
+		if (Rd_decode_bit(rdec, &d->bm_match[state][pos_state]) == 0) {
+			/* literal byte */
+			Bit_model * const bm = d->bm_literal[get_lit_state(LZd_peek_prev(d))];
+
+			if (St_is_char(state)) {
+				state -= (state < 4) ? state : 3;
+				LZd_put_byte(d, Rd_decode_tree8(rdec, bm));
+			} else {
+				state -= (state < 10) ? 3 : 6;
+				LZd_put_byte(d, Rd_decode_matched(rdec, bm, LZd_peek(d, rep0)));
+			}
+		continue;
+		}
+		/* match or repeated match */
+		if (Rd_decode_bit(rdec, &d->bm_rep[state]) != 0) {
+			if (Rd_decode_bit(rdec, &d->bm_rep0[state]) == 0) {
+				if (Rd_decode_bit(rdec, &d->bm_len[state][pos_state]) == 0) {
+					state = St_set_short_rep(state);
+					LZd_put_byte(d, LZd_peek(d, rep0));
+					continue;
+				}
+			} else {
+				unsigned distance;
+
+				if (Rd_decode_bit(rdec, &d->bm_rep1[state]) == 0)
+					distance = rep1;
+				else {
+					if (Rd_decode_bit(rdec, &d->bm_rep2[state]) == 0)
+						distance = rep2;
+					else {
+						distance = rep3;
+						rep3 = rep2;
+					}
+					rep2 = rep1;
+				}
+				rep1 = rep0;
+				rep0 = distance;
+			}
+			state = St_set_rep(state);
+			len = min_match_len + Rd_decode_len(rdec, &d->rep_len_model, pos_state);
+		} else {			/* match */
+			unsigned distance;
+
+			len = min_match_len + Rd_decode_len(rdec, &d->match_len_model, pos_state);
+			distance = Rd_decode_tree6(rdec, d->bm_dis_slot[get_len_state(len)]);
+			if (distance >= start_dis_model) {
+				const unsigned dis_slot = distance;
+				const int direct_bits = (dis_slot >> 1) - 1;
+
+				distance = (2 | (dis_slot & 1)) << direct_bits;
+				if (dis_slot < end_dis_model)
+					distance += Rd_decode_tree_reversed(rdec,
+						d->bm_dis + (distance - dis_slot), direct_bits);
+				else {
+					distance +=
+					  Rd_decode(rdec, direct_bits - dis_align_bits) << dis_align_bits;
+					distance += Rd_decode_tree_reversed4(rdec, d->bm_align);
+					if (distance == 0xFFFFFFFFU) {	/* marker found */
+						Rd_normalize(rdec);
+						LZd_flush_data(d);
+						if (d->write_error)
+							return LZIP_WRITE_ERROR;
+						if (len == min_match_len) {	/* End Of Stream marker */
+							if (LZd_verify_trailer(d))
+								return 0;
+							else
+								return LZIP_BAD_CRC;
+						}
+						if (len == min_match_len + 1) {	/* Sync Flush marker */
+							Rd_load(rdec);
+							continue;
+						}
+						return LZIP_BAD_DATA;	/* unknown marker */
+					}
+				}
+			}
+			rep3 = rep2; rep2 = rep1; rep1 = rep0; rep0 = distance;
+			state = St_set_match(state);
+			if (rep0 >= d->dictionary_size ||
+			   (rep0 >= d->pos && !d->pos_wrapped)) {
+				LZd_flush_data(d);
+				return LZIP_BAD_DATA;
+			}
+		}
+		LZd_copy_block(d, rep0, len);
+	}
+	LZd_flush_data(d);
+	return LZIP_DATA_EOF;
+}
+
+
+int lzip_decompress(unsigned char *inbuf, long in_len,
+			long (*fill)(void*, unsigned long),
+			long (*flush)(void*, unsigned long),
+			unsigned char *outbuf, long out_size,
+			long *in_posp, long *out_posp)
+{
+	unsigned char *outptr = outbuf;
+	struct Range_decoder rdec;
+	struct LZ_decoder *decoder = 0;
+	int retval = 0;
+	bool first_member;
+
+	if (in_posp)
+		*in_posp = 0;
+	if (out_posp)
+		*out_posp = 0;
+
+	if (!Rd_init(&rdec, inbuf, in_len, fill))
+		return LZIP_OOM_INBUF;
+
+	for (first_member = true;; first_member = false) {
+		long data_pos;
+		int size;
+		unsigned dictionary_size;
+		Lzip_header header;
+
+		Rd_reset_member_position(&rdec);
+		for (size = 0; size < Lh_size && !Rd_finished(&rdec); ++size)
+			header[size] = Rd_get_byte(&rdec);
+		if (Rd_finished(&rdec)) {	/* End Of File */
+			if (first_member)
+				retval = LZIP_HEADER1_EOF;
+			else if (Lh_verify_prefix(header, size))
+				retval = LZIP_HEADER2_EOF;
+			break;
+		}
+		if (!Lh_verify_magic(header)) {
+			if (first_member)
+				retval = LZIP_BAD_MAGIC1;
+			else if (Lh_verify_corrupt(header))
+				retval = LZIP_BAD_MAGIC2;
+			break;
+		}
+		if (!Lh_verify_version(header)) {
+			retval = LZIP_BAD_VERSION;
+			break;
+		}
+		dictionary_size = Lh_get_dictionary_size(header);
+		if (dictionary_size < min_dictionary_size ||
+		    dictionary_size > max_dictionary_size) {
+			retval = LZIP_BAD_DICT_SIZE;
+			break;
+		}
+
+		if (!decoder)
+			decoder = malloc(sizeof *decoder);
+		if (!decoder || !LZd_init(decoder, &rdec, dictionary_size,
+					outptr, out_size, flush)) {
+			retval = LZIP_OOM_OUTBUF;
+			break;
+		}
+		retval = LZd_decode_member(decoder);
+		if (in_posp)
+			*in_posp += Rd_member_position(&rdec);
+		data_pos = LZd_data_position(decoder);
+		if (outptr)
+			outptr += data_pos;
+		if (out_posp)
+			*out_posp += data_pos;
+		if (out_size > 0)
+			out_size -= data_pos;
+		LZd_free(decoder);
+		if (retval != 0)
+			break;
+	}
+	if (decoder)
+		free(decoder);
+	Rd_free(&rdec);
+	return retval;
+}
+
+#ifndef STATIC
+EXPORT_SYMBOL_GPL(lzip_decompress);
+MODULE_DESCRIPTION("LZIP Decompressor");
+MODULE_AUTHOR("Antonio Diaz Diaz <antonio@gnu.org>");
+MODULE_LICENSE("GPL");
+#endif
diff -urdN linux-4.14.40/scripts/Makefile.lib linux-4.14.40.new/scripts/Makefile.lib
--- linux-4.14.40/scripts/Makefile.lib	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/scripts/Makefile.lib	2018-06-12 11:49:20.000000000 +0200
@@ -343,6 +343,21 @@
 	bzip2 -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
 	(rm -f $@ ; false)

+# Lzip
+# ---------------------------------------------------------------------------
+# The .lz format has the uncompressed size available at the end of the
+# file, but at offset (member_size - 16). So we append a gzip-style size.
+# Use klzip to compress the kernel image and lzip to compress other things.
+
+quiet_cmd_klzip = LZIP    $@
+cmd_klzip = (cat $(filter-out FORCE,$^) | \
+	lzip -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
+	(rm -f $@ ; false)
+
+quiet_cmd_lzip = LZIP    $@
+cmd_lzip = (cat $(filter-out FORCE,$^) | lzip -9) > $@ || \
+	(rm -f $@ ; false)
+
 # Lzma
 # ---------------------------------------------------------------------------

diff -urdN linux-4.14.40/scripts/extract-ikconfig linux-4.14.40.new/scripts/extract-ikconfig
--- linux-4.14.40/scripts/extract-ikconfig	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/scripts/extract-ikconfig	2018-06-12 11:49:20.000000000 +0200
@@ -59,6 +59,7 @@
 try_decompress '\037\213\010' xy    gunzip
 try_decompress '\3757zXZ\000' abcde unxz
 try_decompress 'BZh'          xy    bunzip2
+try_decompress 'LZIP'         xyz   'lzip -d'
 try_decompress '\135\0\0\0'   xxx   unlzma
 try_decompress '\211\114\132' xy    'lzop -d'
 try_decompress '\002\041\114\030' xyy 'lz4 -d -l'
diff -urdN linux-4.14.40/scripts/extract-vmlinux linux-4.14.40.new/scripts/extract-vmlinux
--- linux-4.14.40/scripts/extract-vmlinux	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/scripts/extract-vmlinux	2018-06-12 11:49:20.000000000 +0200
@@ -55,6 +55,7 @@
 try_decompress '\037\213\010' xy    gunzip
 try_decompress '\3757zXZ\000' abcde unxz
 try_decompress 'BZh'          xy    bunzip2
+try_decompress 'LZIP'         xyz   'lzip -d'
 try_decompress '\135\0\0\0'   xxx   unlzma
 try_decompress '\211\114\132' xy    'lzop -d'

diff -urdN linux-4.14.40/scripts/gen_initramfs_list.sh linux-4.14.40.new/scripts/gen_initramfs_list.sh
--- linux-4.14.40/scripts/gen_initramfs_list.sh	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/scripts/gen_initramfs_list.sh	2018-06-12 11:49:20.000000000 +0200
@@ -249,6 +249,9 @@
 		echo "$output_file" | grep -q "\.bz2$" \
                 && [ -x "`which bzip2 2> /dev/null`" ] \
                 && compr="bzip2 -9 -f"
+		echo "$output_file" | grep -q "\.lz$" \
+                && [ -x "`which lzip 2> /dev/null`" ] \
+                && compr="lzip -9 -f"
 		echo "$output_file" | grep -q "\.lzma$" \
                 && [ -x "`which lzma 2> /dev/null`" ] \
                 && compr="lzma -9 -f"
diff -urdN linux-4.14.40/scripts/package/Makefile linux-4.14.40.new/scripts/package/Makefile
--- linux-4.14.40/scripts/package/Makefile	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/scripts/package/Makefile	2018-06-12 11:49:20.000000000 +0200
@@ -123,8 +123,9 @@
 $(if $(findstring tar-src,$@),,                                     \
 $(if $(findstring bz2,$@),bzip2,                                    \
 $(if $(findstring gz,$@),gzip,                                      \
+$(if $(findstring lz,$@),lzip,                                      \
 $(if $(findstring xz,$@),xz,                                        \
-$(error unknown target $@))))                                       \
+$(error unknown target $@)))))                                      \
 	-f -9 $(perf-tar).tar)

 perf-%pkg: FORCE
@@ -140,8 +141,10 @@
 	@echo '  tar-pkg             - Build the kernel as an uncompressed tarball'
 	@echo '  targz-pkg           - Build the kernel as a gzip compressed tarball'
 	@echo '  tarbz2-pkg          - Build the kernel as a bzip2 compressed tarball'
+	@echo '  tarlz-pkg           - Build the kernel as a lzip compressed tarball'
 	@echo '  tarxz-pkg           - Build the kernel as a xz compressed tarball'
 	@echo '  perf-tar-src-pkg    - Build $(perf-tar).tar source tarball'
 	@echo '  perf-targz-src-pkg  - Build $(perf-tar).tar.gz source tarball'
 	@echo '  perf-tarbz2-src-pkg - Build $(perf-tar).tar.bz2 source tarball'
+	@echo '  perf-tarlz-src-pkg  - Build $(perf-tar).tar.lz source tarball'
 	@echo '  perf-tarxz-src-pkg  - Build $(perf-tar).tar.xz source tarball'
diff -urdN linux-4.14.40/scripts/package/buildtar linux-4.14.40.new/scripts/package/buildtar
--- linux-4.14.40/scripts/package/buildtar	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/scripts/package/buildtar	2018-06-12 11:49:20.000000000 +0200
@@ -35,6 +35,10 @@
 		opts=--bzip2
 		tarball=${tarball}.bz2
 		;;
+	tarlz-pkg)
+		opts=--lzip
+		tarball=${tarball}.lz
+		;;
 	tarxz-pkg)
 		opts=--xz
 		tarball=${tarball}.xz
diff -urdN linux-4.14.40/scripts/patch-kernel linux-4.14.40.new/scripts/patch-kernel
--- linux-4.14.40/scripts/patch-kernel	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/scripts/patch-kernel	2018-06-12 11:49:20.000000000 +0200
@@ -117,6 +117,10 @@
 		ext=".bz2"
 		name="bzip2"
 		uncomp="bunzip2 -dc"
+  elif [ -r ${filebase}.lz ]; then
+		ext=".lz"
+		name="lzip"
+		uncomp="lzip -dc"
   elif [ -r ${filebase}.xz ]; then
                 ext=".xz"
                 name="xz"
diff -urdN linux-4.14.40/tools/testing/selftests/gen_kselftest_tar.sh linux-4.14.40.new/tools/testing/selftests/gen_kselftest_tar.sh
--- linux-4.14.40/tools/testing/selftests/gen_kselftest_tar.sh	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/tools/testing/selftests/gen_kselftest_tar.sh	2018-06-12 11:49:20.000000000 +0200
@@ -29,6 +29,10 @@
 				copts="cvjf"
 				ext=".tar.bz2"
 				;;
+			tarlz)
+				copts="cv --lzip -f"
+				ext=".tar.lz"
+				;;
 			tarxz)
 				copts="cvJf"
 				ext=".tar.xz"
diff -urdN linux-4.14.40/usr/.gitignore linux-4.14.40.new/usr/.gitignore
--- linux-4.14.40/usr/.gitignore	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/usr/.gitignore	2018-06-12 11:49:20.000000000 +0200
@@ -5,6 +5,7 @@
 initramfs_data.cpio
 initramfs_data.cpio.gz
 initramfs_data.cpio.bz2
+initramfs_data.cpio.lz
 initramfs_data.cpio.lzma
 initramfs_list
 include
diff -urdN linux-4.14.40/usr/Kconfig linux-4.14.40.new/usr/Kconfig
--- linux-4.14.40/usr/Kconfig	2018-05-09 09:51:56.000000000 +0200
+++ linux-4.14.40.new/usr/Kconfig	2018-06-12 11:49:20.000000000 +0200
@@ -70,6 +70,15 @@
 	  Support loading of a bzip2 encoded initial ramdisk or cpio buffer
 	  If unsure, say N.

+config RD_LZIP
+	bool "Support initial ramdisk/ramfs compressed using lzip"
+	default y
+	depends on BLK_DEV_INITRD
+	select DECOMPRESS_LZIP
+	help
+	  Support loading of a lzip encoded initial ramdisk or cpio buffer.
+	  If unsure, say N.
+
 config RD_LZMA
 	bool "Support initial ramdisk/ramfs compressed using LZMA"
 	default y
@@ -165,6 +174,18 @@
 	  If you choose this, keep in mind that you need to have the bzip2 tool
 	  available to be able to compress the initram.

+config INITRAMFS_COMPRESSION_LZIP
+	bool "Lzip"
+	depends on RD_LZIP
+	help
+	  Lzip's compression ratio is better than that of gzip and bzip2.
+	  Decompression speed is between gzip and bzip2.  Compression can
+	  be as fast as gzip or slower than bzip2 depending on compression
+	  level.  Lzip can produce a initramfs about a 16% smaller than gzip.
+
+	  If you choose this, keep in mind that you need to have the lzip tool
+	  available to be able to compress the initram.
+
 config INITRAMFS_COMPRESSION_LZMA
 	bool "LZMA"
 	depends on RD_LZMA
@@ -222,12 +243,14 @@
 	default ""      if INITRAMFS_COMPRESSION_NONE
 	default ".gz"   if INITRAMFS_COMPRESSION_GZIP
 	default ".bz2"  if INITRAMFS_COMPRESSION_BZIP2
+	default ".lz"   if INITRAMFS_COMPRESSION_LZIP
 	default ".lzma" if INITRAMFS_COMPRESSION_LZMA
 	default ".xz"   if INITRAMFS_COMPRESSION_XZ
 	default ".lzo"  if INITRAMFS_COMPRESSION_LZO
 	default ".lz4"  if INITRAMFS_COMPRESSION_LZ4
 	default ".gz"   if RD_GZIP
 	default ".lz4"  if RD_LZ4
+	default ".lz"   if RD_LZIP
 	default ".lzo"  if RD_LZO
 	default ".xz"   if RD_XZ
 	default ".lzma" if RD_LZMA