mirror of https://github.com/torvalds/linux.git
crypto: acomp - Add acomp_walk
Add acomp_walk which is similar to skcipher_walk but tailored for acomp. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
42d9f6c774
commit
9c8cf58262
|
|
@ -8,6 +8,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <crypto/internal/acompress.h>
|
#include <crypto/internal/acompress.h>
|
||||||
|
#include <crypto/scatterwalk.h>
|
||||||
#include <linux/cryptouser.h>
|
#include <linux/cryptouser.h>
|
||||||
#include <linux/cpumask.h>
|
#include <linux/cpumask.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
|
|
@ -15,6 +16,8 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/page-flags.h>
|
#include <linux/page-flags.h>
|
||||||
#include <linux/percpu.h>
|
#include <linux/percpu.h>
|
||||||
|
#include <linux/scatterlist.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/smp.h>
|
#include <linux/smp.h>
|
||||||
|
|
@ -27,6 +30,14 @@
|
||||||
|
|
||||||
struct crypto_scomp;
|
struct crypto_scomp;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ACOMP_WALK_SLEEP = 1 << 0,
|
||||||
|
ACOMP_WALK_SRC_LINEAR = 1 << 1,
|
||||||
|
ACOMP_WALK_SRC_FOLIO = 1 << 2,
|
||||||
|
ACOMP_WALK_DST_LINEAR = 1 << 3,
|
||||||
|
ACOMP_WALK_DST_FOLIO = 1 << 4,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct crypto_type crypto_acomp_type;
|
static const struct crypto_type crypto_acomp_type;
|
||||||
|
|
||||||
static void acomp_reqchain_done(void *data, int err);
|
static void acomp_reqchain_done(void *data, int err);
|
||||||
|
|
@ -546,5 +557,110 @@ struct crypto_acomp_stream *crypto_acomp_lock_stream_bh(
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(crypto_acomp_lock_stream_bh);
|
EXPORT_SYMBOL_GPL(crypto_acomp_lock_stream_bh);
|
||||||
|
|
||||||
|
void acomp_walk_done_src(struct acomp_walk *walk, int used)
|
||||||
|
{
|
||||||
|
walk->slen -= used;
|
||||||
|
if ((walk->flags & ACOMP_WALK_SRC_LINEAR))
|
||||||
|
scatterwalk_advance(&walk->in, used);
|
||||||
|
else
|
||||||
|
scatterwalk_done_src(&walk->in, used);
|
||||||
|
|
||||||
|
if ((walk->flags & ACOMP_WALK_SLEEP))
|
||||||
|
cond_resched();
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(acomp_walk_done_src);
|
||||||
|
|
||||||
|
void acomp_walk_done_dst(struct acomp_walk *walk, int used)
|
||||||
|
{
|
||||||
|
walk->dlen -= used;
|
||||||
|
if ((walk->flags & ACOMP_WALK_DST_LINEAR))
|
||||||
|
scatterwalk_advance(&walk->out, used);
|
||||||
|
else
|
||||||
|
scatterwalk_done_dst(&walk->out, used);
|
||||||
|
|
||||||
|
if ((walk->flags & ACOMP_WALK_SLEEP))
|
||||||
|
cond_resched();
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(acomp_walk_done_dst);
|
||||||
|
|
||||||
|
int acomp_walk_next_src(struct acomp_walk *walk)
|
||||||
|
{
|
||||||
|
unsigned int slen = walk->slen;
|
||||||
|
unsigned int max = UINT_MAX;
|
||||||
|
|
||||||
|
if (!preempt_model_preemptible() && (walk->flags & ACOMP_WALK_SLEEP))
|
||||||
|
max = PAGE_SIZE;
|
||||||
|
if ((walk->flags & ACOMP_WALK_SRC_LINEAR)) {
|
||||||
|
walk->in.__addr = (void *)(((u8 *)walk->in.sg) +
|
||||||
|
walk->in.offset);
|
||||||
|
return min(slen, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
return slen ? scatterwalk_next(&walk->in, slen) : 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(acomp_walk_next_src);
|
||||||
|
|
||||||
|
int acomp_walk_next_dst(struct acomp_walk *walk)
|
||||||
|
{
|
||||||
|
unsigned int dlen = walk->dlen;
|
||||||
|
unsigned int max = UINT_MAX;
|
||||||
|
|
||||||
|
if (!preempt_model_preemptible() && (walk->flags & ACOMP_WALK_SLEEP))
|
||||||
|
max = PAGE_SIZE;
|
||||||
|
if ((walk->flags & ACOMP_WALK_DST_LINEAR)) {
|
||||||
|
walk->out.__addr = (void *)(((u8 *)walk->out.sg) +
|
||||||
|
walk->out.offset);
|
||||||
|
return min(dlen, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dlen ? scatterwalk_next(&walk->out, dlen) : 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(acomp_walk_next_dst);
|
||||||
|
|
||||||
|
int acomp_walk_virt(struct acomp_walk *__restrict walk,
|
||||||
|
struct acomp_req *__restrict req)
|
||||||
|
{
|
||||||
|
struct scatterlist *src = req->src;
|
||||||
|
struct scatterlist *dst = req->dst;
|
||||||
|
|
||||||
|
walk->slen = req->slen;
|
||||||
|
walk->dlen = req->dlen;
|
||||||
|
|
||||||
|
if (!walk->slen || !walk->dlen)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
walk->flags = 0;
|
||||||
|
if ((req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP))
|
||||||
|
walk->flags |= ACOMP_WALK_SLEEP;
|
||||||
|
if ((req->base.flags & CRYPTO_ACOMP_REQ_SRC_VIRT))
|
||||||
|
walk->flags |= ACOMP_WALK_SRC_LINEAR;
|
||||||
|
else if ((req->base.flags & CRYPTO_ACOMP_REQ_SRC_FOLIO)) {
|
||||||
|
src = &req->chain.ssg;
|
||||||
|
sg_init_table(src, 1);
|
||||||
|
sg_set_folio(src, req->sfolio, walk->slen, req->soff);
|
||||||
|
}
|
||||||
|
if ((req->base.flags & CRYPTO_ACOMP_REQ_DST_VIRT))
|
||||||
|
walk->flags |= ACOMP_WALK_DST_LINEAR;
|
||||||
|
else if ((req->base.flags & CRYPTO_ACOMP_REQ_DST_FOLIO)) {
|
||||||
|
dst = &req->chain.dsg;
|
||||||
|
sg_init_table(dst, 1);
|
||||||
|
sg_set_folio(dst, req->dfolio, walk->dlen, req->doff);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((walk->flags & ACOMP_WALK_SRC_LINEAR)) {
|
||||||
|
walk->in.sg = (void *)req->svirt;
|
||||||
|
walk->in.offset = 0;
|
||||||
|
} else
|
||||||
|
scatterwalk_start(&walk->in, src);
|
||||||
|
if ((walk->flags & ACOMP_WALK_DST_LINEAR)) {
|
||||||
|
walk->out.sg = (void *)req->dvirt;
|
||||||
|
walk->out.offset = 0;
|
||||||
|
} else
|
||||||
|
scatterwalk_start(&walk->out, dst);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(acomp_walk_virt);
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_DESCRIPTION("Asynchronous compression type");
|
MODULE_DESCRIPTION("Asynchronous compression type");
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include <crypto/acompress.h>
|
#include <crypto/acompress.h>
|
||||||
#include <crypto/algapi.h>
|
#include <crypto/algapi.h>
|
||||||
|
#include <crypto/scatterwalk.h>
|
||||||
#include <linux/compiler_types.h>
|
#include <linux/compiler_types.h>
|
||||||
#include <linux/cpumask_types.h>
|
#include <linux/cpumask_types.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
|
|
@ -75,6 +76,37 @@ struct crypto_acomp_streams {
|
||||||
cpumask_t stream_want;
|
cpumask_t stream_want;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct acomp_walk {
|
||||||
|
union {
|
||||||
|
/* Virtual address of the source. */
|
||||||
|
struct {
|
||||||
|
struct {
|
||||||
|
const void *const addr;
|
||||||
|
} virt;
|
||||||
|
} src;
|
||||||
|
|
||||||
|
/* Private field for the API, do not use. */
|
||||||
|
struct scatter_walk in;
|
||||||
|
};
|
||||||
|
|
||||||
|
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 slen;
|
||||||
|
unsigned int dlen;
|
||||||
|
|
||||||
|
int flags;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transform internal helpers.
|
* Transform internal helpers.
|
||||||
*/
|
*/
|
||||||
|
|
@ -190,4 +222,16 @@ static inline void crypto_acomp_unlock_stream_bh(
|
||||||
{
|
{
|
||||||
spin_unlock_bh(&stream->lock);
|
spin_unlock_bh(&stream->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void acomp_walk_done_src(struct acomp_walk *walk, int used);
|
||||||
|
void acomp_walk_done_dst(struct acomp_walk *walk, int used);
|
||||||
|
int acomp_walk_next_src(struct acomp_walk *walk);
|
||||||
|
int acomp_walk_next_dst(struct acomp_walk *walk);
|
||||||
|
int acomp_walk_virt(struct acomp_walk *__restrict walk,
|
||||||
|
struct acomp_req *__restrict req);
|
||||||
|
|
||||||
|
static inline bool acomp_walk_more_src(const struct acomp_walk *walk, int cur)
|
||||||
|
{
|
||||||
|
return walk->slen != cur;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue