Changeset View
Changeset View
Standalone View
Standalone View
sys/opencrypto/criov.c
Show First 20 Lines • Show All 252 Lines • ▼ Show 20 Lines | m_epg_pages_extent(struct mbuf *m, int idx, u_int pglen) | ||||
for (i = idx + 1; i < m->m_epg_npgs; i++) { | for (i = idx + 1; i < m->m_epg_npgs; i++) { | ||||
if (m->m_epg_pa[i - 1] + PAGE_SIZE != m->m_epg_pa[i]) | if (m->m_epg_pa[i - 1] + PAGE_SIZE != m->m_epg_pa[i]) | ||||
break; | break; | ||||
len += m_epg_pagelen(m, i, 0); | len += m_epg_pagelen(m, i, 0); | ||||
} | } | ||||
return (len); | return (len); | ||||
} | } | ||||
static __inline void * | static void * | ||||
m_epg_segbase(struct mbuf *m, size_t offset) | m_epg_segment(struct mbuf *m, size_t offset, size_t *len) | ||||
{ | { | ||||
u_int i, pglen, pgoff; | u_int i, pglen, pgoff; | ||||
offset += mtod(m, vm_offset_t); | 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); | return (m->m_epg_hdr + offset); | ||||
} | |||||
offset -= m->m_epg_hdrlen; | offset -= m->m_epg_hdrlen; | ||||
pgoff = m->m_epg_1st_off; | pgoff = m->m_epg_1st_off; | ||||
for (i = 0; i < m->m_epg_npgs; i++) { | for (i = 0; i < m->m_epg_npgs; i++) { | ||||
pglen = m_epg_pagelen(m, i, pgoff); | 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 + | return ((void *)PHYS_TO_DMAP(m->m_epg_pa[i] + pgoff + | ||||
offset)); | offset)); | ||||
} | |||||
offset -= pglen; | offset -= pglen; | ||||
pgoff = 0; | pgoff = 0; | ||||
} | } | ||||
KASSERT(offset <= m->m_epg_trllen, ("%s: offset beyond trailer", | KASSERT(offset <= m->m_epg_trllen, ("%s: offset beyond trailer", | ||||
__func__)); | __func__)); | ||||
*len = m->m_epg_trllen - offset; | |||||
return (m->m_epg_trail + 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 * | static __inline void * | ||||
m_epg_contiguous_subsegment(struct mbuf *m, size_t skip, size_t len) | 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); | base = m_epg_segment(m, skip, &seglen); | ||||
if (skip < m->m_epg_hdrlen) { | if (len > seglen) | ||||
if (len > m->m_epg_hdrlen - skip) | |||||
return (NULL); | return (NULL); | ||||
return (m->m_epg_hdr + skip); | return (base); | ||||
} | } | ||||
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); | |||||
} | |||||
void | void | ||||
crypto_cursor_init(struct crypto_buffer_cursor *cc, | crypto_cursor_init(struct crypto_buffer_cursor *cc, | ||||
const struct crypto_buffer *cb) | const struct crypto_buffer *cb) | ||||
{ | { | ||||
memset(cc, 0, sizeof(*cc)); | memset(cc, 0, sizeof(*cc)); | ||||
cc->cc_type = cb->cb_type; | cc->cc_type = cb->cb_type; | ||||
switch (cc->cc_type) { | switch (cc->cc_type) { | ||||
▲ Show 20 Lines • Show All 88 Lines • ▼ Show 20 Lines | |||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
panic("%s: invalid buffer type %d", __func__, cc->cc_type); | panic("%s: invalid buffer type %d", __func__, cc->cc_type); | ||||
#endif | #endif | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
void * | void * | ||||
crypto_cursor_segbase(struct crypto_buffer_cursor *cc) | crypto_cursor_segment(struct crypto_buffer_cursor *cc, size_t *len) | ||||
{ | { | ||||
switch (cc->cc_type) { | switch (cc->cc_type) { | ||||
case CRYPTO_BUF_CONTIG: | case CRYPTO_BUF_CONTIG: | ||||
*len = cc->cc_buf_len; | |||||
return (cc->cc_buf); | return (cc->cc_buf); | ||||
case CRYPTO_BUF_MBUF: | case CRYPTO_BUF_MBUF: | ||||
case CRYPTO_BUF_SINGLE_MBUF: | case CRYPTO_BUF_SINGLE_MBUF: | ||||
if (cc->cc_mbuf == NULL) | if (cc->cc_mbuf == NULL) { | ||||
*len = 0; | |||||
return (NULL); | return (NULL); | ||||
} | |||||
if (cc->cc_mbuf->m_flags & M_EXTPG) | 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); | return (mtod(cc->cc_mbuf, char *) + cc->cc_offset); | ||||
case CRYPTO_BUF_VMPAGE: | case CRYPTO_BUF_VMPAGE: | ||||
*len = PAGE_SIZE - cc->cc_offset; | |||||
return ((char *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS( | return ((char *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS( | ||||
*cc->cc_vmpage)) + cc->cc_offset); | *cc->cc_vmpage)) + cc->cc_offset); | ||||
case CRYPTO_BUF_UIO: | case CRYPTO_BUF_UIO: | ||||
*len = cc->cc_iov->iov_len - cc->cc_offset; | |||||
return ((char *)cc->cc_iov->iov_base + cc->cc_offset); | return ((char *)cc->cc_iov->iov_base + cc->cc_offset); | ||||
default: | default: | ||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
panic("%s: invalid buffer type %d", __func__, cc->cc_type); | panic("%s: invalid buffer type %d", __func__, cc->cc_type); | ||||
#endif | #endif | ||||
*len = 0; | |||||
return (NULL); | return (NULL); | ||||
} | } | ||||
} | } | ||||
void * | |||||
crypto_cursor_segbase(struct crypto_buffer_cursor *cc) | |||||
{ | |||||
size_t len; | |||||
return (crypto_cursor_segment(cc, &len)); | |||||
} | |||||
size_t | size_t | ||||
crypto_cursor_seglen(struct crypto_buffer_cursor *cc) | crypto_cursor_seglen(struct crypto_buffer_cursor *cc) | ||||
{ | { | ||||
switch (cc->cc_type) { | size_t len; | ||||
case CRYPTO_BUF_CONTIG: | |||||
return (cc->cc_buf_len); | crypto_cursor_segment(cc, &len); | ||||
case CRYPTO_BUF_VMPAGE: | return (len); | ||||
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); | |||||
} | |||||
} | } | ||||
void | void | ||||
crypto_cursor_copyback(struct crypto_buffer_cursor *cc, int size, | crypto_cursor_copyback(struct crypto_buffer_cursor *cc, int size, | ||||
const void *vsrc) | const void *vsrc) | ||||
{ | { | ||||
size_t remain, todo; | size_t remain, todo; | ||||
const char *src; | const char *src; | ||||
▲ Show 20 Lines • Show All 398 Lines • Show Last 20 Lines |