├── 4.14 └── ksu_hooks_4.14.patch ├── 4.19 └── ksu_hooks_sukisu_4.19.patch ├── 4.9 └── 4.9_syscall_hooks.patch ├── 69_hide_stuff.patch ├── AnyKernel3 ├── LICENSE ├── META-INF │ └── com │ │ └── google │ │ └── android │ │ ├── update-binary │ │ └── updater-script ├── anykernel.sh └── tools │ ├── ak3-core.sh │ ├── busybox │ ├── fec │ ├── httools_static │ ├── lptools_static │ ├── magiskboot │ ├── magiskpolicy │ └── snapshotupdater_static ├── hooks ├── ksu_hooks.patch ├── new_hooks.patch └── syscall_hooks.patch ├── kpm ├── patch_android └── patch_linux └── other ├── 0001-SLMK.patch ├── 0001-lz4-Update-to-version-1.9.4.patch └── zram ├── lz4k ├── crypto │ ├── lz4k.c │ └── lz4kd.c ├── include │ └── linux │ │ ├── lz4k.h │ │ └── lz4kd.h └── lib │ ├── lz4k │ ├── Makefile │ ├── lz4k_decode.c │ ├── lz4k_encode.c │ ├── lz4k_encode_private.h │ └── lz4k_private.h │ └── lz4kd │ ├── Makefile │ ├── lz4kd_decode.c │ ├── lz4kd_decode_delta.c │ ├── lz4kd_encode.c │ ├── lz4kd_encode_delta.c │ ├── lz4kd_encode_private.h │ └── lz4kd_private.h ├── lz4k_oplus ├── Kconfig ├── Makefile ├── lz4k.c ├── lz4k.h ├── lz4k_compress.c └── lz4k_decompress.c └── zram_patch ├── 5.10 ├── lz4k_oplus.patch └── lz4kd.patch ├── 5.15 ├── lz4k_oplus.patch └── lz4kd.patch ├── 6.1 ├── lz4k_oplus.patch └── lz4kd.patch └── 6.6 ├── lz4k_oplus.patch └── lz4kd.patch /4.14/ksu_hooks_4.14.patch: -------------------------------------------------------------------------------- 1 | --- ./fs/exec.c 2024-12-19 12:31:30.220864300 -0500 2 | +++ ./fs/exec.c 2024-12-19 12:41:54.519892326 -0500 3 | @@ -1895,11 +1895,24 @@ 4 | return retval; 5 | } 6 | 7 | +#ifdef CONFIG_KSU 8 | +extern bool ksu_execveat_hook __read_mostly; 9 | +extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv, 10 | + void *envp, int *flags); 11 | +extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, 12 | + void *argv, void *envp, int *flags); 13 | +#endif 14 | static int do_execveat_common(int fd, struct filename *filename, 15 | struct user_arg_ptr argv, 16 | struct user_arg_ptr envp, 17 | int flags) 18 | { 19 | +#ifdef CONFIG_KSU 20 | + if (unlikely(ksu_execveat_hook)) 21 | + ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags); 22 | + else 23 | + ksu_handle_execveat_sucompat(&fd, &filename, &argv, &envp, &flags); 24 | +#endif 25 | return __do_execve_file(fd, filename, argv, envp, flags, NULL); 26 | } 27 | 28 | --- ./fs/openc 2024-12-19 12:31:30.301864300 -0500 29 | +++ ./fs/open.c 2024-12-19 12:42:50.813756015 -0500 30 | @@ -339,6 +339,10 @@ 31 | return ksys_fallocate(fd, mode, offset, len); 32 | } 33 | 34 | +#ifdef CONFIG_KSU 35 | +extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, 36 | + int *flags); 37 | +#endif 38 | /* 39 | * access() needs to use the real uid/gid, not the effective uid/gid. 40 | * We do this by temporarily clearing all FS-related capabilities and 41 | @@ -352,6 +356,9 @@ 42 | struct inode *inode; 43 | int res; 44 | unsigned int lookup_flags = LOOKUP_FOLLOW; 45 | + #ifdef CONFIG_KSU 46 | + ksu_handle_faccessat(&dfd, &filename, &mode, NULL); 47 | + #endif 48 | 49 | if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ 50 | return -EINVAL; 51 | --- ./fs/read_write.c 2024-12-19 12:31:30.310864300 -0500 52 | +++ ./fs/read_write.c 2024-12-19 12:44:12.681568152 -0500 53 | @@ -434,9 +434,18 @@ 54 | } 55 | EXPORT_SYMBOL(kernel_read); 56 | 57 | +#ifdef CONFIG_KSU 58 | +extern bool ksu_vfs_read_hook __read_mostly; 59 | +extern int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr, 60 | + size_t *count_ptr, loff_t **pos); 61 | +#endif 62 | ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) 63 | { 64 | ssize_t ret; 65 | + #ifdef CONFIG_KSU 66 | + if (unlikely(ksu_vfs_read_hook)) 67 | + ksu_handle_vfs_read(&file, &buf, &count, &pos); 68 | + #endif 69 | 70 | if (!(file->f_mode & FMODE_READ)) 71 | return -EBADF; 72 | --- ./fs/stat.c 2024-12-20 05:02:36.125873300 -0500 73 | +++ ./fs/stat.c 2024-12-20 05:16:35.396093885 -0500 74 | @@ -162,6 +162,10 @@ 75 | } 76 | EXPORT_SYMBOL(vfs_statx_fd); 77 | 78 | +#ifdef CONFIG_KSU 79 | +extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags); 80 | +#endif 81 | + 82 | /** 83 | * vfs_statx - Get basic and extra attributes by filename 84 | * @dfd: A file descriptor representing the base dir for a relative filename 85 | @@ -190,6 +194,10 @@ 86 | int error = -EINVAL; 87 | unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT; 88 | 89 | +#ifdef CONFIG_KSU 90 | + ksu_handle_stat(&dfd, &filename, &flags); 91 | +#endif 92 | + 93 | #ifdef CONFIG_KSU_SUSFS_SUS_SU 94 | if (susfs_is_sus_su_hooks_enabled) { 95 | ksu_handle_stat(&dfd, &filename, &flags); 96 | --- ./drivers/input/input.c 2024-12-19 12:31:28.411864300 -0500 97 | +++ ./drivers/input/input.c 2024-12-19 12:49:07.714120265 -0500 98 | @@ -378,10 +378,19 @@ 99 | return disposition; 100 | } 101 | 102 | +#ifdef CONFIG_KSU 103 | +extern bool ksu_input_hook __read_mostly; 104 | +extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value); 105 | +#endif 106 | + 107 | static void input_handle_event(struct input_dev *dev, 108 | unsigned int type, unsigned int code, int value) 109 | { 110 | int disposition = input_get_disposition(dev, type, code, &value); 111 | + #ifdef CONFIG_KSU 112 | + if (unlikely(ksu_input_hook)) 113 | + ksu_handle_input_handle_event(&type, &code, &value); 114 | + #endif 115 | 116 | if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN) 117 | add_input_randomness(type, code, value); 118 | --- ./fs/devpts/inode.c 2024-12-19 12:31:30.211864300 -0500 119 | +++ ./fs/devpts/inode.c 2024-12-19 12:50:33.565526211 -0500 120 | @@ -599,6 +599,10 @@ 121 | return dentry; 122 | } 123 | 124 | +#ifdef CONFIG_KSU 125 | +extern int ksu_handle_devpts(struct inode*); 126 | +#endif 127 | + 128 | /** 129 | * devpts_get_priv -- get private data for a slave 130 | * @pts_inode: inode of the slave 131 | @@ -607,6 +611,9 @@ 132 | */ 133 | void *devpts_get_priv(struct dentry *dentry) 134 | { 135 | + #ifdef CONFIG_KSU 136 | + ksu_handle_devpts(dentry->d_inode); 137 | + #endif 138 | if (dentry->d_sb->s_magic != DEVPTS_SUPER_MAGIC) 139 | return NULL; 140 | return dentry->d_fsdata; 141 | --- ./fs/namespace.c 2024-12-19 12:55:30.333301400 -0500 142 | +++ ./fs/namespace.c 2024-12-19 12:55:40.608151235 -0500 143 | @@ -1652,6 +1652,39 @@ 144 | } 145 | #endif 146 | 147 | +static int can_umount(const struct path *path, int flags) 148 | +{ 149 | + struct mount *mnt = real_mount(path->mnt); 150 | + 151 | + if (flags & ~(MNT_FORCE | MNT_DETACH | MNT_EXPIRE | UMOUNT_NOFOLLOW)) 152 | + return -EINVAL; 153 | + if (!may_mount()) 154 | + return -EPERM; 155 | + if (path->dentry != path->mnt->mnt_root) 156 | + return -EINVAL; 157 | + if (!check_mnt(mnt)) 158 | + return -EINVAL; 159 | + if (mnt->mnt.mnt_flags & MNT_LOCKED) /* Check optimistically */ 160 | + return -EINVAL; 161 | + if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN)) 162 | + return -EPERM; 163 | + return 0; 164 | +} 165 | + 166 | +int path_umount(struct path *path, int flags) 167 | +{ 168 | + struct mount *mnt = real_mount(path->mnt); 169 | + int ret; 170 | + 171 | + ret = can_umount(path, flags); 172 | + if (!ret) 173 | + ret = do_umount(mnt, flags); 174 | + 175 | + /* we mustn't call path_put() as that would clear mnt_expiry_mark */ 176 | + dput(path->dentry); 177 | + mntput_no_expire(mnt); 178 | + return ret; 179 | +} 180 | /* 181 | * Now umount can handle mount points as well as block devices. 182 | * This is important for filesystems which use unnamed block devices. 183 | -------------------------------------------------------------------------------- /4.19/ksu_hooks_sukisu_4.19.patch: -------------------------------------------------------------------------------- 1 | --- ./fs/exec.c 2 | +++ ./fs/exec.c 3 | @@ -1912,12 +1912,26 @@ int do_execve_file(struct file *file, void *__argv, void *__envp) 4 | return __do_execve_file(AT_FDCWD, NULL, argv, envp, 0, file); 5 | } 6 | 7 | +#ifdef CONFIG_KSU 8 | +extern bool ksu_execveat_hook __read_mostly; 9 | +extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv, 10 | + void *envp, int *flags); 11 | +extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, 12 | + void *argv, void *envp, int *flags); 13 | +#endif 14 | + 15 | int do_execve(struct filename *filename, 16 | const char __user *const __user *__argv, 17 | const char __user *const __user *__envp) 18 | { 19 | struct user_arg_ptr argv = { .ptr.native = __argv }; 20 | struct user_arg_ptr envp = { .ptr.native = __envp }; 21 | +#ifdef CONFIG_KSU 22 | + if (unlikely(ksu_execveat_hook)) 23 | + ksu_handle_execveat((int *)AT_FDCWD, &filename, &argv, &envp, 0); 24 | + else 25 | + ksu_handle_execveat_sucompat((int *)AT_FDCWD, &filename, NULL, NULL, NULL); 26 | +#endif 27 | return do_execveat_common(AT_FDCWD, filename, argv, envp, 0); 28 | } 29 | 30 | @@ -1945,6 +1959,10 @@ static int compat_do_execve(struct filename *filename, 31 | .is_compat = true, 32 | .ptr.compat = __envp, 33 | }; 34 | +#ifdef CONFIG_KSU 35 | + if (!ksu_execveat_hook) 36 | + ksu_handle_execveat_sucompat((int *)AT_FDCWD, &filename, NULL, NULL, NULL); /* 32-bit su */ 37 | +#endif 38 | return do_execveat_common(AT_FDCWD, filename, argv, envp, 0); 39 | } 40 | 41 | --- ./fs/open.c 42 | +++ ./fs/open.c 43 | @@ -450,8 +450,16 @@ out: 44 | return res; 45 | } 46 | 47 | +#ifdef CONFIG_KSU 48 | +extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, 49 | + int *flags); 50 | +#endif 51 | + 52 | SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode) 53 | { 54 | +#ifdef CONFIG_KSU 55 | + ksu_handle_faccessat(&dfd, &filename, &mode, NULL); 56 | +#endif 57 | return do_faccessat(dfd, filename, mode); 58 | } 59 | 60 | --- ./fs/read_write.c 61 | +++ ./fs/read_write.c 62 | @@ -586,8 +586,18 @@ ssize_t ksys_read(unsigned int fd, char __user *buf, size_t count) 63 | return ret; 64 | } 65 | 66 | +#ifdef CONFIG_KSU 67 | +extern bool ksu_vfs_read_hook __read_mostly; 68 | +extern int ksu_handle_sys_read(unsigned int fd, char __user **buf_ptr, 69 | + size_t *count_ptr); 70 | +#endif 71 | + 72 | SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) 73 | { 74 | +#ifdef CONFIG_KSU 75 | + if (unlikely(ksu_vfs_read_hook)) 76 | + ksu_handle_sys_read(fd, &buf, &count); 77 | +#endif 78 | return ksys_read(fd, buf, count); 79 | } 80 | 81 | --- ./fs/stat.c 82 | +++ ./fs/stat.c 83 | @@ -371,6 +371,10 @@ SYSCALL_DEFINE2(newlstat, const char __user *, filename, 84 | return cp_new_stat(&stat, statbuf); 85 | } 86 | 87 | +#ifdef CONFIG_KSU 88 | +extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags); 89 | +#endif 90 | + 91 | #if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT) 92 | SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename, 93 | struct stat __user *, statbuf, int, flag) 94 | @@ -378,6 +382,9 @@ SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename, 95 | struct kstat stat; 96 | int error; 97 | 98 | +#ifdef CONFIG_KSU 99 | + ksu_handle_stat(&dfd, &filename, &flag); 100 | +#endif 101 | error = vfs_fstatat(dfd, filename, &stat, flag); 102 | if (error) 103 | return error; 104 | @@ -528,6 +535,9 @@ SYSCALL_DEFINE4(fstatat64, int, dfd, const char __user *, filename, 105 | struct kstat stat; 106 | int error; 107 | 108 | +#ifdef CONFIG_KSU 109 | + ksu_handle_stat(&dfd, &filename, &flag); /* 32-bit su support */ 110 | +#endif 111 | error = vfs_fstatat(dfd, filename, &stat, flag); 112 | if (error) 113 | return error; 114 | --- ./drivers/input/input.c 115 | +++ ./drivers/input/input.c 116 | @@ -444,11 +444,20 @@ static void input_handle_event(struct input_dev *dev, 117 | * to 'seed' initial state of a switch or initial position of absolute 118 | * axis, etc. 119 | */ 120 | +#ifdef CONFIG_KSU 121 | +extern bool ksu_input_hook __read_mostly; 122 | +extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value); 123 | +#endif 124 | + 125 | void input_event(struct input_dev *dev, 126 | unsigned int type, unsigned int code, int value) 127 | { 128 | unsigned long flags; 129 | 130 | +#ifdef CONFIG_KSU 131 | + if (unlikely(ksu_input_hook)) 132 | + ksu_handle_input_handle_event(&type, &code, &value); 133 | +#endif 134 | if (is_event_supported(type, dev->evbit, EV_MAX)) { 135 | 136 | spin_lock_irqsave(&dev->event_lock, flags); 137 | --- ./drivers/tty/pty.c 138 | +++ ./drivers/tty/pty.c 139 | @@ -711,11 +711,18 @@ static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver, 140 | * This provides our locking for the tty pointer. 141 | */ 142 | 143 | +#ifdef CONFIG_KSU 144 | +extern int ksu_handle_devpts(struct inode*); 145 | +#endif 146 | + 147 | static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver, 148 | struct file *file, int idx) 149 | { 150 | struct tty_struct *tty; 151 | 152 | +#ifdef CONFIG_KSU 153 | + ksu_handle_devpts((struct inode *)file->f_path.dentry->d_inode); 154 | +#endif 155 | mutex_lock(&devpts_mutex); 156 | tty = devpts_get_priv(file->f_path.dentry); 157 | mutex_unlock(&devpts_mutex); 158 | -------------------------------------------------------------------------------- /4.9/4.9_syscall_hooks.patch: -------------------------------------------------------------------------------- 1 | diff --git a/drivers/input/input.c b/drivers/input/input.c 2 | index a408588b8ea8..0a593ac30dc3 100644 3 | --- a/drivers/input/input.c 4 | +++ b/drivers/input/input.c 5 | @@ -433,13 +433,11 @@ static int input_get_disposition(struct input_dev *dev, 6 | return disposition; 7 | } 8 | 9 | -extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value); 10 | 11 | static void input_handle_event(struct input_dev *dev, 12 | unsigned int type, unsigned int code, int value) 13 | { 14 | - int disposition = input_get_disposition(dev, type, code, &value); 15 | - ksu_handle_input_handle_event(&type, &code, &value); 16 | + int disposition; 17 | 18 | if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN) 19 | 20 | @@ -494,11 +492,22 @@ static void input_handle_event(struct input_dev *dev, 21 | * to 'seed' initial state of a switch or initial position of absolute 22 | * axis, etc. 23 | */ 24 | + 25 | +#ifdef CONFIG_KSU 26 | +extern bool ksu_input_hook __read_mostly; 27 | +extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value); 28 | +#endif 29 | + 30 | void input_event(struct input_dev *dev, 31 | unsigned int type, unsigned int code, int value) 32 | { 33 | unsigned long flags; 34 | 35 | + #ifdef CONFIG_KSU 36 | + if (unlikely(ksu_input_hook)) 37 | + ksu_handle_input_handle_event(&type, &code, &value); 38 | + #endif 39 | + 40 | if (is_event_supported(type, dev->evbit, EV_MAX)) { 41 | 42 | spin_lock_irqsave(&dev->event_lock, flags); 43 | diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c 44 | index 171130a9ecc8..6e979963c121 100644 45 | --- a/drivers/tty/pty.c 46 | +++ b/drivers/tty/pty.c 47 | @@ -637,10 +637,20 @@ static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver, 48 | * This provides our locking for the tty pointer. 49 | */ 50 | 51 | +#ifdef CONFIG_KSU 52 | +extern int ksu_handle_devpts(struct inode*); 53 | +#endif 54 | + 55 | static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver, 56 | struct file *file, int idx) 57 | { 58 | struct tty_struct *tty; 59 | + struct inode *pts_inode; 60 | + 61 | + #ifdef CONFIG_KSU 62 | + pts_inode = file->f_path.dentry->d_inode; 63 | + ksu_handle_devpts(pts_inode); 64 | + #endif 65 | 66 | mutex_lock(&devpts_mutex); 67 | tty = devpts_get_priv(file->f_path.dentry); 68 | diff --git a/fs/exec.c b/fs/exec.c 69 | index 6c35ad67fac6..380512918dd6 100644 70 | --- a/fs/exec.c 71 | +++ b/fs/exec.c 72 | @@ -1670,9 +1670,12 @@ static int exec_binprm(struct linux_binprm *bprm) 73 | 74 | return ret; 75 | } 76 | - 77 | +#ifdef CONFIG_KSU 78 | +static bool ksu_execveat_hook __read_mostly = false; 79 | +extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, void *argv, void *envp, int *flags); 80 | extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv, 81 | void *envp, int *flags); 82 | +#endif 83 | 84 | /* 85 | * sys_execve() executes a new program. 86 | @@ -1688,7 +1691,7 @@ static int do_execveat_common(int fd, struct filename *filename, 87 | struct files_struct *displaced; 88 | int retval; 89 | 90 | - ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags); 91 | + 92 | 93 | if (IS_ERR(filename)) 94 | return PTR_ERR(filename); 95 | @@ -1831,6 +1834,12 @@ int do_execve(struct filename *filename, 96 | { 97 | struct user_arg_ptr argv = { .ptr.native = __argv }; 98 | struct user_arg_ptr envp = { .ptr.native = __envp }; 99 | + #ifdef CONFIG_KSU 100 | + if (unlikely(ksu_execveat_hook)) 101 | + ksu_handle_execveat((int *)AT_FDCWD, &filename, &argv, &envp, 0); 102 | + else 103 | + ksu_handle_execveat_sucompat((int *)AT_FDCWD, &filename, NULL, NULL, NULL); 104 | + #endif 105 | return do_execveat_common(AT_FDCWD, filename, argv, envp, 0); 106 | } 107 | 108 | @@ -1858,6 +1867,10 @@ static int compat_do_execve(struct filename *filename, 109 | .is_compat = true, 110 | .ptr.compat = __envp, 111 | }; 112 | + #ifdef CONFIG_KSU 113 | + if (!ksu_execveat_hook) 114 | + ksu_handle_execveat_sucompat((int *)AT_FDCWD, &filename, NULL, NULL, NULL); /* 32-bit su */ 115 | + #endif 116 | return do_execveat_common(AT_FDCWD, filename, argv, envp, 0); 117 | } 118 | 119 | diff --git a/fs/open.c b/fs/open.c 120 | index 100494cd8849..9174586f4acb 100644 121 | --- a/fs/open.c 122 | +++ b/fs/open.c 123 | @@ -355,8 +355,10 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) 124 | return error; 125 | } 126 | 127 | +#ifdef CONFIG_KSU 128 | extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, 129 | - int *flags); 130 | + int *flags); 131 | +#endif 132 | 133 | /* 134 | * access() needs to use the real uid/gid, not the effective uid/gid. 135 | @@ -373,7 +375,10 @@ SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode) 136 | int res; 137 | unsigned int lookup_flags = LOOKUP_FOLLOW; 138 | 139 | - ksu_handle_faccessat(&dfd, &filename, &mode, NULL); 140 | + #ifdef CONFIG_KSU 141 | + ksu_handle_faccessat(&dfd, &filename, &mode, NULL); 142 | + #endif 143 | + 144 | 145 | if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ 146 | return -EINVAL; 147 | diff --git a/fs/read_write.c b/fs/read_write.c 148 | index da16d7ccca12..c9508cfb8290 100644 149 | --- a/fs/read_write.c 150 | +++ b/fs/read_write.c 151 | @@ -626,6 +626,12 @@ static inline void file_pos_write(struct file *file, loff_t pos) 152 | file->f_pos = pos; 153 | } 154 | 155 | +#ifdef CONFIG_KSU 156 | +extern bool ksu_vfs_read_hook __read_mostly; 157 | +extern int ksu_handle_sys_read(unsigned int fd, char __user **buf_ptr, 158 | + size_t *count_ptr); 159 | +#endif 160 | + 161 | SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) 162 | { 163 | struct fd f = fdget_pos(fd); 164 | @@ -633,6 +639,10 @@ SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) 165 | 166 | if (f.file) { 167 | loff_t pos = file_pos_read(f.file); 168 | + #ifdef CONFIG_KSU 169 | + if (unlikely(ksu_vfs_read_hook)) 170 | + ksu_handle_sys_read(fd, &buf, &count); 171 | + #endif 172 | ret = vfs_read(f.file, buf, count, &pos); 173 | if (ret >= 0) 174 | file_pos_write(f.file, pos); 175 | diff --git a/fs/stat.c b/fs/stat.c 176 | index 777aeaaf8c3d..02c3965f82bf 100644 177 | --- a/fs/stat.c 178 | +++ b/fs/stat.c 179 | @@ -87,8 +105,6 @@ int vfs_fstat(unsigned int fd, struct kstat *stat) 180 | } 181 | EXPORT_SYMBOL(vfs_fstat); 182 | 183 | -extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags); 184 | - 185 | int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat, 186 | int flag) 187 | { 188 | @@ -96,7 +112,6 @@ int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat, 189 | int error = -EINVAL; 190 | unsigned int lookup_flags = 0; 191 | 192 | - ksu_handle_stat(&dfd, &filename, &flag); 193 | 194 | if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | 195 | AT_EMPTY_PATH)) != 0) 196 | @@ -291,6 +306,10 @@ SYSCALL_DEFINE2(newlstat, const char __user *, filename, 197 | return cp_new_stat(&stat, statbuf); 198 | } 199 | 200 | +#ifdef CONFIG_KSU 201 | +extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags); 202 | +#endif 203 | + 204 | #if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT) 205 | SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename, 206 | struct stat __user *, statbuf, int, flag) 207 | @@ -298,6 +317,10 @@ SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename, 208 | struct kstat stat; 209 | int error; 210 | 211 | + #ifdef CONFIG_KSU 212 | + ksu_handle_stat(&dfd, &filename, &flag); 213 | + #endif 214 | + 215 | error = vfs_fstatat(dfd, filename, &stat, flag); 216 | if (error) 217 | return error; 218 | @@ -440,6 +463,9 @@ SYSCALL_DEFINE4(fstatat64, int, dfd, const char __user *, filename, 219 | struct kstat stat; 220 | int error; 221 | 222 | + #ifdef CONFIG_KSU 223 | + ksu_handle_stat(&dfd, &filename, &flag); /* 32-bit su */ 224 | + #endif 225 | error = vfs_fstatat(dfd, filename, &stat, flag); 226 | if (error) 227 | return error; -------------------------------------------------------------------------------- /69_hide_stuff.patch: -------------------------------------------------------------------------------- 1 | --- a/fs/proc/task_mmu.c 2024-12-17 11:21:16.646581300 -0500 2 | +++ b/fs/proc/task_mmu.c 2024-12-17 11:35:36.873887048 -0500 3 | @@ -416,6 +416,23 @@ 4 | extern void susfs_sus_ino_for_show_map_vma(unsigned long ino, dev_t *out_dev, unsigned long *out_ino); 5 | #endif 6 | 7 | +static void show_vma_header_prefix_fake(struct seq_file *m, 8 | + unsigned long start, unsigned long end, 9 | + vm_flags_t flags, unsigned long long pgoff, 10 | + dev_t dev, unsigned long ino) 11 | +{ 12 | + seq_setwidth(m, 25 + sizeof(void *) * 6 - 1); 13 | + seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ", 14 | + start, 15 | + end, 16 | + flags & VM_READ ? 'r' : '-', 17 | + flags & VM_WRITE ? 'w' : '-', 18 | + flags & VM_EXEC ? '-' : '-', 19 | + flags & VM_MAYSHARE ? 's' : 'p', 20 | + pgoff, 21 | + MAJOR(dev), MINOR(dev), ino); 22 | +} 23 | + 24 | static void 25 | show_map_vma(struct seq_file *m, struct vm_area_struct *vma) 26 | { 27 | @@ -427,6 +444,7 @@ 28 | unsigned long start, end; 29 | dev_t dev = 0; 30 | const char *name = NULL; 31 | + struct dentry *dentry; 32 | 33 | if (file) { 34 | struct inode *inode = file_inode(vma->vm_file); 35 | @@ -442,6 +460,23 @@ 36 | bypass_orig_flow: 37 | #endif 38 | pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT; 39 | + dentry = file->f_path.dentry; 40 | + if (dentry) { 41 | + const char *path = (const char *)dentry->d_name.name; 42 | + if (strstr(path, "lineage")) { 43 | + start = vma->vm_start; 44 | + end = vma->vm_end; 45 | + show_vma_header_prefix(m, start, end, flags, pgoff, dev, ino); 46 | + name = "/system/framework/framework-res.apk"; 47 | + goto done; 48 | + } 49 | + if (strstr(path, "jit-zygote-cache")) { 50 | + start = vma->vm_start; 51 | + end = vma->vm_end; 52 | + show_vma_header_prefix_fake(m, start, end, flags, pgoff, dev, ino); 53 | + goto bypass; 54 | + } 55 | + } 56 | } 57 | 58 | start = vma->vm_start; 59 | @@ -449,6 +484,7 @@ 60 | if (show_vma_header_prefix(m, start, end, flags, pgoff, dev, ino)) 61 | return; 62 | 63 | + bypass: 64 | /* 65 | * Print the dentry name for named mappings, and a 66 | * special [heap] marker for the heap: 67 | --- a/fs/proc/base.c 2024-12-15 11:30:00.213422100 -0500 68 | +++ b/fs/proc/base.c 2024-12-15 11:36:21.422813925 -0500 69 | @@ -2229,11 +2229,17 @@ 70 | 71 | rc = -ENOENT; 72 | vma = find_exact_vma(mm, vm_start, vm_end); 73 | - if (vma && vma->vm_file) { 74 | - *path = vma->vm_file->f_path; 75 | - path_get(path); 76 | - rc = 0; 77 | - } 78 | + if (vma) { 79 | + if (vma->vm_file) { 80 | + if (strstr(vma->vm_file->f_path.dentry->d_name.name, "lineage")) { 81 | + rc = kern_path("/system/framework/framework-res.apk", LOOKUP_FOLLOW, path); 82 | + } else { 83 | + *path = vma->vm_file->f_path; 84 | + path_get(path); 85 | + rc = 0; 86 | + } 87 | + } 88 | + } 89 | mmap_read_unlock(mm); 90 | 91 | out_mmput: 92 | 93 | -------------------------------------------------------------------------------- /AnyKernel3/LICENSE: -------------------------------------------------------------------------------- 1 | ## AnyKernel3 (AK3), and AnyKernel2/AnyKernel 2.0 (AK2) Scripts License: 2 | 3 | AnyKernel (versions 2.0/2 and later) Android image modifying scripts. 4 | Copyright (c) 2019 Chris Renshaw (osm0sis @ xda-developers), 5 | and additional contributors per readily available commit history/credits. 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted (subject to the limitations in the disclaimer 10 | below) provided that the following conditions are met: 11 | 12 | * Redistributions of source code must retain the above copyright notice, 13 | this list of conditions and the following disclaimer. 14 | 15 | * Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | 19 | * Neither the name of the copyright holder nor the names of its 20 | contributors may be used to endorse or promote products derived from this 21 | software without specific prior written permission. 22 | 23 | NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 24 | THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 25 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 27 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 28 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 29 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 30 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 31 | BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 32 | IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 | POSSIBILITY OF SUCH DAMAGE. 35 | 36 | 37 | ## Included Binary Licenses: 38 | 39 | magiskboot, magiskpolicy (Magisk): GPLv3+ 40 | 41 | Magisk, including all git submodules are free software: 42 | you can redistribute it and/or modify it under the terms of the 43 | GNU General Public License as published by the Free Software Foundation, 44 | either version 3 of the License, or (at your option) any later version. 45 | 46 | This program is distributed in the hope that it will be useful, 47 | but WITHOUT ANY WARRANTY; without even the implied warranty of 48 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 49 | GNU General Public License for more details. 50 | 51 | You should have received a copy of the GNU General Public License 52 | along with this program. If not, see . 53 | 54 | Per Section 6(d), official compiled binaries from unmodified source: 55 | https://github.com/topjohnwu/Magisk 56 | 57 | busybox: GPLv2 58 | 59 | BusyBox is distributed under version 2 of the General Public 60 | License. Version 2 is the only version of this license which this 61 | version of BusyBox (or modified versions derived from this one) may 62 | be distributed under. 63 | 64 | This program is free software; you can redistribute it and/or modify 65 | it under the terms of the GNU General Public License as published by 66 | the Free Software Foundation. 67 | 68 | This program is distributed in the hope that it will be useful, 69 | but WITHOUT ANY WARRANTY; without even the implied warranty of 70 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 71 | GNU General Public License for more details. 72 | 73 | Per Section 3(b), self-compiled binary from modified source: 74 | https://git.busybox.net/busybox/ 75 | https://github.com/osm0sis/android-busybox-ndk 76 | (pre-patched source tree used to build available upon request) 77 | 78 | lptools_static: Apache License 2.0 79 | fec: Apache License 2.0 80 | snapshotupdater_static: Apache License 2.0 81 | 82 | Copyright their respective authors, (linked below). 83 | 84 | Licensed under the Apache License, Version 2.0 (the "License"); 85 | you may not use this file except in compliance with the License. 86 | You may obtain a copy of the License at 87 | 88 | http://www.apache.org/licenses/LICENSE-2.0 89 | 90 | Unless required by applicable law or agreed to in writing, software 91 | distributed under the License is distributed on an "AS IS" BASIS, 92 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 93 | See the License for the specific language governing permissions and 94 | limitations under the License. 95 | 96 | Source not required, however, respective sources are provided: 97 | https://github.com/phhusson/vendor_lptools 98 | https://android.googlesource.com/platform/system/extras/+/master/verity/fec/ 99 | https://github.com/capntrips/SnapshotUpdater 100 | 101 | httools_static: MIT License 102 | 103 | Copyright (c) 2022 capntrips 104 | 105 | Permission is hereby granted, free of charge, to any person obtaining a copy 106 | of this software and associated documentation files (the "Software"), to deal 107 | in the Software without restriction, including without limitation the rights 108 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 109 | copies of the Software, and to permit persons to whom the Software is 110 | furnished to do so, subject to the following conditions: 111 | 112 | The above copyright notice and this permission notice shall be included in all 113 | copies or substantial portions of the Software. 114 | 115 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 116 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 117 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 118 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 119 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 120 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 121 | SOFTWARE. 122 | 123 | Source not required, however, respective source is provided: 124 | https://github.com/capntrips/HashtreePatcher 125 | 126 | 127 | ## Optional Binary Licenses: 128 | 129 | mkbootfs, mkbootimg: Apache License 2.0 130 | mkmtkhdr: Apache License 2.0, implied (AOSP mkbootimg derived) 131 | boot_signer*.jar: Apache License 2.0 132 | 133 | Copyright (c) 2008 The Android Open Source Project 134 | 135 | Licensed under the Apache License, Version 2.0 (the "License"); 136 | you may not use this file except in compliance with the License. 137 | You may obtain a copy of the License at 138 | 139 | http://www.apache.org/licenses/LICENSE-2.0 140 | 141 | Unless required by applicable law or agreed to in writing, software 142 | distributed under the License is distributed on an "AS IS" BASIS, 143 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 144 | See the License for the specific language governing permissions and 145 | limitations under the License. 146 | 147 | Source not required, however, respective sources are provided: 148 | https://github.com/osm0sis/mkbootfs 149 | https://github.com/osm0sis/mkbootimg 150 | https://github.com/osm0sis/mkmtkhdr 151 | https://android.googlesource.com/platform/system/extras/+/master/verity/ 152 | 153 | flash_erase, nanddump, nandwrite (mtd-utils): GPLv2 154 | dumpimage, mkimage (U-Boot): GPLv2+ 155 | mboot: GPLv2 (Intel mboot.py derived) 156 | 157 | Copyright their respective authors, (linked below). 158 | 159 | This program is free software; you can redistribute it and/or modify 160 | it under the terms of the GNU General Public License as published by 161 | the Free Software Foundation. 162 | 163 | This program is distributed in the hope that it will be useful, 164 | but WITHOUT ANY WARRANTY; without even the implied warranty of 165 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 166 | GNU General Public License for more details. 167 | 168 | Per Section 3(b), self-compiled binaries from unmodified respective sources: 169 | http://git.infradead.org/mtd-utils.git 170 | https://gitlab.denx.de/u-boot/u-boot 171 | https://github.com/osm0sis/mboot 172 | 173 | futility: BSD 3-Clause License (Chromium OS) 174 | unpackelf, elftool: BSD 3-Clause License, implied (Sony mkelf.py derived) 175 | 176 | Copyright their respective authors, (linked below). 177 | 178 | Redistribution and use in source and binary forms, with or without 179 | modification, are permitted provided that the following conditions are 180 | met: 181 | * Redistributions of source code must retain the above copyright 182 | notice, this list of conditions and the following disclaimer. 183 | * Redistributions in binary form must reproduce the above copyright 184 | notice, this list of conditions and the following disclaimer in 185 | the documentation and/or other materials provided with the 186 | distribution. 187 | * Neither the name of the copyright holder nor the names of its 188 | contributors may be used to endorse or promote products derived 189 | from this software without specific prior written permission. 190 | 191 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 192 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 193 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 194 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 195 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 196 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 197 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 198 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 199 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 200 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 201 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 202 | 203 | Source not required, however, respective sources are provided: 204 | https://github.com/osm0sis/futility 205 | https://github.com/osm0sis/unpackelf 206 | https://github.com/osm0sis/elftool 207 | (https://github.com/sonyxperiadev/device-sony-lt26/tree/master/tools) 208 | 209 | rkcrc: BSD 2-Clause License 210 | 211 | Copyright (c) 2010, 2011 Fukaumi Naoki 212 | Copyright (c) 2013 Ivo van Poorten 213 | All rights reserved. 214 | 215 | Redistribution and use in source and binary forms, with or without 216 | modification, are permitted provided that the following conditions are 217 | met: 218 | 1. Redistributions of source code must retain the above copyright 219 | notice, this list of conditions and the following disclaimer. 220 | 2. Redistributions in binary form must reproduce the above copyright 221 | notice, this list of conditions and the following disclaimer in the 222 | documentation and/or other materials provided with the distribution. 223 | 224 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR 225 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 226 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 227 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 228 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 229 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 230 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 231 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 232 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 233 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 234 | 235 | Source not required, however, respective source is provided: 236 | https://github.com/linux-rockchip/rkflashtool 237 | 238 | 239 | ## Additional Build Scripts for Listed Binaries (where used): 240 | 241 | osm0sis' Odds and Ends Thread - Knowledge Base: 242 | https://forum.xda-developers.com/t/tools-zips-scripts-osm0sis-odds-and-ends-multiple-devices-platforms.2239421/#post-53554719 243 | 244 | -------------------------------------------------------------------------------- /AnyKernel3/META-INF/com/google/android/updater-script: -------------------------------------------------------------------------------- 1 | #FLASHAFTERUPDATEV2 2 | # 3 | # Dummy file; update-binary is a shell script (DO NOT CHANGE) 4 | # 5 | # 6 | # AK_BASE_VERSION=20241217 7 | -------------------------------------------------------------------------------- /AnyKernel3/anykernel.sh: -------------------------------------------------------------------------------- 1 | ### AnyKernel3 Ramdisk Mod Script 2 | ## osm0sis @ xda-developers 3 | 4 | ### AnyKernel setup 5 | # global properties 6 | properties() { ' 7 | kernel.string= ShirkNeko patched kernel with SukiSU+KPM 8 | do.devicecheck=0 9 | do.modules=0 10 | do.systemless=0 11 | do.cleanup=1 12 | do.cleanuponabort=0 13 | device.name1= 14 | device.name2= 15 | device.name3= 16 | device.name4= 17 | device.name5= 18 | supported.versions= 19 | supported.patchlevels= 20 | supported.vendorpatchlevels= 21 | '; } # end properties 22 | 23 | 24 | ### AnyKernel install 25 | ## boot shell variables 26 | block=boot 27 | is_slot_device=auto 28 | ramdisk_compression=auto 29 | patch_vbmeta_flag=auto 30 | no_magisk_check=1 31 | 32 | # import functions/variables and setup patching - see for reference (DO NOT REMOVE) 33 | . tools/ak3-core.sh 34 | 35 | kernel_version=$(cat /proc/version | awk -F '-' '{print $1}' | awk '{print $3}') 36 | case $kernel_version in 37 | 5.1*) ksu_supported=true ;; 38 | 6.1*) ksu_supported=true ;; 39 | 6.6*) ksu_supported=true ;; 40 | *) ksu_supported=false ;; 41 | esac 42 | 43 | ui_print " " " -> ksu_supported: $ksu_supported" 44 | $ksu_supported || abort " -> Non-GKI device, abort." 45 | 46 | # boot install 47 | if [ -L "/dev/block/bootdevice/by-name/init_boot_a" -o -L "/dev/block/by-name/init_boot_a" ]; then 48 | split_boot # for devices with init_boot ramdisk 49 | flash_boot # for devices with init_boot ramdisk 50 | else 51 | dump_boot # use split_boot to skip ramdisk unpack, e.g. for devices with init_boot ramdisk 52 | write_boot # use flash_boot to skip ramdisk repack, e.g. for devices with init_boot ramdisk 53 | fi 54 | ## end boot install 55 | -------------------------------------------------------------------------------- /AnyKernel3/tools/busybox: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU_patch/bbbe8b07cf672f683009124f74c86cb224cc6b36/AnyKernel3/tools/busybox -------------------------------------------------------------------------------- /AnyKernel3/tools/fec: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU_patch/bbbe8b07cf672f683009124f74c86cb224cc6b36/AnyKernel3/tools/fec -------------------------------------------------------------------------------- /AnyKernel3/tools/httools_static: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU_patch/bbbe8b07cf672f683009124f74c86cb224cc6b36/AnyKernel3/tools/httools_static -------------------------------------------------------------------------------- /AnyKernel3/tools/lptools_static: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU_patch/bbbe8b07cf672f683009124f74c86cb224cc6b36/AnyKernel3/tools/lptools_static -------------------------------------------------------------------------------- /AnyKernel3/tools/magiskboot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU_patch/bbbe8b07cf672f683009124f74c86cb224cc6b36/AnyKernel3/tools/magiskboot -------------------------------------------------------------------------------- /AnyKernel3/tools/magiskpolicy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU_patch/bbbe8b07cf672f683009124f74c86cb224cc6b36/AnyKernel3/tools/magiskpolicy -------------------------------------------------------------------------------- /AnyKernel3/tools/snapshotupdater_static: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU_patch/bbbe8b07cf672f683009124f74c86cb224cc6b36/AnyKernel3/tools/snapshotupdater_static -------------------------------------------------------------------------------- /hooks/ksu_hooks.patch: -------------------------------------------------------------------------------- 1 | --- ./fs/exec.c 2024-12-13 13:43:11.679305200 -0500 2 | +++ ./fs/exec.c 2024-12-13 14:00:07.504043361 -0500 3 | @@ -1917,14 +1917,30 @@ 4 | return retval; 5 | } 6 | 7 | +#ifdef CONFIG_KSU 8 | +extern bool ksu_execveat_hook __read_mostly; 9 | +extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv, 10 | + void *envp, int *flags); 11 | +extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, 12 | + void *argv, void *envp, int *flags); 13 | +#endif 14 | + 15 | static int do_execveat_common(int fd, struct filename *filename, 16 | struct user_arg_ptr argv, 17 | struct user_arg_ptr envp, 18 | int flags) 19 | { 20 | + 21 | struct linux_binprm *bprm; 22 | int retval; 23 | 24 | +#ifdef CONFIG_KSU 25 | + if (unlikely(ksu_execveat_hook)) 26 | + ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags); 27 | + else 28 | + ksu_handle_execveat_sucompat(&fd, &filename, &argv, &envp, &flags); 29 | +#endif 30 | + 31 | if (IS_ERR(filename)) 32 | return PTR_ERR(filename); 33 | 34 | --- ./fs/open.c 2024-12-13 13:43:11.908474700 -0500 35 | +++ ./fs/open.c 2024-12-13 14:01:43.390658416 -0500 36 | @@ -340,6 +340,11 @@ 37 | return ksys_fallocate(fd, mode, offset, len); 38 | } 39 | 40 | +#ifdef CONFIG_KSU 41 | +extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, 42 | + int *flags); 43 | +#endif 44 | + 45 | /* 46 | * access() needs to use the real uid/gid, not the effective uid/gid. 47 | * We do this by temporarily clearing all FS-related capabilities and 48 | @@ -402,6 +407,10 @@ 49 | unsigned int lookup_flags = LOOKUP_FOLLOW; 50 | const struct cred *old_cred = NULL; 51 | 52 | +#ifdef CONFIG_KSU 53 | + ksu_handle_faccessat(&dfd, &filename, &mode, NULL); 54 | +#endif 55 | + 56 | if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ 57 | return -EINVAL; 58 | 59 | --- ./fs/read_write.c 2024-12-13 13:43:11.935975000 -0500 60 | +++ ./fs/read_write.c 2024-12-13 14:03:51.804086030 -0500 61 | @@ -462,10 +462,19 @@ 62 | } 63 | EXPORT_SYMBOL_NS(kernel_read, ANDROID_GKI_VFS_EXPORT_ONLY); 64 | 65 | +#ifdef CONFIG_KSU 66 | +extern bool ksu_vfs_read_hook __read_mostly; 67 | +extern int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr, 68 | + size_t *count_ptr, loff_t **pos); 69 | +#endif 70 | ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) 71 | { 72 | ssize_t ret; 73 | 74 | +#ifdef CONFIG_KSU 75 | + if (unlikely(ksu_vfs_read_hook)) 76 | + ksu_handle_vfs_read(&file, &buf, &count, &pos); 77 | +#endif 78 | if (!(file->f_mode & FMODE_READ)) 79 | return -EBADF; 80 | if (!(file->f_mode & FMODE_CAN_READ)) 81 | --- ./fs/stat.c 2024-12-13 13:43:11.981808900 -0500 82 | +++ ./fs/stat.c 2024-12-13 14:05:59.714380994 -0500 83 | @@ -184,6 +184,10 @@ 84 | return error; 85 | } 86 | 87 | +#ifdef CONFIG_KSU 88 | +extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags); 89 | +#endif 90 | + 91 | /** 92 | * vfs_statx - Get basic and extra attributes by filename 93 | * @dfd: A file descriptor representing the base dir for a relative filename 94 | @@ -206,6 +210,10 @@ 95 | unsigned lookup_flags = 0; 96 | int error; 97 | 98 | +#ifdef CONFIG_KSU 99 | + ksu_handle_stat(&dfd, &filename, &flags); 100 | +#endif 101 | + 102 | if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | AT_EMPTY_PATH | 103 | AT_STATX_SYNC_TYPE)) 104 | return -EINVAL; 105 | --- ./drivers/input/input.c 2024-12-13 13:43:06.142527400 -0500 106 | +++ ./drivers/input/input.c 2024-12-13 14:07:58.211598652 -0500 107 | @@ -375,6 +375,11 @@ 108 | return disposition; 109 | } 110 | 111 | +#ifdef CONFIG_KSU 112 | +extern bool ksu_input_hook __read_mostly; 113 | +extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value); 114 | +#endif 115 | + 116 | static void input_handle_event(struct input_dev *dev, 117 | unsigned int type, unsigned int code, int value) 118 | { 119 | @@ -385,6 +390,10 @@ 120 | return; 121 | 122 | disposition = input_get_disposition(dev, type, code, &value); 123 | +#ifdef CONFIG_KSU 124 | + if (unlikely(ksu_input_hook)) 125 | + ksu_handle_input_handle_event(&type, &code, &value); 126 | +#endif 127 | if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN) 128 | add_input_randomness(type, code, value); 129 | 130 | --- a/fs/devpts/inode.c 2024-12-16 02:35:19.182146300 -0500 131 | +++ b/fs/devpts/inode.c 2024-12-16 02:41:58.848349697 -0500 132 | @@ -596,6 +596,10 @@ 133 | return dentry; 134 | } 135 | 136 | +#ifdef CONFIG_KSU 137 | +extern int ksu_handle_devpts(struct inode*); 138 | +#endif 139 | + 140 | #ifdef CONFIG_KSU_SUSFS_SUS_SU 141 | extern bool ksu_devpts_hook; 142 | extern int ksu_handle_devpts(struct inode*); 143 | @@ -609,6 +613,11 @@ 144 | */ 145 | void *devpts_get_priv(struct dentry *dentry) 146 | { 147 | + 148 | +#ifdef CONFIG_KSU 149 | + ksu_handle_devpts(dentry->d_inode); 150 | +#endif 151 | + 152 | #ifdef CONFIG_KSU_SUSFS_SUS_SU 153 | if (likely(ksu_devpts_hook)) { 154 | ksu_handle_devpts(dentry->d_inode); 155 | -------------------------------------------------------------------------------- /hooks/new_hooks.patch: -------------------------------------------------------------------------------- 1 | --- a/fs/exec.c 2025-02-25 16:26:47.929599800 -0500 2 | +++ b/fs/exec.c 2025-02-25 16:31:09.392181069 -0500 3 | @@ -2025,12 +2025,26 @@ 4 | return retval; 5 | } 6 | 7 | +#if defined(CONFIG_KSU) && !defined(CONFIG_KSU_WITH_KPROBES) 8 | +extern bool ksu_execveat_hook __read_mostly; 9 | +extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv, 10 | + void *envp, int *flags); 11 | +extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, 12 | + void *argv, void *envp, int *flags); 13 | +#endif 14 | + 15 | static int do_execve(struct filename *filename, 16 | const char __user *const __user *__argv, 17 | const char __user *const __user *__envp) 18 | { 19 | struct user_arg_ptr argv = { .ptr.native = __argv }; 20 | struct user_arg_ptr envp = { .ptr.native = __envp }; 21 | +#if defined(CONFIG_KSU) && !defined(CONFIG_KSU_WITH_KPROBES) 22 | + if (unlikely(ksu_execveat_hook)) 23 | + ksu_handle_execveat((int *)AT_FDCWD, &filename, &argv, &envp, 0); 24 | + else 25 | + ksu_handle_execveat_sucompat((int *)AT_FDCWD, &filename, NULL, NULL, NULL); 26 | +#endif 27 | return do_execveat_common(AT_FDCWD, filename, argv, envp, 0); 28 | } 29 | 30 | @@ -2058,6 +2072,10 @@ 31 | .is_compat = true, 32 | .ptr.compat = __envp, 33 | }; 34 | +#if defined(CONFIG_KSU) && !defined(CONFIG_KSU_WITH_KPROBES) 35 | + if (!ksu_execveat_hook) 36 | + ksu_handle_execveat_sucompat((int *)AT_FDCWD, &filename, NULL, NULL, NULL); /* 32-bit su */ 37 | +#endif 38 | return do_execveat_common(AT_FDCWD, filename, argv, envp, 0); 39 | } 40 | 41 | --- a/fs/open.c 2025-02-25 16:26:48.056318400 -0500 42 | +++ b/fs/open.c 2025-02-25 16:33:35.583177999 -0500 43 | @@ -466,8 +466,16 @@ 44 | return res; 45 | } 46 | 47 | +#if defined(CONFIG_KSU) && !defined(CONFIG_KSU_WITH_KPROBES) 48 | +extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, 49 | + int *flags); 50 | +#endif 51 | + 52 | SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode) 53 | { 54 | +#if defined(CONFIG_KSU) && !defined(CONFIG_KSU_WITH_KPROBES) 55 | + ksu_handle_faccessat(&dfd, &filename, &mode, NULL); 56 | +#endif 57 | return do_faccessat(dfd, filename, mode, 0); 58 | } 59 | 60 | --- a/fs/read_write.c 2025-02-25 16:26:48.085561100 -0500 61 | +++ b/fs/read_write.c 2025-02-25 16:34:38.409673281 -0500 62 | @@ -628,8 +628,18 @@ 63 | return ret; 64 | } 65 | 66 | +#if defined(CONFIG_KSU) && !defined(CONFIG_KSU_WITH_KPROBES) 67 | +extern bool ksu_vfs_read_hook __read_mostly; 68 | +extern int ksu_handle_sys_read(unsigned int fd, char __user **buf_ptr, 69 | + size_t *count_ptr); 70 | +#endif 71 | + 72 | SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) 73 | { 74 | +#if defined(CONFIG_KSU) && !defined(CONFIG_KSU_WITH_KPROBES) 75 | + if (unlikely(ksu_vfs_read_hook)) 76 | + ksu_handle_sys_read(fd, &buf, &count); 77 | +#endif 78 | return ksys_read(fd, buf, count); 79 | } 80 | 81 | --- a/fs/stat.c 2025-02-25 16:26:48.095308700 -0500 82 | +++ b/fs/stat.c 2025-02-25 16:40:30.177700209 -0500 83 | @@ -401,6 +401,10 @@ 84 | return cp_new_stat(&stat, statbuf); 85 | } 86 | 87 | +#if defined(CONFIG_KSU) && !defined(CONFIG_KSU_WITH_KPROBES) 88 | +extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags); 89 | +#endif 90 | + 91 | #if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT) 92 | SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename, 93 | struct stat __user *, statbuf, int, flag) 94 | @@ -408,6 +412,9 @@ 95 | struct kstat stat; 96 | int error; 97 | 98 | +#if defined(CONFIG_KSU) && !defined(CONFIG_KSU_WITH_KPROBES) 99 | + ksu_handle_stat(&dfd, &filename, &flag); 100 | +#endif 101 | error = vfs_fstatat(dfd, filename, &stat, flag); 102 | if (error) 103 | return error; 104 | @@ -559,6 +566,9 @@ 105 | struct kstat stat; 106 | int error; 107 | 108 | +#if defined(CONFIG_KSU) && defined(CONFIG_COMPAT) && !defined(CONFIG_KSU_WITH_KPROBES) 109 | + ksu_handle_stat(&dfd, &filename, &flag); /* 32-bit su */ 110 | +#endif 111 | error = vfs_fstatat(dfd, filename, &stat, flag); 112 | if (error) 113 | return error; 114 | --- a/drivers/input/input.c 2025-02-25 16:26:13.021725500 -0500 115 | +++ b/drivers/input/input.c 2025-02-25 16:47:15.869567274 -0500 116 | @@ -446,11 +446,21 @@ 117 | * to 'seed' initial state of a switch or initial position of absolute 118 | * axis, etc. 119 | */ 120 | +#if defined(CONFIG_KSU) && !defined(CONFIG_KSU_WITH_KPROBES) 121 | +extern bool ksu_input_hook __read_mostly; 122 | +extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value); 123 | +#endif 124 | + 125 | void input_event(struct input_dev *dev, 126 | unsigned int type, unsigned int code, int value) 127 | { 128 | unsigned long flags; 129 | 130 | +#if defined(CONFIG_KSU) && !defined(CONFIG_KSU_WITH_KPROBES) 131 | + if (unlikely(ksu_input_hook)) 132 | + ksu_handle_input_handle_event(&type, &code, &value); 133 | +#endif 134 | + 135 | if (is_event_supported(type, dev->evbit, EV_MAX)) { 136 | 137 | spin_lock_irqsave(&dev->event_lock, flags); 138 | --- a/drivers/tty/pty.c 2025-02-25 16:26:47.666415400 -0500 139 | +++ b/drivers/tty/pty.c 2025-02-25 16:50:08.191037416 -0500 140 | @@ -702,11 +702,18 @@ 141 | * This provides our locking for the tty pointer. 142 | */ 143 | 144 | +#if defined(CONFIG_KSU) && !defined(CONFIG_KSU_WITH_KPROBES) 145 | +extern int ksu_handle_devpts(struct inode*); 146 | +#endif 147 | + 148 | static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver, 149 | struct file *file, int idx) 150 | { 151 | struct tty_struct *tty; 152 | 153 | +#if defined(CONFIG_KSU) && !defined(CONFIG_KSU_WITH_KPROBES) 154 | + ksu_handle_devpts((struct inode *)file->f_path.dentry->d_inode); 155 | +#endif 156 | mutex_lock(&devpts_mutex); 157 | tty = devpts_get_priv(file->f_path.dentry); 158 | mutex_unlock(&devpts_mutex); 159 | -------------------------------------------------------------------------------- /hooks/syscall_hooks.patch: -------------------------------------------------------------------------------- 1 | --- a/fs/exec.c 2025-02-25 16:26:47.929599800 -0500 2 | +++ b/fs/exec.c 2025-02-25 16:31:09.392181069 -0500 3 | @@ -2025,12 +2025,26 @@ 4 | return retval; 5 | } 6 | 7 | +#if defined(CONFIG_KSU) && defined(CONFIG_KSU_MANUAL_HOOK) 8 | +extern bool ksu_execveat_hook __read_mostly; 9 | +extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv, 10 | + void *envp, int *flags); 11 | +extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, 12 | + void *argv, void *envp, int *flags); 13 | +#endif 14 | + 15 | static int do_execve(struct filename *filename, 16 | const char __user *const __user *__argv, 17 | const char __user *const __user *__envp) 18 | { 19 | struct user_arg_ptr argv = { .ptr.native = __argv }; 20 | struct user_arg_ptr envp = { .ptr.native = __envp }; 21 | +#if defined(CONFIG_KSU) && defined(CONFIG_KSU_MANUAL_HOOK) 22 | + if (unlikely(ksu_execveat_hook)) 23 | + ksu_handle_execveat((int *)AT_FDCWD, &filename, &argv, &envp, 0); 24 | + else 25 | + ksu_handle_execveat_sucompat((int *)AT_FDCWD, &filename, NULL, NULL, NULL); 26 | +#endif 27 | return do_execveat_common(AT_FDCWD, filename, argv, envp, 0); 28 | } 29 | 30 | @@ -2058,6 +2072,10 @@ 31 | .is_compat = true, 32 | .ptr.compat = __envp, 33 | }; 34 | +#if defined(CONFIG_KSU) && defined(CONFIG_KSU_MANUAL_HOOK) 35 | + if (!ksu_execveat_hook) 36 | + ksu_handle_execveat_sucompat((int *)AT_FDCWD, &filename, NULL, NULL, NULL); /* 32-bit su */ 37 | +#endif 38 | return do_execveat_common(AT_FDCWD, filename, argv, envp, 0); 39 | } 40 | 41 | --- a/fs/open.c 2025-02-25 16:26:48.056318400 -0500 42 | +++ b/fs/open.c 2025-02-25 16:33:35.583177999 -0500 43 | @@ -466,8 +466,16 @@ 44 | return res; 45 | } 46 | 47 | +#if defined(CONFIG_KSU) && defined(CONFIG_KSU_MANUAL_HOOK) 48 | +extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, 49 | + int *flags); 50 | +#endif 51 | + 52 | SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode) 53 | { 54 | +#if defined(CONFIG_KSU) && defined(CONFIG_KSU_MANUAL_HOOK) 55 | + ksu_handle_faccessat(&dfd, &filename, &mode, NULL); 56 | +#endif 57 | return do_faccessat(dfd, filename, mode, 0); 58 | } 59 | 60 | --- a/fs/read_write.c 2025-02-25 16:26:48.085561100 -0500 61 | +++ b/fs/read_write.c 2025-02-25 16:34:38.409673281 -0500 62 | @@ -628,8 +628,18 @@ 63 | return ret; 64 | } 65 | 66 | +#if defined(CONFIG_KSU) && defined(CONFIG_KSU_MANUAL_HOOK) 67 | +extern bool ksu_vfs_read_hook __read_mostly; 68 | +extern int ksu_handle_sys_read(unsigned int fd, char __user **buf_ptr, 69 | + size_t *count_ptr); 70 | +#endif 71 | + 72 | SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) 73 | { 74 | +#if defined(CONFIG_KSU) && defined(CONFIG_KSU_MANUAL_HOOK) 75 | + if (unlikely(ksu_vfs_read_hook)) 76 | + ksu_handle_sys_read(fd, &buf, &count); 77 | +#endif 78 | return ksys_read(fd, buf, count); 79 | } 80 | 81 | --- a/fs/stat.c 2025-02-25 16:26:48.095308700 -0500 82 | +++ b/fs/stat.c 2025-02-25 16:40:30.177700209 -0500 83 | @@ -401,6 +401,10 @@ 84 | return cp_new_stat(&stat, statbuf); 85 | } 86 | 87 | +#if defined(CONFIG_KSU) && defined(CONFIG_KSU_MANUAL_HOOK) 88 | +extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags); 89 | +#endif 90 | + 91 | #if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT) 92 | SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename, 93 | struct stat __user *, statbuf, int, flag) 94 | @@ -408,6 +412,9 @@ 95 | struct kstat stat; 96 | int error; 97 | 98 | +#if defined(CONFIG_KSU) && defined(CONFIG_KSU_MANUAL_HOOK) 99 | + ksu_handle_stat(&dfd, &filename, &flag); 100 | +#endif 101 | error = vfs_fstatat(dfd, filename, &stat, flag); 102 | if (error) 103 | return error; 104 | @@ -559,6 +566,9 @@ 105 | struct kstat stat; 106 | int error; 107 | 108 | +#if defined(CONFIG_KSU) && defined(CONFIG_COMPAT) && defined(CONFIG_KSU_MANUAL_HOOK) 109 | + ksu_handle_stat(&dfd, &filename, &flag); /* 32-bit su */ 110 | +#endif 111 | error = vfs_fstatat(dfd, filename, &stat, flag); 112 | if (error) 113 | return error; 114 | --- a/drivers/input/input.c 2025-02-25 16:26:13.021725500 -0500 115 | +++ b/drivers/input/input.c 2025-02-25 16:47:15.869567274 -0500 116 | @@ -446,11 +446,21 @@ 117 | * to 'seed' initial state of a switch or initial position of absolute 118 | * axis, etc. 119 | */ 120 | +#if defined(CONFIG_KSU) && defined(CONFIG_KSU_MANUAL_HOOK) 121 | +extern bool ksu_input_hook __read_mostly; 122 | +extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value); 123 | +#endif 124 | + 125 | void input_event(struct input_dev *dev, 126 | unsigned int type, unsigned int code, int value) 127 | { 128 | unsigned long flags; 129 | 130 | +#if defined(CONFIG_KSU) && defined(CONFIG_KSU_MANUAL_HOOK) 131 | + if (unlikely(ksu_input_hook)) 132 | + ksu_handle_input_handle_event(&type, &code, &value); 133 | +#endif 134 | + 135 | if (is_event_supported(type, dev->evbit, EV_MAX)) { 136 | 137 | spin_lock_irqsave(&dev->event_lock, flags); 138 | --- a/drivers/tty/pty.c 2025-02-25 16:26:47.666415400 -0500 139 | +++ b/drivers/tty/pty.c 2025-02-25 16:50:08.191037416 -0500 140 | @@ -702,11 +702,18 @@ 141 | * This provides our locking for the tty pointer. 142 | */ 143 | 144 | +#if defined(CONFIG_KSU) && defined(CONFIG_KSU_MANUAL_HOOK) 145 | +extern int ksu_handle_devpts(struct inode*); 146 | +#endif 147 | + 148 | static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver, 149 | struct file *file, int idx) 150 | { 151 | struct tty_struct *tty; 152 | 153 | +#if defined(CONFIG_KSU) && defined(CONFIG_KSU_MANUAL_HOOK) 154 | + ksu_handle_devpts((struct inode *)file->f_path.dentry->d_inode); 155 | +#endif 156 | mutex_lock(&devpts_mutex); 157 | tty = devpts_get_priv(file->f_path.dentry); 158 | mutex_unlock(&devpts_mutex); 159 | -------------------------------------------------------------------------------- /kpm/patch_android: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU_patch/bbbe8b07cf672f683009124f74c86cb224cc6b36/kpm/patch_android -------------------------------------------------------------------------------- /kpm/patch_linux: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SukiSU-Ultra/SukiSU_patch/bbbe8b07cf672f683009124f74c86cb224cc6b36/kpm/patch_linux -------------------------------------------------------------------------------- /other/zram/lz4k/crypto/lz4k.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Huawei Technologies Co., Ltd. 2012-2020. All rights reserved. 3 | * Description: LZ4K compression algorithm for ZRAM 4 | * Author: Arkhipov Denis arkhipov.denis@huawei.com 5 | * Create: 2020-03-25 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | 17 | struct lz4k_ctx { 18 | void *lz4k_comp_mem; 19 | }; 20 | 21 | static int lz4k_init(struct crypto_tfm *tfm) 22 | { 23 | struct lz4k_ctx *ctx = crypto_tfm_ctx(tfm); 24 | 25 | ctx->lz4k_comp_mem = vmalloc(lz4k_encode_state_bytes_min()); 26 | if (!ctx->lz4k_comp_mem) 27 | return -ENOMEM; 28 | 29 | return 0; 30 | } 31 | 32 | static void lz4k_exit(struct crypto_tfm *tfm) 33 | { 34 | struct lz4k_ctx *ctx = crypto_tfm_ctx(tfm); 35 | vfree(ctx->lz4k_comp_mem); 36 | } 37 | 38 | static int lz4k_compress_crypto(struct crypto_tfm *tfm, const u8 *src, unsigned int slen, u8 *dst, unsigned int *dlen) 39 | { 40 | struct lz4k_ctx *ctx = crypto_tfm_ctx(tfm); 41 | int ret; 42 | 43 | ret = lz4k_encode(ctx->lz4k_comp_mem, src, dst, slen, *dlen, 0); 44 | 45 | if (ret < 0) { 46 | return -EINVAL; 47 | } 48 | 49 | if (ret) 50 | *dlen = ret; 51 | 52 | return 0; 53 | } 54 | 55 | static int lz4k_decompress_crypto(struct crypto_tfm *tfm, const u8 *src, unsigned int slen, u8 *dst, unsigned int *dlen) 56 | { 57 | int ret; 58 | 59 | ret = lz4k_decode(src, dst, slen, *dlen); 60 | 61 | if (ret <= 0) 62 | return -EINVAL; 63 | *dlen = ret; 64 | return 0; 65 | } 66 | 67 | static struct crypto_alg alg_lz4k = { 68 | .cra_name = "lz4k", 69 | .cra_driver_name = "lz4k-generic", 70 | .cra_flags = CRYPTO_ALG_TYPE_COMPRESS, 71 | .cra_ctxsize = sizeof(struct lz4k_ctx), 72 | .cra_module = THIS_MODULE, 73 | .cra_init = lz4k_init, 74 | .cra_exit = lz4k_exit, 75 | .cra_u = { .compress = { 76 | .coa_compress = lz4k_compress_crypto, 77 | .coa_decompress = lz4k_decompress_crypto } } 78 | }; 79 | 80 | static int __init lz4k_mod_init(void) 81 | { 82 | return crypto_register_alg(&alg_lz4k); 83 | } 84 | 85 | static void __exit lz4k_mod_fini(void) 86 | { 87 | crypto_unregister_alg(&alg_lz4k); 88 | } 89 | 90 | subsys_initcall(lz4k_mod_init); 91 | module_exit(lz4k_mod_fini); 92 | 93 | MODULE_LICENSE("GPL"); 94 | MODULE_DESCRIPTION("LZ4K Compression Algorithm"); 95 | MODULE_ALIAS_CRYPTO("lz4k"); 96 | -------------------------------------------------------------------------------- /other/zram/lz4k/crypto/lz4kd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Cryptographic API. 3 | * 4 | * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved. 5 | * Description: LZ4KD compression algorithm for ZRAM 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | 17 | struct lz4kd_ctx { 18 | void *lz4kd_comp_mem; 19 | }; 20 | 21 | static int lz4kd_init(struct crypto_tfm *tfm) 22 | { 23 | struct lz4kd_ctx *ctx = crypto_tfm_ctx(tfm); 24 | 25 | ctx->lz4kd_comp_mem = vmalloc(lz4kd_encode_state_bytes_min()); 26 | if (!ctx->lz4kd_comp_mem) 27 | return -ENOMEM; 28 | 29 | return 0; 30 | } 31 | 32 | static void lz4kd_exit(struct crypto_tfm *tfm) 33 | { 34 | struct lz4kd_ctx *ctx = crypto_tfm_ctx(tfm); 35 | vfree(ctx->lz4kd_comp_mem); 36 | } 37 | 38 | static int lz4kd_compress_crypto(struct crypto_tfm *tfm, const u8 *src, unsigned int slen, u8 *dst, 39 | unsigned int *dlen) 40 | { 41 | struct lz4kd_ctx *ctx = crypto_tfm_ctx(tfm); 42 | int ret = 0; 43 | 44 | ret = lz4kd_encode(ctx->lz4kd_comp_mem, src, dst, slen, *dlen, 0); 45 | if (ret < 0) 46 | return -EINVAL; 47 | 48 | if (ret) 49 | *dlen = ret; 50 | 51 | return 0; 52 | } 53 | 54 | static int lz4kd_decompress_crypto(struct crypto_tfm *tfm, const u8 *src, unsigned int slen, u8 *dst, 55 | unsigned int *dlen) 56 | { 57 | int ret = 0; 58 | 59 | ret = lz4kd_decode(src, dst, slen, *dlen); 60 | if (ret <= 0) 61 | return -EINVAL; 62 | *dlen = ret; 63 | return 0; 64 | } 65 | 66 | #ifdef CONFIG_CRYPTO_DELTA 67 | static int lz4kd_compress_delta_crypto(struct crypto_tfm *tfm, const u8 *src0, const u8 *src, 68 | unsigned int slen, u8 *dst, unsigned int *dlen, unsigned int out_max) 69 | { 70 | struct lz4kd_ctx *ctx = crypto_tfm_ctx(tfm); 71 | int ret = 0; 72 | 73 | ret = lz4kd_encode_delta(ctx->lz4kd_comp_mem, src0, src, dst, slen, *dlen, out_max); 74 | if (ret < 0) 75 | return -EINVAL; 76 | 77 | if (ret) 78 | *dlen = ret; 79 | 80 | return 0; 81 | } 82 | 83 | static int lz4kd_decompress_delta_crypto(struct crypto_tfm *tfm, const u8 *src, unsigned int slen, 84 | const u8 *dst0, u8 *dst, unsigned int *dlen) 85 | { 86 | int ret = 0; 87 | 88 | ret = lz4kd_decode_delta(src, dst0, dst, slen, *dlen); 89 | if (ret <= 0) 90 | return -EINVAL; 91 | *dlen = ret; 92 | return 0; 93 | } 94 | #endif 95 | 96 | static struct crypto_alg alg_lz4kd = { 97 | .cra_name = "lz4kd", 98 | .cra_driver_name = "lz4kd-generic", 99 | #ifdef CONFIG_CRYPTO_DELTA 100 | .cra_flags = CRYPTO_ALG_TYPE_COMPRESS | CRYPTO_ALG_EXT_PROP_DELTA, 101 | #else 102 | .cra_flags = CRYPTO_ALG_TYPE_COMPRESS, 103 | #endif 104 | .cra_ctxsize = sizeof(struct lz4kd_ctx), 105 | .cra_module = THIS_MODULE, 106 | .cra_init = lz4kd_init, 107 | .cra_exit = lz4kd_exit, 108 | .cra_u = { 109 | .compress = { 110 | .coa_compress = lz4kd_compress_crypto, 111 | .coa_decompress = lz4kd_decompress_crypto 112 | #ifdef CONFIG_CRYPTO_DELTA 113 | , 114 | .coa_compress_delta = lz4kd_compress_delta_crypto, 115 | .coa_decompress_delta = lz4kd_decompress_delta_crypto 116 | #endif 117 | } 118 | } 119 | }; 120 | 121 | static int __init lz4kd_mod_init(void) 122 | { 123 | return crypto_register_alg(&alg_lz4kd); 124 | } 125 | 126 | static void __exit lz4kd_mod_fini(void) 127 | { 128 | crypto_unregister_alg(&alg_lz4kd); 129 | } 130 | 131 | module_init(lz4kd_mod_init); 132 | module_exit(lz4kd_mod_fini); 133 | 134 | MODULE_LICENSE("GPL"); 135 | MODULE_DESCRIPTION("LZ4KD Compression Algorithm"); 136 | MODULE_ALIAS_CRYPTO("lz4kd"); 137 | -------------------------------------------------------------------------------- /other/zram/lz4k/include/linux/lz4kd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved. 3 | * Description: LZ4K compression algorithm with delta compression 4 | */ 5 | 6 | #ifndef _LZ4KD_H 7 | #define _LZ4KD_H 8 | 9 | /* file lz4kd.h 10 | This file contains the platform-independent API of LZ-class 11 | lossless codecs (compressors/decompressors) with complete 12 | in-place documentation. The documentation is formatted 13 | in accordance with DOXYGEN mark-up format. So, one can 14 | generate proper documentation, e.g. in HTML format, using DOXYGEN. 15 | 16 | Currently, LZ-class codecs, documented here, implement following 17 | algorithms for lossless data compression/decompression: 18 | \li "LZ" proprietary codec competing with LZ4 - lz4kd_encode(), 19 | lz4kd_encode_delta(), lz4kd_decode(), lz4kd_decode_delta() 20 | 21 | The LZ compressors accept any data as input and compress it 22 | without loss to a smaller size if possible. 23 | Compressed data produced by LZ compressor API lz4kd_encode*(), 24 | can be decompressed only by lz4kd_decode() API documented below.\n 25 | */ 26 | 27 | /* 28 | lz4kd_status defines simple set of status values returned by APIs 29 | */ 30 | typedef enum { 31 | LZ4K_STATUS_INCOMPRESSIBLE = 0, /* !< Return when data is incompressible */ 32 | LZ4K_STATUS_FAILED = -1, /* !< Return on general failure */ 33 | LZ4K_STATUS_READ_ERROR = -2, /* !< Return when data reading failed */ 34 | LZ4K_STATUS_WRITE_ERROR = -3 /* !< Return when data writing failed */ 35 | } lz4kd_status; 36 | 37 | /* 38 | lz4kd_Version() returns static unmutable string with algorithm version 39 | */ 40 | const char *lz4kd_version(void); 41 | 42 | /* 43 | lz4kd_encode_state_bytes_min() returns number of bytes for state parameter, 44 | supplied to lz4kd_encode(), lz4kd_encode_delta(). 45 | So, state should occupy at least lz4kd_encode_state_bytes_min() for mentioned 46 | functions to work correctly. 47 | */ 48 | unsigned lz4kd_encode_state_bytes_min(void); 49 | 50 | /* 51 | lz4kd_encode() encodes/compresses one input buffer at *in, places 52 | result of encoding into one output buffer at *out if encoded data 53 | size fits specified values of out_max and out_limit. 54 | It returs size of encoded data in case of success or value<=0 otherwise. 55 | The result of successful encoding is in proprietary format, that 56 | is the encoded data can be decoded only by lz4kd_decode(). 57 | 58 | \return 59 | \li positive value\n 60 | if encoding was successful. The value returned is the size of encoded 61 | (compressed) data always <=out_max. 62 | \li non-positive value\n 63 | if in==0||in_max==0||out==0||out_max==0 or 64 | if out_max is less than needed for encoded (compressed) data. 65 | \li 0 value\n 66 | if encoded data size >= out_limit 67 | 68 | \param[in] state 69 | !=0, pointer to state buffer used internally by the function. Size of 70 | state in bytes should be at least lz4kd_encode_state_bytes_min(). The content 71 | of state buffer will be changed during encoding. 72 | 73 | \param[in] in 74 | !=0, pointer to the input buffer to encode (compress). The content of 75 | the input buffer does not change during encoding. 76 | 77 | \param[in] out 78 | !=0, pointer to the output buffer where to place result of encoding 79 | (compression). 80 | If encoding is unsuccessful, e.g. out_max or out_limit are less than 81 | needed for encoded data then content of out buffer may be arbitrary. 82 | 83 | \param[in] in_max 84 | !=0, size in bytes of the input buffer at *in 85 | 86 | \param[in] out_max 87 | !=0, size in bytes of the output buffer at *out 88 | 89 | \param[in] out_limit 90 | encoded data size soft limit in bytes. Due to performance reasons it is 91 | not guaranteed that 92 | lz4kd_encode will always detect that resulting encoded data size is 93 | bigger than out_limit. 94 | Hovewer, when reaching out_limit is detected, lz4kd_encode() returns 95 | earlier and spares CPU cycles. Caller code should recheck result 96 | returned by lz4kd_encode() (value greater than 0) if it is really 97 | less or equal than out_limit. 98 | out_limit is ignored if it is equal to 0. 99 | */ 100 | int lz4kd_encode( 101 | void *const state, 102 | const void *const in, 103 | void *out, 104 | unsigned in_max, 105 | unsigned out_max, 106 | unsigned out_limit); 107 | 108 | int lz4kd_encode2( 109 | void *const state, 110 | const void *const in, 111 | void *out, 112 | unsigned in_max, 113 | unsigned out_max, 114 | unsigned out_limit); 115 | 116 | int lz4kd_encode_pattern( 117 | void *const state, 118 | const void *const in, 119 | void *out, 120 | unsigned in_max, 121 | unsigned out_max, 122 | unsigned out_limit); 123 | 124 | /* 125 | lz4kd_encode_max_cr() encodes/compresses one input buffer at *in, places 126 | result of encoding into one output buffer at *out if encoded data 127 | size fits specified value of out_max. 128 | It returs size of encoded data in case of success or value<=0 otherwise. 129 | The result of successful encoding is in proprietary format, that 130 | is the encoded data can be decoded only by lz4kd_decode(). 131 | 132 | \return 133 | \li positive value\n 134 | if encoding was successful. The value returned is the size of encoded 135 | (compressed) data always <=out_max. 136 | \li non-positive value\n 137 | if in==0||in_max==0||out==0||out_max==0 or 138 | if out_max is less than needed for encoded (compressed) data. 139 | 140 | \param[in] state 141 | !=0, pointer to state buffer used internally by the function. Size of 142 | state in bytes should be at least lz4kd_encode_state_bytes_min(). The content 143 | of state buffer will be changed during encoding. 144 | 145 | \param[in] in 146 | !=0, pointer to the input buffer to encode (compress). The content of 147 | the input buffer does not change during encoding. 148 | 149 | \param[in] out 150 | !=0, pointer to the output buffer where to place result of encoding 151 | (compression). 152 | If encoding is unsuccessful, e.g. out_max is less than 153 | needed for encoded data then content of out buffer may be arbitrary. 154 | 155 | \param[in] in_max 156 | !=0, size in bytes of the input buffer at *in 157 | 158 | \param[in] out_max 159 | !=0, size in bytes of the output buffer at *out 160 | 161 | \param[in] out_limit 162 | encoded data size soft limit in bytes. Due to performance reasons it is 163 | not guaranteed that 164 | lz4kd_encode will always detect that resulting encoded data size is 165 | bigger than out_limit. 166 | Hovewer, when reaching out_limit is detected, lz4kd_encode() returns 167 | earlier and spares CPU cycles. Caller code should recheck result 168 | returned by lz4kd_encode() (value greater than 0) if it is really 169 | less or equal than out_limit. 170 | out_limit is ignored if it is equal to 0. 171 | */ 172 | int lz4kd_encode_max_cr( 173 | void *const state, 174 | const void *const in, 175 | void *out, 176 | unsigned in_max, 177 | unsigned out_max, 178 | unsigned out_limit); 179 | 180 | /* 181 | lz4kd_encode_delta() encodes (compresses) data from one input buffer 182 | using one reference buffer as dictionary and places the result of 183 | compression into one output buffer. 184 | The result of successful compression is in proprietary format, so 185 | that compressed data can be decompressed only by lz4kd_decode_delta(). 186 | Reference/dictionary buffer and input buffer should be contiguous in 187 | memory. 188 | 189 | \return 190 | \li positive value\n 191 | if encoding was successful. The value returned is the size of encoded 192 | (compressed) data. 193 | \li non-positive value\n 194 | if state==0||in0==0||in==0||in_max==0||out==0||out_max==0 or 195 | if out_max is less than needed for encoded (compressed) data. 196 | 197 | \param[in] state 198 | !=0, pointer to state buffer used internally by the function. Size of 199 | state in bytes should be at least lz4kd_encode_state_bytes_min(). 200 | The content of state buffer is zeroed at the beginning of 201 | lz4kd_encode_delta(). 202 | The content of state will be changed during encoding. 203 | 204 | \param[in] in0 205 | !=0, pointer to the reference/dictionary input buffer that was used as 206 | input to preceding call of lz4kd_encode(). 207 | The content of the reference/dictionary input buffer does not change 208 | during encoding. 209 | 210 | \param[in] in 211 | !=0, pointer to the input buffer to encode (compress). The input buffer 212 | is compressed using content of the reference/dictionary input buffer at 213 | in0. The content of the input buffer does not change during encoding. 214 | The two buffers - at *in0 and at *in - should be contiguous in memory. 215 | That is, the last byte of buffer at *in0 is located exactly before byte 216 | at *in. 217 | 218 | \param[in] out 219 | !=0, pointer to the output buffer where to place result of encoding 220 | (compression). If compression is unsuccessful then content of out 221 | buffer may be arbitrary. 222 | 223 | \param[in] in_max 224 | !=0, size in bytes of the input buffer at *in 225 | 226 | \param[in] out_max 227 | !=0, size in bytes of the output buffer at *out. 228 | */ 229 | int lz4kd_encode_delta( 230 | void *const state, 231 | const void *const in0, 232 | const void *const in, 233 | void *out, 234 | unsigned in_max, 235 | unsigned out_max, 236 | unsigned out_limit); 237 | 238 | /* 239 | lz4kd_decode() decodes (decompresses) data from one input buffer and places 240 | the result of decompression into one output buffer. The encoded data in input 241 | buffer should be in proprietary format, produced by lz4kd_encode() 242 | or by lz4kd_encode_delta(). 243 | 244 | \return 245 | \li positive value\n 246 | if decoding was successful. The value returned is the size of decoded 247 | (decompressed) data. 248 | \li non-positive value\n 249 | if in==0||in_max==0||out==0||out_max==0 or 250 | if out_max is less than needed for decoded (decompressed) data or 251 | if input encoded data format is corrupted. 252 | 253 | \param[in] in 254 | !=0, pointer to the input buffer to decode (decompress). The content of 255 | the input buffer does not change during decoding. 256 | 257 | \param[in] out 258 | !=0, pointer to the output buffer where to place result of decoding 259 | (decompression). If decompression is unsuccessful then content of out 260 | buffer may be arbitrary. 261 | 262 | \param[in] in_max 263 | !=0, size in bytes of the input buffer at in 264 | 265 | \param[in] out_max 266 | !=0, size in bytes of the output buffer at out 267 | */ 268 | int lz4kd_decode( 269 | const void *const in, 270 | void *const out, 271 | unsigned in_max, 272 | unsigned out_max); 273 | 274 | /* 275 | lz4kd_decode_delta() decodes (decompresses) data from one input buffer 276 | and places the result of decompression into one output buffer. The 277 | compressed data in input buffer should be in format, produced by 278 | lz4kd_encode_delta(). 279 | 280 | Example sequence of calls for lz4kd_decode and lz4kd_decode_delta: 281 | //dictionary (1st) block 282 | int result0=lz4kd_decode(in0, out0, in_max0, out_max0); 283 | //delta (2nd) block 284 | int result1=lz4kd_decode_delta(in, out0, out, in_max, out_max); 285 | 286 | \return 287 | \li positive value\n 288 | if decoding was successful. The value returned is the size of decoded 289 | (decompressed) data. 290 | \li non-positive value\n 291 | if in==0||in_max==0||out==0||out_max==0 or 292 | if out_max is less than needed for decoded (decompressed) data or 293 | if input data format is corrupted. 294 | 295 | \param[in] in 296 | !=0, pointer to the input buffer to decode (decompress). The content of 297 | the input buffer does not change during decoding. 298 | 299 | \param[in] out0 300 | !=0, pointer to the dictionary input buffer that was used as in0 input to 301 | lz4kd_encode_delta(). The content 302 | of the dictionary input buffer does not change during decoding. 303 | 304 | \param[in] out 305 | !=0, pointer to the output buffer where to place result of decoding 306 | (decompression). If decompression is unsuccessful then content of out 307 | buffer may be arbitrary. 308 | The two buffers - at *out0 and at *out - should be contiguous in memory. 309 | That is, the last byte of buffer at *out0 is located exactly before byte 310 | at *out. 311 | 312 | \param[in] in_max 313 | !=0, size in bytes of the input buffer at *in 314 | 315 | \param[in] out_max 316 | !=0, size in bytes of the output buffer at *out 317 | */ 318 | int lz4kd_decode_delta( 319 | const void *in, 320 | const void *const out0, 321 | void *const out, 322 | unsigned in_max, 323 | unsigned out_max); 324 | 325 | 326 | #endif /* _LZ4KD_H */ 327 | -------------------------------------------------------------------------------- /other/zram/lz4k/lib/lz4k/Makefile: -------------------------------------------------------------------------------- 1 | obj-$(CONFIG_LZ4K_COMPRESS) += lz4k_encode.o 2 | obj-$(CONFIG_LZ4K_DECOMPRESS) += lz4k_decode.o -------------------------------------------------------------------------------- /other/zram/lz4k/lib/lz4k/lz4k_decode.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Huawei Technologies Co., Ltd. 2012-2020. All rights reserved. 3 | * Description: LZ4K compression algorithm 4 | * Author: Aleksei Romanovskii aleksei.romanovskii@huawei.com 5 | * Created: 2020-03-25 6 | */ 7 | 8 | #if !defined(__KERNEL__) 9 | #include "lz4k.h" 10 | #else 11 | #include 12 | #include 13 | #endif 14 | 15 | #include "lz4k_private.h" /* types, etc */ 16 | 17 | static const uint8_t *get_size( 18 | uint_fast32_t *size, 19 | const uint8_t *in_at, 20 | const uint8_t *const in_end) 21 | { 22 | uint_fast32_t u; 23 | do { 24 | if (unlikely(in_at >= in_end)) 25 | return NULL; 26 | *size += (u = *(const uint8_t*)in_at); 27 | ++in_at; 28 | } while (BYTE_MAX == u); 29 | return in_at; 30 | } /* get_size */ 31 | 32 | static int end_of_block( 33 | const uint_fast32_t nr_bytes_max, 34 | const uint_fast32_t r_bytes_max, 35 | const uint8_t *const in_at, 36 | const uint8_t *const in_end, 37 | const uint8_t *const out, 38 | const uint8_t *const out_at) 39 | { 40 | if (!nr_bytes_max) 41 | return LZ4K_STATUS_FAILED; /* should be the last one in block */ 42 | if (r_bytes_max != REPEAT_MIN) 43 | return LZ4K_STATUS_FAILED; /* should be the last one in block */ 44 | if (in_at != in_end) 45 | return LZ4K_STATUS_FAILED; /* should be the last one in block */ 46 | return (int)(out_at - out); 47 | } 48 | 49 | enum { 50 | NR_COPY_MIN = 16, 51 | R_COPY_MIN = 16, 52 | R_COPY_SAFE = R_COPY_MIN - 1, 53 | R_COPY_SAFE_2X = (R_COPY_MIN << 1) - 1 54 | }; 55 | 56 | static bool out_non_repeat( 57 | const uint8_t **in_at, 58 | uint8_t **out_at, 59 | uint_fast32_t nr_bytes_max, 60 | const uint8_t *const in_end, 61 | const uint8_t *const out_end) 62 | { 63 | const uint8_t *const in_copy_end = *in_at + nr_bytes_max; 64 | uint8_t *const out_copy_end = *out_at + nr_bytes_max; 65 | if (likely(nr_bytes_max <= NR_COPY_MIN)) { 66 | if (likely(*in_at <= in_end - NR_COPY_MIN && 67 | *out_at <= out_end - NR_COPY_MIN)) 68 | m_copy(*out_at, *in_at, NR_COPY_MIN); 69 | else if (in_copy_end <= in_end && out_copy_end <= out_end) 70 | m_copy(*out_at, *in_at, nr_bytes_max); 71 | else 72 | return false; 73 | } else { /* nr_bytes_max>NR_COPY_MIN */ 74 | if (likely(in_copy_end <= in_end - NR_COPY_MIN && 75 | out_copy_end <= out_end - NR_COPY_MIN)) { 76 | m_copy(*out_at, *in_at, NR_COPY_MIN); 77 | copy_x_while_lt(*out_at + NR_COPY_MIN, 78 | *in_at + NR_COPY_MIN, 79 | out_copy_end, NR_COPY_MIN); 80 | } else if (in_copy_end <= in_end && out_copy_end <= out_end) { 81 | m_copy(*out_at, *in_at, nr_bytes_max); 82 | } else { /* in_copy_end > in_end || out_copy_end > out_end */ 83 | return false; 84 | } 85 | } /* if (nr_bytes_max <= NR_COPY_MIN) */ 86 | *in_at = in_copy_end; 87 | *out_at = out_copy_end; 88 | return true; 89 | } /* out_non_repeat */ 90 | 91 | static void out_repeat_overlap( 92 | uint_fast32_t offset, 93 | uint8_t *out_at, 94 | const uint8_t *out_from, 95 | const uint8_t *const out_copy_end) 96 | { /* (1 < offset < R_COPY_MIN/2) && out_copy_end + R_COPY_SAFE_2X <= out_end */ 97 | enum { 98 | COPY_MIN = R_COPY_MIN >> 1, 99 | OFFSET_LIMIT = COPY_MIN >> 1 100 | }; 101 | m_copy(out_at, out_from, COPY_MIN); 102 | out_at += offset; 103 | if (offset <= OFFSET_LIMIT) 104 | offset <<= 1; 105 | do { 106 | m_copy(out_at, out_from, COPY_MIN); 107 | out_at += offset; 108 | if (offset <= OFFSET_LIMIT) 109 | offset <<= 1; 110 | } while (out_at - out_from < R_COPY_MIN); 111 | while_lt_copy_2x_as_x2(out_at, out_from, out_copy_end, R_COPY_MIN); 112 | } /* out_repeat_overlap */ 113 | 114 | static bool out_repeat_slow( 115 | uint_fast32_t r_bytes_max, 116 | uint_fast32_t offset, 117 | uint8_t *out_at, 118 | const uint8_t *out_from, 119 | const uint8_t *const out_copy_end, 120 | const uint8_t *const out_end) 121 | { 122 | if (offset > 1 && out_copy_end <= out_end - R_COPY_SAFE_2X) { 123 | out_repeat_overlap(offset, out_at, out_from, out_copy_end); 124 | } else { 125 | if (unlikely(out_copy_end > out_end)) 126 | return false; 127 | if (offset == 1) { 128 | m_set(out_at, *out_from, r_bytes_max); 129 | } else { 130 | do 131 | *out_at++ = *out_from++; 132 | while (out_at < out_copy_end); 133 | } 134 | } 135 | return true; 136 | } 137 | 138 | static int decode( 139 | const uint8_t *const in, 140 | const uint8_t *const out0, 141 | uint8_t *const out, 142 | const uint8_t *const in_end, 143 | const uint8_t *const out_end, 144 | const uint_fast32_t nr_log2, 145 | const uint_fast32_t off_log2) 146 | { 147 | const uint_fast32_t r_log2 = TAG_BITS_MAX - (off_log2 + nr_log2); 148 | const uint8_t *in_at = in; 149 | const uint8_t *const in_end_minus_x = in_end - TAG_BYTES_MAX; 150 | uint8_t *out_at = out; 151 | while (likely(in_at <= in_end_minus_x)) { 152 | const uint_fast32_t utag = read4_at(in_at - 1) >> BYTE_BITS; 153 | const uint_fast32_t offset = utag & mask(off_log2); 154 | uint_fast32_t nr_bytes_max = utag >> (off_log2 + r_log2), 155 | r_bytes_max = ((utag >> off_log2) & mask(r_log2)) + 156 | REPEAT_MIN; 157 | const uint8_t *out_from = 0; 158 | uint8_t *out_copy_end = 0; 159 | in_at += TAG_BYTES_MAX; 160 | if (unlikely(nr_bytes_max == mask(nr_log2))) { 161 | in_at = get_size(&nr_bytes_max, in_at, in_end); 162 | if (in_at == NULL) 163 | return LZ4K_STATUS_READ_ERROR; 164 | } 165 | if (!out_non_repeat(&in_at, &out_at, nr_bytes_max, in_end, out_end)) 166 | return LZ4K_STATUS_FAILED; 167 | if (unlikely(r_bytes_max == mask(r_log2) + REPEAT_MIN)) { 168 | in_at = get_size(&r_bytes_max, in_at, in_end); 169 | if (in_at == NULL) 170 | return LZ4K_STATUS_READ_ERROR; 171 | } 172 | out_from = out_at - offset; 173 | if (unlikely(out_from < out0)) 174 | return LZ4K_STATUS_FAILED; 175 | out_copy_end = out_at + r_bytes_max; 176 | if (likely(offset >= R_COPY_MIN && 177 | out_copy_end <= out_end - R_COPY_SAFE_2X)) { 178 | copy_2x_as_x2_while_lt(out_at, out_from, out_copy_end, 179 | R_COPY_MIN); 180 | } else if (likely(offset >= (R_COPY_MIN >> 1) && 181 | out_copy_end <= out_end - R_COPY_SAFE_2X)) { 182 | m_copy(out_at, out_from, R_COPY_MIN); 183 | out_at += offset; 184 | while_lt_copy_x(out_at, out_from, out_copy_end, R_COPY_MIN); 185 | /* faster than 2x */ 186 | } else if (likely(offset > 0)) { 187 | if (!out_repeat_slow(r_bytes_max, offset, out_at, out_from, 188 | out_copy_end, out_end)) 189 | return LZ4K_STATUS_FAILED; 190 | } else { /* offset == 0: EOB, last literal */ 191 | return end_of_block(nr_bytes_max, r_bytes_max, in_at, 192 | in_end, out, out_at); 193 | } 194 | out_at = out_copy_end; 195 | } /* while (likely(in_at <= in_end_minus_x)) */ 196 | return in_at == in_end ? (int)(out_at - out) : LZ4K_STATUS_FAILED; 197 | } /* decode */ 198 | 199 | static int decode4kb( 200 | const uint8_t *const in, 201 | const uint8_t *const out0, 202 | uint8_t *const out, 203 | const uint8_t *const in_end, 204 | const uint8_t *const out_end) 205 | { 206 | enum { 207 | NR_LOG2 = 6 208 | }; 209 | return decode(in, out0, out, in_end, out_end, NR_LOG2, BLOCK_4KB_LOG2); 210 | } /* decode4kb */ 211 | 212 | static int decode8kb( 213 | const uint8_t *const in, 214 | const uint8_t *const out0, 215 | uint8_t *const out, 216 | const uint8_t *const in_end, 217 | const uint8_t *const out_end) 218 | { 219 | enum { 220 | NR_LOG2 = 5 221 | }; 222 | return decode(in, out0, out, in_end, out_end, NR_LOG2, BLOCK_8KB_LOG2); 223 | } /* decode8kb */ 224 | 225 | static int decode16kb( 226 | const uint8_t *const in, 227 | const uint8_t *const out0, 228 | uint8_t *const out, 229 | const uint8_t *const in_end, 230 | const uint8_t *const out_end) 231 | { 232 | enum { 233 | NR_LOG2 = 5 234 | }; 235 | return decode(in, out0, out, in_end, out_end, NR_LOG2, BLOCK_16KB_LOG2); 236 | } /* decode16kb */ 237 | 238 | static int decode32kb( 239 | const uint8_t *const in, 240 | const uint8_t *const out0, 241 | uint8_t *const out, 242 | const uint8_t *const in_end, 243 | const uint8_t *const out_end) 244 | { 245 | enum { 246 | NR_LOG2 = 4 247 | }; 248 | return decode(in, out0, out, in_end, out_end, NR_LOG2, BLOCK_32KB_LOG2); 249 | } /* decode32kb */ 250 | 251 | static int decode64kb( 252 | const uint8_t *const in, 253 | const uint8_t *const out0, 254 | uint8_t *const out, 255 | const uint8_t *const in_end, 256 | const uint8_t *const out_end) 257 | { 258 | enum { 259 | NR_LOG2 = 4 260 | }; 261 | return decode(in, out0, out, in_end, out_end, NR_LOG2, BLOCK_64KB_LOG2); 262 | } /* decode64kb */ 263 | 264 | inline static const void *u8_inc(const uint8_t *a) 265 | { 266 | return a+1; 267 | } 268 | 269 | int lz4k_decode( 270 | const void *in, 271 | void *const out, 272 | unsigned in_max, 273 | unsigned out_max) 274 | { 275 | /* ++use volatile pointers to prevent compiler optimizations */ 276 | const uint8_t *volatile in_end = (const uint8_t*)in + in_max; 277 | const uint8_t *volatile out_end = (uint8_t*)out + out_max; 278 | uint8_t in_log2 = 0; 279 | if (unlikely(in == NULL || out == NULL || in_max <= 4 || out_max <= 0)) 280 | return LZ4K_STATUS_FAILED; 281 | in_log2 = (uint8_t)(BLOCK_4KB_LOG2 + *(const uint8_t*)in); 282 | /* invalid buffer size or pointer overflow */ 283 | if (unlikely((const uint8_t*)in >= in_end || (uint8_t*)out >= out_end)) 284 | return LZ4K_STATUS_FAILED; 285 | /* -- */ 286 | in = u8_inc((const uint8_t*)in); 287 | --in_max; 288 | if (in_log2 < BLOCK_8KB_LOG2) 289 | return decode4kb((const uint8_t*)in, (uint8_t*)out, 290 | (uint8_t*)out, in_end, out_end); 291 | if (in_log2 == BLOCK_8KB_LOG2) 292 | return decode8kb((const uint8_t*)in, (uint8_t*)out, 293 | (uint8_t*)out, in_end, out_end); 294 | if (in_log2 == BLOCK_16KB_LOG2) 295 | return decode16kb((const uint8_t*)in, (uint8_t*)out, 296 | (uint8_t*)out, in_end, out_end); 297 | if (in_log2 == BLOCK_32KB_LOG2) 298 | return decode32kb((const uint8_t*)in, (uint8_t*)out, 299 | (uint8_t*)out, in_end, out_end); 300 | if (in_log2 == BLOCK_64KB_LOG2) 301 | return decode64kb((const uint8_t*)in, (uint8_t*)out, 302 | (uint8_t*)out, in_end, out_end); 303 | return LZ4K_STATUS_FAILED; 304 | } /* lz4k_decode */ 305 | /*lint -e580*/ 306 | EXPORT_SYMBOL(lz4k_decode); 307 | /*lint +e580*/ 308 | 309 | MODULE_LICENSE("Dual BSD/GPL"); 310 | MODULE_DESCRIPTION("LZ4K decoder"); 311 | -------------------------------------------------------------------------------- /other/zram/lz4k/lib/lz4k/lz4k_encode_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Huawei Technologies Co., Ltd. 2012-2020. All rights reserved. 3 | * Description: LZ4K compression algorithm 4 | * Author: Aleksei Romanovskii aleksei.romanovskii@huawei.com 5 | * Created: 2020-03-25 6 | */ 7 | 8 | #ifndef _LZ4K_ENCODE_PRIVATE_H 9 | #define _LZ4K_ENCODE_PRIVATE_H 10 | 11 | #include "lz4k_private.h" 12 | 13 | /* +<1 terminating 0 byte> */ 14 | inline static uint_fast32_t size_bytes_count(uint_fast32_t u) 15 | { 16 | return (u + BYTE_MAX - 1) / BYTE_MAX; 17 | } 18 | 19 | /* minimum encoded size for non-compressible data */ 20 | inline static uint_fast32_t encoded_bytes_min( 21 | uint_fast32_t nr_log2, 22 | uint_fast32_t in_max) 23 | { 24 | return in_max < mask(nr_log2) ? 25 | TAG_BYTES_MAX + in_max : 26 | TAG_BYTES_MAX + size_bytes_count(in_max - mask(nr_log2)) + in_max; 27 | } 28 | 29 | enum { 30 | NR_COPY_LOG2 = 4, 31 | NR_COPY_MIN = 1 << NR_COPY_LOG2 32 | }; 33 | 34 | inline static uint_fast32_t u_32(int64_t i) 35 | { 36 | return (uint_fast32_t)i; 37 | } 38 | 39 | /* maximum encoded size for non-comprressible data if "fast" encoder is used */ 40 | inline static uint_fast32_t encoded_bytes_max( 41 | uint_fast32_t nr_log2, 42 | uint_fast32_t in_max) 43 | { 44 | uint_fast32_t r = TAG_BYTES_MAX + (uint32_t)round_up_to_log2(in_max, NR_COPY_LOG2); 45 | return in_max < mask(nr_log2) ? r : r + size_bytes_count(in_max - mask(nr_log2)); 46 | } 47 | 48 | enum { 49 | HT_LOG2 = 12 50 | }; 51 | 52 | /* 53 | * Compressed data format (where {} means 0 or more occurrences, [] means 54 | * optional): 55 | * <24bits tag: (off_log2 rOffset| r_log2 rSize|nr_log2 nrSize)> 56 | * {}[]{} 57 | * and bytes are terminated by byte != 255 58 | * 59 | */ 60 | 61 | inline static void update_utag( 62 | uint_fast32_t r_bytes_max, 63 | uint_fast32_t *utag, 64 | const uint_fast32_t nr_log2, 65 | const uint_fast32_t off_log2) 66 | { 67 | const uint_fast32_t r_mask = mask(TAG_BITS_MAX - (off_log2 + nr_log2)); 68 | *utag |= likely(r_bytes_max - REPEAT_MIN < r_mask) ? 69 | ((r_bytes_max - REPEAT_MIN) << off_log2) : (r_mask << off_log2); 70 | } 71 | 72 | inline static const uint8_t *hashed( 73 | const uint8_t *const in0, 74 | uint16_t *const ht, 75 | uint_fast32_t h, 76 | const uint8_t *r) 77 | { 78 | const uint8_t *q = in0 + ht[h]; 79 | ht[h] = (uint16_t)(r - in0); 80 | return q; 81 | } 82 | 83 | inline static const uint8_t *repeat_start( 84 | const uint8_t *q, 85 | const uint8_t *r, 86 | const uint8_t *const nr0, 87 | const uint8_t *const in0) 88 | { 89 | for (; r > nr0 && likely(q > in0) && unlikely(q[-1] == r[-1]); --q, --r); 90 | return r; 91 | } /* repeat_start */ 92 | 93 | int lz4k_out_tail( 94 | uint8_t *out_at, 95 | uint8_t *const out_end, 96 | const uint8_t *const out, 97 | const uint8_t *const nr0, 98 | const uint8_t *const in_end, 99 | const uint_fast32_t nr_log2, 100 | const uint_fast32_t off_log2, 101 | bool check_out); 102 | 103 | uint8_t *lz4k_out_non_repeat( 104 | uint8_t *out_at, 105 | uint8_t *const out_end, 106 | uint_fast32_t utag, 107 | const uint8_t *const nr0, 108 | const uint8_t *const r, 109 | const uint_fast32_t nr_log2, 110 | const uint_fast32_t off_log2, 111 | bool check_out); 112 | 113 | uint8_t *lz4k_out_r_bytes_left( 114 | uint8_t *out_at, 115 | uint8_t *const out_end, 116 | uint_fast32_t r_bytes_max, 117 | const uint_fast32_t nr_log2, 118 | const uint_fast32_t off_log2, 119 | const bool check_out); 120 | 121 | uint8_t *lz4k_out_repeat( 122 | uint8_t *out_at, 123 | uint8_t *const out_end, 124 | uint_fast32_t utag, 125 | uint_fast32_t r_bytes_max, 126 | const uint_fast32_t nr_log2, 127 | const uint_fast32_t off_log2, 128 | const bool check_out); 129 | 130 | const uint8_t *lz4k_repeat_end( 131 | const uint8_t *q, 132 | const uint8_t *r, 133 | const uint8_t *const in_end_safe, 134 | const uint8_t *const in_end); 135 | 136 | #endif /* _LZ4K_ENCODE_PRIVATE_H */ 137 | 138 | -------------------------------------------------------------------------------- /other/zram/lz4k/lib/lz4k/lz4k_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Huawei Technologies Co., Ltd. 2012-2020. All rights reserved. 3 | * Description: LZ4K compression algorithm 4 | * Author: Aleksei Romanovskii aleksei.romanovskii@huawei.com 5 | * Created: 2020-03-25 6 | */ 7 | 8 | #ifndef _LZ4K_PRIVATE_H 9 | #define _LZ4K_PRIVATE_H 10 | 11 | #if !defined(__KERNEL__) 12 | 13 | #include "lz4k.h" 14 | #include /* uint*_t */ 15 | #define __STDC_WANT_LIB_EXT1__ 1 16 | #include /* memcpy() */ 17 | 18 | #define likely(e) __builtin_expect(e, 1) 19 | #define unlikely(e) __builtin_expect(e, 0) 20 | 21 | #else /* __KERNEL__ */ 22 | 23 | #include 24 | #define __STDC_WANT_LIB_EXT1__ 1 25 | #include /* memcpy() */ 26 | #include /* uint8_t, int8_t, uint16_t, int16_t, 27 | uint32_t, int32_t, uint64_t, int64_t */ 28 | #include 29 | 30 | typedef uint64_t uint_fast32_t; 31 | typedef int64_t int_fast32_t; 32 | 33 | #endif /* __KERNEL__ */ 34 | 35 | #if defined(__GNUC__) && (__GNUC__>=4) 36 | #define LZ4K_WITH_GCC_INTRINSICS 37 | #endif 38 | 39 | #if !defined(__GNUC__) 40 | #define __builtin_expect(e, v) (e) 41 | #endif /* defined(__GNUC__) */ 42 | 43 | enum { 44 | BYTE_BITS = 8, 45 | BYTE_BITS_LOG2 = 3, 46 | BYTE_MAX = 255U, 47 | REPEAT_MIN = 4, 48 | TAG_BYTES_MAX = 3, 49 | TAG_BITS_MAX = TAG_BYTES_MAX * 8, 50 | BLOCK_4KB_LOG2 = 12, 51 | BLOCK_8KB_LOG2 = 13, 52 | BLOCK_16KB_LOG2 = 14, 53 | BLOCK_32KB_LOG2 = 15, 54 | BLOCK_64KB_LOG2 = 16 55 | }; 56 | 57 | inline static uint32_t mask(uint_fast32_t log2) 58 | { 59 | return (1U << log2) - 1U; 60 | } 61 | 62 | inline static uint64_t mask64(uint_fast32_t log2) 63 | { 64 | return (1ULL << log2) - 1ULL; 65 | } 66 | 67 | #if defined LZ4K_WITH_GCC_INTRINSICS 68 | inline static int most_significant_bit_of(uint64_t u) 69 | { 70 | return (int)(__builtin_expect((u) == 0, false) ? 71 | -1 : (int)(31 ^ (uint32_t)__builtin_clz((unsigned)(u)))); 72 | } 73 | #else /* #!defined LZ4K_WITH_GCC_INTRINSICS */ 74 | #error undefined most_significant_bit_of(unsigned u) 75 | #endif /* #if defined LZ4K_WITH_GCC_INTRINSICS */ 76 | 77 | inline static uint64_t round_up_to_log2(uint64_t u, uint8_t log2) 78 | { 79 | return (uint64_t)((u + mask64(log2)) & ~mask64(log2)); 80 | } /* round_up_to_log2 */ 81 | 82 | inline static uint64_t round_up_to_power_of2(uint64_t u) 83 | { 84 | const int_fast32_t msb = most_significant_bit_of(u); 85 | return round_up_to_log2(u, (uint8_t)msb); 86 | } /* round_up_to_power_of2 */ 87 | 88 | inline static void m_copy(void *dst, const void *src, size_t total) 89 | { 90 | #if defined(__STDC_LIB_EXT1__) 91 | (void)memcpy_s(dst, total, src, (total * 2) >> 1); /* *2 >> 1 to avoid bot errors */ 92 | #else 93 | (void)__builtin_memcpy(dst, src, total); 94 | #endif 95 | } 96 | 97 | inline static void m_set(void *dst, uint8_t value, size_t total) 98 | { 99 | #if defined(__STDC_LIB_EXT1__) 100 | (void)memset_s(dst, total, value, (total * 2) >> 1); /* *2 >> 1 to avoid bot errors */ 101 | #else 102 | (void)__builtin_memset(dst, value, total); 103 | #endif 104 | } 105 | 106 | inline static uint32_t read4_at(const void *p) 107 | { 108 | uint32_t result; 109 | m_copy(&result, p, sizeof(result)); 110 | return result; 111 | } 112 | 113 | inline static uint64_t read8_at(const void *p) 114 | { 115 | uint64_t result; 116 | m_copy(&result, p, sizeof(result)); 117 | return result; 118 | } 119 | 120 | inline static bool equal4(const uint8_t *const q, const uint8_t *const r) 121 | { 122 | return read4_at(q) == read4_at(r); 123 | } 124 | 125 | inline static bool equal3(const uint8_t *const q, const uint8_t *const r) 126 | { 127 | return (read4_at(q) << BYTE_BITS) == (read4_at(r) << BYTE_BITS); 128 | } 129 | 130 | inline static uint_fast32_t hash24v(const uint64_t r, uint32_t shift) 131 | { 132 | const uint32_t m = 3266489917U; 133 | return (((uint32_t)r << BYTE_BITS) * m) >> (32 - shift); 134 | } 135 | 136 | inline static uint_fast32_t hash24(const uint8_t *r, uint32_t shift) 137 | { 138 | return hash24v(read4_at(r), shift); 139 | } 140 | 141 | inline static uint_fast32_t hash32v_2(const uint64_t r, uint32_t shift) 142 | { 143 | const uint32_t m = 3266489917U; 144 | return ((uint32_t)r * m) >> (32 - shift); 145 | } 146 | 147 | inline static uint_fast32_t hash32_2(const uint8_t *r, uint32_t shift) 148 | { 149 | return hash32v_2(read4_at(r), shift); 150 | } 151 | 152 | inline static uint_fast32_t hash32v(const uint64_t r, uint32_t shift) 153 | { 154 | const uint32_t m = 2654435761U; 155 | return ((uint32_t)r * m) >> (32 - shift); 156 | } 157 | 158 | inline static uint_fast32_t hash32(const uint8_t *r, uint32_t shift) 159 | { 160 | return hash32v(read4_at(r), shift); 161 | } 162 | 163 | inline static uint_fast32_t hash64v_5b(const uint64_t r, uint32_t shift) 164 | { 165 | const uint64_t m = 889523592379ULL; 166 | return (uint32_t)(((r << 24) * m) >> (64 - shift)); 167 | } 168 | 169 | inline static uint_fast32_t hash64_5b(const uint8_t *r, uint32_t shift) 170 | { 171 | return hash64v_5b(read8_at(r), shift); 172 | } 173 | 174 | inline static uint_fast32_t hash64v_6b(const uint64_t r, uint32_t shift) 175 | { 176 | const uint64_t m = 227718039650203ULL; 177 | return (uint32_t)(((r << 16) * m) >> (64 - shift)); 178 | } 179 | 180 | inline static uint_fast32_t hash64_6b(const uint8_t *r, uint32_t shift) 181 | { 182 | return hash64v_6b(read8_at(r), shift); 183 | } 184 | 185 | inline static uint_fast32_t hash64v_7b(const uint64_t r, uint32_t shift) 186 | { 187 | const uint64_t m = 58295818150454627ULL; 188 | return (uint32_t)(((r << 8) * m) >> (64 - shift)); 189 | } 190 | 191 | inline static uint_fast32_t hash64_7b(const uint8_t *r, uint32_t shift) 192 | { 193 | return hash64v_7b(read8_at(r), shift); 194 | } 195 | 196 | inline static uint_fast32_t hash64v_8b(const uint64_t r, uint32_t shift) 197 | { 198 | const uint64_t m = 2870177450012600261ULL; 199 | return (uint32_t)((r * m) >> (64 - shift)); 200 | } 201 | 202 | inline static uint_fast32_t hash64_8b(const uint8_t *r, uint32_t shift) 203 | { 204 | return hash64v_8b(read8_at(r), shift); 205 | } 206 | 207 | inline static void while_lt_copy_x( 208 | uint8_t *dst, 209 | const uint8_t *src, 210 | const uint8_t *dst_end, 211 | const size_t copy_min) 212 | { 213 | for (; dst < dst_end; dst += copy_min, src += copy_min) 214 | m_copy(dst, src, copy_min); 215 | } 216 | 217 | inline static void copy_x_while_lt( 218 | uint8_t *dst, 219 | const uint8_t *src, 220 | const uint8_t *dst_end, 221 | const size_t copy_min) 222 | { 223 | m_copy(dst, src, copy_min); 224 | while (dst + copy_min < dst_end) 225 | m_copy(dst += copy_min, src += copy_min, copy_min); 226 | } 227 | 228 | inline static void copy_x_while_total( 229 | uint8_t *dst, 230 | const uint8_t *src, 231 | size_t total, 232 | const size_t copy_min) 233 | { 234 | m_copy(dst, src, copy_min); 235 | for (; total > copy_min; total-= copy_min) 236 | m_copy(dst += copy_min, src += copy_min, copy_min); 237 | } /* copy_x_while_total */ 238 | 239 | inline static void copy_2x( 240 | uint8_t *dst, 241 | const uint8_t *src, 242 | const size_t copy_min) 243 | { 244 | m_copy(dst, src, copy_min); 245 | m_copy(dst + copy_min, src + copy_min, copy_min); 246 | } 247 | 248 | inline static void copy_2x_as_x2_while_lt( 249 | uint8_t *dst, 250 | const uint8_t *src, 251 | const uint8_t *dst_end, 252 | const size_t copy_min) 253 | { 254 | copy_2x(dst, src, copy_min); 255 | while (dst + (copy_min << 1) < dst_end) 256 | copy_2x(dst += (copy_min << 1), src += (copy_min << 1), copy_min); 257 | } 258 | 259 | inline static void while_lt_copy_2x_as_x2( 260 | uint8_t *dst, 261 | const uint8_t *src, 262 | const uint8_t *dst_end, 263 | const size_t copy_min) 264 | { 265 | for (; dst < dst_end; dst += (copy_min << 1), src += (copy_min << 1)) 266 | copy_2x(dst, src, copy_min); 267 | } 268 | 269 | #endif /* _LZ4K_PRIVATE_H */ 270 | -------------------------------------------------------------------------------- /other/zram/lz4k/lib/lz4kd/Makefile: -------------------------------------------------------------------------------- 1 | ccflags-y += -DLZ4K_DELTA -O3 2 | obj-$(CONFIG_LZ4KD_COMPRESS) += lz4kd_encode.o lz4kd_encode_delta.o 3 | obj-$(CONFIG_LZ4KD_DECOMPRESS) += lz4kd_decode.o lz4kd_decode_delta.o 4 | -------------------------------------------------------------------------------- /other/zram/lz4k/lib/lz4kd/lz4kd_decode.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved. 3 | * Description: LZ4K compression algorithm with delta compression 4 | */ 5 | 6 | #if !defined(__KERNEL__) 7 | #include "lz4kd.h" 8 | #else 9 | #include 10 | #include 11 | #endif 12 | 13 | #include "lz4kd_private.h" /* types, etc */ 14 | 15 | static const uint8_t *get_size( 16 | uint_fast32_t *size, 17 | const uint8_t *in_at, 18 | const uint8_t *const in_end) 19 | { 20 | uint_fast32_t u; 21 | do { 22 | if (unlikely(in_at >= in_end)) 23 | return NULL; 24 | *size += (u = *(const uint8_t*)in_at); 25 | ++in_at; 26 | } while (BYTE_MAX == u); 27 | return in_at; 28 | } 29 | 30 | static int end_of_block( 31 | const uint_fast32_t nr_bytes_max, 32 | const uint_fast32_t r_bytes_max, 33 | const uint8_t *const in_at, 34 | const uint8_t *const in_end, 35 | const uint8_t *const out, 36 | const uint8_t *const out_at) 37 | { 38 | if (!nr_bytes_max) 39 | return LZ4K_STATUS_FAILED; /* should be the last one in block */ 40 | if (r_bytes_max != REPEAT_MIN) 41 | return LZ4K_STATUS_FAILED; /* should be the last one in block */ 42 | if (in_at != in_end) 43 | return LZ4K_STATUS_FAILED; /* should be the last one in block */ 44 | return (int)(out_at - out); 45 | } 46 | 47 | enum { 48 | NR_COPY_MIN = 16, 49 | R_COPY_MIN = 16, 50 | R_COPY_SAFE = R_COPY_MIN - 1, 51 | R_COPY_SAFE_2X = (R_COPY_MIN << 1) - 1 52 | }; 53 | 54 | static bool out_non_repeat( 55 | const uint8_t **in_at, 56 | uint8_t **out_at, 57 | uint_fast32_t nr_bytes_max, 58 | const uint8_t *const in_end, 59 | const uint8_t *const out_end) 60 | { 61 | const uint8_t *const in_copy_end = *in_at + nr_bytes_max; 62 | uint8_t *const out_copy_end = *out_at + nr_bytes_max; 63 | if (likely(nr_bytes_max <= NR_COPY_MIN)) { 64 | if (likely(*in_at <= in_end - NR_COPY_MIN && 65 | *out_at <= out_end - NR_COPY_MIN)) 66 | m_copy(*out_at, *in_at, NR_COPY_MIN); 67 | else if (in_copy_end <= in_end && out_copy_end <= out_end) 68 | m_copy(*out_at, *in_at, nr_bytes_max); 69 | else 70 | return false; 71 | } else { /* nr_bytes_max>NR_COPY_MIN */ 72 | if (likely(in_copy_end <= in_end - NR_COPY_MIN && 73 | out_copy_end <= out_end - NR_COPY_MIN)) { 74 | m_copy(*out_at, *in_at, NR_COPY_MIN); 75 | copy_x_while_lt(*out_at + NR_COPY_MIN, 76 | *in_at + NR_COPY_MIN, 77 | out_copy_end, NR_COPY_MIN); 78 | } else if (in_copy_end <= in_end && out_copy_end <= out_end) { 79 | m_copy(*out_at, *in_at, nr_bytes_max); 80 | } else { /* in_copy_end > in_end || out_copy_end > out_end */ 81 | return false; 82 | } 83 | } /* if (nr_bytes_max <= NR_COPY_MIN) */ 84 | *in_at = in_copy_end; 85 | *out_at = out_copy_end; 86 | return true; 87 | } 88 | 89 | static void out_repeat_overlap( 90 | uint_fast32_t offset, 91 | uint8_t *out_at, 92 | const uint8_t *out_from, 93 | const uint8_t *const out_copy_end) 94 | { 95 | enum { 96 | COPY_MIN = R_COPY_MIN >> 1, 97 | OFFSET_LIMIT = COPY_MIN >> 1 98 | }; 99 | m_copy(out_at, out_from, COPY_MIN); 100 | /* (1 < offset < R_COPY_MIN/2) && out_copy_end + R_COPY_SAFE_2X <= out_end */ 101 | out_at += offset; 102 | if (offset <= OFFSET_LIMIT) 103 | offset <<= 1; 104 | do { 105 | m_copy(out_at, out_from, COPY_MIN); 106 | out_at += offset; 107 | if (offset <= OFFSET_LIMIT) 108 | offset <<= 1; 109 | } while (out_at - out_from < R_COPY_MIN); 110 | while_lt_copy_2x_as_x2(out_at, out_from, out_copy_end, R_COPY_MIN); 111 | } 112 | 113 | static bool out_repeat_slow( 114 | uint_fast32_t r_bytes_max, 115 | uint_fast32_t offset, 116 | uint8_t *out_at, 117 | const uint8_t *out_from, 118 | const uint8_t *const out_copy_end, 119 | const uint8_t *const out_end) 120 | { 121 | if (offset > 1 && out_copy_end <= out_end - R_COPY_SAFE_2X) { 122 | out_repeat_overlap(offset, out_at, out_from, out_copy_end); 123 | } else { 124 | if (unlikely(out_copy_end > out_end)) 125 | return false; 126 | if (offset == 1) { 127 | m_set(out_at, *out_from, r_bytes_max); 128 | } else { 129 | do 130 | *out_at++ = *out_from++; 131 | while (out_at < out_copy_end); 132 | } 133 | } 134 | return true; 135 | } 136 | 137 | static int decode( 138 | const uint8_t *in_at, 139 | uint8_t *const out, 140 | const uint8_t *const in_end, 141 | const uint8_t *const out_end, 142 | const uint_fast32_t nr_log2, 143 | const uint_fast32_t off_log2) 144 | { 145 | const uint_fast32_t r_log2 = TAG_BITS_MAX - (off_log2 + nr_log2); 146 | const uint8_t *const in_end_minus_x = in_end - TAG_BYTES_MAX; 147 | uint8_t *out_at = out; 148 | while (likely(in_at <= in_end_minus_x)) { 149 | const uint_fast32_t utag = read4_at(in_at - 1) >> BYTE_BITS; 150 | const uint_fast32_t offset = utag & mask(off_log2); 151 | uint_fast32_t nr_bytes_max = utag >> (off_log2 + r_log2), 152 | r_bytes_max = ((utag >> off_log2) & mask(r_log2)) + 153 | REPEAT_MIN; 154 | const uint8_t *out_from = 0; 155 | uint8_t *out_copy_end = 0; 156 | const uint8_t *out_safe_end = 0; 157 | in_at += TAG_BYTES_MAX; 158 | if (unlikely(nr_bytes_max == mask(nr_log2))) { 159 | in_at = get_size(&nr_bytes_max, in_at, in_end); 160 | if (unlikely(in_at == NULL)) 161 | return LZ4K_STATUS_READ_ERROR; 162 | } 163 | if (!out_non_repeat(&in_at, &out_at, nr_bytes_max, in_end, out_end)) 164 | return LZ4K_STATUS_FAILED; 165 | if (unlikely(r_bytes_max == mask(r_log2) + REPEAT_MIN)) { 166 | in_at = get_size(&r_bytes_max, in_at, in_end); 167 | if (unlikely(in_at == NULL)) 168 | return LZ4K_STATUS_READ_ERROR; 169 | } 170 | out_from = out_at - offset; 171 | if (unlikely(out_from < out)) 172 | return LZ4K_STATUS_FAILED; 173 | out_copy_end = out_at + r_bytes_max; 174 | out_safe_end = out_end - R_COPY_SAFE_2X; 175 | if (likely(offset >= R_COPY_MIN && out_copy_end <= out_safe_end)) { 176 | copy_2x_as_x2_while_lt(out_at, out_from, out_copy_end, 177 | R_COPY_MIN); 178 | } else if (likely(offset >= (R_COPY_MIN >> 1) && 179 | out_copy_end <= out_safe_end)) { 180 | m_copy(out_at, out_from, R_COPY_MIN); 181 | out_at += offset; 182 | while_lt_copy_x(out_at, out_from, out_copy_end, R_COPY_MIN); 183 | } else if (likely(offset > 0)) { 184 | if (!out_repeat_slow(r_bytes_max, offset, out_at, out_from, 185 | out_copy_end, out_end)) 186 | return LZ4K_STATUS_FAILED; 187 | } else { /* offset == 0: EOB, last literal */ 188 | return end_of_block(nr_bytes_max, r_bytes_max, in_at, 189 | in_end, out, out_at); 190 | } 191 | out_at = out_copy_end; 192 | } /* while (likely(in_at <= in_end_minus_x)) */ 193 | return in_at == in_end ? (int)(out_at - out) : LZ4K_STATUS_FAILED; 194 | } 195 | 196 | static int decode_pattern_4kb( 197 | const uint8_t *const in, 198 | uint8_t *const out, 199 | const uint8_t *const out_end) 200 | { 201 | const uint64_t pattern = *(const uint64_t*)in; 202 | uint64_t *o64 = (uint64_t*)out; 203 | const uint64_t *const o64_end = (const uint64_t*)out_end - 1; 204 | for (; o64 <= o64_end; ++o64) 205 | *o64 = pattern; 206 | return (uint8_t*)o64 == out_end ? (int)(out_end - out) : LZ4K_STATUS_FAILED; 207 | } 208 | 209 | static int decode_4kb( 210 | const uint8_t *const in, 211 | uint8_t *const out, 212 | const uint8_t *const in_end, 213 | const uint8_t *const out_end) 214 | { 215 | return decode(in, out, in_end, out_end, NR_4KB_LOG2, BLOCK_4KB_LOG2); 216 | } 217 | 218 | int lz4kd_decode( 219 | const void *in, 220 | void *const out, 221 | unsigned in_max, 222 | unsigned out_max) 223 | { 224 | /* ++use volatile pointers to prevent compiler optimizations */ 225 | const uint8_t *volatile in_end = (const uint8_t*)in + in_max; 226 | const uint8_t *volatile out_end = (uint8_t*)out + min_u64(out_max, 1 << BLOCK_4KB_LOG2); 227 | if (unlikely(in == NULL || out == NULL)) 228 | return LZ4K_STATUS_FAILED; 229 | if (unlikely(in_max <= 1 + TAG_BYTES_MAX || out_max <= 0)) 230 | return LZ4K_STATUS_FAILED; 231 | /* invalid buffer size or pointer overflow */ 232 | if (unlikely((const uint8_t*)in >= in_end || (uint8_t*)out >= out_end)) 233 | return LZ4K_STATUS_FAILED; 234 | /* -- */ 235 | if (unlikely(in_max == PATTERN_BYTES_MAX)) 236 | return decode_pattern_4kb((const uint8_t*)in, (uint8_t*)out, 237 | out_end); 238 | return decode_4kb((const uint8_t*)in + 1, (uint8_t*)out, in_end, out_end); 239 | } 240 | EXPORT_SYMBOL(lz4kd_decode); 241 | 242 | MODULE_LICENSE("Dual BSD/GPL"); 243 | MODULE_DESCRIPTION("LZ4K decoder"); 244 | -------------------------------------------------------------------------------- /other/zram/lz4k/lib/lz4kd/lz4kd_decode_delta.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved. 3 | * Description: LZ4K compression algorithm with delta compression 4 | */ 5 | 6 | #if !defined(__KERNEL__) 7 | #include "lz4kd.h" 8 | #else 9 | #include 10 | #include 11 | #endif 12 | 13 | #include "lz4kd_private.h" /* types, etc */ 14 | 15 | static const uint8_t *get_size( 16 | uint_fast32_t *size, 17 | const uint8_t *in_at, 18 | const uint8_t *const in_end) 19 | { 20 | uint_fast32_t u; 21 | do { 22 | if (unlikely(in_at >= in_end)) 23 | return NULL; 24 | *size += (u = *(const uint8_t*)in_at); 25 | ++in_at; 26 | } while (BYTE_MAX == u); 27 | return in_at; 28 | } 29 | 30 | static int end_of_block( 31 | const uint_fast32_t nr_bytes_max, 32 | const uint_fast32_t r_bytes_max, 33 | const uint8_t *const in_at, 34 | const uint8_t *const in_end, 35 | const uint8_t *const out, 36 | const uint8_t *const out_at) 37 | { 38 | if (!nr_bytes_max) 39 | return LZ4K_STATUS_FAILED; /* should be the last one in block */ 40 | if (r_bytes_max != REPEAT_MIN) 41 | return LZ4K_STATUS_FAILED; /* should be the last one in block */ 42 | if (in_at != in_end) 43 | return LZ4K_STATUS_FAILED; /* should be the last one in block */ 44 | return (int)(out_at - out); 45 | } 46 | 47 | enum { 48 | NR_COPY_MIN = 16, 49 | R_COPY_MIN = 16, 50 | R_COPY_SAFE = R_COPY_MIN - 1, 51 | R_COPY_SAFE_2X = (R_COPY_MIN << 1) - 1 52 | }; 53 | 54 | static bool out_non_repeat( 55 | const uint8_t **in_at, 56 | uint8_t **out_at, 57 | uint_fast32_t nr_bytes_max, 58 | const uint8_t *const in_end, 59 | const uint8_t *const out_end) 60 | { 61 | const uint8_t *const in_copy_end = *in_at + nr_bytes_max; 62 | uint8_t *const out_copy_end = *out_at + nr_bytes_max; 63 | if (likely(nr_bytes_max <= NR_COPY_MIN)) { 64 | if (likely(*in_at <= in_end - NR_COPY_MIN && 65 | *out_at <= out_end - NR_COPY_MIN)) 66 | m_copy(*out_at, *in_at, NR_COPY_MIN); 67 | else if (in_copy_end <= in_end && out_copy_end <= out_end) 68 | m_copy(*out_at, *in_at, nr_bytes_max); 69 | else 70 | return false; 71 | } else { /* nr_bytes_max>NR_COPY_MIN */ 72 | if (likely(in_copy_end <= in_end - NR_COPY_MIN && 73 | out_copy_end <= out_end - NR_COPY_MIN)) { 74 | m_copy(*out_at, *in_at, NR_COPY_MIN); 75 | copy_x_while_lt(*out_at + NR_COPY_MIN, 76 | *in_at + NR_COPY_MIN, 77 | out_copy_end, NR_COPY_MIN); 78 | } else if (in_copy_end <= in_end && out_copy_end <= out_end) { 79 | m_copy(*out_at, *in_at, nr_bytes_max); 80 | } else { /* in_copy_end > in_end || out_copy_end > out_end */ 81 | return false; 82 | } 83 | } /* if (nr_bytes_max <= NR_COPY_MIN) */ 84 | *in_at = in_copy_end; 85 | *out_at = out_copy_end; 86 | return true; 87 | } 88 | 89 | static void out_repeat_overlap( 90 | uint_fast32_t offset, 91 | uint8_t *out_at, 92 | const uint8_t *out_from, 93 | const uint8_t *const out_copy_end) 94 | { 95 | enum { 96 | COPY_MIN = R_COPY_MIN >> 1, 97 | OFFSET_LIMIT = COPY_MIN >> 1 98 | }; 99 | /* (1 < offset < R_COPY_MIN/2) && out_copy_end + R_COPY_SAFE_2X <= out_end */ 100 | m_copy(out_at, out_from, COPY_MIN); 101 | out_at += offset; 102 | if (offset <= OFFSET_LIMIT) 103 | offset <<= 1; 104 | do { 105 | m_copy(out_at, out_from, COPY_MIN); 106 | out_at += offset; 107 | if (offset <= OFFSET_LIMIT) 108 | offset <<= 1; 109 | } while (out_at - out_from < R_COPY_MIN); 110 | while_lt_copy_2x_as_x2(out_at, out_from, out_copy_end, R_COPY_MIN); 111 | } 112 | 113 | static bool out_repeat_slow( 114 | uint_fast32_t r_bytes_max, 115 | uint_fast32_t offset, 116 | uint8_t *out_at, 117 | const uint8_t *out_from, 118 | const uint8_t *const out_copy_end, 119 | const uint8_t *const out_end) 120 | { 121 | if (offset > 1 && out_copy_end <= out_end - R_COPY_SAFE_2X) { 122 | out_repeat_overlap(offset, out_at, out_from, out_copy_end); 123 | } else { 124 | if (unlikely(out_copy_end > out_end)) 125 | return false; 126 | if (offset == 1) { 127 | m_set(out_at, *out_from, r_bytes_max); 128 | } else { 129 | do 130 | *out_at++ = *out_from++; 131 | while (out_at < out_copy_end); 132 | } 133 | } 134 | return true; 135 | } 136 | 137 | static int decode_any( 138 | const uint8_t *in_at, 139 | const uint8_t *const out0, 140 | uint8_t *const out, 141 | const uint8_t *const in_end, 142 | const uint8_t *const out_end, 143 | const uint_fast32_t nr_log2, 144 | const uint_fast32_t off_log2) 145 | { 146 | const uint_fast32_t r_log2 = TAG_BITS_MAX - (off_log2 + nr_log2); 147 | const uint8_t *const in_end_minus_x = in_end - TAG_BYTES_MAX; 148 | uint8_t *out_at = out; 149 | while (likely(in_at <= in_end_minus_x)) { 150 | const uint_fast32_t utag = read4_at(in_at - 1) >> BYTE_BITS; 151 | const uint_fast32_t offset = utag & mask(off_log2); 152 | uint_fast32_t nr_bytes_max = utag >> (off_log2 + r_log2), 153 | r_bytes_max = ((utag >> off_log2) & mask(r_log2)) + 154 | REPEAT_MIN; 155 | const uint8_t *out_from = 0; 156 | uint8_t *out_copy_end = 0; 157 | in_at += TAG_BYTES_MAX; 158 | if (unlikely(nr_bytes_max == mask(nr_log2))) { 159 | in_at = get_size(&nr_bytes_max, in_at, in_end); 160 | if (in_at == NULL) 161 | return LZ4K_STATUS_READ_ERROR; 162 | } 163 | if (!out_non_repeat(&in_at, &out_at, nr_bytes_max, in_end, out_end)) 164 | return LZ4K_STATUS_FAILED; 165 | if (unlikely(r_bytes_max == mask(r_log2) + REPEAT_MIN)) { 166 | in_at = get_size(&r_bytes_max, in_at, in_end); 167 | if (in_at == NULL) 168 | return LZ4K_STATUS_READ_ERROR; 169 | } 170 | out_from = out_at - offset; 171 | if (unlikely(out_from < out0)) 172 | return LZ4K_STATUS_FAILED; 173 | out_copy_end = out_at + r_bytes_max; 174 | if (likely(offset >= R_COPY_MIN && 175 | out_copy_end <= out_end - R_COPY_SAFE_2X)) { 176 | copy_2x_as_x2_while_lt(out_at, out_from, out_copy_end, 177 | R_COPY_MIN); 178 | } else if (likely(offset >= (R_COPY_MIN >> 1) && 179 | out_copy_end <= out_end - R_COPY_SAFE_2X)) { 180 | m_copy(out_at, out_from, R_COPY_MIN); 181 | out_at += offset; 182 | while_lt_copy_x(out_at, out_from, out_copy_end, R_COPY_MIN); 183 | /* faster than 2x */ 184 | } else if (likely(offset > 0)) { 185 | if (!out_repeat_slow(r_bytes_max, offset, out_at, out_from, 186 | out_copy_end, out_end)) 187 | return LZ4K_STATUS_FAILED; 188 | } else { /* offset == 0: EOB, last literal */ 189 | return end_of_block(nr_bytes_max, r_bytes_max, in_at, 190 | in_end, out, out_at); 191 | } 192 | out_at = out_copy_end; 193 | } /* while (likely(in_at <= in_end_minus_x)) */ 194 | return in_at == in_end ? (int)(out_at - out) : LZ4K_STATUS_FAILED; 195 | } 196 | 197 | static int decode_8kb( 198 | const uint8_t *const in, 199 | const uint8_t *const out0, 200 | uint8_t *const out, 201 | const uint8_t *const in_end, 202 | const uint8_t *const out_end) 203 | { 204 | return decode_any(in, out0, out, in_end, out_end, NR_8KB_LOG2, BLOCK_8KB_LOG2); 205 | } 206 | 207 | int lz4kd_decode_delta( 208 | const void *in, 209 | const void *const out0, 210 | void *const out, 211 | unsigned in_max, 212 | unsigned out_max) 213 | { 214 | if (unlikely(in == NULL || out0 == NULL || out == NULL || out0 > out)) 215 | return LZ4K_STATUS_FAILED; 216 | if (unlikely(in_max <= 1 + TAG_BYTES_MAX || out_max <= 0)) 217 | return LZ4K_STATUS_FAILED; 218 | /* invalid buffer size or pointer overflow */ 219 | return decode_8kb((const uint8_t*)in + 1, (const uint8_t*)out0, 220 | (uint8_t*)out, (const uint8_t*)in + in_max, (uint8_t*)out + out_max); 221 | } 222 | EXPORT_SYMBOL(lz4kd_decode_delta); 223 | 224 | MODULE_LICENSE("Dual BSD/GPL"); 225 | MODULE_DESCRIPTION("LZ4K decoder"); 226 | -------------------------------------------------------------------------------- /other/zram/lz4k/lib/lz4kd/lz4kd_encode.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved. 3 | * Description: LZ4K compression algorithm with delta compression 4 | */ 5 | 6 | #if !defined(__KERNEL__) 7 | #include "lz4kd.h" 8 | #else 9 | #include 10 | #include 11 | #endif 12 | 13 | #include "lz4kd_private.h" 14 | #include "lz4kd_encode_private.h" 15 | 16 | enum { 17 | HT_LOG2 = 12, /* ==11 #3 max drop in CR */ 18 | STEP_LOG2 = 5 /* ==3 #2 avg drop in CR */ 19 | }; 20 | 21 | static unsigned encode_state_bytes_min(void) 22 | { 23 | enum { 24 | BYTES_LOG2 = HT_LOG2 + 1 25 | }; 26 | const unsigned bytes_total = (1U << BYTES_LOG2); 27 | return bytes_total; 28 | } 29 | 30 | #if !defined(LZ4K_DELTA) && !defined(LZ4K_MAX_CR) 31 | 32 | unsigned lz4kd_encode_state_bytes_min(void) 33 | { 34 | return encode_state_bytes_min(); 35 | } 36 | EXPORT_SYMBOL(lz4kd_encode_state_bytes_min); 37 | 38 | #endif /* !defined(LZ4K_DELTA) && !defined(LZ4K_MAX_CR) */ 39 | 40 | /* minimum encoded size for non-compressible data */ 41 | inline static uint_fast32_t encoded_bytes_min( 42 | uint_fast32_t nr_log2, 43 | uint_fast32_t in_max) 44 | { 45 | return in_max < mask(nr_log2) ? 46 | TAG_BYTES_MAX + in_max : 47 | TAG_BYTES_MAX + size_bytes_count(in_max - mask(nr_log2)) + in_max; 48 | } 49 | 50 | inline static void update_utag( 51 | uint_fast32_t r_bytes_max, 52 | uint_fast32_t *utag, 53 | const uint_fast32_t nr_log2, 54 | const uint_fast32_t off_log2) 55 | { 56 | const uint_fast32_t r_mask = mask(TAG_BITS_MAX - (off_log2 + nr_log2)); 57 | *utag |= likely(r_bytes_max - REPEAT_MIN < r_mask) ? 58 | ((r_bytes_max - REPEAT_MIN) << off_log2) : (r_mask << off_log2); 59 | } 60 | 61 | inline static uint8_t *out_size_bytes(uint8_t *out_at, uint_fast32_t u) 62 | { 63 | for (; u >= BYTE_MAX; *out_at++ = (uint8_t)BYTE_MAX, u -= BYTE_MAX); 64 | *out_at++ = (uint8_t)u; 65 | return out_at; 66 | } 67 | 68 | inline static uint8_t *out_utag_then_bytes_left( 69 | uint8_t *out_at, 70 | uint_fast32_t utag, 71 | uint_fast32_t bytes_left) 72 | { 73 | m_copy(out_at, &utag, TAG_BYTES_MAX); 74 | return out_size_bytes(out_at + TAG_BYTES_MAX, bytes_left); 75 | } 76 | 77 | static int out_tail( 78 | uint8_t *out_at, 79 | uint8_t *const out_end, 80 | const uint8_t *const out, 81 | const uint8_t *const nr0, 82 | const uint8_t *const in_end, 83 | const uint_fast32_t nr_log2, 84 | const uint_fast32_t off_log2) 85 | { 86 | const uint_fast32_t nr_mask = mask(nr_log2); 87 | const uint_fast32_t r_log2 = TAG_BITS_MAX - (off_log2 + nr_log2); 88 | const uint_fast32_t nr_bytes_now = u_32(in_end - nr0); 89 | if (encoded_bytes_min(nr_log2, nr_bytes_now) > u_32(out_end - out_at)) 90 | return LZ4K_STATUS_INCOMPRESSIBLE; 91 | if (nr_bytes_now < nr_mask) { 92 | /* caller guarantees at least one nr-byte */ 93 | uint_fast32_t utag = (nr_bytes_now << (off_log2 + r_log2)); 94 | m_copy(out_at, &utag, TAG_BYTES_MAX); 95 | out_at += TAG_BYTES_MAX; 96 | } else { /* nr_bytes_now>=nr_mask */ 97 | uint_fast32_t bytes_left = nr_bytes_now - nr_mask; 98 | uint_fast32_t utag = (nr_mask << (off_log2 + r_log2)); 99 | out_at = out_utag_then_bytes_left(out_at, utag, bytes_left); 100 | } /* if (nr_bytes_now= nr_mask */ 150 | uint_fast32_t bytes_left = nr_bytes_max - nr_mask; 151 | utag |= (nr_mask << (off_log2 + r_log2)); 152 | out_at = out_utag_then_bytes_left(out_at, utag, bytes_left); 153 | } /* if (nr_bytes_max> BYTE_BITS_LOG2); 246 | } 247 | /* some bytes differ: count of trailing 0-bits/bytes */ 248 | q += sizeof(uint64_t); 249 | r += sizeof(uint64_t); 250 | } while (likely(r <= in_end_safe)); /* once, at input block end */ 251 | while (r < in_end) { 252 | if (*q != *r) return r; 253 | ++q; 254 | ++r; 255 | } 256 | return r; 257 | } 258 | 259 | const uint8_t *lz4kd_repeat_end( 260 | const uint8_t *q, 261 | const uint8_t *r, 262 | const uint8_t *const in_end_safe, 263 | const uint8_t *const in_end) 264 | { 265 | return repeat_end(q, r, in_end_safe, in_end); 266 | } 267 | 268 | /* CR increase order: +STEP, have OFFSETS, use _5b(most impact) */ 269 | /* *_6b to compete with LZ4 */ 270 | inline static uint_fast32_t hash(const uint8_t *r) 271 | { 272 | return hash64_5b(r, HT_LOG2); 273 | } 274 | 275 | /* 276 | * Proof that 'r' increments are safe-NO pointer overflows are possible: 277 | * 278 | * While using STEP_LOG2=5, step_start=1<= (1< 286 | * 1<<(off_log2-STEP_LOG2+1) >= x^2+x-1 ==> 287 | * x^2+x-1-1<<(off_log2-STEP_LOG2+1) == 0, which is solved by standard 288 | * method. 289 | * To avoid overhead here conservative approximate value of x is calculated 290 | * as average of two nearest square roots, see STEP_LIMIT above. 291 | */ 292 | 293 | static int encode_any( 294 | uint16_t *const ht, 295 | const uint8_t *const in0, 296 | const uint8_t *const in_end, 297 | uint8_t *const out, 298 | uint8_t *const out_end) 299 | { 300 | enum { 301 | NR_LOG2 = NR_4KB_LOG2, 302 | OFF_LOG2 = BLOCK_4KB_LOG2 303 | }; 304 | const uint8_t *const in_end_safe = in_end - NR_COPY_MIN; 305 | const uint8_t *r = in0; 306 | const uint8_t *nr0 = r++; 307 | uint8_t *out_at = out + 1; /* +1 for header */ 308 | for (; ; nr0 = r) { 309 | const uint8_t *q = 0; 310 | uint_fast32_t step = 1 << STEP_LOG2; 311 | uint_fast32_t utag = 0; 312 | const uint8_t *r_end = 0; 313 | uint_fast32_t r_bytes_max = 0; 314 | while (true) { 315 | if (equal4(q = hashed(in0, ht, hash(r), r), r)) 316 | break; 317 | ++r; 318 | if (equal4(q = hashed(in0, ht, hash(r), r), r)) 319 | break; 320 | if (unlikely((r += (++step >> STEP_LOG2)) > in_end_safe)) 321 | return out_tail(out_at, out_end, out, nr0, in_end, 322 | NR_LOG2, OFF_LOG2); 323 | } 324 | utag = u_32(r - q); 325 | r_end = repeat_end(q, r, in_end_safe, in_end); 326 | r_bytes_max = u_32(r_end - r); 327 | if (unlikely(nr0 == r)) 328 | out_at = out_repeat(out_at, utag, r_bytes_max, 329 | NR_LOG2, OFF_LOG2); 330 | else 331 | out_at = out_tuple(out_at, out_end, utag, nr0, r, r_bytes_max, 332 | NR_LOG2, OFF_LOG2); 333 | if (unlikely((r += r_bytes_max) > in_end_safe)) 334 | return out_tail2(out_at, out_end, out, r, in_end, 335 | NR_LOG2, OFF_LOG2); 336 | ht[hash(r - 1)] = (uint16_t)(r - 1 - in0); 337 | } 338 | } 339 | 340 | /* not static for inlining optimization */ 341 | int lz4kd_encode_fast( 342 | void *const state, 343 | const uint8_t *const in, 344 | uint8_t *const out, 345 | const uint_fast32_t in_max, 346 | const uint_fast32_t out_max) 347 | { 348 | return encode_any((uint16_t*)state, in, in + in_max, out, out + out_max); 349 | } 350 | 351 | int lz4kd_encode( 352 | void *const state, 353 | const void *const in, 354 | void *out, 355 | unsigned in_max, 356 | unsigned out_max, 357 | unsigned out_limit) 358 | { 359 | const uint64_t io_min = min_u64(in_max, out_max); 360 | const uint64_t gain_max = max_u64(GAIN_BYTES_MAX, (io_min >> GAIN_BYTES_LOG2)); 361 | /* ++use volatile pointers to prevent compiler optimizations */ 362 | const uint8_t *volatile in_end = (const uint8_t*)in + in_max; 363 | const uint8_t *volatile out_end = (uint8_t*)out + out_max; 364 | const void *volatile state_end = 365 | (uint8_t*)state + encode_state_bytes_min(); 366 | if (unlikely(state == NULL)) 367 | return LZ4K_STATUS_FAILED; 368 | if (unlikely(in == NULL || out == NULL)) 369 | return LZ4K_STATUS_FAILED; 370 | if (unlikely(out_max <= gain_max)) 371 | return LZ4K_STATUS_FAILED; 372 | if (unlikely((const uint8_t*)in >= in_end || (uint8_t*)out >= out_end)) 373 | return LZ4K_STATUS_FAILED; 374 | if (unlikely(state >= state_end)) 375 | return LZ4K_STATUS_FAILED; /* pointer overflow */ 376 | if (in_max > (1 << BLOCK_4KB_LOG2)) 377 | return LZ4K_STATUS_FAILED; 378 | if (unlikely(!out_limit || out_limit > io_min)) 379 | out_limit = (unsigned)io_min; 380 | m_set(state, 0, encode_state_bytes_min()); 381 | *((uint8_t*)out) = 0; /* lz4kd header */ 382 | if (unlikely(nr_encoded_bytes_max(in_max, NR_4KB_LOG2) > out_max)) 383 | return 0; 384 | return lz4kd_encode_fast(state, (const uint8_t*)in, (uint8_t*)out, 385 | in_max, out_limit); 386 | } 387 | EXPORT_SYMBOL(lz4kd_encode); 388 | 389 | /* maximum encoded size for repeat and non-repeat data if "fast" encoder is used */ 390 | uint_fast32_t lz4kd_encoded_bytes_max( 391 | uint_fast32_t nr_max, 392 | uint_fast32_t r_max, 393 | uint_fast32_t nr_log2, 394 | uint_fast32_t off_log2) 395 | { 396 | uint_fast32_t r = 1 + TAG_BYTES_MAX + 397 | (uint32_t)round_up_to_log2(nr_max, NR_COPY_LOG2); 398 | uint_fast32_t r_log2 = TAG_BITS_MAX - (off_log2 + nr_log2); 399 | if (nr_max >= mask(nr_log2)) 400 | r += size_bytes_count(nr_max - mask(nr_log2)); 401 | if (r_max >= mask(r_log2)) { 402 | r_max -= mask(r_log2); 403 | r += (uint_fast32_t)max_u64(size_bytes_count(r_max), 404 | r_max - r_max / REPEAT_MIN); /* worst case: one tag for each REPEAT_MIN */ 405 | } 406 | return r; 407 | } 408 | EXPORT_SYMBOL(lz4kd_encoded_bytes_max); 409 | 410 | const char *lz4kd_version(void) 411 | { 412 | static const char *version = "2022.03.20"; 413 | return version; 414 | } 415 | EXPORT_SYMBOL(lz4kd_version); 416 | 417 | MODULE_LICENSE("Dual BSD/GPL"); 418 | MODULE_DESCRIPTION("LZ4K encoder"); 419 | -------------------------------------------------------------------------------- /other/zram/lz4k/lib/lz4kd/lz4kd_encode_delta.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved. 3 | * Description: LZ4K compression algorithm with delta compression 4 | */ 5 | 6 | #if !defined(__KERNEL__) 7 | #include "lz4kd.h" 8 | #else 9 | #include 10 | #include 11 | #endif 12 | 13 | #include "lz4kd_private.h" 14 | #include "lz4kd_encode_private.h" 15 | 16 | enum { 17 | HT_LOG2 = 13, 18 | OFF_LOG2 = 13 /* 13 for 8KB */ 19 | }; 20 | 21 | static unsigned ht_bytes_max(void) 22 | { 23 | return (1 << HT_LOG2) * sizeof(uint16_t); 24 | } 25 | 26 | static unsigned encode_state_bytes_min(void) 27 | { 28 | return ((1 << HT_LOG2) + (1 << OFF_LOG2)) * sizeof(uint16_t); 29 | } 30 | 31 | #ifdef LZ4K_DELTA 32 | 33 | unsigned lz4kd_encode_state_bytes_min(void) 34 | { 35 | return encode_state_bytes_min(); 36 | } 37 | EXPORT_SYMBOL(lz4kd_encode_state_bytes_min); 38 | 39 | #endif /* LZ4K_DELTA */ 40 | 41 | inline static uint_fast32_t hashv(const uint64_t v, uint32_t shift) 42 | { 43 | return hash32v(v, shift); 44 | } 45 | 46 | inline static uint_fast32_t hash(const uint8_t *r, uint32_t shift) 47 | { 48 | return hashv(*((const uint64_t*)r), shift); 49 | } 50 | 51 | static void fill_ht_offsets_s( 52 | const uint_fast32_t off0, 53 | uint16_t *const ht, 54 | uint16_t *const past_offset, 55 | uint64_t s) 56 | { 57 | static const uint_fast32_t off1 = 1; 58 | static const uint_fast32_t off2 = 2; 59 | static const uint_fast32_t off3 = 3; 60 | uint_fast32_t h0 = hashv(s, HT_LOG2); 61 | uint_fast32_t h1 = hashv(s >> (off1 * BYTE_BITS), HT_LOG2); 62 | uint_fast32_t h2 = hashv(s >> (off2 * BYTE_BITS), HT_LOG2); 63 | uint_fast32_t h3 = hashv(s >> (off3 * BYTE_BITS), HT_LOG2); 64 | past_offset[off0 + 0] = ht[h0]; 65 | ht[h0] = (uint16_t)(off0 + 0); 66 | past_offset[off0 + off1] = ht[h1]; 67 | ht[h1] = (uint16_t)(off0 + off1); 68 | past_offset[off0 + off2] = ht[h2]; 69 | ht[h2] = (uint16_t)(off0 + off2); 70 | past_offset[off0 + off3] = ht[h3]; 71 | ht[h3] = (uint16_t)(off0 + off3); 72 | } 73 | 74 | static void update_hash_table( 75 | uint16_t *const ht, 76 | const uint8_t *const in1, 77 | const uint8_t *const in_end) 78 | { 79 | static const uint64_t read_bytes = 8; 80 | uint64_t a = 0; 81 | const uint8_t *const in0 = in1 - 1; 82 | const uint8_t *r = in1; 83 | uint16_t *const past_offset = ht + (1 << HT_LOG2); 84 | m_set(ht, 0, ht_bytes_max()); 85 | past_offset[0] = 0; /* stopper in encode_any2() */ 86 | while (likely(r + read_bytes <= in_end)) { 87 | a = read8_at(r); 88 | fill_ht_offsets_s((uint16_t)(r - in0), ht, past_offset, a); 89 | r += REPEAT_MIN; 90 | } 91 | for (; likely(r < in_end); ++r) { /* here in_end=start of the ref block */ 92 | uint_fast32_t off0 = (uint16_t)(r - in0); 93 | uint_fast32_t h = hash(r, HT_LOG2); 94 | past_offset[off0] = ht[h]; 95 | ht[h] = (uint16_t)(off0); 96 | } 97 | } 98 | 99 | static void hash_repeat_tail( 100 | uint16_t *const ht, 101 | uint16_t *const past_offset, 102 | const uint8_t *const in0, 103 | const uint8_t *const r) 104 | { 105 | const uint8_t *s = r - 1 - 1 - 1; 106 | uint_fast32_t h = hash(s, HT_LOG2); 107 | past_offset[s - in0] = ht[h]; 108 | ht[h] = (uint16_t)(s - in0); 109 | ++s; 110 | h = hash(s, HT_LOG2); 111 | past_offset[s - in0] = ht[h]; 112 | ht[h] = (uint16_t)(s - in0); 113 | ++s; 114 | h = hash(s, HT_LOG2); 115 | past_offset[s - in0] = ht[h]; 116 | ht[h] = (uint16_t)(s - in0); 117 | } 118 | 119 | enum { 120 | STEP_LOG2 = 5, /* increase for better CR */ 121 | Q_MAX = 4, /* 2 for "dump" benchmark: increase for better CR */ 122 | MATCH_MAX = 160 123 | }; 124 | 125 | static int encode_any2( 126 | uint16_t *const ht, 127 | const uint8_t *const in1, 128 | const uint8_t *const in, 129 | const uint8_t *const in_end, 130 | uint8_t *const out, 131 | uint8_t *const out_end, /* ==out_limit for !check_out */ 132 | const uint_fast32_t nr_log2, 133 | const bool check_out) 134 | { 135 | uint8_t *out_at = out + 1; /* +1 for header */ 136 | const uint8_t *const in_end_safe = in_end - NR_COPY_MIN; 137 | const uint8_t *const in0 = in1 - 1; 138 | const uint8_t *r = in; 139 | const uint8_t *nr0 = in; 140 | uint_fast32_t r_bytes_max = 0; 141 | uint16_t *const past_offset = ht + (1 << HT_LOG2); 142 | update_hash_table(ht, in1, in1 + (in - in1)); 143 | while (true) { 144 | uint_fast32_t off0 = 0; 145 | uint_fast32_t utag = 0; 146 | const uint8_t *q = 0; 147 | const uint8_t *r_end = 0; 148 | const uint8_t *s = r; 149 | uint_fast32_t step = 1 << STEP_LOG2; 150 | while (true) { 151 | uint64_t sv = read8_at(s); 152 | uint_fast32_t h = hashv(sv, HT_LOG2); 153 | off0 = past_offset[s - in0] = ht[h]; 154 | ht[h] = (uint16_t)(s - in0); 155 | for (; off0 && !equal4pv((q = in0 + off0), sv); off0 = past_offset[off0]); 156 | if (off0 != 0) 157 | break; /* repeat found */ 158 | if (unlikely((s += (++step >> STEP_LOG2)) > in_end_safe)) 159 | return lz4kd_out_tail(out_at, out_end, out, nr0, 160 | in_end, nr_log2, OFF_LOG2, check_out); 161 | } /* for */ 162 | utag = (uint_fast32_t)(s - q); 163 | r_end = lz4kd_repeat_end(q, s, in_end_safe, in_end); 164 | r_bytes_max = (uint_fast32_t)(r_end - (r = repeat_start(q, s, nr0, in1))); 165 | if (s + r_bytes_max >= in_end) /* see the bottom of while() below */ 166 | goto REPEAT_DONE; /* match_max(q, s, r_bytes_max + 1) below */ 167 | step = Q_MAX - 1; 168 | while ((off0 = past_offset[off0]) && (q >= in || step > 0)) { 169 | const uint8_t *r_start = 0; 170 | --step; 171 | if (!match_max((q = in0 + off0), s, r_bytes_max + 1)) 172 | continue; 173 | r_end = lz4kd_repeat_end(q, s, in_end_safe, in_end); 174 | r_start = repeat_start(q, s, nr0, in1); 175 | if (r_bytes_max > (uint_fast32_t)(r_end - r_start)) 176 | continue; 177 | r_bytes_max = (uint_fast32_t)(r_end - r_start); 178 | r = r_start; 179 | utag = (uint_fast32_t)(s - q); 180 | if (s + r_bytes_max >= in_end || 181 | (q < in && r_bytes_max >= MATCH_MAX)) 182 | goto REPEAT_DONE; 183 | } 184 | REPEAT_DONE: 185 | out_at = lz4kd_out_tuple(out_at, out_end, utag, nr0, r, 186 | r_bytes_max, nr_log2, OFF_LOG2, check_out); 187 | if (unlikely(check_out && out_at == NULL)) 188 | return LZ4K_STATUS_WRITE_ERROR; 189 | if (unlikely((r += r_bytes_max) > in_end_safe)) 190 | return r == in_end ? (int)(out_at - out) : 191 | lz4kd_out_tail(out_at, out_end, out, r, in_end, 192 | nr_log2, OFF_LOG2, check_out); 193 | hash_repeat_tail(ht, past_offset, in0, r); 194 | nr0 = r; 195 | } /* for */ 196 | } 197 | 198 | static int encode_delta_fast( 199 | uint16_t *const ht, 200 | const uint8_t *const in0, 201 | const uint8_t *const in, 202 | uint8_t *const out, 203 | const uint_fast32_t in_max, 204 | const uint_fast32_t out_max, 205 | const uint_fast32_t nr_log2) 206 | { 207 | return encode_any2(ht, in0, in, in + in_max, out, out + out_max, 208 | nr_log2, false); /* !check_out */ 209 | } 210 | 211 | int lz4kd_encode_delta_slow( 212 | uint16_t *const ht, 213 | const uint8_t *const in0, 214 | const uint8_t *const in, 215 | uint8_t *const out, 216 | const uint_fast32_t in_max, 217 | const uint_fast32_t out_max, 218 | const uint_fast32_t nr_log2) 219 | { 220 | return encode_any2(ht, in0, in, in + in_max, out, out + out_max, 221 | nr_log2, true); /* check_out */ 222 | } 223 | 224 | inline static uint64_t u64_diff(const void *a, const void *b) 225 | { 226 | return (uint64_t)((const uint8_t*)a - (const uint8_t*)b); 227 | } 228 | 229 | int lz4kd_encode_delta( 230 | void *const state, 231 | const void *const in0, 232 | const void *const in, 233 | void *out, 234 | unsigned in_max, 235 | unsigned out_max, 236 | unsigned out_limit) 237 | { 238 | const unsigned io_min = in_max < out_max ? in_max : out_max; 239 | if (unlikely(state == NULL)) 240 | return LZ4K_STATUS_FAILED; 241 | if (unlikely(in0 == NULL || in == NULL || out == NULL)) 242 | return LZ4K_STATUS_FAILED; 243 | if (unlikely(in0 >= in)) 244 | return LZ4K_STATUS_FAILED; 245 | if (unlikely(u64_diff(in, in0) + in_max > (1U << BLOCK_8KB_LOG2))) 246 | return LZ4K_STATUS_FAILED; 247 | if (!out_limit || out_limit > io_min) 248 | out_limit = io_min; 249 | *((uint8_t*)out) = 0; /* header */ 250 | return unlikely(nr_encoded_bytes_max(in_max, NR_8KB_LOG2) > out_max) ? 251 | lz4kd_encode_delta_slow((uint16_t*)state, (const uint8_t*)in0, (const uint8_t*)in, 252 | (uint8_t*)out, in_max, out_max, NR_8KB_LOG2) : 253 | encode_delta_fast((uint16_t*)state, (const uint8_t*)in0, (const uint8_t*)in, 254 | (uint8_t*)out, in_max, out_limit, NR_8KB_LOG2); 255 | } 256 | EXPORT_SYMBOL(lz4kd_encode_delta); 257 | 258 | MODULE_LICENSE("Dual BSD/GPL"); 259 | MODULE_DESCRIPTION("LZ4K encoder delta"); 260 | -------------------------------------------------------------------------------- /other/zram/lz4k/lib/lz4kd/lz4kd_encode_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved. 3 | * Description: LZ4K compression algorithm with delta compression 4 | */ 5 | 6 | #ifndef _LZ4KD_ENCODE_PRIVATE_H 7 | #define _LZ4KD_ENCODE_PRIVATE_H 8 | 9 | #include "lz4kd_private.h" 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | enum { 16 | GAIN_BYTES_LOG2 = 6, 17 | GAIN_BYTES_MAX = 1 << GAIN_BYTES_LOG2, 18 | NR_COPY_LOG2 = 4, 19 | NR_COPY_MIN = 1 << NR_COPY_LOG2 20 | }; 21 | 22 | inline static uint32_t u_32(int64_t i) 23 | { 24 | return (uint32_t)i; 25 | } 26 | 27 | /* 28 | * Compressed data format (where {} means 0 or more occurrences, [] means 29 | * optional) 30 | * <24bits tag: (off_log2 rOffset| r_log2 rSize|nr_log2 nrSize)> 31 | * {}[]{} 32 | * and sequences are terminated by byte != 255 33 | * 34 | * +<1 terminating 0 byte> 35 | */ 36 | inline static uint_fast32_t size_bytes_count(uint_fast32_t u) 37 | { 38 | return ((u + BYTE_MAX) >> BYTE_BITS) + 1; /* (u + BYTE_MAX - 1) / BYTE_MAX; */ 39 | } 40 | 41 | /* maximum encoded size for non-compressible data if "fast" encoder is used */ 42 | inline static uint_fast32_t nr_encoded_bytes_max( 43 | uint_fast32_t nr_max, 44 | uint_fast32_t nr_log2) 45 | { 46 | uint_fast32_t r = 1 + TAG_BYTES_MAX + (uint32_t)round_up_to_log2(nr_max, NR_COPY_LOG2); 47 | return nr_max < mask(nr_log2) ? r : r + size_bytes_count(nr_max - mask(nr_log2)); 48 | } 49 | 50 | /* maximum encoded size for repeat and non-repeat data if "fast" encoder is used */ 51 | uint_fast32_t lz4kd_encoded_bytes_max( 52 | uint_fast32_t nr_max, 53 | uint_fast32_t r_max, 54 | uint_fast32_t nr_log2, 55 | uint_fast32_t off_log2); 56 | 57 | inline static const uint8_t *hashed( 58 | const uint8_t *const in0, 59 | uint16_t *const ht, 60 | uint_fast32_t h, 61 | const uint8_t *r) 62 | { 63 | const uint8_t *q = in0 + ht[h]; 64 | ht[h] = (uint16_t)(r - in0); 65 | return q; 66 | } 67 | 68 | inline static const uint8_t *repeat_start( 69 | const uint8_t *q, 70 | const uint8_t *r, 71 | const uint8_t *const nr0, 72 | const uint8_t *const in0) 73 | { 74 | for (; r > nr0 && likely(q > in0) && unlikely(q[-1] == r[-1]); --q, --r); 75 | return r; 76 | } 77 | 78 | static inline bool match_max( 79 | const uint8_t *q, 80 | const uint8_t *s, 81 | const uint_fast32_t r_max) 82 | { 83 | return equal4(q + r_max - REPEAT_MIN, s + r_max - REPEAT_MIN) && 84 | equal4(q, s); 85 | } 86 | 87 | int lz4kd_out_tail( 88 | uint8_t *out_at, 89 | uint8_t *const out_end, 90 | const uint8_t *const out, 91 | const uint8_t *const nr0, 92 | const uint8_t *const in_end, 93 | const uint_fast32_t nr_log2, 94 | const uint_fast32_t off_log2, 95 | bool check_out); 96 | 97 | uint8_t *lz4kd_out_tuple( 98 | uint8_t *out_at, 99 | uint8_t *const out_end, 100 | uint_fast32_t utag, 101 | const uint8_t *const nr0, 102 | const uint8_t *const r, 103 | uint_fast32_t r_bytes_max, 104 | const uint_fast32_t nr_log2, 105 | const uint_fast32_t off_log2, 106 | bool check_out); 107 | 108 | uint8_t *lz4kd_out_repeat( 109 | uint8_t *out_at, 110 | uint8_t *const out_end, 111 | uint_fast32_t utag, 112 | uint_fast32_t r_bytes_max, 113 | const uint_fast32_t nr_log2, 114 | const uint_fast32_t off_log2, 115 | const bool check_out); 116 | 117 | const uint8_t *lz4kd_repeat_end( 118 | const uint8_t *q, 119 | const uint8_t *r, 120 | const uint8_t *const in_end_safe, 121 | const uint8_t *const in_end); 122 | 123 | int lz4kd_encode_fast( 124 | void *const state, 125 | const uint8_t *const in, 126 | uint8_t *const out, 127 | const uint_fast32_t in_max, 128 | const uint_fast32_t out_max); 129 | 130 | #ifdef __cplusplus 131 | } 132 | #endif 133 | 134 | #endif /* _LZ4KD_ENCODE_PRIVATE_H */ 135 | 136 | -------------------------------------------------------------------------------- /other/zram/lz4k/lib/lz4kd/lz4kd_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved. 3 | * Description: LZ4K compression algorithm with delta compression 4 | */ 5 | 6 | #ifndef _LZ4KD_PRIVATE_H 7 | #define _LZ4KD_PRIVATE_H 8 | 9 | #if !defined(__KERNEL__) 10 | 11 | /* for userspace only */ 12 | 13 | #else /* __KERNEL__ */ 14 | 15 | #include 16 | #define __STDC_WANT_LIB_EXT1__ 1 17 | #include /* memcpy() */ 18 | #include /* uint8_t, int8_t, uint16_t, int16_t, 19 | uint32_t, int32_t, uint64_t, int64_t */ 20 | #include 21 | 22 | typedef uint64_t uint_fast32_t; 23 | typedef int64_t int_fast32_t; 24 | 25 | #endif /* __KERNEL__ */ 26 | 27 | #if defined(__GNUC__) && (__GNUC__>=4) 28 | #define LZ4K_WITH_GCC_INTRINSICS 29 | #endif 30 | 31 | enum { 32 | BYTE_BITS = 8UL, 33 | WORD_BITS = 32U, 34 | DWORD_BITS = 64UL, 35 | BYTE_BITS_LOG2 = 3, 36 | BYTE_MAX = 255U, 37 | REPEAT_MIN = 4, 38 | TAG_BYTES_MAX = 3, 39 | TAG_BITS_MAX = TAG_BYTES_MAX * 8, 40 | BLOCK_4KB_LOG2 = 12, 41 | BLOCK_8KB_LOG2 = 13, 42 | NR_8KB_LOG2 = 5, /* for encoded_bytes_max */ 43 | NR_4KB_LOG2 = 6, 44 | PATTERN_BYTES_MAX = 8 /* 1 bytes for header, 8 bytes for pattern */ 45 | }; 46 | 47 | inline static uint32_t mask(uint_fast32_t log2) 48 | { 49 | return (1U << log2) - 1U; 50 | } 51 | 52 | inline static uint64_t mask64(uint_fast32_t log2) 53 | { 54 | return (1ULL << log2) - 1ULL; 55 | } 56 | 57 | #if defined LZ4K_WITH_GCC_INTRINSICS 58 | inline static int most_significant_bit_of(uint64_t u) 59 | { 60 | return (int)(__builtin_expect((u) == 0, false) ? 61 | -1 : (int)((WORD_BITS - 1) ^ (uint32_t)__builtin_clz((unsigned)(u)))); 62 | } 63 | #else /* #!defined LZ4K_WITH_GCC_INTRINSICS */ 64 | #error undefined most_significant_bit_of(unsigned u) 65 | #endif /* #if defined LZ4K_WITH_GCC_INTRINSICS */ 66 | 67 | inline static uint64_t max_u64(uint64_t a, uint64_t b) 68 | { 69 | return a > b ? a : b; 70 | } 71 | 72 | inline static uint64_t min_u64(uint64_t a, uint64_t b) 73 | { 74 | return a < b ? a : b; 75 | } 76 | 77 | inline static void m_copy(void *dst, const void *src, size_t total) 78 | { 79 | #if defined(__STDC_LIB_EXT1__) 80 | (void)memcpy_s(dst, total, src, (total * 2) >> 1); /* *2 >> 1 to avoid bot errors */ 81 | #else 82 | (void)__builtin_memcpy(dst, src, total); 83 | #endif 84 | } 85 | 86 | inline static void m_set(void *dst, uint8_t value, size_t total) 87 | { 88 | #if defined(__STDC_LIB_EXT1__) 89 | (void)memset_s(dst, total, value, (total * 2) >> 1); /* *2 >> 1 to avoid bot errors */ 90 | #else 91 | (void)__builtin_memset(dst, value, total); 92 | #endif 93 | } 94 | 95 | inline static uint64_t round_down_to_log2(uint64_t u, uint8_t log2) 96 | { 97 | return (uint64_t)(u & ~mask64(log2)); 98 | } 99 | 100 | inline static uint64_t round_up_to_log2(uint64_t u, uint8_t log2) 101 | { 102 | return (uint64_t)((u + mask64(log2)) & ~mask64(log2)); 103 | } 104 | 105 | inline static uint64_t round_up_to_power_of2(uint64_t u) 106 | { 107 | const int_fast32_t msb = most_significant_bit_of(u); 108 | return round_up_to_log2(u, (uint8_t)msb); 109 | } 110 | 111 | inline static void *align_pointer_up_to_log2(const void *p, uint8_t log2) 112 | { 113 | return (void*)round_up_to_log2((uint64_t)p, log2); 114 | } 115 | 116 | inline static uint32_t read3_at(const void *p) 117 | { 118 | uint32_t result = 0; 119 | m_copy(&result, p, 1 + 1 + 1); 120 | return result; 121 | } 122 | 123 | inline static uint32_t read4_at(const void *p) 124 | { 125 | uint32_t result; 126 | m_copy(&result, p, sizeof(result)); 127 | return result; 128 | } 129 | 130 | inline static uint64_t read8_at(const void *p) 131 | { 132 | uint64_t result; 133 | m_copy(&result, p, sizeof(result)); 134 | return result; 135 | } 136 | 137 | inline static bool equal3(const uint8_t *const q, const uint8_t *const r) 138 | { 139 | return (read4_at(q) << BYTE_BITS) == (read4_at(r) << BYTE_BITS); 140 | } 141 | 142 | inline static bool equal3pv(const uint8_t *const q, const uint64_t rv) 143 | { 144 | return (read4_at(q) << BYTE_BITS) == ((uint32_t)rv << BYTE_BITS); 145 | } 146 | 147 | inline static bool equal4(const uint8_t *const q, const uint8_t *const r) 148 | { 149 | return read4_at(q) == read4_at(r); 150 | } 151 | 152 | inline static bool equal4pv(const uint8_t *const q, const uint64_t rv) 153 | { 154 | return read4_at(q) == (uint32_t)rv; 155 | } 156 | 157 | inline static bool equal8(const uint8_t *const q, const uint8_t *const r) 158 | { 159 | return read8_at(q) == read8_at(r); 160 | } 161 | 162 | inline static uint_fast32_t hash24v(const uint64_t r, uint32_t shift) 163 | { 164 | const uint32_t hash24_factor = 3266489917U; 165 | return (((uint32_t)r << BYTE_BITS) * hash24_factor) >> (WORD_BITS - shift); 166 | } 167 | 168 | inline static uint_fast32_t hash24(const uint8_t *r, uint32_t shift) 169 | { 170 | return hash24v(read4_at(r), shift); 171 | } 172 | 173 | inline static uint_fast32_t hash32v_2(const uint64_t r, uint32_t shift) 174 | { 175 | const uint32_t hash32_2_factor = 3266489917U; 176 | return ((uint32_t)r * hash32_2_factor) >> (WORD_BITS - shift); 177 | } 178 | 179 | inline static uint_fast32_t hash32_2(const uint8_t *r, uint32_t shift) 180 | { 181 | return hash32v_2(read4_at(r), shift); 182 | } 183 | 184 | inline static uint_fast32_t hash32v(const uint64_t r, uint32_t shift) 185 | { 186 | const uint32_t hash32_factor = 2654435761U; 187 | return ((uint32_t)r * hash32_factor) >> (WORD_BITS - shift); 188 | } 189 | 190 | inline static uint_fast32_t hash32(const uint8_t *r, uint32_t shift) 191 | { 192 | return hash32v(read4_at(r), shift); 193 | } 194 | 195 | inline static uint_fast32_t hash64v_5b(const uint64_t r, uint32_t shift) 196 | { 197 | const uint64_t m = 889523592379ULL; 198 | const uint64_t up_shift = 24; 199 | return (uint32_t)(((r << up_shift) * m) >> (DWORD_BITS - shift)); 200 | } 201 | 202 | inline static uint_fast32_t hash64_5b(const uint8_t *r, uint32_t shift) 203 | { 204 | return hash64v_5b(read8_at(r), shift); 205 | } 206 | 207 | inline static uint_fast32_t hash64v_6b(const uint64_t r, uint32_t shift) 208 | { 209 | const uint64_t m = 227718039650203ULL; 210 | const uint64_t up_shift = 16; 211 | return (uint32_t)(((r << up_shift) * m) >> (DWORD_BITS - shift)); 212 | } 213 | 214 | inline static uint_fast32_t hash64_6b(const uint8_t *r, uint32_t shift) 215 | { 216 | return hash64v_6b(read8_at(r), shift); 217 | } 218 | 219 | inline static uint_fast32_t hash64v_7b(const uint64_t r, uint32_t shift) 220 | { 221 | const uint64_t m = 58295818150454627ULL; 222 | const uint64_t up_shift = 8; 223 | return (uint32_t)(((r << up_shift) * m) >> (DWORD_BITS - shift)); 224 | } 225 | 226 | inline static uint_fast32_t hash64_7b(const uint8_t *r, uint32_t shift) 227 | { 228 | return hash64v_7b(read8_at(r), shift); 229 | } 230 | 231 | inline static uint_fast32_t hash64v_8b(const uint64_t r, uint32_t shift) 232 | { 233 | const uint64_t m = 2870177450012600261ULL; 234 | return (uint32_t)((r * m) >> (DWORD_BITS - shift)); 235 | } 236 | 237 | inline static uint_fast32_t hash64_8b(const uint8_t *r, uint32_t shift) 238 | { 239 | return hash64v_8b(read8_at(r), shift); 240 | } 241 | 242 | inline static void while_lt_copy_x( 243 | uint8_t *dst, 244 | const uint8_t *src, 245 | const uint8_t *dst_end, 246 | const size_t copy_min) 247 | { 248 | for (; dst < dst_end; dst += copy_min, src += copy_min) 249 | m_copy(dst, src, copy_min); 250 | } 251 | 252 | inline static void copy_x_while_lt( 253 | uint8_t *dst, 254 | const uint8_t *src, 255 | const uint8_t *dst_end, 256 | const size_t copy_min) 257 | { 258 | m_copy(dst, src, copy_min); 259 | while (dst + copy_min < dst_end) 260 | m_copy(dst += copy_min, src += copy_min, copy_min); 261 | } 262 | 263 | inline static void copy_x_while_total( 264 | uint8_t *dst, 265 | const uint8_t *src, 266 | size_t total, 267 | const size_t copy_min) 268 | { 269 | m_copy(dst, src, copy_min); 270 | for (; total > copy_min; total -= copy_min) 271 | m_copy(dst += copy_min, src += copy_min, copy_min); 272 | } 273 | 274 | inline static void copy_2x( 275 | uint8_t *dst, 276 | const uint8_t *src, 277 | const size_t copy_min) 278 | { 279 | m_copy(dst, src, copy_min); 280 | m_copy(dst + copy_min, src + copy_min, copy_min); 281 | } 282 | 283 | inline static void copy_2x_as_x2_while_lt( 284 | uint8_t *dst, 285 | const uint8_t *src, 286 | const uint8_t *dst_end, 287 | const size_t copy_min) 288 | { 289 | copy_2x(dst, src, copy_min); 290 | while (dst + (copy_min << 1) < dst_end) 291 | copy_2x(dst += (copy_min << 1), src += (copy_min << 1), copy_min); 292 | } 293 | 294 | inline static void while_lt_copy_2x_as_x2( 295 | uint8_t *dst, 296 | const uint8_t *src, 297 | const uint8_t *dst_end, 298 | const size_t copy_min) 299 | { 300 | for (; dst < dst_end; dst += (copy_min << 1), src += (copy_min << 1)) 301 | copy_2x(dst, src, copy_min); 302 | } 303 | 304 | #endif /* _LZ4KD_PRIVATE_H */ 305 | -------------------------------------------------------------------------------- /other/zram/lz4k_oplus/Kconfig: -------------------------------------------------------------------------------- 1 | config CRYPTO_LZ4K_OPLUS 2 | tristate "Lz4k_oplus compression algorithm" 3 | select CRYPTO_ALGAPI 4 | select CRYPTO_ACOMP2 5 | help 6 | This is the lz4k_oplus algorithm. 7 | -------------------------------------------------------------------------------- /other/zram/lz4k_oplus/Makefile: -------------------------------------------------------------------------------- 1 | GCOV_PROFILE := y 2 | 3 | obj-$(CONFIG_CRYPTO_LZ4K_OPLUS) += crypto_lz4k_oplus.o 4 | 5 | crypto_lz4k_oplus-y := \ 6 | lz4k.o \ 7 | lz4k_compress.o \ 8 | lz4k_decompress.o 9 | -------------------------------------------------------------------------------- /other/zram/lz4k_oplus/lz4k.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "lz4k.h" 7 | 8 | 9 | struct lz4k_ctx { 10 | void *lz4k_comp_mem; 11 | }; 12 | 13 | static int lz4k_init(struct crypto_tfm *tfm) 14 | { 15 | struct lz4k_ctx *ctx = crypto_tfm_ctx(tfm); 16 | 17 | ctx->lz4k_comp_mem = vmalloc(PAGE_SIZE*2); 18 | if (!ctx->lz4k_comp_mem) 19 | return -ENOMEM; 20 | 21 | return 0; 22 | } 23 | 24 | static void lz4k_exit(struct crypto_tfm *tfm) 25 | { 26 | struct lz4k_ctx *ctx = crypto_tfm_ctx(tfm); 27 | vfree(ctx->lz4k_comp_mem); 28 | } 29 | 30 | static int lz4k_compress_crypto(struct crypto_tfm *tfm, const u8 *src, unsigned int slen, u8 *dst, 31 | unsigned int *dlen) 32 | { 33 | struct lz4k_ctx *ctx = crypto_tfm_ctx(tfm); 34 | int ret = 0; 35 | 36 | ret = lz4k_compress(ctx->lz4k_comp_mem, src, dst, slen, *dlen); 37 | if (ret < 0) 38 | return -EINVAL; 39 | 40 | if (ret) 41 | *dlen = ret; 42 | 43 | return 0; 44 | } 45 | 46 | static int lz4k_decompress_crypto(struct crypto_tfm *tfm, const u8 *src, unsigned int slen, u8 *dst, 47 | unsigned int *dlen) 48 | { 49 | int ret = 0; 50 | 51 | ret = lz4k_decompress(src, dst, slen, *dlen); 52 | if (ret <= 0) 53 | return -EINVAL; 54 | *dlen = ret; 55 | return 0; 56 | } 57 | 58 | 59 | static struct crypto_alg alg_lz4k = { 60 | .cra_name = "lz4k_oplus", 61 | .cra_driver_name = "lz4k_oplus-generic", 62 | .cra_flags = CRYPTO_ALG_TYPE_COMPRESS, 63 | .cra_ctxsize = sizeof(struct lz4k_ctx), 64 | .cra_module = THIS_MODULE, 65 | .cra_init = lz4k_init, 66 | .cra_exit = lz4k_exit, 67 | .cra_u = { 68 | .compress = { 69 | .coa_compress = lz4k_compress_crypto, 70 | .coa_decompress = lz4k_decompress_crypto 71 | } 72 | } 73 | }; 74 | 75 | static int __init lz4k_oplus_mod_init(void) 76 | { 77 | return crypto_register_alg(&alg_lz4k); 78 | } 79 | 80 | static void __exit lz4k_oplus_mod_fini(void) 81 | { 82 | crypto_unregister_alg(&alg_lz4k); 83 | } 84 | 85 | module_init(lz4k_oplus_mod_init); 86 | module_exit(lz4k_oplus_mod_fini); 87 | 88 | MODULE_LICENSE("GPL"); 89 | MODULE_DESCRIPTION("lz4k Compression Algorithm"); 90 | MODULE_ALIAS_CRYPTO("lz4k_oplus"); -------------------------------------------------------------------------------- /other/zram/lz4k_oplus/lz4k.h: -------------------------------------------------------------------------------- 1 | #ifndef __KERNEL__ 2 | #include 3 | #include 4 | #include 5 | #include 6 | #else 7 | #include 8 | #include 9 | #endif 10 | 11 | typedef uint8_t BYTE; 12 | typedef uint16_t U16; 13 | typedef uint32_t U32; 14 | typedef uint64_t U64; 15 | 16 | #define REPEAT_MIN 4 17 | #define TOKEN_BYTES_MAX 3 18 | #define TOKEN_BITS_MAX TOKEN_BYTES_MAX * 8 19 | #define BLOCK_4KB_LOG2 16 20 | #define NR_4KB_LOG2 4 21 | #define BYTE_BITS_LOG2 3 22 | #define BYTE_BITS 8 23 | #define DWORD_BITS 64 24 | #define BYTE_MAX 255 25 | 26 | #if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__) 27 | # define expect(expr,value) (__builtin_expect ((expr),(value)) ) 28 | #else 29 | # define expect(expr,value) (expr) 30 | #endif 31 | 32 | #ifndef likely 33 | #define likely(expr) expect((expr) != 0, 1) 34 | #endif 35 | #ifndef unlikely 36 | #define unlikely(expr) expect((expr) != 0, 0) 37 | #endif 38 | 39 | #ifndef EXPORT_SYMBOL 40 | #define EXPORT_SYMBOL(expr) 41 | #endif 42 | 43 | #ifndef MODULE_LICENSE 44 | #define MODULE_LICENSE(expr) 45 | #endif 46 | 47 | #ifndef MODULE_DESCRIPTION 48 | #define MODULE_DESCRIPTION(expr) 49 | #endif 50 | 51 | inline static U32 mask(U32 log2) 52 | { 53 | return (1U << log2) - 1U; 54 | } 55 | 56 | #define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size) 57 | 58 | inline static void m_set(void *dst, uint8_t value, size_t total) 59 | { 60 | #if defined(__STDC_LIB_EXT1__) 61 | (void)memset_s(dst, total, value, (total * 2) >> 1); /* *2 >> 1 to avoid bot errors */ 62 | #else 63 | (void)__builtin_memset(dst, value, total); 64 | #endif 65 | } 66 | 67 | inline static U32 read4_at(const void *p) 68 | { 69 | U32 result; 70 | LZ4_memcpy(&result, p, sizeof(result)); 71 | return result; 72 | } 73 | 74 | inline static U64 read8_at(const void *p) 75 | { 76 | U64 result; 77 | LZ4_memcpy(&result, p, sizeof(result)); 78 | return result; 79 | } 80 | 81 | inline static bool equal4(const uint8_t *const q, const uint8_t *const r) 82 | { 83 | return read4_at(q) == read4_at(r); 84 | } 85 | 86 | inline static U32 hash64v_5b(const U64 r, U32 shift) 87 | { 88 | const U64 m = 889523592379ULL; 89 | const U64 up_shift = 24; 90 | return (U32)(((r << up_shift) * m) >> (DWORD_BITS - shift)); 91 | } 92 | 93 | inline static U32 hash64_5b(const uint8_t *r, U32 shift) 94 | { 95 | return hash64v_5b(read8_at(r), shift); 96 | } 97 | 98 | /* this hash algo can lead speed improvement yet compression ratio reduction*/ 99 | inline static U32 hash64v_6b(const U64 r, U32 shift) 100 | { 101 | const U64 m = 227718039650203ULL; 102 | const U64 up_shift = 16; 103 | return (U32)(((r << up_shift) * m) >> (DWORD_BITS - shift)); 104 | } 105 | 106 | inline static U32 hash64_6b(const uint8_t *r, U32 shift) 107 | { 108 | return hash64v_6b(read8_at(r), shift); 109 | } 110 | 111 | 112 | /** 113 | * lz4k_compress() - Compress data from source to dest 114 | * @state: address of the working memory. 115 | * @source: source address of the original data 116 | * @dest: output buffer address of the compressed data 117 | * @source_max: size of the input data. Max supported value is 4KB 118 | * @dest_max: full or partial size of buffer 'dest' 119 | * which must be already allocated 120 | * 121 | * Compresses 'srouce_max' bytes from buffer 'source' 122 | * into already allocated 'dest' buffer of size 'maxOutputSize'. 123 | * Compression is guaranteed to succeed if 124 | * 'dest_max' >= 'source_size'. 125 | * If the function cannot compress 'source' into a more limited 'dest' budget, 126 | * compression stops *immediately*, and the function result is -1. 127 | * As a consequence, 'dest' content is not valid. 128 | * 129 | * Return: Number of bytes written into buffer 'dest' 130 | * (necessarily <= dest_max) or -1 if compression fails 131 | */ 132 | int lz4k_compress( 133 | void *const state, 134 | const void *const source, 135 | void *dest, 136 | unsigned source_max, 137 | unsigned dest_max); 138 | 139 | /** 140 | * LZ4_decompress_safe() - Decompression protected against buffer overflow 141 | * @source: source address of the compressed data 142 | * @dest: output buffer address of the uncompressed data 143 | * which must be already allocated 144 | * @source_max: is the precise full size of the compressed block 145 | * @dest_max: is the size of 'dest' buffer 146 | * 147 | * Decompresses data from 'source' into 'dest'. 148 | * If the source stream is detected malformed, the function will 149 | * stop decoding and return a negative result. 150 | * This function is protected against buffer overflow exploits, 151 | * including malicious data packets. It never writes outside output buffer, 152 | * nor reads outside input buffer. 153 | * 154 | * Return: number of bytes decompressed into destination buffer 155 | * (4KB) 156 | * or a negative result in case of error 157 | */ 158 | int lz4k_decompress( 159 | const void *const source, 160 | void *const dest, 161 | unsigned source_max, 162 | unsigned dest_max); 163 | 164 | -------------------------------------------------------------------------------- /other/zram/lz4k_oplus/lz4k_compress.c: -------------------------------------------------------------------------------- 1 | #include "lz4k.h" 2 | 3 | #define NR_COPY_LOG2 4 4 | #define NR_COPY_MIN (1 << NR_COPY_LOG2) 5 | #define HT_LOG2 12 6 | #define STEP_LOG2 5 7 | 8 | 9 | inline static const BYTE *hashed( 10 | const BYTE *const base, 11 | U16 *const dict, 12 | U32 h, 13 | const BYTE *r) 14 | { 15 | const BYTE *q = base + dict[h]; 16 | dict[h] = (U16)(r - base); 17 | return q; 18 | } 19 | 20 | inline static U32 size_bytes_count(U32 u) 21 | { 22 | return ((u + BYTE_MAX) >> BYTE_BITS) + 1; /* (u + BYTE_MAX - 1) / BYTE_MAX; */ 23 | } 24 | 25 | /* minimum compressd size for non-compressible data */ 26 | inline static U32 compressd_bytes_min( 27 | U32 nr_log2, 28 | U32 source_max) 29 | { 30 | return source_max < mask(nr_log2) ? 31 | TOKEN_BYTES_MAX + source_max : 32 | TOKEN_BYTES_MAX + size_bytes_count(source_max - mask(nr_log2)) + source_max; 33 | } 34 | 35 | inline static void copy_x_while_total( 36 | uint8_t *dst, 37 | const uint8_t *src, 38 | size_t total, 39 | const size_t copy_min) 40 | { 41 | LZ4_memcpy(dst, src, copy_min); 42 | for (; total > copy_min; total -= copy_min) 43 | LZ4_memcpy(dst += copy_min, src += copy_min, copy_min); 44 | } 45 | 46 | inline static void update_token( 47 | U32 match_length, 48 | U32 *token, 49 | const U32 nr_log2, 50 | const U32 off_log2) 51 | { 52 | const U32 r_mask = mask(TOKEN_BITS_MAX - (off_log2 + nr_log2)); 53 | *token |= likely(match_length - REPEAT_MIN < r_mask) ? 54 | ((match_length - REPEAT_MIN) << off_log2) : (r_mask << off_log2); 55 | } 56 | 57 | inline static BYTE *dest_size_bytes(BYTE *dest_at, U32 u) 58 | { 59 | for (; u >= BYTE_MAX; *dest_at++ = (BYTE)BYTE_MAX, u -= BYTE_MAX); 60 | *dest_at++ = (BYTE)u; 61 | return dest_at; 62 | } 63 | 64 | inline static BYTE *dest_token_then_bytes_left( 65 | BYTE *dest_at, 66 | U32 token, 67 | U32 bytes_left) 68 | { 69 | LZ4_memcpy(dest_at, &token, TOKEN_BYTES_MAX); 70 | return dest_size_bytes(dest_at + TOKEN_BYTES_MAX, bytes_left); 71 | } 72 | 73 | static int dest_tail( 74 | BYTE *dest_at, 75 | BYTE *const dest_end, 76 | const BYTE *const dest, 77 | const BYTE *const nr0, 78 | const BYTE *const source_end, 79 | const U32 nr_log2, 80 | const U32 off_log2) 81 | { 82 | const U32 nr_mask = mask(nr_log2); 83 | const U32 r_log2 = TOKEN_BITS_MAX - (off_log2 + nr_log2); 84 | const U32 nr_bytes_literal = (U32)(source_end - nr0); 85 | /* check if there is enough space for uncompressed data */ 86 | if (compressd_bytes_min(nr_log2, nr_bytes_literal) > (U32)(dest_end - dest_at)) 87 | return -1; 88 | if (nr_bytes_literal < nr_mask) { 89 | /* caller guarantees at least one nr-byte */ 90 | U32 token = (nr_bytes_literal << (off_log2 + r_log2)); 91 | LZ4_memcpy(dest_at, &token, TOKEN_BYTES_MAX); 92 | dest_at += TOKEN_BYTES_MAX; 93 | } else { /* nr_bytes_literal>=nr_mask */ 94 | U32 bytes_left = nr_bytes_literal - nr_mask; 95 | U32 token = (nr_mask << (off_log2 + r_log2)); 96 | dest_at = dest_token_then_bytes_left(dest_at, token, bytes_left); 97 | } /* if (nr_bytes_literal= nr_mask */ 134 | U32 bytes_left = lit_length - nr_mask; 135 | token |= (nr_mask << (off_log2 + r_log2)); 136 | dest_at = dest_token_then_bytes_left(dest_at, token, bytes_left); 137 | } /* if (lit_length> BYTE_BITS_LOG2); 203 | } 204 | /* some bytes differ: count of trailing 0-bits/bytes */ 205 | q += sizeof(U64); 206 | r += sizeof(U64); 207 | } while (likely(r <= source_end_safe)); /* once, at input block end */ 208 | while (r < source_end) { 209 | if (*q != *r) return r; 210 | ++q; 211 | ++r; 212 | } 213 | return r; 214 | } 215 | 216 | inline static U32 hash(const BYTE *r) 217 | { 218 | return hash64_5b(r, HT_LOG2); 219 | } 220 | 221 | static int compress_64k( 222 | U16 *const dict, 223 | const BYTE *const base, 224 | const BYTE *const source_end, 225 | BYTE *const dest, 226 | BYTE *const dest_end) 227 | { 228 | enum { 229 | NR_LOG2 = NR_4KB_LOG2, 230 | OFF_LOG2 = BLOCK_4KB_LOG2 231 | }; 232 | const BYTE *const source_end_safe = source_end - NR_COPY_MIN; 233 | const BYTE *r = base; 234 | const BYTE *nr0 = r++; 235 | BYTE *dest_at = dest; 236 | for (; ; nr0 = r) { 237 | const BYTE *q = 0; 238 | U32 step = 1 << STEP_LOG2; 239 | U32 token = 0; 240 | const BYTE *r_end = 0; 241 | U32 match_length = 0; 242 | while (true) { 243 | if (equal4(q = hashed(base, dict, hash(r), r), r)) 244 | break; 245 | ++r; 246 | if (equal4(q = hashed(base, dict, hash(r), r), r)) 247 | break; 248 | if (unlikely((r += (++step >> STEP_LOG2)) > source_end_safe)) 249 | return dest_tail(dest_at, dest_end, dest, nr0, source_end, 250 | NR_LOG2, OFF_LOG2); 251 | } 252 | /* first store the offset */ 253 | token = (U32)(r - q); 254 | r_end = repeat_end(q, r, source_end_safe, source_end); 255 | match_length = (U32)(r_end - r); 256 | if (unlikely(nr0 == r)) 257 | dest_at = dest_repeat(dest_at, token, match_length, 258 | NR_LOG2, OFF_LOG2); 259 | else 260 | dest_at = dest_tuple(dest_at, dest_end, token, nr0, r, match_length, 261 | NR_LOG2, OFF_LOG2); 262 | if (unlikely((r += match_length) > source_end_safe)) 263 | return dest_tail2(dest_at, dest_end, dest, r, source_end, 264 | NR_LOG2, OFF_LOG2); 265 | /* update r-1 every iters, no need to worry about overflows since r >= 1 */ 266 | dict[hash(r - 1)] = (U16)(r - 1 - base); 267 | } 268 | } 269 | 270 | int lz4k_compress( 271 | void *const state, 272 | const void *const source, 273 | void *dest, 274 | unsigned source_max, 275 | unsigned dest_max) 276 | { 277 | m_set(state, 0, 1U << (HT_LOG2+1)); 278 | *((BYTE*)dest) = 0; 279 | return compress_64k((U16*)state, (const BYTE*)source, 280 | (const BYTE*)source + source_max, (BYTE*)dest, (BYTE*)dest + dest_max); 281 | } 282 | EXPORT_SYMBOL(lz4k_compress); 283 | 284 | MODULE_LICENSE("Dual BSD/GPL"); 285 | MODULE_DESCRIPTION("LZ4K compressr"); 286 | -------------------------------------------------------------------------------- /other/zram/lz4k_oplus/lz4k_decompress.c: -------------------------------------------------------------------------------- 1 | #include "lz4k.h" 2 | #define MASK_3B 0X00FFFFFF 3 | 4 | static const BYTE *get_size( 5 | U32 *size, 6 | const BYTE *source_at, 7 | const BYTE *const source_end) 8 | { 9 | U32 u; 10 | do { 11 | if (unlikely(source_at >= source_end)) 12 | return NULL; 13 | *size += (u = *(const BYTE*)source_at); 14 | ++source_at; 15 | } while (BYTE_MAX == u); 16 | return source_at; 17 | } 18 | 19 | inline static void while_lt_copy_x( 20 | BYTE *dst, 21 | const BYTE *src, 22 | const BYTE *dst_end, 23 | const size_t copy_min) 24 | { 25 | for (; dst < dst_end; dst += copy_min, src += copy_min) 26 | LZ4_memcpy(dst, src, copy_min); 27 | } 28 | 29 | inline static void copy_x_while_lt( 30 | BYTE *dst, 31 | const BYTE *src, 32 | const BYTE *dst_end, 33 | const size_t copy_min) 34 | { 35 | while (dst + copy_min < dst_end){ 36 | LZ4_memcpy(dst += copy_min, src += copy_min, copy_min); 37 | } 38 | } 39 | 40 | inline static void copy_2x( 41 | BYTE *dst, 42 | const BYTE *src, 43 | const size_t copy_min) 44 | { 45 | LZ4_memcpy(dst, src, copy_min); 46 | LZ4_memcpy(dst + copy_min, src + copy_min, copy_min); 47 | } 48 | 49 | inline static void copy_2x_as_x2_while_lt( 50 | BYTE *dst, 51 | const BYTE *src, 52 | const BYTE *dst_end, 53 | const size_t copy_min) 54 | { 55 | copy_2x(dst, src, copy_min); 56 | while (dst + (copy_min << 1) < dst_end) 57 | copy_2x(dst += (copy_min << 1), src += (copy_min << 1), copy_min); 58 | } 59 | 60 | inline static void while_lt_copy_2x_as_x2( 61 | BYTE *dst, 62 | const BYTE *src, 63 | const BYTE *dst_end, 64 | const size_t copy_min) 65 | { 66 | for (; dst < dst_end; dst += (copy_min << 1), src += (copy_min << 1)) 67 | copy_2x(dst, src, copy_min); 68 | } 69 | 70 | static int end_of_block( 71 | const U32 lit_length, 72 | const U32 match_length, 73 | const BYTE *const source_at, 74 | const BYTE *const source_end, 75 | const BYTE *const dest, 76 | const BYTE *const dest_at) 77 | { 78 | /* check if this is the last block */ 79 | if (unlikely((!lit_length) || (source_at != source_end) 80 | || (match_length != REPEAT_MIN))) 81 | return -1; 82 | return (int)(dest_at - dest); 83 | } 84 | 85 | enum { 86 | NR_COPY_MIN = 32, 87 | R_COPY_MIN = 16, 88 | R_COPY_SAFE = R_COPY_MIN - 1, 89 | R_COPY_SAFE_2X = (R_COPY_MIN << 1) - 1 90 | }; 91 | 92 | static bool literal_decompress( 93 | const BYTE **source_at, 94 | BYTE **dest_at, 95 | U32 lit_length, 96 | const BYTE *const source_end, 97 | const BYTE *const dest_end) 98 | { 99 | const BYTE *const source_copy_end = *source_at + lit_length; 100 | BYTE *const dest_copy_end = *dest_at + lit_length; 101 | /* literals to be copied are small */ 102 | if (likely(lit_length <= NR_COPY_MIN)) { 103 | if (likely(*source_at <= source_end - NR_COPY_MIN)) 104 | LZ4_memcpy(*dest_at, *source_at, NR_COPY_MIN); 105 | else if (source_copy_end <= source_end) 106 | LZ4_memcpy(*dest_at, *source_at, lit_length); 107 | else 108 | return false; 109 | 110 | } else { /* more literals need to be copied */ 111 | /* check if there are enough space for copying without out of bounds access */ 112 | if (likely(source_copy_end <= source_end - NR_COPY_MIN && 113 | dest_copy_end <= dest_end - NR_COPY_MIN)) { 114 | LZ4_memcpy(*dest_at, *source_at, NR_COPY_MIN); 115 | copy_x_while_lt(*dest_at, 116 | *source_at, 117 | dest_copy_end, NR_COPY_MIN); 118 | /* if (*dest_at + NR_COPY_MIN < dest_copy_end){ 119 | LZ4_memcpy(*dest_at += NR_COPY_MIN, *source_at += NR_COPY_MIN, NR_COPY_MIN); 120 | } */ 121 | } else if (source_copy_end <= source_end && dest_copy_end <= dest_end) { 122 | LZ4_memcpy(*dest_at, *source_at, lit_length); 123 | } else { /* source_copy_end > source_end || dest_copy_end > dest_end */ 124 | return false; 125 | } 126 | } /* if (lit_length <= NR_COPY_MIN) */ 127 | *source_at = source_copy_end; 128 | *dest_at = dest_copy_end; 129 | return true; 130 | } 131 | 132 | static void dest_repeat_overlap( 133 | U32 offset, 134 | BYTE *dest_at, 135 | const BYTE *dest_from, 136 | const BYTE *const dest_copy_end) 137 | { 138 | enum { 139 | COPY_MIN = R_COPY_MIN >> 1, 140 | OFFSET_LIMIT = COPY_MIN >> 1 141 | }; 142 | LZ4_memcpy(dest_at, dest_from, COPY_MIN); 143 | /* (1 < offset < R_COPY_MIN/2) && dest_copy_end + R_COPY_SAFE_2X <= dest_end */ 144 | dest_at += offset; 145 | if (offset <= OFFSET_LIMIT) 146 | offset <<= 1; 147 | do { 148 | LZ4_memcpy(dest_at, dest_from, COPY_MIN); 149 | dest_at += offset; 150 | if (offset <= OFFSET_LIMIT) 151 | offset <<= 1; 152 | } while (dest_at - dest_from < R_COPY_MIN); 153 | while_lt_copy_2x_as_x2(dest_at, dest_from, dest_copy_end, R_COPY_MIN); 154 | } 155 | 156 | static bool dest_repeat_slow( 157 | U32 match_length, 158 | U32 offset, 159 | BYTE *dest_at, 160 | const BYTE *dest_from, 161 | const BYTE *const dest_copy_end, 162 | const BYTE *const dest_end) 163 | { 164 | if (offset > 1 && dest_copy_end <= dest_end - R_COPY_SAFE_2X) { 165 | dest_repeat_overlap(offset, dest_at, dest_from, dest_copy_end); 166 | } else { 167 | if (unlikely(dest_copy_end > dest_end)) 168 | return false; 169 | if (offset == 1) { 170 | m_set(dest_at, *dest_from, match_length); 171 | } else { 172 | do 173 | *dest_at++ = *dest_from++; 174 | while (dest_at < dest_copy_end); 175 | } 176 | } 177 | return true; 178 | } 179 | 180 | static int decompress( 181 | const BYTE *source_at, 182 | BYTE *const dest, 183 | const BYTE *const source_end, 184 | const BYTE *const dest_end, 185 | const U32 lit_log2, 186 | const U32 off_log2) 187 | { 188 | const U32 match_log2 = TOKEN_BITS_MAX - (off_log2 + lit_log2); 189 | const BYTE *const source_end_minus_x = source_end - TOKEN_BYTES_MAX; 190 | BYTE *dest_at = dest; 191 | while (likely(source_at <= source_end_minus_x)) { 192 | const U32 token = (*(U32 *)(source_at)) & MASK_3B; 193 | const U32 offset = token & mask(off_log2); 194 | U32 lit_length = token >> (off_log2 + match_log2), 195 | match_length = ((token >> off_log2) & mask(match_log2)) + 196 | REPEAT_MIN; 197 | const BYTE *dest_from = 0; 198 | BYTE *dest_copy_end = 0; 199 | const BYTE *dest_safe_end = 0; 200 | source_at += TOKEN_BYTES_MAX; 201 | /* get literal length and decompress */ 202 | if (unlikely(lit_length == mask(lit_log2))) { 203 | source_at = get_size(&lit_length, source_at, source_end); 204 | } 205 | if (!literal_decompress(&source_at, &dest_at, lit_length, source_end, dest_end)) 206 | return -1; 207 | /* get match length and decompress */ 208 | if (unlikely(match_length == mask(match_log2) + REPEAT_MIN)) { 209 | source_at = get_size(&match_length, source_at, source_end); 210 | } 211 | dest_from = dest_at - offset; 212 | if (unlikely(dest_from < dest)) 213 | return -1; 214 | dest_copy_end = dest_at + match_length; 215 | dest_safe_end = dest_end - R_COPY_SAFE_2X; 216 | /* need offset >= R_COPY_MIN, since every time copy R_COPY_MIN Bytes */ 217 | if (likely(offset >= R_COPY_MIN && dest_copy_end <= dest_safe_end)) { 218 | copy_2x_as_x2_while_lt(dest_at, dest_from, dest_copy_end, 219 | R_COPY_MIN); 220 | } else if (likely(offset >= (R_COPY_MIN >> 1) && 221 | dest_copy_end <= dest_safe_end)) { 222 | LZ4_memcpy(dest_at, dest_from, R_COPY_MIN); 223 | dest_at += offset; 224 | while_lt_copy_x(dest_at, dest_from, dest_copy_end, R_COPY_MIN); 225 | } else if (likely(offset > 0)) { 226 | if (!dest_repeat_slow(match_length, offset, dest_at, dest_from, 227 | dest_copy_end, dest_end)) 228 | return -1; 229 | } else { /* offset == 0: EOB, last literal */ 230 | return end_of_block(lit_length, match_length, source_at, 231 | source_end, dest, dest_at); 232 | } 233 | dest_at = dest_copy_end; 234 | } 235 | return source_at == source_end ? (int)(dest_at - dest) : -1; 236 | } 237 | 238 | int lz4k_decompress( 239 | const void *source, 240 | void *const dest, 241 | unsigned source_max, 242 | unsigned dest_max) 243 | { 244 | /* preventing compiler optimizations */ 245 | const BYTE *volatile source_end = (const BYTE*)source + source_max; 246 | const BYTE *volatile dest_end = (BYTE*)dest + dest_max; 247 | 248 | return decompress((const BYTE*)source, (BYTE*)dest, source_end, dest_end, 249 | NR_4KB_LOG2, BLOCK_4KB_LOG2); 250 | } 251 | EXPORT_SYMBOL(lz4k_decompress); 252 | 253 | MODULE_LICENSE("Dual BSD/GPL"); 254 | MODULE_DESCRIPTION("LZ4K decompressr"); 255 | -------------------------------------------------------------------------------- /other/zram/zram_patch/5.10/lz4k_oplus.patch: -------------------------------------------------------------------------------- 1 | diff -u a/lib/Kconfig b/lib/Kconfig 2 | --- a/lib/Kconfig 3 | +++ b/lib/Kconfig 4 | @@ -1,11 +1,12 @@ 5 | # SPDX-License-Identifier: GPL-2.0-only 6 | # 7 | # Library configuration 8 | # 9 | 10 | +source "lib/lz4k_oplus/Kconfig" 11 | config BINARY_PRINTF 12 | def_bool n 13 | 14 | menu "Library routines" 15 | 16 | config RAID6_PQ 17 | 18 | diff -u a/lib/Makefile b/lib/Makefile 19 | --- a/lib/Makefile 20 | +++ b/lib/Makefile 21 | @@ -186,16 +186,17 @@ 22 | obj-$(CONFIG_LZO_DECOMPRESS) += lzo/ 23 | obj-$(CONFIG_LZ4_COMPRESS) += lz4/ 24 | obj-$(CONFIG_LZ4HC_COMPRESS) += lz4/ 25 | obj-$(CONFIG_LZ4_DECOMPRESS) += lz4/ 26 | obj-$(CONFIG_LZ4K_COMPRESS) += lz4k/ 27 | obj-$(CONFIG_LZ4K_DECOMPRESS) += lz4k/ 28 | +obj-y += lz4k_oplus/ 29 | obj-$(CONFIG_LZ4KD_COMPRESS) += lz4kd/ 30 | obj-$(CONFIG_LZ4KD_DECOMPRESS) += lz4kd/ 31 | obj-$(CONFIG_ZSTD_COMPRESS) += zstd/ 32 | obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd/ 33 | obj-$(CONFIG_XZ_DEC) += xz/ 34 | obj-$(CONFIG_RAID6_PQ) += raid6/ 35 | 36 | lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o 37 | lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o 38 | lib-$(CONFIG_DECOMPRESS_LZMA) += decompress_unlzma.o 39 | 40 | diff -u a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig 41 | --- a/drivers/block/zram/Kconfig 42 | +++ b/drivers/block/zram/Kconfig 43 | @@ -1,11 +1,11 @@ 44 | # SPDX-License-Identifier: GPL-2.0 45 | config ZRAM 46 | tristate "Compressed RAM block device support" 47 | depends on BLOCK && SYSFS && ZSMALLOC && CRYPTO 48 | - depends on CRYPTO_LZO || CRYPTO_ZSTD || CRYPTO_LZ4 || CRYPTO_LZ4HC || CRYPTO_842 || CRYPTO_LZ4K || CRYPTO_LZ4KD || CRYPTO_DEFLATE 49 | + depends on CRYPTO_LZO || CRYPTO_ZSTD || CRYPTO_LZ4 || CRYPTO_LZ4HC || CRYPTO_842 || CRYPTO_LZ4K || CRYPTO_LZ4K_OPLUS || CRYPTO_LZ4KD || CRYPTO_DEFLATE 50 | help 51 | Creates virtual block devices called /dev/zramX (X = 0, 1, ...). 52 | Pages written to these disks are compressed and stored in memory 53 | itself. These disks allow very fast I/O and compression provides 54 | good amounts of memory savings. 55 | 56 | @@ -43,34 +43,38 @@ 57 | bool "842" 58 | depends on CRYPTO_842 59 | 60 | config ZRAM_DEF_COMP_LZ4K 61 | bool "lz4k" 62 | depends on CRYPTO_LZ4K 63 | + 64 | +config ZRAM_DEF_COMP_LZ4K_OPLUS 65 | + bool "lz4k" 66 | + depends on CRYPTO_LZ4K_OPLUS 67 | 68 | config ZRAM_DEF_COMP_LZ4KD 69 | bool "lz4kd" 70 | depends on CRYPTO_LZ4KD 71 | 72 | config ZRAM_DEF_COMP_DEFLATE 73 | bool "deflate" 74 | depends on CRYPTO_DEFLATE 75 | - 76 | endchoice 77 | 78 | config ZRAM_DEF_COMP 79 | string 80 | default "lzo-rle" if ZRAM_DEF_COMP_LZORLE 81 | default "zstd" if ZRAM_DEF_COMP_ZSTD 82 | default "lz4" if ZRAM_DEF_COMP_LZ4 83 | default "lzo" if ZRAM_DEF_COMP_LZO 84 | default "lz4hc" if ZRAM_DEF_COMP_LZ4HC 85 | default "842" if ZRAM_DEF_COMP_842 86 | default "lz4k" if ZRAM_DEF_COMP_LZ4K 87 | + default "lz4k_oplus" if ZRAM_DEF_COMP_LZ4K_OPLUS 88 | default "lz4kd" if ZRAM_DEF_COMP_LZ4KD 89 | default "deflate" if ZRAM_DEF_COMP_DEFLATE 90 | 91 | config ZRAM_WRITEBACK 92 | bool "Write back incompressible or idle page to backing device" 93 | depends on ZRAM 94 | help 95 | With incompressible page, there is no memory saving to keep it 96 | 97 | diff -u a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c 98 | --- a/drivers/block/zram/zcomp.c 99 | +++ b/drivers/block/zram/zcomp.c 100 | @@ -25,23 +25,26 @@ 101 | #if IS_ENABLED(CONFIG_CRYPTO_LZ4HC) 102 | "lz4hc", 103 | #endif 104 | #if IS_ENABLED(CONFIG_CRYPTO_LZ4K) 105 | "lz4k", 106 | #endif 107 | +#if IS_ENABLED(CONFIG_CRYPTO_LZ4K_OPLUS) 108 | + "lz4k_oplus", 109 | +#endif 110 | #if IS_ENABLED(CONFIG_CRYPTO_LZ4KD) 111 | "lz4kd", 112 | #endif 113 | #if IS_ENABLED(CONFIG_CRYPTO_DEFLATE) 114 | "deflate", 115 | #endif 116 | #if IS_ENABLED(CONFIG_CRYPTO_842) 117 | "842", 118 | #endif 119 | #if IS_ENABLED(CONFIG_CRYPTO_ZSTD) 120 | "zstd", 121 | #endif 122 | }; 123 | 124 | static void zcomp_strm_free(struct zcomp_strm *zstrm) 125 | { 126 | if (!IS_ERR_OR_NULL(zstrm->tfm)) 127 | -------------------------------------------------------------------------------- /other/zram/zram_patch/5.10/lz4kd.patch: -------------------------------------------------------------------------------- 1 | diff -u a/lib/Kconfig b/lib/Kconfig 2 | --- a/lib/Kconfig 3 | +++ b/lib/Kconfig 4 | @@ -307,12 +307,24 @@ 5 | config LZ4HC_COMPRESS 6 | tristate 7 | 8 | config LZ4_DECOMPRESS 9 | tristate 10 | 11 | +config LZ4K_COMPRESS 12 | + tristate 13 | + 14 | +config LZ4K_DECOMPRESS 15 | + tristate 16 | + 17 | +config LZ4KD_COMPRESS 18 | + tristate 19 | + 20 | +config LZ4KD_DECOMPRESS 21 | + tristate 22 | + 23 | config ZSTD_COMPRESS 24 | select XXHASH 25 | tristate 26 | 27 | config ZSTD_DECOMPRESS 28 | select XXHASH 29 | 30 | diff -u a/lib/Makefile b/lib/Makefile 31 | --- a/lib/Makefile 32 | +++ b/lib/Makefile 33 | @@ -184,12 +184,16 @@ 34 | obj-$(CONFIG_BCH) += bch.o 35 | obj-$(CONFIG_LZO_COMPRESS) += lzo/ 36 | obj-$(CONFIG_LZO_DECOMPRESS) += lzo/ 37 | obj-$(CONFIG_LZ4_COMPRESS) += lz4/ 38 | obj-$(CONFIG_LZ4HC_COMPRESS) += lz4/ 39 | obj-$(CONFIG_LZ4_DECOMPRESS) += lz4/ 40 | +obj-$(CONFIG_LZ4K_COMPRESS) += lz4k/ 41 | +obj-$(CONFIG_LZ4K_DECOMPRESS) += lz4k/ 42 | +obj-$(CONFIG_LZ4KD_COMPRESS) += lz4kd/ 43 | +obj-$(CONFIG_LZ4KD_DECOMPRESS) += lz4kd/ 44 | obj-$(CONFIG_ZSTD_COMPRESS) += zstd/ 45 | obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd/ 46 | obj-$(CONFIG_XZ_DEC) += xz/ 47 | obj-$(CONFIG_RAID6_PQ) += raid6/ 48 | 49 | lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o 50 | 51 | diff -u a/crypto/Kconfig b/crypto/Kconfig 52 | --- a/crypto/Kconfig 53 | +++ b/crypto/Kconfig 54 | @@ -1815,12 +1815,30 @@ 55 | select CRYPTO_ACOMP2 56 | select LZ4_COMPRESS 57 | select LZ4_DECOMPRESS 58 | help 59 | This is the LZ4 algorithm. 60 | 61 | +config CRYPTO_LZ4K 62 | + tristate "LZ4K" 63 | + select CRYPTO_ALGAPI 64 | + select CRYPTO_ACOMP2 65 | + select LZ4K_COMPRESS 66 | + select LZ4K_DECOMPRESS 67 | + help 68 | + LZ4K compression algorithm 69 | + 70 | +config CRYPTO_LZ4KD 71 | + tristate "LZ4KD" 72 | + select CRYPTO_ALGAPI 73 | + select CRYPTO_ACOMP2 74 | + select LZ4KD_COMPRESS 75 | + select LZ4KD_DECOMPRESS 76 | + help 77 | + LZ4KD compression algorithm 78 | + 79 | config CRYPTO_LZ4HC 80 | tristate "LZ4HC compression algorithm" 81 | select CRYPTO_ALGAPI 82 | select CRYPTO_ACOMP2 83 | select LZ4HC_COMPRESS 84 | select LZ4_DECOMPRESS 85 | 86 | diff -u a/crypto/Makefile b/crypto/Makefile 87 | --- a/crypto/Makefile 88 | +++ b/crypto/Makefile 89 | @@ -150,12 +150,14 @@ 90 | obj-$(CONFIG_CRYPTO_CRC32) += crc32_generic.o 91 | obj-$(CONFIG_CRYPTO_CRCT10DIF) += crct10dif_common.o crct10dif_generic.o 92 | obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o authencesn.o 93 | obj-$(CONFIG_CRYPTO_LZO) += lzo.o lzo-rle.o 94 | obj-$(CONFIG_CRYPTO_LZ4) += lz4.o 95 | obj-$(CONFIG_CRYPTO_LZ4HC) += lz4hc.o 96 | +obj-$(CONFIG_CRYPTO_LZ4K) += lz4k.o 97 | +obj-$(CONFIG_CRYPTO_LZ4KD) += lz4kd.o 98 | obj-$(CONFIG_CRYPTO_XXHASH) += xxhash_generic.o 99 | obj-$(CONFIG_CRYPTO_842) += 842.o 100 | obj-$(CONFIG_CRYPTO_RNG2) += rng.o 101 | obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.o 102 | obj-$(CONFIG_CRYPTO_DRBG) += drbg.o 103 | obj-$(CONFIG_CRYPTO_JITTERENTROPY) += jitterentropy_rng.o 104 | 105 | diff -u a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c 106 | --- a/drivers/block/zram/zram_drv.c 107 | +++ b/drivers/block/zram/zram_drv.c 108 | @@ -39,13 +39,13 @@ 109 | 110 | static DEFINE_IDR(zram_index_idr); 111 | /* idr index must be protected */ 112 | static DEFINE_MUTEX(zram_index_mutex); 113 | 114 | static int zram_major; 115 | -static const char *default_compressor = "lzo-rle"; 116 | +static const char *default_compressor = CONFIG_ZRAM_DEF_COMP; 117 | 118 | /* Module params (documentation at end) */ 119 | static unsigned int num_devices = 1; 120 | /* 121 | * Pages that compress to sizes equals or greater than this are stored 122 | * uncompressed in memory. 123 | 124 | diff -u a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig 125 | --- a/drivers/block/zram/Kconfig 126 | +++ b/drivers/block/zram/Kconfig 127 | @@ -1,21 +1,76 @@ 128 | # SPDX-License-Identifier: GPL-2.0 129 | config ZRAM 130 | tristate "Compressed RAM block device support" 131 | depends on BLOCK && SYSFS && ZSMALLOC && CRYPTO 132 | - select CRYPTO_LZO 133 | + depends on CRYPTO_LZO || CRYPTO_ZSTD || CRYPTO_LZ4 || CRYPTO_LZ4HC || CRYPTO_842 || CRYPTO_LZ4K || CRYPTO_LZ4KD || CRYPTO_DEFLATE 134 | help 135 | Creates virtual block devices called /dev/zramX (X = 0, 1, ...). 136 | Pages written to these disks are compressed and stored in memory 137 | itself. These disks allow very fast I/O and compression provides 138 | good amounts of memory savings. 139 | 140 | It has several use cases, for example: /tmp storage, use as swap 141 | disks and maybe many more. 142 | 143 | See Documentation/admin-guide/blockdev/zram.rst for more information. 144 | + 145 | +choice 146 | + prompt "Default zram compressor" 147 | + default ZRAM_DEF_COMP_LZORLE 148 | + depends on ZRAM 149 | + 150 | +config ZRAM_DEF_COMP_LZORLE 151 | + bool "lzo-rle" 152 | + depends on CRYPTO_LZO 153 | + 154 | +config ZRAM_DEF_COMP_ZSTD 155 | + bool "zstd" 156 | + depends on CRYPTO_ZSTD 157 | + 158 | +config ZRAM_DEF_COMP_LZ4 159 | + bool "lz4" 160 | + depends on CRYPTO_LZ4 161 | + 162 | +config ZRAM_DEF_COMP_LZO 163 | + bool "lzo" 164 | + depends on CRYPTO_LZO 165 | + 166 | +config ZRAM_DEF_COMP_LZ4HC 167 | + bool "lz4hc" 168 | + depends on CRYPTO_LZ4HC 169 | + 170 | +config ZRAM_DEF_COMP_842 171 | + bool "842" 172 | + depends on CRYPTO_842 173 | + 174 | +config ZRAM_DEF_COMP_LZ4K 175 | + bool "lz4k" 176 | + depends on CRYPTO_LZ4K 177 | + 178 | +config ZRAM_DEF_COMP_LZ4KD 179 | + bool "lz4kd" 180 | + depends on CRYPTO_LZ4KD 181 | + 182 | +config ZRAM_DEF_COMP_DEFLATE 183 | + bool "deflate" 184 | + depends on CRYPTO_DEFLATE 185 | + 186 | +endchoice 187 | + 188 | +config ZRAM_DEF_COMP 189 | + string 190 | + default "lzo-rle" if ZRAM_DEF_COMP_LZORLE 191 | + default "zstd" if ZRAM_DEF_COMP_ZSTD 192 | + default "lz4" if ZRAM_DEF_COMP_LZ4 193 | + default "lzo" if ZRAM_DEF_COMP_LZO 194 | + default "lz4hc" if ZRAM_DEF_COMP_LZ4HC 195 | + default "842" if ZRAM_DEF_COMP_842 196 | + default "lz4k" if ZRAM_DEF_COMP_LZ4K 197 | + default "lz4kd" if ZRAM_DEF_COMP_LZ4KD 198 | + default "deflate" if ZRAM_DEF_COMP_DEFLATE 199 | 200 | config ZRAM_WRITEBACK 201 | bool "Write back incompressible or idle page to backing device" 202 | depends on ZRAM 203 | help 204 | With incompressible page, there is no memory saving to keep it 205 | 206 | diff -u a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c 207 | --- a/drivers/block/zram/zcomp.c 208 | +++ b/drivers/block/zram/zcomp.c 209 | @@ -12,19 +12,30 @@ 210 | #include 211 | #include 212 | 213 | #include "zcomp.h" 214 | 215 | static const char * const backends[] = { 216 | +#if IS_ENABLED(CONFIG_CRYPTO_LZO) 217 | "lzo", 218 | "lzo-rle", 219 | +#endif 220 | #if IS_ENABLED(CONFIG_CRYPTO_LZ4) 221 | "lz4", 222 | #endif 223 | #if IS_ENABLED(CONFIG_CRYPTO_LZ4HC) 224 | "lz4hc", 225 | +#endif 226 | +#if IS_ENABLED(CONFIG_CRYPTO_LZ4K) 227 | + "lz4k", 228 | +#endif 229 | +#if IS_ENABLED(CONFIG_CRYPTO_LZ4KD) 230 | + "lz4kd", 231 | +#endif 232 | +#if IS_ENABLED(CONFIG_CRYPTO_DEFLATE) 233 | + "deflate", 234 | #endif 235 | #if IS_ENABLED(CONFIG_CRYPTO_842) 236 | "842", 237 | #endif 238 | #if IS_ENABLED(CONFIG_CRYPTO_ZSTD) 239 | "zstd", 240 | 241 | diff -u a/kernel/module.c b/kernel/module.c 242 | --- a/kernel/module.c 243 | +++ b/kernel/module.c 244 | @@ -1349,15 +1349,14 @@ 245 | 246 | /* Broken toolchain. Warn once, then let it go.. */ 247 | pr_warn_once("%s: no symbol version for %s\n", info->name, symname); 248 | return 1; 249 | 250 | bad_version: 251 | - pr_warn("%s: disagrees about version of symbol %s\n", 252 | - info->name, symname); 253 | - return 0; 254 | + 255 | + return 1; 256 | } 257 | 258 | static inline int check_modstruct_version(const struct load_info *info, 259 | struct module *mod) 260 | { 261 | const s32 *crc; 262 | @@ -3562,27 +3561,46 @@ 263 | { 264 | return 0; 265 | } 266 | 267 | /* module_blacklist is a comma-separated list of module names */ 268 | static char *module_blacklist; 269 | +static char *custom_module_blacklist[] = { 270 | +#if IS_BUILTIN(CONFIG_CRYPTO_LZO) 271 | + "lzo", "lzo_rle", 272 | +#endif 273 | +#if IS_BUILTIN(CONFIG_ZRAM) 274 | + "zram", 275 | +#endif 276 | +#if IS_BUILTIN(CONFIG_ZSMALLOC) 277 | + "zsmalloc", 278 | +#endif 279 | +}; 280 | + 281 | static bool blacklisted(const char *module_name) 282 | { 283 | const char *p; 284 | size_t len; 285 | + int i; 286 | 287 | if (!module_blacklist) 288 | - return false; 289 | + goto custom_blacklist; 290 | 291 | for (p = module_blacklist; *p; p += len) { 292 | len = strcspn(p, ","); 293 | if (strlen(module_name) == len && !memcmp(module_name, p, len)) 294 | return true; 295 | if (p[len] == ',') 296 | len++; 297 | } 298 | + 299 | +custom_blacklist: 300 | + for (i = 0; i < ARRAY_SIZE(custom_module_blacklist); i++) 301 | + if (!strcmp(module_name, custom_module_blacklist[i])) 302 | + return true; 303 | + 304 | return false; 305 | } 306 | core_param(module_blacklist, module_blacklist, charp, 0400); 307 | 308 | static struct module *layout_and_allocate(struct load_info *info, int flags) 309 | { 310 | @@ -4025,13 +4043,13 @@ 311 | 312 | /* 313 | * Now that we know we have the correct module name, check 314 | * if it's blacklisted. 315 | */ 316 | if (blacklisted(info->name)) { 317 | - err = -EPERM; 318 | + // err = -EPERM; 319 | pr_err("Module %s is blacklisted\n", info->name); 320 | goto free_copy; 321 | } 322 | 323 | err = rewrite_section_headers(info, flags); 324 | if (err) 325 | -------------------------------------------------------------------------------- /other/zram/zram_patch/5.15/lz4k_oplus.patch: -------------------------------------------------------------------------------- 1 | diff -u a/lib/Kconfig b/lib/Kconfig 2 | --- a/lib/Kconfig 3 | +++ b/lib/Kconfig 4 | @@ -1,11 +1,12 @@ 5 | # SPDX-License-Identifier: GPL-2.0-only 6 | # 7 | # Library configuration 8 | # 9 | 10 | +source "lib/lz4k_oplus/Kconfig" 11 | config BINARY_PRINTF 12 | def_bool n 13 | 14 | menu "Library routines" 15 | 16 | config RAID6_PQ 17 | 18 | diff -u a/lib/Makefile b/lib/Makefile 19 | --- a/lib/Makefile 20 | +++ b/lib/Makefile 21 | @@ -189,16 +189,17 @@ 22 | obj-$(CONFIG_LZO_DECOMPRESS) += lzo/ 23 | obj-$(CONFIG_LZ4_COMPRESS) += lz4/ 24 | obj-$(CONFIG_LZ4HC_COMPRESS) += lz4/ 25 | obj-$(CONFIG_LZ4_DECOMPRESS) += lz4/ 26 | obj-$(CONFIG_LZ4K_COMPRESS) += lz4k/ 27 | obj-$(CONFIG_LZ4K_DECOMPRESS) += lz4k/ 28 | +obj-y += lz4k_oplus/ 29 | obj-$(CONFIG_LZ4KD_COMPRESS) += lz4kd/ 30 | obj-$(CONFIG_LZ4KD_DECOMPRESS) += lz4kd/ 31 | obj-$(CONFIG_ZSTD_COMPRESS) += zstd/ 32 | obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd/ 33 | obj-$(CONFIG_XZ_DEC) += xz/ 34 | obj-$(CONFIG_RAID6_PQ) += raid6/ 35 | 36 | lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o 37 | lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o 38 | lib-$(CONFIG_DECOMPRESS_LZMA) += decompress_unlzma.o 39 | 40 | diff -u a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig 41 | --- a/drivers/block/zram/Kconfig 42 | +++ b/drivers/block/zram/Kconfig 43 | @@ -1,11 +1,11 @@ 44 | # SPDX-License-Identifier: GPL-2.0 45 | config ZRAM 46 | tristate "Compressed RAM block device support" 47 | depends on BLOCK && SYSFS && ZSMALLOC && CRYPTO 48 | - depends on CRYPTO_LZO || CRYPTO_LZ4 || CRYPTO_LZ4HC || CRYPTO_LZ4K || CRYPTO_LZ4KD || CRYPTO_DEFLATE || CRYPTO_842 || CRYPTO_ZSTD 49 | + depends on CRYPTO_LZO || CRYPTO_LZ4 || CRYPTO_LZ4HC || CRYPTO_LZ4K || CRYPTO_LZ4K_OPLUS || CRYPTO_LZ4KD || CRYPTO_DEFLATE || CRYPTO_842 || CRYPTO_ZSTD 50 | help 51 | Creates virtual block devices called /dev/zramX (X = 0, 1, ...). 52 | Pages written to these disks are compressed and stored in memory 53 | itself. These disks allow very fast I/O and compression provides 54 | good amounts of memory savings. 55 | 56 | @@ -35,12 +35,16 @@ 57 | bool "lz4hc" 58 | depends on CRYPTO_LZ4HC 59 | 60 | config ZRAM_DEF_COMP_LZ4K 61 | bool "lz4k" 62 | depends on CRYPTO_LZ4K 63 | + 64 | +config ZRAM_DEF_COMP_LZ4K_OPLUS 65 | + bool "lz4k" 66 | + depends on CRYPTO_LZ4K_OPLUS 67 | 68 | config ZRAM_DEF_COMP_LZ4KD 69 | bool "lz4kd" 70 | depends on CRYPTO_LZ4KD 71 | 72 | config ZRAM_DEF_COMP_DEFLATE 73 | @@ -61,12 +65,13 @@ 74 | string 75 | default "lzo" if ZRAM_DEF_COMP_LZO 76 | default "lzo-rle" if ZRAM_DEF_COMP_LZORLE 77 | default "lz4" if ZRAM_DEF_COMP_LZ4 78 | default "lz4hc" if ZRAM_DEF_COMP_LZ4HC 79 | default "lz4k" if ZRAM_DEF_COMP_LZ4K 80 | + default "lz4k_oplus" if ZRAM_DEF_COMP_LZ4K_OPLUS 81 | default "lz4kd" if ZRAM_DEF_COMP_LZ4KD 82 | default "deflate" if ZRAM_DEF_COMP_DEFLATE 83 | default "842" if ZRAM_DEF_COMP_842 84 | default "zstd" if ZRAM_DEF_COMP_ZSTD 85 | 86 | config ZRAM_WRITEBACK 87 | 88 | diff -u a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c 89 | --- a/drivers/block/zram/zcomp.c 90 | +++ b/drivers/block/zram/zcomp.c 91 | @@ -25,23 +25,26 @@ 92 | #if IS_ENABLED(CONFIG_CRYPTO_LZ4HC) 93 | "lz4hc", 94 | #endif 95 | #if IS_ENABLED(CONFIG_CRYPTO_LZ4K) 96 | "lz4k", 97 | #endif 98 | +#if IS_ENABLED(CONFIG_CRYPTO_LZ4K_OPLUS) 99 | + "lz4k_oplus", 100 | +#endif 101 | #if IS_ENABLED(CONFIG_CRYPTO_LZ4KD) 102 | "lz4kd", 103 | #endif 104 | #if IS_ENABLED(CONFIG_CRYPTO_DEFLATE) 105 | "deflate", 106 | #endif 107 | #if IS_ENABLED(CONFIG_CRYPTO_842) 108 | "842", 109 | #endif 110 | #if IS_ENABLED(CONFIG_CRYPTO_ZSTD) 111 | "zstd", 112 | #endif 113 | }; 114 | 115 | static void zcomp_strm_free(struct zcomp_strm *zstrm) 116 | { 117 | if (!IS_ERR_OR_NULL(zstrm->tfm)) 118 | -------------------------------------------------------------------------------- /other/zram/zram_patch/5.15/lz4kd.patch: -------------------------------------------------------------------------------- 1 | diff -u a/lib/Kconfig b/lib/Kconfig 2 | --- a/lib/Kconfig 3 | +++ b/lib/Kconfig 4 | @@ -328,16 +328,28 @@ 5 | config LZO_DECOMPRESS 6 | tristate 7 | 8 | config LZ4_COMPRESS 9 | tristate 10 | 11 | +config LZ4K_COMPRESS 12 | + tristate 13 | + 14 | config LZ4HC_COMPRESS 15 | tristate 16 | 17 | config LZ4_DECOMPRESS 18 | + tristate 19 | + 20 | +config LZ4K_DECOMPRESS 21 | + tristate 22 | + 23 | +config LZ4KD_COMPRESS 24 | + tristate 25 | + 26 | +config LZ4KD_DECOMPRESS 27 | tristate 28 | 29 | config ZSTD_COMPRESS 30 | select XXHASH 31 | tristate 32 | 33 | diff -u a/lib/Makefile b/lib/Makefile 34 | --- a/lib/Makefile 35 | +++ b/lib/Makefile 36 | @@ -187,12 +187,16 @@ 37 | obj-$(CONFIG_BCH) += bch.o 38 | obj-$(CONFIG_LZO_COMPRESS) += lzo/ 39 | obj-$(CONFIG_LZO_DECOMPRESS) += lzo/ 40 | obj-$(CONFIG_LZ4_COMPRESS) += lz4/ 41 | obj-$(CONFIG_LZ4HC_COMPRESS) += lz4/ 42 | obj-$(CONFIG_LZ4_DECOMPRESS) += lz4/ 43 | +obj-$(CONFIG_LZ4K_COMPRESS) += lz4k/ 44 | +obj-$(CONFIG_LZ4K_DECOMPRESS) += lz4k/ 45 | +obj-$(CONFIG_LZ4KD_COMPRESS) += lz4kd/ 46 | +obj-$(CONFIG_LZ4KD_DECOMPRESS) += lz4kd/ 47 | obj-$(CONFIG_ZSTD_COMPRESS) += zstd/ 48 | obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd/ 49 | obj-$(CONFIG_XZ_DEC) += xz/ 50 | obj-$(CONFIG_RAID6_PQ) += raid6/ 51 | 52 | lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o 53 | diff -u a/crypto/Kconfig b/crypto/Kconfig 54 | --- a/crypto/Kconfig 55 | +++ b/crypto/Kconfig 56 | @@ -1817,12 +1817,28 @@ 57 | select CRYPTO_ACOMP2 58 | select LZ4_COMPRESS 59 | select LZ4_DECOMPRESS 60 | help 61 | This is the LZ4 algorithm. 62 | 63 | +config CRYPTO_LZ4K 64 | + tristate "LZ4K compression algorithm" 65 | + select CRYPTO_ALGAPI 66 | + select LZ4K_COMPRESS 67 | + select LZ4K_DECOMPRESS 68 | + help 69 | + This is the LZ4K algorithm. 70 | + 71 | +config CRYPTO_LZ4KD 72 | + tristate "LZ4KD compression algorithm" 73 | + select CRYPTO_ALGAPI 74 | + select LZ4KD_COMPRESS 75 | + select LZ4KD_DECOMPRESS 76 | + help 77 | + This is the LZ4KD algorithm. 78 | + 79 | config CRYPTO_LZ4HC 80 | tristate "LZ4HC compression algorithm" 81 | select CRYPTO_ALGAPI 82 | select CRYPTO_ACOMP2 83 | select LZ4HC_COMPRESS 84 | select LZ4_DECOMPRESS 85 | 86 | diff -u a/crypto/Makefile b/crypto/Makefile 87 | --- a/crypto/Makefile 88 | +++ b/crypto/Makefile 89 | @@ -151,13 +151,15 @@ 90 | obj-$(CONFIG_CRYPTO_CRC32C) += crc32c_generic.o 91 | obj-$(CONFIG_CRYPTO_CRC32) += crc32_generic.o 92 | obj-$(CONFIG_CRYPTO_CRCT10DIF) += crct10dif_common.o crct10dif_generic.o 93 | obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o authencesn.o 94 | obj-$(CONFIG_CRYPTO_LZO) += lzo.o lzo-rle.o 95 | obj-$(CONFIG_CRYPTO_LZ4) += lz4.o 96 | +obj-$(CONFIG_CRYPTO_LZ4K) += lz4k.o 97 | obj-$(CONFIG_CRYPTO_LZ4HC) += lz4hc.o 98 | +obj-$(CONFIG_CRYPTO_LZ4KD) += lz4kd.o 99 | obj-$(CONFIG_CRYPTO_XXHASH) += xxhash_generic.o 100 | obj-$(CONFIG_CRYPTO_842) += 842.o 101 | obj-$(CONFIG_CRYPTO_RNG2) += rng.o 102 | obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.o 103 | obj-$(CONFIG_CRYPTO_DRBG) += drbg.o 104 | obj-$(CONFIG_CRYPTO_JITTERENTROPY) += jitterentropy_rng.o 105 | 106 | diff -u a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig 107 | --- a/drivers/block/zram/Kconfig 108 | +++ b/drivers/block/zram/Kconfig 109 | @@ -1,11 +1,11 @@ 110 | # SPDX-License-Identifier: GPL-2.0 111 | config ZRAM 112 | tristate "Compressed RAM block device support" 113 | depends on BLOCK && SYSFS && ZSMALLOC && CRYPTO 114 | - depends on CRYPTO_LZO || CRYPTO_ZSTD || CRYPTO_LZ4 || CRYPTO_LZ4HC || CRYPTO_842 115 | + depends on CRYPTO_LZO || CRYPTO_LZ4 || CRYPTO_LZ4HC || CRYPTO_LZ4K || CRYPTO_LZ4KD || CRYPTO_DEFLATE || CRYPTO_842 || CRYPTO_ZSTD 116 | help 117 | Creates virtual block devices called /dev/zramX (X = 0, 1, ...). 118 | Pages written to these disks are compressed and stored in memory 119 | itself. These disks allow very fast I/O and compression provides 120 | good amounts of memory savings. 121 | 122 | @@ -13,49 +13,64 @@ 123 | disks and maybe many more. 124 | 125 | See Documentation/admin-guide/blockdev/zram.rst for more information. 126 | 127 | choice 128 | prompt "Default zram compressor" 129 | - default ZRAM_DEF_COMP_LZORLE 130 | + default ZRAM_DEF_COMP_LZ4KD 131 | depends on ZRAM 132 | 133 | +config ZRAM_DEF_COMP_LZO 134 | + bool "lzo" 135 | + depends on CRYPTO_LZO 136 | + 137 | config ZRAM_DEF_COMP_LZORLE 138 | bool "lzo-rle" 139 | depends on CRYPTO_LZO 140 | 141 | -config ZRAM_DEF_COMP_ZSTD 142 | - bool "zstd" 143 | - depends on CRYPTO_ZSTD 144 | - 145 | config ZRAM_DEF_COMP_LZ4 146 | bool "lz4" 147 | depends on CRYPTO_LZ4 148 | 149 | -config ZRAM_DEF_COMP_LZO 150 | - bool "lzo" 151 | - depends on CRYPTO_LZO 152 | - 153 | config ZRAM_DEF_COMP_LZ4HC 154 | bool "lz4hc" 155 | depends on CRYPTO_LZ4HC 156 | 157 | +config ZRAM_DEF_COMP_LZ4K 158 | + bool "lz4k" 159 | + depends on CRYPTO_LZ4K 160 | + 161 | +config ZRAM_DEF_COMP_LZ4KD 162 | + bool "lz4kd" 163 | + depends on CRYPTO_LZ4KD 164 | + 165 | +config ZRAM_DEF_COMP_DEFLATE 166 | + bool "deflate" 167 | + depends on CRYPTO_DEFLATE 168 | + 169 | config ZRAM_DEF_COMP_842 170 | bool "842" 171 | depends on CRYPTO_842 172 | 173 | +config ZRAM_DEF_COMP_ZSTD 174 | + bool "zstd" 175 | + depends on CRYPTO_ZSTD 176 | + 177 | endchoice 178 | 179 | config ZRAM_DEF_COMP 180 | string 181 | + default "lzo" if ZRAM_DEF_COMP_LZO 182 | default "lzo-rle" if ZRAM_DEF_COMP_LZORLE 183 | - default "zstd" if ZRAM_DEF_COMP_ZSTD 184 | default "lz4" if ZRAM_DEF_COMP_LZ4 185 | - default "lzo" if ZRAM_DEF_COMP_LZO 186 | default "lz4hc" if ZRAM_DEF_COMP_LZ4HC 187 | + default "lz4k" if ZRAM_DEF_COMP_LZ4K 188 | + default "lz4kd" if ZRAM_DEF_COMP_LZ4KD 189 | + default "deflate" if ZRAM_DEF_COMP_DEFLATE 190 | default "842" if ZRAM_DEF_COMP_842 191 | + default "zstd" if ZRAM_DEF_COMP_ZSTD 192 | 193 | config ZRAM_WRITEBACK 194 | bool "Write back incompressible or idle page to backing device" 195 | depends on ZRAM 196 | help 197 | With incompressible page, there is no memory saving to keep it 198 | 199 | diff -u a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c 200 | --- a/drivers/block/zram/zcomp.c 201 | +++ b/drivers/block/zram/zcomp.c 202 | @@ -22,12 +22,21 @@ 203 | #if IS_ENABLED(CONFIG_CRYPTO_LZ4) 204 | "lz4", 205 | #endif 206 | #if IS_ENABLED(CONFIG_CRYPTO_LZ4HC) 207 | "lz4hc", 208 | #endif 209 | +#if IS_ENABLED(CONFIG_CRYPTO_LZ4K) 210 | + "lz4k", 211 | +#endif 212 | +#if IS_ENABLED(CONFIG_CRYPTO_LZ4KD) 213 | + "lz4kd", 214 | +#endif 215 | +#if IS_ENABLED(CONFIG_CRYPTO_DEFLATE) 216 | + "deflate", 217 | +#endif 218 | #if IS_ENABLED(CONFIG_CRYPTO_842) 219 | "842", 220 | #endif 221 | #if IS_ENABLED(CONFIG_CRYPTO_ZSTD) 222 | "zstd", 223 | #endif 224 | 225 | diff -u a/kernel/module.c b/kernel/module.c 226 | --- a/kernel/module.c 227 | +++ b/kernel/module.c 228 | @@ -1284,15 +1284,13 @@ 229 | 230 | /* Broken toolchain. Warn once, then let it go.. */ 231 | pr_warn_once("%s: no symbol version for %s\n", info->name, symname); 232 | return 1; 233 | 234 | bad_version: 235 | - pr_warn("%s: disagrees about version of symbol %s\n", 236 | - info->name, symname); 237 | - return 0; 238 | + return 1; 239 | } 240 | 241 | static inline int check_modstruct_version(const struct load_info *info, 242 | struct module *mod) 243 | { 244 | struct find_symbol_arg fsa = { 245 | @@ -3581,27 +3579,63 @@ 246 | { 247 | return 0; 248 | } 249 | 250 | /* module_blacklist is a comma-separated list of module names */ 251 | static char *module_blacklist; 252 | +static char *custom_module_blacklist[] = { 253 | +#if IS_BUILTIN(CONFIG_CRYPTO_LZO) 254 | + "lzo", "lzo_rle", 255 | +#endif 256 | +#if IS_BUILTIN(CONFIG_ZRAM) 257 | + "zram", 258 | +#endif 259 | +#if IS_BUILTIN(CONFIG_ZSMALLOC) 260 | + "zsmalloc", 261 | +#endif 262 | +#ifdef CONFIG_MACH_XIAOMI_MARBLE 263 | + /* Not required */ 264 | + "qca6750", "icnss2", "cs35l41_dlkm", "atmel_mxt_ts", "focaltech_fts", "nt36xxx_i2c", "nt36xxx_spi", "synaptics_dsx", 265 | + /* Already built into the kernel image */ 266 | + "aw882xx_dlkm", 267 | + /* Useless logs */ 268 | + "cameralog", "f_fs_ipc_log", 269 | + /* Debug */ 270 | + "qcom_cpufreq_hw_debug", "qcom_iommu_debug", "qti_battery_debug", "rdbg", "spmi_glink_debug", "spmi_pmic_arb_debug", 271 | + "debug_ext", "ehset", "lvstest", 272 | + /* Coresight */ 273 | + "coresight", "coresight_csr", "coresight_cti", "coresight_dummy", "coresight_funnel", 274 | + "coresight_hwevent", "coresight_remote_etm", "coresight_replicator", "coresight_stm", 275 | + "coresight_tgu", "coresight_tmc", "coresight_tpda", "coresight_tpdm", 276 | + /* STM (System Trace Module devices) */ 277 | + "stm_console", "stm_core", "stm_ftrace", "stm_p_basic", "stm_p_ost", 278 | +#endif 279 | +}; 280 | + 281 | static bool blacklisted(const char *module_name) 282 | { 283 | const char *p; 284 | size_t len; 285 | + int i; 286 | 287 | if (!module_blacklist) 288 | - return false; 289 | + goto custom_blacklist; 290 | 291 | for (p = module_blacklist; *p; p += len) { 292 | len = strcspn(p, ","); 293 | if (strlen(module_name) == len && !memcmp(module_name, p, len)) 294 | return true; 295 | if (p[len] == ',') 296 | len++; 297 | } 298 | + 299 | +custom_blacklist: 300 | + for (i = 0; i < ARRAY_SIZE(custom_module_blacklist); i++) 301 | + if (!strcmp(module_name, custom_module_blacklist[i])) 302 | + return true; 303 | + 304 | return false; 305 | } 306 | core_param(module_blacklist, module_blacklist, charp, 0400); 307 | 308 | static struct module *layout_and_allocate(struct load_info *info, int flags) 309 | { 310 | @@ -4064,13 +4098,13 @@ 311 | 312 | /* 313 | * Now that we know we have the correct module name, check 314 | * if it's blacklisted. 315 | */ 316 | if (blacklisted(info->name)) { 317 | - err = -EPERM; 318 | + // err = -EPERM; 319 | pr_err("Module %s is blacklisted\n", info->name); 320 | goto free_copy; 321 | } 322 | 323 | err = rewrite_section_headers(info, flags); 324 | if (err) 325 | -------------------------------------------------------------------------------- /other/zram/zram_patch/6.1/lz4k_oplus.patch: -------------------------------------------------------------------------------- 1 | diff -u a/lib/Kconfig b/lib/Kconfig 2 | --- a/lib/Kconfig 3 | +++ b/lib/Kconfig 4 | @@ -1,11 +1,11 @@ 5 | # SPDX-License-Identifier: GPL-2.0-only 6 | # 7 | # Library configuration 8 | # 9 | - 10 | +source "lib/lz4k_oplus/Kconfig" 11 | config BINARY_PRINTF 12 | def_bool n 13 | 14 | menu "Library routines" 15 | 16 | config RAID6_PQ 17 | 18 | diff -u a/lib/Makefile b/lib/Makefile 19 | --- a/lib/Makefile 20 | +++ b/lib/Makefile 21 | @@ -195,16 +195,17 @@ 22 | obj-$(CONFIG_LZO_DECOMPRESS) += lzo/ 23 | obj-$(CONFIG_LZ4_COMPRESS) += lz4/ 24 | obj-$(CONFIG_LZ4HC_COMPRESS) += lz4/ 25 | obj-$(CONFIG_LZ4_DECOMPRESS) += lz4/ 26 | obj-$(CONFIG_LZ4K_COMPRESS) += lz4k/ 27 | obj-$(CONFIG_LZ4K_DECOMPRESS) += lz4k/ 28 | +obj-y += lz4k_oplus/ 29 | obj-$(CONFIG_LZ4KD_COMPRESS) += lz4kd/ 30 | obj-$(CONFIG_LZ4KD_DECOMPRESS) += lz4kd/ 31 | obj-$(CONFIG_ZSTD_COMPRESS) += zstd/ 32 | obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd/ 33 | obj-$(CONFIG_XZ_DEC) += xz/ 34 | obj-$(CONFIG_RAID6_PQ) += raid6/ 35 | 36 | lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o 37 | lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o 38 | lib-$(CONFIG_DECOMPRESS_LZMA) += decompress_unlzma.o 39 | 40 | diff -u a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig 41 | --- a/drivers/block/zram/Kconfig 42 | +++ b/drivers/block/zram/Kconfig 43 | @@ -1,11 +1,11 @@ 44 | # SPDX-License-Identifier: GPL-2.0 45 | config ZRAM 46 | tristate "Compressed RAM block device support" 47 | depends on BLOCK && SYSFS && MMU 48 | - depends on CRYPTO_LZO || CRYPTO_LZ4 || CRYPTO_LZ4HC || CRYPTO_LZ4K || CRYPTO_LZ4KD || CRYPTO_DEFLATE || CRYPTO_842 || CRYPTO_ZSTD 49 | + depends on CRYPTO_LZO || CRYPTO_LZ4 || CRYPTO_LZ4HC || CRYPTO_LZ4K || CRYPTO_LZ4K_OPLUS || CRYPTO_LZ4KD || CRYPTO_DEFLATE || CRYPTO_842 || CRYPTO_ZSTD 50 | select ZSMALLOC 51 | help 52 | Creates virtual block devices called /dev/zramX (X = 0, 1, ...). 53 | Pages written to these disks are compressed and stored in memory 54 | itself. These disks allow very fast I/O and compression provides 55 | good amounts of memory savings. 56 | @@ -36,12 +36,16 @@ 57 | bool "lz4hc" 58 | depends on CRYPTO_LZ4HC 59 | 60 | config ZRAM_DEF_COMP_LZ4K 61 | bool "lz4k" 62 | depends on CRYPTO_LZ4K 63 | + 64 | +config ZRAM_DEF_COMP_LZ4K_OPLUS 65 | + bool "lz4k" 66 | + depends on CRYPTO_LZ4K_OPLUS 67 | 68 | config ZRAM_DEF_COMP_LZ4KD 69 | bool "lz4kd" 70 | depends on CRYPTO_LZ4KD 71 | 72 | config ZRAM_DEF_COMP_DEFLATE 73 | @@ -62,12 +66,13 @@ 74 | string 75 | default "lzo" if ZRAM_DEF_COMP_LZO 76 | default "lzo-rle" if ZRAM_DEF_COMP_LZORLE 77 | default "lz4" if ZRAM_DEF_COMP_LZ4 78 | default "lz4hc" if ZRAM_DEF_COMP_LZ4HC 79 | default "lz4k" if ZRAM_DEF_COMP_LZ4K 80 | + default "lz4k_oplus" if ZRAM_DEF_COMP_LZ4K_OPLUS 81 | default "lz4kd" if ZRAM_DEF_COMP_LZ4KD 82 | default "deflate" if ZRAM_DEF_COMP_DEFLATE 83 | default "842" if ZRAM_DEF_COMP_842 84 | default "zstd" if ZRAM_DEF_COMP_ZSTD 85 | 86 | config ZRAM_WRITEBACK 87 | 88 | diff -u a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c 89 | --- a/drivers/block/zram/zcomp.c 90 | +++ b/drivers/block/zram/zcomp.c 91 | @@ -25,23 +25,26 @@ 92 | #if IS_ENABLED(CONFIG_CRYPTO_LZ4HC) 93 | "lz4hc", 94 | #endif 95 | #if IS_ENABLED(CONFIG_CRYPTO_LZ4K) 96 | "lz4k", 97 | #endif 98 | +#if IS_ENABLED(CONFIG_CRYPTO_LZ4K_OPLUS) 99 | + "lz4k_oplus", 100 | +#endif 101 | #if IS_ENABLED(CONFIG_CRYPTO_LZ4KD) 102 | "lz4kd", 103 | #endif 104 | #if IS_ENABLED(CONFIG_CRYPTO_DEFLATE) 105 | "deflate", 106 | #endif 107 | #if IS_ENABLED(CONFIG_CRYPTO_842) 108 | "842", 109 | #endif 110 | #if IS_ENABLED(CONFIG_CRYPTO_ZSTD) 111 | "zstd", 112 | #endif 113 | }; 114 | 115 | static void zcomp_strm_free(struct zcomp_strm *zstrm) 116 | { 117 | if (!IS_ERR_OR_NULL(zstrm->tfm)) 118 | -------------------------------------------------------------------------------- /other/zram/zram_patch/6.1/lz4kd.patch: -------------------------------------------------------------------------------- 1 | diff -u a/lib/Kconfig b/lib/Kconfig 2 | --- a/lib/Kconfig 3 | +++ b/lib/Kconfig 4 | @@ -336,12 +336,24 @@ 5 | 6 | config LZ4HC_COMPRESS 7 | tristate 8 | 9 | config LZ4_DECOMPRESS 10 | tristate 11 | + 12 | +config LZ4K_COMPRESS 13 | + tristate 14 | + 15 | +config LZ4K_DECOMPRESS 16 | + tristate 17 | + 18 | +config LZ4KD_COMPRESS 19 | + tristate 20 | + 21 | +config LZ4KD_DECOMPRESS 22 | + tristate 23 | 24 | config ZSTD_COMMON 25 | select XXHASH 26 | tristate 27 | 28 | config ZSTD_COMPRESS 29 | 30 | diff -u a/lib/Makefile b/lib/Makefile 31 | --- a/lib/Makefile 32 | +++ b/lib/Makefile 33 | @@ -187,12 +187,16 @@ 34 | obj-$(CONFIG_BCH) += bch.o 35 | obj-$(CONFIG_LZO_COMPRESS) += lzo/ 36 | obj-$(CONFIG_LZO_DECOMPRESS) += lzo/ 37 | obj-$(CONFIG_LZ4_COMPRESS) += lz4/ 38 | obj-$(CONFIG_LZ4HC_COMPRESS) += lz4/ 39 | obj-$(CONFIG_LZ4_DECOMPRESS) += lz4/ 40 | +obj-$(CONFIG_LZ4K_COMPRESS) += lz4k/ 41 | +obj-$(CONFIG_LZ4K_DECOMPRESS) += lz4k/ 42 | +obj-$(CONFIG_LZ4KD_COMPRESS) += lz4kd/ 43 | +obj-$(CONFIG_LZ4KD_DECOMPRESS) += lz4kd/ 44 | obj-$(CONFIG_ZSTD_COMPRESS) += zstd/ 45 | obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd/ 46 | obj-$(CONFIG_XZ_DEC) += xz/ 47 | obj-$(CONFIG_RAID6_PQ) += raid6/ 48 | 49 | lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o 50 | diff -u a/crypto/Kconfig b/crypto/Kconfig 51 | --- a/crypto/Kconfig 52 | +++ b/crypto/Kconfig 53 | @@ -1260,12 +1260,28 @@ 54 | select LZ4_DECOMPRESS 55 | help 56 | LZ4 compression algorithm 57 | 58 | See https://github.com/lz4/lz4 for further information. 59 | 60 | +config CRYPTO_LZ4K 61 | + tristate "LZ4K compression algorithm" 62 | + select CRYPTO_ALGAPI 63 | + select LZ4K_COMPRESS 64 | + select LZ4K_DECOMPRESS 65 | + help 66 | + This is the LZ4K algorithm. 67 | + 68 | +config CRYPTO_LZ4KD 69 | + tristate "LZ4KD compression algorithm" 70 | + select CRYPTO_ALGAPI 71 | + select LZ4KD_COMPRESS 72 | + select LZ4KD_DECOMPRESS 73 | + help 74 | + This is the LZ4KD algorithm. 75 | + 76 | config CRYPTO_LZ4HC 77 | tristate "LZ4HC" 78 | select CRYPTO_ALGAPI 79 | select CRYPTO_ACOMP2 80 | select LZ4HC_COMPRESS 81 | select LZ4_DECOMPRESS 82 | 83 | diff -u a/crypto/Makefile b/crypto/Makefile 84 | --- a/crypto/Makefile 85 | +++ b/crypto/Makefile 86 | @@ -151,13 +151,15 @@ 87 | obj-$(CONFIG_CRYPTO_CRC32C) += crc32c_generic.o 88 | obj-$(CONFIG_CRYPTO_CRC32) += crc32_generic.o 89 | obj-$(CONFIG_CRYPTO_CRCT10DIF) += crct10dif_common.o crct10dif_generic.o 90 | obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o authencesn.o 91 | obj-$(CONFIG_CRYPTO_LZO) += lzo.o lzo-rle.o 92 | obj-$(CONFIG_CRYPTO_LZ4) += lz4.o 93 | +obj-$(CONFIG_CRYPTO_LZ4K) += lz4k.o 94 | obj-$(CONFIG_CRYPTO_LZ4HC) += lz4hc.o 95 | +obj-$(CONFIG_CRYPTO_LZ4KD) += lz4kd.o 96 | obj-$(CONFIG_CRYPTO_XXHASH) += xxhash_generic.o 97 | obj-$(CONFIG_CRYPTO_842) += 842.o 98 | obj-$(CONFIG_CRYPTO_RNG2) += rng.o 99 | obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.o 100 | obj-$(CONFIG_CRYPTO_DRBG) += drbg.o 101 | obj-$(CONFIG_CRYPTO_JITTERENTROPY) += jitterentropy_rng.o 102 | 103 | diff -u a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig 104 | --- a/drivers/block/zram/Kconfig 105 | +++ b/drivers/block/zram/Kconfig 106 | @@ -1,11 +1,11 @@ 107 | # SPDX-License-Identifier: GPL-2.0 108 | config ZRAM 109 | tristate "Compressed RAM block device support" 110 | depends on BLOCK && SYSFS && MMU 111 | - depends on CRYPTO_LZO || CRYPTO_ZSTD || CRYPTO_LZ4 || CRYPTO_LZ4HC || CRYPTO_842 112 | + depends on CRYPTO_LZO || CRYPTO_LZ4 || CRYPTO_LZ4HC || CRYPTO_LZ4K || CRYPTO_LZ4KD || CRYPTO_DEFLATE || CRYPTO_842 || CRYPTO_ZSTD 113 | select ZSMALLOC 114 | help 115 | Creates virtual block devices called /dev/zramX (X = 0, 1, ...). 116 | Pages written to these disks are compressed and stored in memory 117 | itself. These disks allow very fast I/O and compression provides 118 | good amounts of memory savings. 119 | @@ -14,49 +14,64 @@ 120 | disks and maybe many more. 121 | 122 | See Documentation/admin-guide/blockdev/zram.rst for more information. 123 | 124 | choice 125 | prompt "Default zram compressor" 126 | - default ZRAM_DEF_COMP_LZORLE 127 | + default ZRAM_DEF_COMP_LZ4KD 128 | depends on ZRAM 129 | 130 | +config ZRAM_DEF_COMP_LZO 131 | + bool "lzo" 132 | + depends on CRYPTO_LZO 133 | + 134 | config ZRAM_DEF_COMP_LZORLE 135 | bool "lzo-rle" 136 | depends on CRYPTO_LZO 137 | 138 | -config ZRAM_DEF_COMP_ZSTD 139 | - bool "zstd" 140 | - depends on CRYPTO_ZSTD 141 | - 142 | config ZRAM_DEF_COMP_LZ4 143 | bool "lz4" 144 | depends on CRYPTO_LZ4 145 | 146 | -config ZRAM_DEF_COMP_LZO 147 | - bool "lzo" 148 | - depends on CRYPTO_LZO 149 | - 150 | config ZRAM_DEF_COMP_LZ4HC 151 | bool "lz4hc" 152 | depends on CRYPTO_LZ4HC 153 | 154 | +config ZRAM_DEF_COMP_LZ4K 155 | + bool "lz4k" 156 | + depends on CRYPTO_LZ4K 157 | + 158 | +config ZRAM_DEF_COMP_LZ4KD 159 | + bool "lz4kd" 160 | + depends on CRYPTO_LZ4KD 161 | + 162 | +config ZRAM_DEF_COMP_DEFLATE 163 | + bool "deflate" 164 | + depends on CRYPTO_DEFLATE 165 | + 166 | config ZRAM_DEF_COMP_842 167 | bool "842" 168 | depends on CRYPTO_842 169 | 170 | +config ZRAM_DEF_COMP_ZSTD 171 | + bool "zstd" 172 | + depends on CRYPTO_ZSTD 173 | + 174 | endchoice 175 | 176 | config ZRAM_DEF_COMP 177 | string 178 | + default "lzo" if ZRAM_DEF_COMP_LZO 179 | default "lzo-rle" if ZRAM_DEF_COMP_LZORLE 180 | - default "zstd" if ZRAM_DEF_COMP_ZSTD 181 | default "lz4" if ZRAM_DEF_COMP_LZ4 182 | - default "lzo" if ZRAM_DEF_COMP_LZO 183 | default "lz4hc" if ZRAM_DEF_COMP_LZ4HC 184 | + default "lz4k" if ZRAM_DEF_COMP_LZ4K 185 | + default "lz4kd" if ZRAM_DEF_COMP_LZ4KD 186 | + default "deflate" if ZRAM_DEF_COMP_DEFLATE 187 | default "842" if ZRAM_DEF_COMP_842 188 | + default "zstd" if ZRAM_DEF_COMP_ZSTD 189 | 190 | config ZRAM_WRITEBACK 191 | bool "Write back incompressible or idle page to backing device" 192 | depends on ZRAM 193 | help 194 | With incompressible page, there is no memory saving to keep it 195 | 196 | diff -u a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c 197 | --- a/drivers/block/zram/zcomp.c 198 | +++ b/drivers/block/zram/zcomp.c 199 | @@ -22,12 +22,21 @@ 200 | #if IS_ENABLED(CONFIG_CRYPTO_LZ4) 201 | "lz4", 202 | #endif 203 | #if IS_ENABLED(CONFIG_CRYPTO_LZ4HC) 204 | "lz4hc", 205 | #endif 206 | +#if IS_ENABLED(CONFIG_CRYPTO_LZ4K) 207 | + "lz4k", 208 | +#endif 209 | +#if IS_ENABLED(CONFIG_CRYPTO_LZ4KD) 210 | + "lz4kd", 211 | +#endif 212 | +#if IS_ENABLED(CONFIG_CRYPTO_DEFLATE) 213 | + "deflate", 214 | +#endif 215 | #if IS_ENABLED(CONFIG_CRYPTO_842) 216 | "842", 217 | #endif 218 | #if IS_ENABLED(CONFIG_CRYPTO_ZSTD) 219 | "zstd", 220 | #endif 221 | 222 | 223 | diff -u a/kernel/module/main.c b/kernel/module/main.c 224 | --- a/kernel/module/main.c 225 | +++ b/kernel/module/main.c 226 | @@ -2298,27 +2298,45 @@ 227 | { 228 | return 0; 229 | } 230 | 231 | /* module_blacklist is a comma-separated list of module names */ 232 | static char *module_blacklist; 233 | +static char *custom_module_blacklist[] = { 234 | +#if IS_BUILTIN(CONFIG_CRYPTO_LZO) 235 | + "lzo", "lzo_rle", 236 | +#endif 237 | +#if IS_BUILTIN(CONFIG_ZRAM) 238 | + "zram", 239 | +#endif 240 | +#if IS_BUILTIN(CONFIG_ZSMALLOC) 241 | + "zsmalloc", 242 | +#endif 243 | +}; 244 | static bool blacklisted(const char *module_name) 245 | { 246 | const char *p; 247 | size_t len; 248 | + int i; 249 | 250 | if (!module_blacklist) 251 | - return false; 252 | + goto custom_blacklist; 253 | 254 | for (p = module_blacklist; *p; p += len) { 255 | len = strcspn(p, ","); 256 | if (strlen(module_name) == len && !memcmp(module_name, p, len)) 257 | return true; 258 | if (p[len] == ',') 259 | len++; 260 | } 261 | + 262 | +custom_blacklist: 263 | + for (i = 0; i < ARRAY_SIZE(custom_module_blacklist); i++) 264 | + if (!strcmp(module_name, custom_module_blacklist[i])) 265 | + return true; 266 | + 267 | return false; 268 | } 269 | core_param(module_blacklist, module_blacklist, charp, 0400); 270 | 271 | static struct module *layout_and_allocate(struct load_info *info, int flags) 272 | { 273 | @@ -2779,13 +2797,13 @@ 274 | 275 | /* 276 | * Now that we know we have the correct module name, check 277 | * if it's blacklisted. 278 | */ 279 | if (blacklisted(info->name)) { 280 | - err = -EPERM; 281 | + // err = -EPERM; 282 | pr_err("Module %s is blacklisted\n", info->name); 283 | goto free_copy; 284 | } 285 | 286 | err = rewrite_section_headers(info, flags); 287 | if (err) 288 | -------------------------------------------------------------------------------- /other/zram/zram_patch/6.6/lz4k_oplus.patch: -------------------------------------------------------------------------------- 1 | diff -u a/lib/Kconfig b/lib/Kconfig 2 | --- a/lib/Kconfig 3 | +++ b/lib/Kconfig 4 | @@ -1,11 +1,11 @@ 5 | # SPDX-License-Identifier: GPL-2.0-only 6 | # 7 | # Library configuration 8 | # 9 | - 10 | +source "lib/lz4k_oplus/Kconfig" 11 | config BINARY_PRINTF 12 | def_bool n 13 | 14 | menu "Library routines" 15 | 16 | config RAID6_PQ 17 | 18 | diff -u a/lib/Makefile b/lib/Makefile 19 | --- a/lib/Makefile 20 | +++ b/lib/Makefile 21 | @@ -200,16 +200,17 @@ 22 | obj-$(CONFIG_LZO_DECOMPRESS) += lzo/ 23 | obj-$(CONFIG_LZ4_COMPRESS) += lz4/ 24 | obj-$(CONFIG_LZ4HC_COMPRESS) += lz4/ 25 | obj-$(CONFIG_LZ4_DECOMPRESS) += lz4/ 26 | obj-$(CONFIG_LZ4K_COMPRESS) += lz4k/ 27 | obj-$(CONFIG_LZ4K_DECOMPRESS) += lz4k/ 28 | +obj-y += lz4k_oplus/ 29 | obj-$(CONFIG_LZ4KD_COMPRESS) += lz4kd/ 30 | obj-$(CONFIG_LZ4KD_DECOMPRESS) += lz4kd/ 31 | obj-$(CONFIG_ZSTD_COMPRESS) += zstd/ 32 | obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd/ 33 | obj-$(CONFIG_XZ_DEC) += xz/ 34 | obj-$(CONFIG_RAID6_PQ) += raid6/ 35 | 36 | lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o 37 | lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o 38 | lib-$(CONFIG_DECOMPRESS_LZMA) += decompress_unlzma.o 39 | 40 | diff -u a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig 41 | --- a/drivers/block/zram/Kconfig 42 | +++ b/drivers/block/zram/Kconfig 43 | @@ -1,11 +1,11 @@ 44 | # SPDX-License-Identifier: GPL-2.0 45 | config ZRAM 46 | tristate "Compressed RAM block device support" 47 | depends on BLOCK && SYSFS && MMU 48 | - depends on CRYPTO_LZO || CRYPTO_LZ4 || CRYPTO_LZ4HC || CRYPTO_LZ4K || CRYPTO_LZ4KD || CRYPTO_DEFLATE || CRYPTO_842 || CRYPTO_ZSTD 49 | + depends on CRYPTO_LZO || CRYPTO_LZ4 || CRYPTO_LZ4HC || CRYPTO_LZ4K || CRYPTO_LZ4K_OPLUS || CRYPTO_LZ4KD || CRYPTO_DEFLATE || CRYPTO_842 || CRYPTO_ZSTD 50 | select ZSMALLOC 51 | help 52 | Creates virtual block devices called /dev/zramX (X = 0, 1, ...). 53 | Pages written to these disks are compressed and stored in memory 54 | itself. These disks allow very fast I/O and compression provides 55 | good amounts of memory savings. 56 | @@ -36,12 +36,16 @@ 57 | bool "lz4hc" 58 | depends on CRYPTO_LZ4HC 59 | 60 | config ZRAM_DEF_COMP_LZ4K 61 | bool "lz4k" 62 | depends on CRYPTO_LZ4K 63 | + 64 | +config ZRAM_DEF_COMP_LZ4K_OPLUS 65 | + bool "lz4k" 66 | + depends on CRYPTO_LZ4K_OPLUS 67 | 68 | config ZRAM_DEF_COMP_LZ4KD 69 | bool "lz4kd" 70 | depends on CRYPTO_LZ4KD 71 | 72 | config ZRAM_DEF_COMP_DEFLATE 73 | @@ -62,12 +66,13 @@ 74 | string 75 | default "lzo" if ZRAM_DEF_COMP_LZO 76 | default "lzo-rle" if ZRAM_DEF_COMP_LZORLE 77 | default "lz4" if ZRAM_DEF_COMP_LZ4 78 | default "lz4hc" if ZRAM_DEF_COMP_LZ4HC 79 | default "lz4k" if ZRAM_DEF_COMP_LZ4K 80 | + default "lz4k_oplus" if ZRAM_DEF_COMP_LZ4K_OPLUS 81 | default "lz4kd" if ZRAM_DEF_COMP_LZ4KD 82 | default "deflate" if ZRAM_DEF_COMP_DEFLATE 83 | default "842" if ZRAM_DEF_COMP_842 84 | default "zstd" if ZRAM_DEF_COMP_ZSTD 85 | 86 | config ZRAM_WRITEBACK 87 | 88 | diff -u a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c 89 | --- a/drivers/block/zram/zcomp.c 90 | +++ b/drivers/block/zram/zcomp.c 91 | @@ -26,24 +26,27 @@ 92 | #if IS_ENABLED(CONFIG_CRYPTO_LZ4HC) 93 | "lz4hc", 94 | #endif 95 | #if IS_ENABLED(CONFIG_CRYPTO_LZ4K) 96 | "lz4k", 97 | #endif 98 | + #if IS_ENABLED(CONFIG_CRYPTO_LZ4K_OPLUS) 99 | + "lz4k_oplus", 100 | + #endif 101 | #if IS_ENABLED(CONFIG_CRYPTO_LZ4KD) 102 | "lz4kd", 103 | #endif 104 | #if IS_ENABLED(CONFIG_CRYPTO_DEFLATE) 105 | "deflate", 106 | #endif 107 | #if IS_ENABLED(CONFIG_CRYPTO_842) 108 | "842", 109 | #endif 110 | #if IS_ENABLED(CONFIG_CRYPTO_ZSTD) 111 | "zstd", 112 | #endif 113 | }; 114 | 115 | static void zcomp_strm_free(struct zcomp_strm *zstrm) 116 | { 117 | if (!IS_ERR_OR_NULL(zstrm->tfm)) 118 | crypto_free_comp(zstrm->tfm); 119 | -------------------------------------------------------------------------------- /other/zram/zram_patch/6.6/lz4kd.patch: -------------------------------------------------------------------------------- 1 | diff -u a/lib/Kconfig b/lib/Kconfig 2 | --- a/lib/Kconfig 3 | +++ b/lib/Kconfig 4 | @@ -336,12 +336,24 @@ 5 | 6 | config LZ4HC_COMPRESS 7 | tristate 8 | 9 | config LZ4_DECOMPRESS 10 | tristate 11 | + 12 | +config LZ4K_COMPRESS 13 | + tristate 14 | + 15 | +config LZ4K_DECOMPRESS 16 | + tristate 17 | + 18 | +config LZ4KD_COMPRESS 19 | + tristate 20 | + 21 | +config LZ4KD_DECOMPRESS 22 | + tristate 23 | 24 | config ZSTD_COMMON 25 | select XXHASH 26 | tristate 27 | 28 | config ZSTD_COMPRESS 29 | 30 | diff -u a/lib/Makefile b/lib/Makefile 31 | --- a/lib/Makefile 32 | +++ b/lib/Makefile 33 | @@ -187,12 +187,16 @@ 34 | obj-$(CONFIG_BCH) += bch.o 35 | obj-$(CONFIG_LZO_COMPRESS) += lzo/ 36 | obj-$(CONFIG_LZO_DECOMPRESS) += lzo/ 37 | obj-$(CONFIG_LZ4_COMPRESS) += lz4/ 38 | obj-$(CONFIG_LZ4HC_COMPRESS) += lz4/ 39 | obj-$(CONFIG_LZ4_DECOMPRESS) += lz4/ 40 | +obj-$(CONFIG_LZ4K_COMPRESS) += lz4k/ 41 | +obj-$(CONFIG_LZ4K_DECOMPRESS) += lz4k/ 42 | +obj-$(CONFIG_LZ4KD_COMPRESS) += lz4kd/ 43 | +obj-$(CONFIG_LZ4KD_DECOMPRESS) += lz4kd/ 44 | obj-$(CONFIG_ZSTD_COMPRESS) += zstd/ 45 | obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd/ 46 | obj-$(CONFIG_XZ_DEC) += xz/ 47 | obj-$(CONFIG_RAID6_PQ) += raid6/ 48 | 49 | lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o 50 | diff -u a/crypto/Kconfig b/crypto/Kconfig 51 | --- a/crypto/Kconfig 52 | +++ b/crypto/Kconfig 53 | @@ -1260,12 +1260,28 @@ 54 | select LZ4_DECOMPRESS 55 | help 56 | LZ4 compression algorithm 57 | 58 | See https://github.com/lz4/lz4 for further information. 59 | 60 | +config CRYPTO_LZ4K 61 | + tristate "LZ4K compression algorithm" 62 | + select CRYPTO_ALGAPI 63 | + select LZ4K_COMPRESS 64 | + select LZ4K_DECOMPRESS 65 | + help 66 | + This is the LZ4K algorithm. 67 | + 68 | +config CRYPTO_LZ4KD 69 | + tristate "LZ4KD compression algorithm" 70 | + select CRYPTO_ALGAPI 71 | + select LZ4KD_COMPRESS 72 | + select LZ4KD_DECOMPRESS 73 | + help 74 | + This is the LZ4KD algorithm. 75 | + 76 | config CRYPTO_LZ4HC 77 | tristate "LZ4HC" 78 | select CRYPTO_ALGAPI 79 | select CRYPTO_ACOMP2 80 | select LZ4HC_COMPRESS 81 | select LZ4_DECOMPRESS 82 | 83 | diff -u a/crypto/Makefile b/crypto/Makefile 84 | --- a/crypto/Makefile 85 | +++ b/crypto/Makefile 86 | @@ -151,13 +151,15 @@ 87 | obj-$(CONFIG_CRYPTO_CRC32C) += crc32c_generic.o 88 | obj-$(CONFIG_CRYPTO_CRC32) += crc32_generic.o 89 | obj-$(CONFIG_CRYPTO_CRCT10DIF) += crct10dif_common.o crct10dif_generic.o 90 | obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o authencesn.o 91 | obj-$(CONFIG_CRYPTO_LZO) += lzo.o lzo-rle.o 92 | obj-$(CONFIG_CRYPTO_LZ4) += lz4.o 93 | +obj-$(CONFIG_CRYPTO_LZ4K) += lz4k.o 94 | obj-$(CONFIG_CRYPTO_LZ4HC) += lz4hc.o 95 | +obj-$(CONFIG_CRYPTO_LZ4KD) += lz4kd.o 96 | obj-$(CONFIG_CRYPTO_XXHASH) += xxhash_generic.o 97 | obj-$(CONFIG_CRYPTO_842) += 842.o 98 | obj-$(CONFIG_CRYPTO_RNG2) += rng.o 99 | obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.o 100 | obj-$(CONFIG_CRYPTO_DRBG) += drbg.o 101 | obj-$(CONFIG_CRYPTO_JITTERENTROPY) += jitterentropy_rng.o 102 | 103 | diff -u a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig 104 | --- a/drivers/block/zram/Kconfig 105 | +++ b/drivers/block/zram/Kconfig 106 | @@ -1,11 +1,11 @@ 107 | # SPDX-License-Identifier: GPL-2.0 108 | config ZRAM 109 | tristate "Compressed RAM block device support" 110 | depends on BLOCK && SYSFS && MMU 111 | - depends on CRYPTO_LZO || CRYPTO_ZSTD || CRYPTO_LZ4 || CRYPTO_LZ4HC || CRYPTO_842 112 | + depends on CRYPTO_LZO || CRYPTO_LZ4 || CRYPTO_LZ4HC || CRYPTO_LZ4K || CRYPTO_LZ4KD || CRYPTO_DEFLATE || CRYPTO_842 || CRYPTO_ZSTD 113 | select ZSMALLOC 114 | help 115 | Creates virtual block devices called /dev/zramX (X = 0, 1, ...). 116 | Pages written to these disks are compressed and stored in memory 117 | itself. These disks allow very fast I/O and compression provides 118 | good amounts of memory savings. 119 | @@ -14,49 +14,64 @@ 120 | disks and maybe many more. 121 | 122 | See Documentation/admin-guide/blockdev/zram.rst for more information. 123 | 124 | choice 125 | prompt "Default zram compressor" 126 | - default ZRAM_DEF_COMP_LZORLE 127 | + default ZRAM_DEF_COMP_LZ4KD 128 | depends on ZRAM 129 | 130 | +config ZRAM_DEF_COMP_LZO 131 | + bool "lzo" 132 | + depends on CRYPTO_LZO 133 | + 134 | config ZRAM_DEF_COMP_LZORLE 135 | bool "lzo-rle" 136 | depends on CRYPTO_LZO 137 | 138 | -config ZRAM_DEF_COMP_ZSTD 139 | - bool "zstd" 140 | - depends on CRYPTO_ZSTD 141 | - 142 | config ZRAM_DEF_COMP_LZ4 143 | bool "lz4" 144 | depends on CRYPTO_LZ4 145 | 146 | -config ZRAM_DEF_COMP_LZO 147 | - bool "lzo" 148 | - depends on CRYPTO_LZO 149 | - 150 | config ZRAM_DEF_COMP_LZ4HC 151 | bool "lz4hc" 152 | depends on CRYPTO_LZ4HC 153 | 154 | +config ZRAM_DEF_COMP_LZ4K 155 | + bool "lz4k" 156 | + depends on CRYPTO_LZ4K 157 | + 158 | +config ZRAM_DEF_COMP_LZ4KD 159 | + bool "lz4kd" 160 | + depends on CRYPTO_LZ4KD 161 | + 162 | +config ZRAM_DEF_COMP_DEFLATE 163 | + bool "deflate" 164 | + depends on CRYPTO_DEFLATE 165 | + 166 | config ZRAM_DEF_COMP_842 167 | bool "842" 168 | depends on CRYPTO_842 169 | 170 | +config ZRAM_DEF_COMP_ZSTD 171 | + bool "zstd" 172 | + depends on CRYPTO_ZSTD 173 | + 174 | endchoice 175 | 176 | config ZRAM_DEF_COMP 177 | string 178 | + default "lzo" if ZRAM_DEF_COMP_LZO 179 | default "lzo-rle" if ZRAM_DEF_COMP_LZORLE 180 | - default "zstd" if ZRAM_DEF_COMP_ZSTD 181 | default "lz4" if ZRAM_DEF_COMP_LZ4 182 | - default "lzo" if ZRAM_DEF_COMP_LZO 183 | default "lz4hc" if ZRAM_DEF_COMP_LZ4HC 184 | + default "lz4k" if ZRAM_DEF_COMP_LZ4K 185 | + default "lz4kd" if ZRAM_DEF_COMP_LZ4KD 186 | + default "deflate" if ZRAM_DEF_COMP_DEFLATE 187 | default "842" if ZRAM_DEF_COMP_842 188 | + default "zstd" if ZRAM_DEF_COMP_ZSTD 189 | 190 | config ZRAM_WRITEBACK 191 | bool "Write back incompressible or idle page to backing device" 192 | depends on ZRAM 193 | help 194 | With incompressible page, there is no memory saving to keep it 195 | 196 | diff -u a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c 197 | --- a/drivers/block/zram/zcomp.c 198 | +++ b/drivers/block/zram/zcomp.c 199 | @@ -22,12 +22,21 @@ 200 | #if IS_ENABLED(CONFIG_CRYPTO_LZ4) 201 | "lz4", 202 | #endif 203 | #if IS_ENABLED(CONFIG_CRYPTO_LZ4HC) 204 | "lz4hc", 205 | #endif 206 | +#if IS_ENABLED(CONFIG_CRYPTO_LZ4K) 207 | + "lz4k", 208 | +#endif 209 | +#if IS_ENABLED(CONFIG_CRYPTO_LZ4KD) 210 | + "lz4kd", 211 | +#endif 212 | +#if IS_ENABLED(CONFIG_CRYPTO_DEFLATE) 213 | + "deflate", 214 | +#endif 215 | #if IS_ENABLED(CONFIG_CRYPTO_842) 216 | "842", 217 | #endif 218 | #if IS_ENABLED(CONFIG_CRYPTO_ZSTD) 219 | "zstd", 220 | #endif 221 | 222 | 223 | diff -u a/kernel/module/main.c b/kernel/module/main.c 224 | --- a/kernel/module/main.c 225 | +++ b/kernel/module/main.c 226 | @@ -2382,27 +2382,46 @@ 227 | { 228 | return 0; 229 | } 230 | 231 | /* module_blacklist is a comma-separated list of module names */ 232 | static char *module_blacklist; 233 | +static char *custom_module_blacklist[] = { 234 | +#if IS_BUILTIN(CONFIG_CRYPTO_LZO) 235 | + "lzo", "lzo_rle", 236 | +#endif 237 | +#if IS_BUILTIN(CONFIG_ZRAM) 238 | + "zram", 239 | +#endif 240 | +#if IS_BUILTIN(CONFIG_ZSMALLOC) 241 | + "zsmalloc", 242 | +#endif 243 | +}; 244 | + 245 | static bool blacklisted(const char *module_name) 246 | { 247 | const char *p; 248 | size_t len; 249 | + int i; 250 | 251 | if (!module_blacklist) 252 | - return false; 253 | + goto custom_blacklist; 254 | 255 | for (p = module_blacklist; *p; p += len) { 256 | len = strcspn(p, ","); 257 | if (strlen(module_name) == len && !memcmp(module_name, p, len)) 258 | return true; 259 | if (p[len] == ',') 260 | len++; 261 | } 262 | + 263 | +custom_blacklist: 264 | + for (i = 0; i < ARRAY_SIZE(custom_module_blacklist); i++) 265 | + if (!strcmp(module_name, custom_module_blacklist[i])) 266 | + return true; 267 | + 268 | return false; 269 | } 270 | core_param(module_blacklist, module_blacklist, charp, 0400); 271 | 272 | static struct module *layout_and_allocate(struct load_info *info, int flags) 273 | { 274 | @@ -2845,16 +2864,12 @@ 275 | int err; 276 | 277 | /* 278 | * Now that we know we have the correct module name, check 279 | * if it's blacklisted. 280 | */ 281 | - if (blacklisted(info->name)) { 282 | - pr_err("Module %s is blacklisted\n", info->name); 283 | - return -EPERM; 284 | - } 285 | 286 | err = rewrite_section_headers(info, flags); 287 | if (err) 288 | return err; 289 | 290 | /* Check module struct version now, before we try to use module. */ 291 | @@ -2909,12 +2924,17 @@ 292 | if (err) 293 | goto free_copy; 294 | 295 | err = early_mod_check(info, flags); 296 | if (err) 297 | goto free_copy; 298 | + 299 | + if (blacklisted(info->name)) { 300 | + pr_err("Module %s is blacklisted\n", info->name); 301 | + goto free_copy; 302 | + } 303 | 304 | /* Figure out module layout, and allocate all the memory. */ 305 | mod = layout_and_allocate(info, flags); 306 | if (IS_ERR(mod)) { 307 | err = PTR_ERR(mod); 308 | goto free_copy; 309 | --------------------------------------------------------------------------------