git: a017868e2818 - stable/13 - crypto: Add crypto_cursor_segment() to fetch both base and length.

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Thu, 21 Oct 2021 17:07:14 UTC
The branch stable/13 has been updated by jhb:

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

commit a017868e281874261a560ba1e3069b4e14b7483e
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2021-05-25 23:59:19 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2021-10-21 15:51:26 +0000

    crypto: Add crypto_cursor_segment() to fetch both base and length.
    
    This function combines crypto_cursor_segbase() and
    crypto_cursor_seglen() into a single function.  This is mostly
    beneficial in the unmapped mbuf case where back to back calls of these
    two functions have to iterate over the sub-components of unmapped
    mbufs twice.
    
    Bump __FreeBSD_version for crypto drivers in ports.
    
    Suggested by:   markj
    Reviewed by:    markj
    Sponsored by:   Netflix
    Differential Revision:  https://reviews.freebsd.org/D30445
    
    (cherry picked from commit beb817edfe22cdea91e19a60c42caabd9404da48)
---
 share/man/man9/Makefile        |   1 +
 share/man/man9/crypto_buffer.9 |  11 ++++-
 sys/opencrypto/criov.c         | 109 ++++++++++++++---------------------------
 sys/opencrypto/cryptodev.h     |   1 +
 sys/sys/param.h                |   2 +-
 5 files changed, 50 insertions(+), 74 deletions(-)

diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
index acdfa7cc6d8e..c180742bdb4b 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -929,6 +929,7 @@ MLINKS+=crypto_buffer.9 crypto_apply.9 \
 	crypto_buffer.9 crypto_cursor_copydata_noadv.9 \
 	crypto_buffer.9 crypto_cursor_segbase.9 \
 	crypto_buffer.9 crypto_cursor_seglen.9 \
+	crypto_buffer.9 crypto_cursor_segment.9 \
 	crypto_buffer.9 CRYPTO_HAS_OUTPUT_BUFFER.9
 MLINKS+=crypto_driver.9 crypto_copyback.9 \
 	crypto_driver.9 crypto_copydata.9 \
diff --git a/share/man/man9/crypto_buffer.9 b/share/man/man9/crypto_buffer.9
index df6128650cd4..a16206e8e607 100644
--- a/share/man/man9/crypto_buffer.9
+++ b/share/man/man9/crypto_buffer.9
@@ -94,6 +94,8 @@
 .Fa "void *dst"
 .Fc
 .Ft void *
+.Fn crypto_cursor_segment "struct crypto_buffer_cursor *cc" "size_t *len"
+.Ft void *
 .Fn crypto_cursor_segbase "struct crypto_buffer_cursor *cc"
 .Ft size_t
 .Fn crypto_cursor_seglen "struct crypto_buffer_cursor *cc"
@@ -293,6 +295,12 @@ is similar to
 except that it does not change the current position of
 .Fa cc .
 .Pp
+.Fn crypto_cursor_segment
+returns the start of the virtually-contiguous segment at the current position of
+.Fa cc .
+The length of the segment is stored in
+.Fa len .
+.Pp
 .Fn crypto_cursor_segbase
 and
 .Fn crypto_cursor_seglen
@@ -307,8 +315,9 @@ return the return value from the caller-supplied callback function.
 .Pp
 .Fn crypto_buffer_contiguous_subsegment ,
 .Fn crypto_contiguous_subsegment ,
-and
 .Fn crypto_cursor_segbase ,
+and
+.Fn crypto_cursor_segment
 return a pointer to a contiguous segment or
 .Dv NULL .
 .Pp
diff --git a/sys/opencrypto/criov.c b/sys/opencrypto/criov.c
index df053b314d41..25702e3592fe 100644
--- a/sys/opencrypto/criov.c
+++ b/sys/opencrypto/criov.c
@@ -258,78 +258,44 @@ m_epg_pages_extent(struct mbuf *m, int idx, u_int pglen)
 	return (len);
 }
 
-static __inline void *
-m_epg_segbase(struct mbuf *m, size_t offset)
+static void *
+m_epg_segment(struct mbuf *m, size_t offset, size_t *len)
 {
 	u_int i, pglen, pgoff;
 
 	offset += mtod(m, vm_offset_t);
-	if (offset < m->m_epg_hdrlen)
+	if (offset < m->m_epg_hdrlen) {
+		*len = m->m_epg_hdrlen - offset;
 		return (m->m_epg_hdr + offset);
+	}
 	offset -= m->m_epg_hdrlen;
 	pgoff = m->m_epg_1st_off;
 	for (i = 0; i < m->m_epg_npgs; i++) {
 		pglen = m_epg_pagelen(m, i, pgoff);
-		if (offset < pglen)
+		if (offset < pglen) {
+			*len = m_epg_pages_extent(m, i, pglen) - offset;
 			return ((void *)PHYS_TO_DMAP(m->m_epg_pa[i] + pgoff +
 			    offset));
+		}
 		offset -= pglen;
 		pgoff = 0;
 	}
 	KASSERT(offset <= m->m_epg_trllen, ("%s: offset beyond trailer",
 	    __func__));
+	*len = m->m_epg_trllen - offset;
 	return (m->m_epg_trail + offset);
 }
 
-static __inline size_t
-m_epg_seglen(struct mbuf *m, size_t offset)
-{
-	u_int i, pglen, pgoff;
-
-	offset += mtod(m, vm_offset_t);
-	if (offset < m->m_epg_hdrlen)
-		return (m->m_epg_hdrlen - offset);
-	offset -= m->m_epg_hdrlen;
-	pgoff = m->m_epg_1st_off;
-	for (i = 0; i < m->m_epg_npgs; i++) {
-		pglen = m_epg_pagelen(m, i, pgoff);
-		if (offset < pglen)
-			return (m_epg_pages_extent(m, i, pglen) - offset);
-		offset -= pglen;
-		pgoff = 0;
-	}
-	KASSERT(offset <= m->m_epg_trllen, ("%s: offset beyond trailer",
-	    __func__));
-	return (m->m_epg_trllen - offset);
-}
-
 static __inline void *
 m_epg_contiguous_subsegment(struct mbuf *m, size_t skip, size_t len)
 {
-	u_int i, pglen, pgoff;
+	void *base;
+	size_t seglen;
 
-	skip += mtod(m, vm_offset_t);
-	if (skip < m->m_epg_hdrlen) {
-		if (len > m->m_epg_hdrlen - skip)
-			return (NULL);
-		return (m->m_epg_hdr + skip);
-	}
-	skip -= m->m_epg_hdrlen;
-	pgoff = m->m_epg_1st_off;
-	for (i = 0; i < m->m_epg_npgs; i++) {
-		pglen = m_epg_pagelen(m, i, pgoff);
-		if (skip < pglen) {
-			if (len > m_epg_pages_extent(m, i, pglen) - skip)
-				return (NULL);
-			return ((void *)PHYS_TO_DMAP(m->m_epg_pa[i] + pgoff +
-			    skip));
-		}
-		skip -= pglen;
-		pgoff = 0;
-	}
-	KASSERT(skip <= m->m_epg_trllen && len <= m->m_epg_trllen - skip,
-	    ("%s: segment beyond trailer", __func__));
-	return (m->m_epg_trail + skip);
+	base = m_epg_segment(m, skip, &seglen);
+	if (len > seglen)
+		return (NULL);
+	return (base);
 }
 
 void
@@ -435,54 +401,53 @@ crypto_cursor_advance(struct crypto_buffer_cursor *cc, size_t amount)
 }
 
 void *
-crypto_cursor_segbase(struct crypto_buffer_cursor *cc)
+crypto_cursor_segment(struct crypto_buffer_cursor *cc, size_t *len)
 {
 	switch (cc->cc_type) {
 	case CRYPTO_BUF_CONTIG:
+		*len = cc->cc_buf_len;
 		return (cc->cc_buf);
 	case CRYPTO_BUF_MBUF:
 	case CRYPTO_BUF_SINGLE_MBUF:
-		if (cc->cc_mbuf == NULL)
+		if (cc->cc_mbuf == NULL) {
+			*len = 0;
 			return (NULL);
+		}
 		if (cc->cc_mbuf->m_flags & M_EXTPG)
-			return (m_epg_segbase(cc->cc_mbuf, cc->cc_offset));
+			return (m_epg_segment(cc->cc_mbuf, cc->cc_offset, len));
+		*len = cc->cc_mbuf->m_len - cc->cc_offset;
 		return (mtod(cc->cc_mbuf, char *) + cc->cc_offset);
 	case CRYPTO_BUF_VMPAGE:
+		*len = PAGE_SIZE - cc->cc_offset;
 		return ((char *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(
 		    *cc->cc_vmpage)) + cc->cc_offset);
 	case CRYPTO_BUF_UIO:
+		*len = cc->cc_iov->iov_len - cc->cc_offset;
 		return ((char *)cc->cc_iov->iov_base + cc->cc_offset);
 	default:
 #ifdef INVARIANTS
 		panic("%s: invalid buffer type %d", __func__, cc->cc_type);
 #endif
+		*len = 0;
 		return (NULL);
 	}
 }
 
+void *
+crypto_cursor_segbase(struct crypto_buffer_cursor *cc)
+{
+	size_t len;
+
+	return (crypto_cursor_segment(cc, &len));
+}
+
 size_t
 crypto_cursor_seglen(struct crypto_buffer_cursor *cc)
 {
-	switch (cc->cc_type) {
-	case CRYPTO_BUF_CONTIG:
-		return (cc->cc_buf_len);
-	case CRYPTO_BUF_VMPAGE:
-		return (PAGE_SIZE - cc->cc_offset);
-	case CRYPTO_BUF_MBUF:
-	case CRYPTO_BUF_SINGLE_MBUF:
-		if (cc->cc_mbuf == NULL)
-			return (0);
-		if (cc->cc_mbuf->m_flags & M_EXTPG)
-			return (m_epg_seglen(cc->cc_mbuf, cc->cc_offset));
-		return (cc->cc_mbuf->m_len - cc->cc_offset);
-	case CRYPTO_BUF_UIO:
-		return (cc->cc_iov->iov_len - cc->cc_offset);
-	default:
-#ifdef INVARIANTS
-		panic("%s: invalid buffer type %d", __func__, cc->cc_type);
-#endif
-		return (0);
-	}
+	size_t len;
+
+	crypto_cursor_segment(cc, &len);
+	return (len);
 }
 
 void
diff --git a/sys/opencrypto/cryptodev.h b/sys/opencrypto/cryptodev.h
index f60f4e63735a..4d9b735366b8 100644
--- a/sys/opencrypto/cryptodev.h
+++ b/sys/opencrypto/cryptodev.h
@@ -726,6 +726,7 @@ size_t	crypto_buffer_len(struct crypto_buffer *cb);
 void	crypto_cursor_init(struct crypto_buffer_cursor *cc,
 	    const struct crypto_buffer *cb);
 void	crypto_cursor_advance(struct crypto_buffer_cursor *cc, size_t amount);
+void	*crypto_cursor_segment(struct crypto_buffer_cursor *cc, size_t *len);
 void	*crypto_cursor_segbase(struct crypto_buffer_cursor *cc);
 size_t	crypto_cursor_seglen(struct crypto_buffer_cursor *cc);
 void	crypto_cursor_copyback(struct crypto_buffer_cursor *cc, int size,
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 799ba1a9af42..fd177d5a23a1 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -60,7 +60,7 @@
  *		in the range 5 to 9.
  */
 #undef __FreeBSD_version
-#define __FreeBSD_version 1300517	/* Master, propagated to newvers */
+#define __FreeBSD_version 1300518	/* Master, propagated to newvers */
 
 /*
  * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,