git: 6a13905b5ab3 - stable/13 - OCF: Add crypto_clonereq().

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Fri, 29 Apr 2022 23:12:29 UTC
The branch stable/13 has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=6a13905b5ab39f2f4ed8f5c9c8b6af204925088d

commit 6a13905b5ab39f2f4ed8f5c9c8b6af204925088d
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2022-01-04 22:22:12 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2022-04-29 22:41:27 +0000

    OCF: Add crypto_clonereq().
    
    This function clones an existing crypto request, but associates the
    new request with a specified session.  The intended use case is for
    drivers to be able to fall back to software by cloning a request and
    dispatch it to an internally allocated software session.
    
    Reviewed by:    markj
    Sponsored by:   Chelsio Communications
    Differential Revision:  https://reviews.freebsd.org/D33607
    
    (cherry picked from commit 74d3f1b63dbea05038e966cf4bb69a01b0589500)
---
 share/man/man9/Makefile         |  3 ++-
 share/man/man9/crypto_request.9 | 25 ++++++++++++++++++++++---
 sys/opencrypto/crypto.c         | 21 +++++++++++++++++++++
 sys/opencrypto/cryptodev.h      |  4 ++++
 4 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
index a7c3d69f4e70..0c686813118e 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -951,7 +951,8 @@ MLINKS+=crypto_driver.9 crypto_copyback.9 \
 	crypto_driver.9 CRYPTODEV_PROCESS.9 \
 	crypto_driver.9 hmac_init_ipad.9 \
 	crypto_driver.9 hmac_init_opad.9
-MLINKS+=crypto_request.9 crypto_destroyreq.9 \
+MLINKS+=crypto_request.9 crypto_clonereq.9 \
+	crypto_request.9 crypto_destroyreq.9 \
 	crypto_request.9 crypto_dispatch.9 \
 	crypto_request.9 crypto_freereq.9 \
 	crypto_request.9 crypto_getreq.9 \
diff --git a/share/man/man9/crypto_request.9 b/share/man/man9/crypto_request.9
index 6253e49dfb32..bc71a870f831 100644
--- a/share/man/man9/crypto_request.9
+++ b/share/man/man9/crypto_request.9
@@ -38,6 +38,8 @@
 .Nd symmetric cryptographic operations
 .Sh SYNOPSIS
 .In opencrypto/cryptodev.h
+.Ft "struct cryptop *"
+.Fn crypto_clonereq "crypto_session_t cses" "struct cryptop *crp" "int how"
 .Ft int
 .Fn crypto_dispatch "struct cryptop *crp"
 .Ft void
@@ -72,8 +74,10 @@ and is associated with an active session.
 .Pp
 Requests can either be allocated dynamically or use caller-supplied
 storage.
-Dynamically allocated requests should be allocated by
+Dynamically allocated requests should be allocated by either
 .Fn crypto_getreq
+or
+.Fn crypto_clonereq ,
 and freed by
 .Fn crypto_freereq
 once the request has completed.
@@ -83,13 +87,16 @@ at the start of each operation and destroyed by
 .Fn crypto_destroyreq
 once the request has completed.
 .Pp
-For both
-.Fn crypto_getreq
+For
+.Fn crypto_clonereq ,
+.Fn crypto_getreq ,
 and
 .Fn crypto_initreq ,
 .Fa cses
 is a reference to an active session.
 For
+.Fn crypto_clonereq
+and
 .Fn crypto_getreq ,
 .Fa how
 is passed to
@@ -99,6 +106,18 @@ and should be set to either
 or
 .Dv M_WAITOK .
 .Pp
+.Fn crypto_clonereq
+allocates a new request that inherits request inputs such as request buffers
+from the original
+.Fa crp
+request.
+However, the new request is associated with the
+.Fa cses
+session rather than inheriting the session from
+.Fa crp .
+.Fa crp
+must not be a completed request.
+.Pp
 Once a request has been initialized,
 the caller should set fields in the structure to describe
 request-specific parameters.
diff --git a/sys/opencrypto/crypto.c b/sys/opencrypto/crypto.c
index 69dd75ab1d0c..1c5074e847ed 100644
--- a/sys/opencrypto/crypto.c
+++ b/sys/opencrypto/crypto.c
@@ -1847,6 +1847,27 @@ crypto_getreq(crypto_session_t cses, int how)
 	return (crp);
 }
 
+/*
+ * Clone a crypto request, but associate it with the specified session
+ * rather than inheriting the session from the original request.  The
+ * fields describing the request buffers are copied, but not the
+ * opaque field or callback function.
+ */
+struct cryptop *
+crypto_clonereq(struct cryptop *crp, crypto_session_t cses, int how)
+{
+	struct cryptop *new;
+
+	MPASS((crp->crp_flags & CRYPTO_F_DONE) == 0);
+	new = crypto_getreq(cses, how);
+	if (new == NULL)
+		return (NULL);
+
+	memcpy(&new->crp_startcopy, &crp->crp_startcopy,
+	    __rangeof(struct cryptop, crp_startcopy, crp_endcopy));
+	return (new);
+}
+
 /*
  * Invoke the callback on behalf of the driver.
  */
diff --git a/sys/opencrypto/cryptodev.h b/sys/opencrypto/cryptodev.h
index 8aa9f80ec696..90ed5f460776 100644
--- a/sys/opencrypto/cryptodev.h
+++ b/sys/opencrypto/cryptodev.h
@@ -463,6 +463,7 @@ struct cryptop {
 					 * should always check and use the new
 					 * value on future requests.
 					 */
+#define	crp_startcopy	crp_flags
 	int		crp_flags;
 
 #define	CRYPTO_F_BATCH		0x0008	/* Batch op if possible */
@@ -503,6 +504,7 @@ struct cryptop {
 
 	const void	*crp_cipher_key; /* New cipher key if non-NULL. */
 	const void	*crp_auth_key;	/* New auth key if non-NULL. */
+#define	crp_endcopy	crp_opaque
 
 	void		*crp_opaque;	/* Opaque pointer, passed along */
 
@@ -686,6 +688,8 @@ void	crypto_done(struct cryptop *crp);
 void	crypto_kdone(struct cryptkop *);
 int	crypto_getfeat(int *);
 
+struct cryptop *crypto_clonereq(struct cryptop *crp, crypto_session_t cses,
+    int how);
 void	crypto_destroyreq(struct cryptop *crp);
 void	crypto_initreq(struct cryptop *crp, crypto_session_t cses);
 void	crypto_freereq(struct cryptop *crp);