hc
2024-05-11 297b60346df8beafee954a0fd7c2d64f33f3b9bc
kernel/crypto/scompress.c
....@@ -1,15 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Synchronous Compression operations
34 *
45 * Copyright 2015 LG Electronics Inc.
56 * Copyright (c) 2016, Intel Corporation
67 * Author: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
7
- *
8
- * This program is free software; you can redistribute it and/or modify it
9
- * under the terms of the GNU General Public License as published by the Free
10
- * Software Foundation; either version 2 of the License, or (at your option)
11
- * any later version.
12
- *
138 */
149 #include <linux/errno.h>
1510 #include <linux/kernel.h>
....@@ -29,9 +24,17 @@
2924 #include <crypto/internal/scompress.h>
3025 #include "internal.h"
3126
27
+struct scomp_scratch {
28
+ spinlock_t lock;
29
+ void *src;
30
+ void *dst;
31
+};
32
+
33
+static DEFINE_PER_CPU(struct scomp_scratch, scomp_scratch) = {
34
+ .lock = __SPIN_LOCK_UNLOCKED(scomp_scratch.lock),
35
+};
36
+
3237 static const struct crypto_type crypto_scomp_type;
33
-static void * __percpu *scomp_src_scratches;
34
-static void * __percpu *scomp_dst_scratches;
3538 static int scomp_scratch_users;
3639 static DEFINE_MUTEX(scomp_lock);
3740
....@@ -40,15 +43,12 @@
4043 {
4144 struct crypto_report_comp rscomp;
4245
43
- strncpy(rscomp.type, "scomp", sizeof(rscomp.type));
46
+ memset(&rscomp, 0, sizeof(rscomp));
4447
45
- if (nla_put(skb, CRYPTOCFGA_REPORT_COMPRESS,
46
- sizeof(struct crypto_report_comp), &rscomp))
47
- goto nla_put_failure;
48
- return 0;
48
+ strscpy(rscomp.type, "scomp", sizeof(rscomp.type));
4949
50
-nla_put_failure:
51
- return -EMSGSIZE;
50
+ return nla_put(skb, CRYPTOCFGA_REPORT_COMPRESS,
51
+ sizeof(rscomp), &rscomp);
5252 }
5353 #else
5454 static int crypto_scomp_report(struct sk_buff *skb, struct crypto_alg *alg)
....@@ -65,76 +65,53 @@
6565 seq_puts(m, "type : scomp\n");
6666 }
6767
68
-static void crypto_scomp_free_scratches(void * __percpu *scratches)
68
+static void crypto_scomp_free_scratches(void)
6969 {
70
+ struct scomp_scratch *scratch;
7071 int i;
71
-
72
- if (!scratches)
73
- return;
74
-
75
- for_each_possible_cpu(i)
76
- vfree(*per_cpu_ptr(scratches, i));
77
-
78
- free_percpu(scratches);
79
-}
80
-
81
-static void * __percpu *crypto_scomp_alloc_scratches(void)
82
-{
83
- void * __percpu *scratches;
84
- int i;
85
-
86
- scratches = alloc_percpu(void *);
87
- if (!scratches)
88
- return NULL;
8972
9073 for_each_possible_cpu(i) {
91
- void *scratch;
74
+ scratch = per_cpu_ptr(&scomp_scratch, i);
9275
93
- scratch = vmalloc_node(SCOMP_SCRATCH_SIZE, cpu_to_node(i));
94
- if (!scratch)
76
+ vfree(scratch->src);
77
+ vfree(scratch->dst);
78
+ scratch->src = NULL;
79
+ scratch->dst = NULL;
80
+ }
81
+}
82
+
83
+static int crypto_scomp_alloc_scratches(void)
84
+{
85
+ struct scomp_scratch *scratch;
86
+ int i;
87
+
88
+ for_each_possible_cpu(i) {
89
+ void *mem;
90
+
91
+ scratch = per_cpu_ptr(&scomp_scratch, i);
92
+
93
+ mem = vmalloc_node(SCOMP_SCRATCH_SIZE, cpu_to_node(i));
94
+ if (!mem)
9595 goto error;
96
- *per_cpu_ptr(scratches, i) = scratch;
97
- }
98
-
99
- return scratches;
100
-
101
-error:
102
- crypto_scomp_free_scratches(scratches);
103
- return NULL;
104
-}
105
-
106
-static void crypto_scomp_free_all_scratches(void)
107
-{
108
- if (!--scomp_scratch_users) {
109
- crypto_scomp_free_scratches(scomp_src_scratches);
110
- crypto_scomp_free_scratches(scomp_dst_scratches);
111
- scomp_src_scratches = NULL;
112
- scomp_dst_scratches = NULL;
113
- }
114
-}
115
-
116
-static int crypto_scomp_alloc_all_scratches(void)
117
-{
118
- if (!scomp_scratch_users++) {
119
- scomp_src_scratches = crypto_scomp_alloc_scratches();
120
- if (!scomp_src_scratches)
121
- return -ENOMEM;
122
- scomp_dst_scratches = crypto_scomp_alloc_scratches();
123
- if (!scomp_dst_scratches) {
124
- crypto_scomp_free_scratches(scomp_src_scratches);
125
- scomp_src_scratches = NULL;
126
- return -ENOMEM;
127
- }
96
+ scratch->src = mem;
97
+ mem = vmalloc_node(SCOMP_SCRATCH_SIZE, cpu_to_node(i));
98
+ if (!mem)
99
+ goto error;
100
+ scratch->dst = mem;
128101 }
129102 return 0;
103
+error:
104
+ crypto_scomp_free_scratches();
105
+ return -ENOMEM;
130106 }
131107
132108 static int crypto_scomp_init_tfm(struct crypto_tfm *tfm)
133109 {
134
- int ret;
110
+ int ret = 0;
135111
136112 mutex_lock(&scomp_lock);
137
- ret = crypto_scomp_alloc_all_scratches();
113
+ if (!scomp_scratch_users++)
114
+ ret = crypto_scomp_alloc_scratches();
138115 mutex_unlock(&scomp_lock);
139116
140117 return ret;
....@@ -146,42 +123,41 @@
146123 void **tfm_ctx = acomp_tfm_ctx(tfm);
147124 struct crypto_scomp *scomp = *tfm_ctx;
148125 void **ctx = acomp_request_ctx(req);
149
- const int cpu = get_cpu();
150
- u8 *scratch_src = *per_cpu_ptr(scomp_src_scratches, cpu);
151
- u8 *scratch_dst = *per_cpu_ptr(scomp_dst_scratches, cpu);
126
+ struct scomp_scratch *scratch;
152127 int ret;
153128
154
- if (!req->src || !req->slen || req->slen > SCOMP_SCRATCH_SIZE) {
155
- ret = -EINVAL;
156
- goto out;
157
- }
129
+ if (!req->src || !req->slen || req->slen > SCOMP_SCRATCH_SIZE)
130
+ return -EINVAL;
158131
159
- if (req->dst && !req->dlen) {
160
- ret = -EINVAL;
161
- goto out;
162
- }
132
+ if (req->dst && !req->dlen)
133
+ return -EINVAL;
163134
164135 if (!req->dlen || req->dlen > SCOMP_SCRATCH_SIZE)
165136 req->dlen = SCOMP_SCRATCH_SIZE;
166137
167
- scatterwalk_map_and_copy(scratch_src, req->src, 0, req->slen, 0);
138
+ scratch = raw_cpu_ptr(&scomp_scratch);
139
+ spin_lock(&scratch->lock);
140
+
141
+ scatterwalk_map_and_copy(scratch->src, req->src, 0, req->slen, 0);
168142 if (dir)
169
- ret = crypto_scomp_compress(scomp, scratch_src, req->slen,
170
- scratch_dst, &req->dlen, *ctx);
143
+ ret = crypto_scomp_compress(scomp, scratch->src, req->slen,
144
+ scratch->dst, &req->dlen, *ctx);
171145 else
172
- ret = crypto_scomp_decompress(scomp, scratch_src, req->slen,
173
- scratch_dst, &req->dlen, *ctx);
146
+ ret = crypto_scomp_decompress(scomp, scratch->src, req->slen,
147
+ scratch->dst, &req->dlen, *ctx);
174148 if (!ret) {
175149 if (!req->dst) {
176150 req->dst = sgl_alloc(req->dlen, GFP_ATOMIC, NULL);
177
- if (!req->dst)
151
+ if (!req->dst) {
152
+ ret = -ENOMEM;
178153 goto out;
154
+ }
179155 }
180
- scatterwalk_map_and_copy(scratch_dst, req->dst, 0, req->dlen,
156
+ scatterwalk_map_and_copy(scratch->dst, req->dst, 0, req->dlen,
181157 1);
182158 }
183159 out:
184
- put_cpu();
160
+ spin_unlock(&scratch->lock);
185161 return ret;
186162 }
187163
....@@ -202,7 +178,8 @@
202178 crypto_free_scomp(*ctx);
203179
204180 mutex_lock(&scomp_lock);
205
- crypto_scomp_free_all_scratches();
181
+ if (!--scomp_scratch_users)
182
+ crypto_scomp_free_scratches();
206183 mutex_unlock(&scomp_lock);
207184 }
208185
....@@ -289,9 +266,9 @@
289266 }
290267 EXPORT_SYMBOL_GPL(crypto_register_scomp);
291268
292
-int crypto_unregister_scomp(struct scomp_alg *alg)
269
+void crypto_unregister_scomp(struct scomp_alg *alg)
293270 {
294
- return crypto_unregister_alg(&alg->base);
271
+ crypto_unregister_alg(&alg->base);
295272 }
296273 EXPORT_SYMBOL_GPL(crypto_unregister_scomp);
297274