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
This commit is contained in:
John Baldwin 2021-05-25 16:59:19 -07:00
parent 6b313a3a60
commit beb817edfe
5 changed files with 50 additions and 74 deletions

View File

@ -925,6 +925,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 \

View File

@ -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

View File

@ -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

View File

@ -661,6 +661,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,

View File

@ -76,7 +76,7 @@
* cannot include sys/param.h and should only be updated here.
*/
#undef __FreeBSD_version
#define __FreeBSD_version 1400016
#define __FreeBSD_version 1400017
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,