diff mbox series

[v2,3/3] crypto: skcipher - Eliminate duplicate virt.addr field

Message ID 2234a3dc7c2765c6067824288961f9d6841a5b0a.1741318360.git.herbert@gondor.apana.org.au
State Superseded
Headers show
Series crypto: scatterwalk - scatterwalk_next and memcpy_sglist | expand

Commit Message

Herbert Xu March 7, 2025, 3:36 a.m. UTC
Reuse the addr field from struct scatter_walk for skcipher_walk.

Keep the existing virt.addr fields but make them const for the
user to access the mapped address.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---
 crypto/skcipher.c                  | 29 ++++++++++++-----------------
 include/crypto/algapi.h            |  5 +++--
 include/crypto/internal/skcipher.h | 26 +++++++++++++++++++++-----
 3 files changed, 36 insertions(+), 24 deletions(-)

Comments

Eric Biggers March 7, 2025, 9:48 p.m. UTC | #1
On Fri, Mar 07, 2025 at 11:36:21AM +0800, Herbert Xu wrote:
> diff --git a/crypto/skcipher.c b/crypto/skcipher.c
> index 92def074374a..24bb78f45bfb 100644
> --- a/crypto/skcipher.c
> +++ b/crypto/skcipher.c
> @@ -43,14 +43,12 @@ static inline void skcipher_map_src(struct skcipher_walk *walk)
>  {
>  	/* XXX */
>  	walk->in.maddr = scatterwalk_map(&walk->in);
> -	walk->src.virt.addr = walk->in.addr;
>  }

This patch makes all the callers of scatterwalk_map() assign the returned
address to the struct scatter_walk itself.  So that should just be done by
scatterwalk_map() itself.  Then skcipher_map_src() and skcipher_map_dst() should
be removed and the callers updated to use scatterwalk_map(&walk->in) and
scatterwalk_map(&walk->out) directly.

> @@ -214,7 +209,7 @@ static int skcipher_next_fast(struct skcipher_walk *walk)
>  		(u8 *)(sg_page(walk->out.sg) + (walk->out.offset >> PAGE_SHIFT));
>  
>  	skcipher_map_src(walk);
> -	walk->dst.virt.addr = walk->src.virt.addr;
> +	walk->out.maddr = walk->in.maddr;
>  
>  	if (diff) {
>  		walk->flags |= SKCIPHER_WALK_DIFF;

Note that this will have to be rebased on top of
https://lore.kernel.org/r/20250306033305.163767-1-ebiggers@kernel.org
(sorry for missing that earlier).

- Eric
diff mbox series

Patch

diff --git a/crypto/skcipher.c b/crypto/skcipher.c
index 92def074374a..24bb78f45bfb 100644
--- a/crypto/skcipher.c
+++ b/crypto/skcipher.c
@@ -43,14 +43,12 @@  static inline void skcipher_map_src(struct skcipher_walk *walk)
 {
 	/* XXX */
 	walk->in.maddr = scatterwalk_map(&walk->in);
-	walk->src.virt.addr = walk->in.addr;
 }
 
 static inline void skcipher_map_dst(struct skcipher_walk *walk)
 {
 	/* XXX */
 	walk->out.maddr = scatterwalk_map(&walk->out);
-	walk->dst.virt.addr = walk->out.addr;
 }
 
 static inline gfp_t skcipher_walk_gfp(struct skcipher_walk *walk)
@@ -100,8 +98,7 @@  int skcipher_walk_done(struct skcipher_walk *walk, int res)
 				    SKCIPHER_WALK_DIFF)))) {
 		scatterwalk_advance(&walk->in, n);
 	} else if (walk->flags & SKCIPHER_WALK_DIFF) {
-		scatterwalk_unmap(walk->src.virt.addr);
-		scatterwalk_advance(&walk->in, n);
+		scatterwalk_done_src(&walk->in, n);
 	} else if (walk->flags & SKCIPHER_WALK_COPY) {
 		scatterwalk_advance(&walk->in, n);
 		skcipher_map_dst(walk);
@@ -116,11 +113,8 @@  int skcipher_walk_done(struct skcipher_walk *walk, int res)
 			 */
 			res = -EINVAL;
 			total = 0;
-		} else {
-			u8 *buf = PTR_ALIGN(walk->buffer, walk->alignmask + 1);
-
-			memcpy_to_scatterwalk(&walk->out, buf, n);
-		}
+		} else
+			memcpy_to_scatterwalk(&walk->out, walk->out.addr, n);
 		goto dst_done;
 	}
 
@@ -162,7 +156,7 @@  static int skcipher_next_slow(struct skcipher_walk *walk, unsigned int bsize)
 {
 	unsigned alignmask = walk->alignmask;
 	unsigned n;
-	u8 *buffer;
+	void *buffer;
 
 	if (!walk->buffer)
 		walk->buffer = walk->page;
@@ -176,10 +170,11 @@  static int skcipher_next_slow(struct skcipher_walk *walk, unsigned int bsize)
 			return skcipher_walk_done(walk, -ENOMEM);
 		walk->buffer = buffer;
 	}
-	walk->dst.virt.addr = PTR_ALIGN(buffer, alignmask + 1);
-	walk->src.virt.addr = walk->dst.virt.addr;
 
-	memcpy_from_scatterwalk(walk->src.virt.addr, &walk->in, bsize);
+	buffer = PTR_ALIGN(buffer, alignmask + 1);
+	memcpy_from_scatterwalk(buffer, &walk->in, bsize);
+	walk->out.maddr = buffer;
+	walk->in.maddr = walk->out.maddr;
 
 	walk->nbytes = bsize;
 	walk->flags |= SKCIPHER_WALK_SLOW;
@@ -189,7 +184,7 @@  static int skcipher_next_slow(struct skcipher_walk *walk, unsigned int bsize)
 
 static int skcipher_next_copy(struct skcipher_walk *walk)
 {
-	u8 *tmp = walk->page;
+	void *tmp = walk->page;
 
 	skcipher_map_src(walk);
 	memcpy(tmp, walk->src.virt.addr, walk->nbytes);
@@ -199,8 +194,8 @@  static int skcipher_next_copy(struct skcipher_walk *walk)
 	 * processed (which might be less than walk->nbytes) is known.
 	 */
 
-	walk->src.virt.addr = tmp;
-	walk->dst.virt.addr = tmp;
+	walk->in.maddr = tmp;
+	walk->out.maddr = tmp;
 	return 0;
 }
 
@@ -214,7 +209,7 @@  static int skcipher_next_fast(struct skcipher_walk *walk)
 		(u8 *)(sg_page(walk->out.sg) + (walk->out.offset >> PAGE_SHIFT));
 
 	skcipher_map_src(walk);
-	walk->dst.virt.addr = walk->src.virt.addr;
+	walk->out.maddr = walk->in.maddr;
 
 	if (diff) {
 		walk->flags |= SKCIPHER_WALK_DIFF;
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h
index 8f1dfb758ced..79ccd8ab287a 100644
--- a/include/crypto/algapi.h
+++ b/include/crypto/algapi.h
@@ -121,14 +121,15 @@  struct crypto_queue {
 };
 
 struct scatter_walk {
-	struct scatterlist *sg;
-	unsigned int offset;
+	/* Must be the first member, see struct skcipher_walk. */
 	union {
 		void *const addr;
 
 		/* Private API field, do not touch. */
 		union crypto_no_such_thing *maddr;
 	};
+	struct scatterlist *sg;
+	unsigned int offset;
 };
 
 struct crypto_attr_alg {
diff --git a/include/crypto/internal/skcipher.h b/include/crypto/internal/skcipher.h
index d6ae7a86fed2..c705124432c5 100644
--- a/include/crypto/internal/skcipher.h
+++ b/include/crypto/internal/skcipher.h
@@ -56,15 +56,31 @@  struct crypto_lskcipher_spawn {
 
 struct skcipher_walk {
 	union {
+		/* Virtual address of the source. */
 		struct {
-			void *addr;
-		} virt;
-	} src, dst;
+			struct {
+				void *const addr;
+			} virt;
+		} src;
+
+		/* Private field for the API, do not use. */
+		struct scatter_walk in;
+	};
 
-	struct scatter_walk in;
 	unsigned int nbytes;
 
-	struct scatter_walk out;
+	union {
+		/* Virtual address of the destination. */
+		struct {
+			struct {
+				void *const addr;
+			} virt;
+		} dst;
+
+		/* Private field for the API, do not use. */
+		struct scatter_walk out;
+	};
+
 	unsigned int total;
 
 	u8 *page;