Skip to content

Commit 65775cf

Browse files
committedMar 15, 2025
crypto: scatterwalk - Change scatterwalk_next calling convention
Rather than returning the address and storing the length into an argument pointer, add an address field to the walk struct and use that to store the address. The length is returned directly. Change the done functions to use this stored address instead of getting them from the caller. Split the address into two using a union. The user should only access the const version so that it is never changed. Signed-off-by: Herbert Xu <[email protected]>
1 parent b949f55 commit 65775cf

File tree

14 files changed

+78
-78
lines changed

14 files changed

+78
-78
lines changed
 

‎arch/arm/crypto/ghash-ce-glue.c

+3-4
Original file line numberDiff line numberDiff line change
@@ -460,11 +460,10 @@ static void gcm_calculate_auth_mac(struct aead_request *req, u64 dg[], u32 len)
460460

461461
do {
462462
unsigned int n;
463-
const u8 *p;
464463

465-
p = scatterwalk_next(&walk, len, &n);
466-
gcm_update_mac(dg, p, n, buf, &buf_count, ctx);
467-
scatterwalk_done_src(&walk, p, n);
464+
n = scatterwalk_next(&walk, len);
465+
gcm_update_mac(dg, walk.addr, n, buf, &buf_count, ctx);
466+
scatterwalk_done_src(&walk, n);
468467

469468
if (unlikely(len / SZ_4K > (len - n) / SZ_4K)) {
470469
kernel_neon_end();

‎arch/arm64/crypto/aes-ce-ccm-glue.c

+4-5
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,11 @@ static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[])
157157

158158
do {
159159
unsigned int n;
160-
const u8 *p;
161160

162-
p = scatterwalk_next(&walk, len, &n);
163-
macp = ce_aes_ccm_auth_data(mac, p, n, macp, ctx->key_enc,
164-
num_rounds(ctx));
165-
scatterwalk_done_src(&walk, p, n);
161+
n = scatterwalk_next(&walk, len);
162+
macp = ce_aes_ccm_auth_data(mac, walk.addr, n, macp,
163+
ctx->key_enc, num_rounds(ctx));
164+
scatterwalk_done_src(&walk, n);
166165
len -= n;
167166
} while (len);
168167
}

‎arch/arm64/crypto/ghash-ce-glue.c

+3-4
Original file line numberDiff line numberDiff line change
@@ -309,11 +309,10 @@ static void gcm_calculate_auth_mac(struct aead_request *req, u64 dg[], u32 len)
309309

310310
do {
311311
unsigned int n;
312-
const u8 *p;
313312

314-
p = scatterwalk_next(&walk, len, &n);
315-
gcm_update_mac(dg, p, n, buf, &buf_count, ctx);
316-
scatterwalk_done_src(&walk, p, n);
313+
n = scatterwalk_next(&walk, len);
314+
gcm_update_mac(dg, walk.addr, n, buf, &buf_count, ctx);
315+
scatterwalk_done_src(&walk, n);
317316
len -= n;
318317
} while (len);
319318

‎arch/arm64/crypto/sm4-ce-ccm-glue.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,10 @@ static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[])
113113

114114
do {
115115
unsigned int n, orig_n;
116-
const u8 *p, *orig_p;
116+
const u8 *p;
117117

118-
orig_p = scatterwalk_next(&walk, assoclen, &orig_n);
119-
p = orig_p;
118+
orig_n = scatterwalk_next(&walk, assoclen);
119+
p = walk.addr;
120120
n = orig_n;
121121

122122
while (n > 0) {
@@ -149,7 +149,7 @@ static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[])
149149
}
150150
}
151151

152-
scatterwalk_done_src(&walk, orig_p, orig_n);
152+
scatterwalk_done_src(&walk, orig_n);
153153
assoclen -= orig_n;
154154
} while (assoclen);
155155
}

‎arch/arm64/crypto/sm4-ce-gcm-glue.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,10 @@ static void gcm_calculate_auth_mac(struct aead_request *req, u8 ghash[])
8383

8484
do {
8585
unsigned int n, orig_n;
86-
const u8 *p, *orig_p;
86+
const u8 *p;
8787

88-
orig_p = scatterwalk_next(&walk, assoclen, &orig_n);
89-
p = orig_p;
88+
orig_n = scatterwalk_next(&walk, assoclen);
89+
p = walk.addr;
9090
n = orig_n;
9191

9292
if (n + buflen < GHASH_BLOCK_SIZE) {
@@ -118,7 +118,7 @@ static void gcm_calculate_auth_mac(struct aead_request *req, u8 ghash[])
118118
memcpy(&buffer[0], p, buflen);
119119
}
120120

121-
scatterwalk_done_src(&walk, orig_p, orig_n);
121+
scatterwalk_done_src(&walk, orig_n);
122122
assoclen -= orig_n;
123123
} while (assoclen);
124124

‎arch/s390/crypto/aes_s390.c

+9-12
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ struct s390_xts_ctx {
6666
struct gcm_sg_walk {
6767
struct scatter_walk walk;
6868
unsigned int walk_bytes;
69-
u8 *walk_ptr;
7069
unsigned int walk_bytes_remain;
7170
u8 buf[AES_BLOCK_SIZE];
7271
unsigned int buf_bytes;
@@ -789,8 +788,7 @@ static inline unsigned int _gcm_sg_clamp_and_map(struct gcm_sg_walk *gw)
789788
{
790789
if (gw->walk_bytes_remain == 0)
791790
return 0;
792-
gw->walk_ptr = scatterwalk_next(&gw->walk, gw->walk_bytes_remain,
793-
&gw->walk_bytes);
791+
gw->walk_bytes = scatterwalk_next(&gw->walk, gw->walk_bytes_remain);
794792
return gw->walk_bytes;
795793
}
796794

@@ -799,10 +797,9 @@ static inline void _gcm_sg_unmap_and_advance(struct gcm_sg_walk *gw,
799797
{
800798
gw->walk_bytes_remain -= nbytes;
801799
if (out)
802-
scatterwalk_done_dst(&gw->walk, gw->walk_ptr, nbytes);
800+
scatterwalk_done_dst(&gw->walk, nbytes);
803801
else
804-
scatterwalk_done_src(&gw->walk, gw->walk_ptr, nbytes);
805-
gw->walk_ptr = NULL;
802+
scatterwalk_done_src(&gw->walk, nbytes);
806803
}
807804

808805
static int gcm_in_walk_go(struct gcm_sg_walk *gw, unsigned int minbytesneeded)
@@ -828,14 +825,14 @@ static int gcm_in_walk_go(struct gcm_sg_walk *gw, unsigned int minbytesneeded)
828825
}
829826

830827
if (!gw->buf_bytes && gw->walk_bytes >= minbytesneeded) {
831-
gw->ptr = gw->walk_ptr;
828+
gw->ptr = gw->walk.addr;
832829
gw->nbytes = gw->walk_bytes;
833830
goto out;
834831
}
835832

836833
while (1) {
837834
n = min(gw->walk_bytes, AES_BLOCK_SIZE - gw->buf_bytes);
838-
memcpy(gw->buf + gw->buf_bytes, gw->walk_ptr, n);
835+
memcpy(gw->buf + gw->buf_bytes, gw->walk.addr, n);
839836
gw->buf_bytes += n;
840837
_gcm_sg_unmap_and_advance(gw, n, false);
841838
if (gw->buf_bytes >= minbytesneeded) {
@@ -869,13 +866,13 @@ static int gcm_out_walk_go(struct gcm_sg_walk *gw, unsigned int minbytesneeded)
869866
}
870867

871868
if (gw->walk_bytes >= minbytesneeded) {
872-
gw->ptr = gw->walk_ptr;
869+
gw->ptr = gw->walk.addr;
873870
gw->nbytes = gw->walk_bytes;
874871
goto out;
875872
}
876873

877-
scatterwalk_unmap(gw->walk_ptr);
878-
gw->walk_ptr = NULL;
874+
/* XXX */
875+
scatterwalk_unmap(gw->walk.addr);
879876

880877
gw->ptr = gw->buf;
881878
gw->nbytes = sizeof(gw->buf);
@@ -914,7 +911,7 @@ static int gcm_out_walk_done(struct gcm_sg_walk *gw, unsigned int bytesdone)
914911
if (!_gcm_sg_clamp_and_map(gw))
915912
return i;
916913
n = min(gw->walk_bytes, bytesdone - i);
917-
memcpy(gw->walk_ptr, gw->buf + i, n);
914+
memcpy(gw->walk.addr, gw->buf + i, n);
918915
_gcm_sg_unmap_and_advance(gw, n, true);
919916
}
920917
} else

‎arch/x86/crypto/aegis128-aesni-glue.c

+3-4
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,9 @@ static void crypto_aegis128_aesni_process_ad(
7171

7272
scatterwalk_start(&walk, sg_src);
7373
while (assoclen != 0) {
74-
unsigned int size;
75-
const u8 *mapped = scatterwalk_next(&walk, assoclen, &size);
74+
unsigned int size = scatterwalk_next(&walk, assoclen);
75+
const u8 *src = walk.addr;
7676
unsigned int left = size;
77-
const u8 *src = mapped;
7877

7978
if (pos + size >= AEGIS128_BLOCK_SIZE) {
8079
if (pos > 0) {
@@ -97,7 +96,7 @@ static void crypto_aegis128_aesni_process_ad(
9796
pos += left;
9897
assoclen -= size;
9998

100-
scatterwalk_done_src(&walk, mapped, size);
99+
scatterwalk_done_src(&walk, size);
101100
}
102101

103102
if (pos > 0) {

‎arch/x86/crypto/aesni-intel_glue.c

+4-5
Original file line numberDiff line numberDiff line change
@@ -1306,12 +1306,11 @@ static void gcm_process_assoc(const struct aes_gcm_key *key, u8 ghash_acc[16],
13061306
scatterwalk_start(&walk, sg_src);
13071307

13081308
while (assoclen) {
1309-
unsigned int orig_len_this_step;
1310-
const u8 *orig_src = scatterwalk_next(&walk, assoclen,
1311-
&orig_len_this_step);
1309+
unsigned int orig_len_this_step = scatterwalk_next(
1310+
&walk, assoclen);
13121311
unsigned int len_this_step = orig_len_this_step;
13131312
unsigned int len;
1314-
const u8 *src = orig_src;
1313+
const u8 *src = walk.addr;
13151314

13161315
if (unlikely(pos)) {
13171316
len = min(len_this_step, 16 - pos);
@@ -1335,7 +1334,7 @@ static void gcm_process_assoc(const struct aes_gcm_key *key, u8 ghash_acc[16],
13351334
pos = len_this_step;
13361335
}
13371336
next:
1338-
scatterwalk_done_src(&walk, orig_src, orig_len_this_step);
1337+
scatterwalk_done_src(&walk, orig_len_this_step);
13391338
if (need_resched()) {
13401339
kernel_fpu_end();
13411340
kernel_fpu_begin();

‎crypto/aegis128-core.c

+3-4
Original file line numberDiff line numberDiff line change
@@ -284,10 +284,9 @@ static void crypto_aegis128_process_ad(struct aegis_state *state,
284284

285285
scatterwalk_start(&walk, sg_src);
286286
while (assoclen != 0) {
287-
unsigned int size;
288-
const u8 *mapped = scatterwalk_next(&walk, assoclen, &size);
287+
unsigned int size = scatterwalk_next(&walk, assoclen);
288+
const u8 *src = walk.addr;
289289
unsigned int left = size;
290-
const u8 *src = mapped;
291290

292291
if (pos + size >= AEGIS_BLOCK_SIZE) {
293292
if (pos > 0) {
@@ -308,7 +307,7 @@ static void crypto_aegis128_process_ad(struct aegis_state *state,
308307

309308
pos += left;
310309
assoclen -= size;
311-
scatterwalk_done_src(&walk, mapped, size);
310+
scatterwalk_done_src(&walk, size);
312311
}
313312

314313
if (pos > 0) {

‎crypto/scatterwalk.c

+6-8
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,11 @@ inline void memcpy_from_scatterwalk(void *buf, struct scatter_walk *walk,
3434
unsigned int nbytes)
3535
{
3636
do {
37-
const void *src_addr;
3837
unsigned int to_copy;
3938

40-
src_addr = scatterwalk_next(walk, nbytes, &to_copy);
41-
memcpy(buf, src_addr, to_copy);
42-
scatterwalk_done_src(walk, src_addr, to_copy);
39+
to_copy = scatterwalk_next(walk, nbytes);
40+
memcpy(buf, walk->addr, to_copy);
41+
scatterwalk_done_src(walk, to_copy);
4342
buf += to_copy;
4443
nbytes -= to_copy;
4544
} while (nbytes);
@@ -50,12 +49,11 @@ inline void memcpy_to_scatterwalk(struct scatter_walk *walk, const void *buf,
5049
unsigned int nbytes)
5150
{
5251
do {
53-
void *dst_addr;
5452
unsigned int to_copy;
5553

56-
dst_addr = scatterwalk_next(walk, nbytes, &to_copy);
57-
memcpy(dst_addr, buf, to_copy);
58-
scatterwalk_done_dst(walk, dst_addr, to_copy);
54+
to_copy = scatterwalk_next(walk, nbytes);
55+
memcpy(walk->addr, buf, to_copy);
56+
scatterwalk_done_dst(walk, to_copy);
5957
buf += to_copy;
6058
nbytes -= to_copy;
6159
} while (nbytes);

‎crypto/skcipher.c

+7-3
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,16 @@ static int skcipher_walk_next(struct skcipher_walk *walk);
4141

4242
static inline void skcipher_map_src(struct skcipher_walk *walk)
4343
{
44-
walk->src.virt.addr = scatterwalk_map(&walk->in);
44+
/* XXX */
45+
walk->in.__addr = scatterwalk_map(&walk->in);
46+
walk->src.virt.addr = walk->in.addr;
4547
}
4648

4749
static inline void skcipher_map_dst(struct skcipher_walk *walk)
4850
{
49-
walk->dst.virt.addr = scatterwalk_map(&walk->out);
51+
/* XXX */
52+
walk->out.__addr = scatterwalk_map(&walk->out);
53+
walk->dst.virt.addr = walk->out.addr;
5054
}
5155

5256
static inline gfp_t skcipher_walk_gfp(struct skcipher_walk *walk)
@@ -120,7 +124,7 @@ int skcipher_walk_done(struct skcipher_walk *walk, int res)
120124
goto dst_done;
121125
}
122126

123-
scatterwalk_done_dst(&walk->out, walk->dst.virt.addr, n);
127+
scatterwalk_done_dst(&walk->out, n);
124128
dst_done:
125129

126130
if (res > 0)

‎drivers/crypto/nx/nx.c

+3-4
Original file line numberDiff line numberDiff line change
@@ -154,17 +154,16 @@ struct nx_sg *nx_walk_and_build(struct nx_sg *nx_dst,
154154
struct scatter_walk walk;
155155
struct nx_sg *nx_sg = nx_dst;
156156
unsigned int n, len = *src_len;
157-
char *dst;
158157

159158
/* we need to fast forward through @start bytes first */
160159
scatterwalk_start_at_pos(&walk, sg_src, start);
161160

162161
while (len && (nx_sg - nx_dst) < sglen) {
163-
dst = scatterwalk_next(&walk, len, &n);
162+
n = scatterwalk_next(&walk, len);
164163

165-
nx_sg = nx_build_sg_list(nx_sg, dst, &n, sglen - (nx_sg - nx_dst));
164+
nx_sg = nx_build_sg_list(nx_sg, walk.addr, &n, sglen - (nx_sg - nx_dst));
166165

167-
scatterwalk_done_src(&walk, dst, n);
166+
scatterwalk_done_src(&walk, n);
168167
len -= n;
169168
}
170169
/* update to_process */

‎include/crypto/algapi.h

+7
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ struct rtattr;
5454
struct scatterlist;
5555
struct seq_file;
5656
struct sk_buff;
57+
union crypto_no_such_thing;
5758

5859
struct crypto_instance {
5960
struct crypto_alg alg;
@@ -108,6 +109,12 @@ struct crypto_queue {
108109
struct scatter_walk {
109110
struct scatterlist *sg;
110111
unsigned int offset;
112+
union {
113+
void *const addr;
114+
115+
/* Private API field, do not touch. */
116+
union crypto_no_such_thing *__addr;
117+
};
111118
};
112119

113120
struct crypto_attr_alg {

‎include/crypto/scatterwalk.h

+18-17
Original file line numberDiff line numberDiff line change
@@ -120,18 +120,20 @@ static inline void *scatterwalk_map(struct scatter_walk *walk)
120120
* scatterwalk_next() - Get the next data buffer in a scatterlist walk
121121
* @walk: the scatter_walk
122122
* @total: the total number of bytes remaining, > 0
123-
* @nbytes_ret: (out) the next number of bytes available, <= @total
124123
*
125-
* Return: A virtual address for the next segment of data from the scatterlist.
126-
* The caller must call scatterwalk_done_src() or scatterwalk_done_dst()
127-
* when it is done using this virtual address.
124+
* A virtual address for the next segment of data from the scatterlist will
125+
* be placed into @walk->addr. The caller must call scatterwalk_done_src()
126+
* or scatterwalk_done_dst() when it is done using this virtual address.
127+
*
128+
* Returns: the next number of bytes available, <= @total
128129
*/
129-
static inline void *scatterwalk_next(struct scatter_walk *walk,
130-
unsigned int total,
131-
unsigned int *nbytes_ret)
130+
static inline unsigned int scatterwalk_next(struct scatter_walk *walk,
131+
unsigned int total)
132132
{
133-
*nbytes_ret = scatterwalk_clamp(walk, total);
134-
return scatterwalk_map(walk);
133+
unsigned int nbytes = scatterwalk_clamp(walk, total);
134+
135+
walk->__addr = scatterwalk_map(walk);
136+
return nbytes;
135137
}
136138

137139
static inline void scatterwalk_unmap(const void *vaddr)
@@ -149,32 +151,31 @@ static inline void scatterwalk_advance(struct scatter_walk *walk,
149151
/**
150152
* scatterwalk_done_src() - Finish one step of a walk of source scatterlist
151153
* @walk: the scatter_walk
152-
* @vaddr: the address returned by scatterwalk_next()
153154
* @nbytes: the number of bytes processed this step, less than or equal to the
154155
* number of bytes that scatterwalk_next() returned.
155156
*
156-
* Use this if the @vaddr was not written to, i.e. it is source data.
157+
* Use this if the mapped address was not written to, i.e. it is source data.
157158
*/
158159
static inline void scatterwalk_done_src(struct scatter_walk *walk,
159-
const void *vaddr, unsigned int nbytes)
160+
unsigned int nbytes)
160161
{
161-
scatterwalk_unmap(vaddr);
162+
scatterwalk_unmap(walk->addr);
162163
scatterwalk_advance(walk, nbytes);
163164
}
164165

165166
/**
166167
* scatterwalk_done_dst() - Finish one step of a walk of destination scatterlist
167168
* @walk: the scatter_walk
168-
* @vaddr: the address returned by scatterwalk_next()
169169
* @nbytes: the number of bytes processed this step, less than or equal to the
170170
* number of bytes that scatterwalk_next() returned.
171171
*
172-
* Use this if the @vaddr may have been written to, i.e. it is destination data.
172+
* Use this if the mapped address may have been written to, i.e. it is
173+
* destination data.
173174
*/
174175
static inline void scatterwalk_done_dst(struct scatter_walk *walk,
175-
void *vaddr, unsigned int nbytes)
176+
unsigned int nbytes)
176177
{
177-
scatterwalk_unmap(vaddr);
178+
scatterwalk_unmap(walk->addr);
178179
/*
179180
* Explicitly check ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE instead of just
180181
* relying on flush_dcache_page() being a no-op when not implemented,

0 commit comments

Comments
 (0)
Please sign in to comment.