├── 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 |
--------------------------------------------------------------------------------