acompress.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /*
  3. * Asynchronous Compression operations
  4. *
  5. * Copyright (c) 2016, Intel Corporation
  6. * Authors: Weigang Li <weigang.li@intel.com>
  7. * Giovanni Cabiddu <giovanni.cabiddu@intel.com>
  8. */
  9. #ifndef _CRYPTO_ACOMP_INT_H
  10. #define _CRYPTO_ACOMP_INT_H
  11. #include <crypto/acompress.h>
  12. #include <crypto/algapi.h>
  13. #include <crypto/scatterwalk.h>
  14. #include <linux/compiler_types.h>
  15. #include <linux/cpumask_types.h>
  16. #include <linux/spinlock.h>
  17. #include <linux/workqueue_types.h>
  18. #define ACOMP_FBREQ_ON_STACK(name, req) \
  19. char __##name##_req[sizeof(struct acomp_req) + \
  20. MAX_SYNC_COMP_REQSIZE] CRYPTO_MINALIGN_ATTR; \
  21. struct acomp_req *name = acomp_fbreq_on_stack_init( \
  22. __##name##_req, (req))
  23. /**
  24. * struct acomp_alg - asynchronous compression algorithm
  25. *
  26. * @compress: Function performs a compress operation
  27. * @decompress: Function performs a de-compress operation
  28. * @init: Initialize the cryptographic transformation object.
  29. * This function is used to initialize the cryptographic
  30. * transformation object. This function is called only once at
  31. * the instantiation time, right after the transformation context
  32. * was allocated. In case the cryptographic hardware has some
  33. * special requirements which need to be handled by software, this
  34. * function shall check for the precise requirement of the
  35. * transformation and put any software fallbacks in place.
  36. * @exit: Deinitialize the cryptographic transformation object. This is a
  37. * counterpart to @init, used to remove various changes set in
  38. * @init.
  39. *
  40. * @base: Common crypto API algorithm data structure
  41. * @calg: Cmonn algorithm data structure shared with scomp
  42. */
  43. struct acomp_alg {
  44. int (*compress)(struct acomp_req *req);
  45. int (*decompress)(struct acomp_req *req);
  46. int (*init)(struct crypto_acomp *tfm);
  47. void (*exit)(struct crypto_acomp *tfm);
  48. union {
  49. struct COMP_ALG_COMMON;
  50. struct comp_alg_common calg;
  51. };
  52. };
  53. struct crypto_acomp_stream {
  54. spinlock_t lock;
  55. void *ctx;
  56. };
  57. struct crypto_acomp_streams {
  58. /* These must come first because of struct scomp_alg. */
  59. void *(*alloc_ctx)(void);
  60. void (*free_ctx)(void *);
  61. struct crypto_acomp_stream __percpu *streams;
  62. struct work_struct stream_work;
  63. cpumask_t stream_want;
  64. };
  65. struct acomp_walk {
  66. union {
  67. /* Virtual address of the source. */
  68. struct {
  69. struct {
  70. const void *const addr;
  71. } virt;
  72. } src;
  73. /* Private field for the API, do not use. */
  74. struct scatter_walk in;
  75. };
  76. union {
  77. /* Virtual address of the destination. */
  78. struct {
  79. struct {
  80. void *const addr;
  81. } virt;
  82. } dst;
  83. /* Private field for the API, do not use. */
  84. struct scatter_walk out;
  85. };
  86. unsigned int slen;
  87. unsigned int dlen;
  88. int flags;
  89. };
  90. /*
  91. * Transform internal helpers.
  92. */
  93. static inline void *acomp_request_ctx(struct acomp_req *req)
  94. {
  95. return req->__ctx;
  96. }
  97. static inline void *acomp_tfm_ctx(struct crypto_acomp *tfm)
  98. {
  99. return tfm->base.__crt_ctx;
  100. }
  101. static inline void acomp_request_complete(struct acomp_req *req,
  102. int err)
  103. {
  104. crypto_request_complete(&req->base, err);
  105. }
  106. /**
  107. * crypto_register_acomp() -- Register asynchronous compression algorithm
  108. *
  109. * Function registers an implementation of an asynchronous
  110. * compression algorithm
  111. *
  112. * @alg: algorithm definition
  113. *
  114. * Return: zero on success; error code in case of error
  115. */
  116. int crypto_register_acomp(struct acomp_alg *alg);
  117. /**
  118. * crypto_unregister_acomp() -- Unregister asynchronous compression algorithm
  119. *
  120. * Function unregisters an implementation of an asynchronous
  121. * compression algorithm
  122. *
  123. * @alg: algorithm definition
  124. */
  125. void crypto_unregister_acomp(struct acomp_alg *alg);
  126. int crypto_register_acomps(struct acomp_alg *algs, int count);
  127. void crypto_unregister_acomps(struct acomp_alg *algs, int count);
  128. static inline bool acomp_request_issg(struct acomp_req *req)
  129. {
  130. return !(req->base.flags & (CRYPTO_ACOMP_REQ_SRC_VIRT |
  131. CRYPTO_ACOMP_REQ_DST_VIRT));
  132. }
  133. static inline bool acomp_request_src_isvirt(struct acomp_req *req)
  134. {
  135. return req->base.flags & CRYPTO_ACOMP_REQ_SRC_VIRT;
  136. }
  137. static inline bool acomp_request_dst_isvirt(struct acomp_req *req)
  138. {
  139. return req->base.flags & CRYPTO_ACOMP_REQ_DST_VIRT;
  140. }
  141. static inline bool acomp_request_isvirt(struct acomp_req *req)
  142. {
  143. return req->base.flags & (CRYPTO_ACOMP_REQ_SRC_VIRT |
  144. CRYPTO_ACOMP_REQ_DST_VIRT);
  145. }
  146. static inline bool acomp_request_src_isnondma(struct acomp_req *req)
  147. {
  148. return req->base.flags & CRYPTO_ACOMP_REQ_SRC_NONDMA;
  149. }
  150. static inline bool acomp_request_dst_isnondma(struct acomp_req *req)
  151. {
  152. return req->base.flags & CRYPTO_ACOMP_REQ_DST_NONDMA;
  153. }
  154. static inline bool acomp_request_isnondma(struct acomp_req *req)
  155. {
  156. return req->base.flags & (CRYPTO_ACOMP_REQ_SRC_NONDMA |
  157. CRYPTO_ACOMP_REQ_DST_NONDMA);
  158. }
  159. static inline bool crypto_acomp_req_virt(struct crypto_acomp *tfm)
  160. {
  161. return crypto_tfm_req_virt(&tfm->base);
  162. }
  163. void crypto_acomp_free_streams(struct crypto_acomp_streams *s);
  164. int crypto_acomp_alloc_streams(struct crypto_acomp_streams *s);
  165. #define crypto_acomp_lock_stream_bh(...) __acquire_ret(_crypto_acomp_lock_stream_bh(__VA_ARGS__), &__ret->lock);
  166. struct crypto_acomp_stream *_crypto_acomp_lock_stream_bh(
  167. struct crypto_acomp_streams *s) __acquires_ret;
  168. static inline void crypto_acomp_unlock_stream_bh(
  169. struct crypto_acomp_stream *stream) __releases(&stream->lock)
  170. {
  171. spin_unlock_bh(&stream->lock);
  172. }
  173. void acomp_walk_done_src(struct acomp_walk *walk, int used);
  174. void acomp_walk_done_dst(struct acomp_walk *walk, int used);
  175. int acomp_walk_next_src(struct acomp_walk *walk);
  176. int acomp_walk_next_dst(struct acomp_walk *walk);
  177. int acomp_walk_virt(struct acomp_walk *__restrict walk,
  178. struct acomp_req *__restrict req, bool atomic);
  179. static inline bool acomp_walk_more_src(const struct acomp_walk *walk, int cur)
  180. {
  181. return walk->slen != cur;
  182. }
  183. static inline u32 acomp_request_flags(struct acomp_req *req)
  184. {
  185. return crypto_request_flags(&req->base) & ~CRYPTO_ACOMP_REQ_PRIVATE;
  186. }
  187. static inline struct crypto_acomp *crypto_acomp_fb(struct crypto_acomp *tfm)
  188. {
  189. return __crypto_acomp_tfm(crypto_acomp_tfm(tfm)->fb);
  190. }
  191. static inline struct acomp_req *acomp_fbreq_on_stack_init(
  192. char *buf, struct acomp_req *old)
  193. {
  194. struct crypto_acomp *tfm = crypto_acomp_reqtfm(old);
  195. struct acomp_req *req = (void *)buf;
  196. crypto_stack_request_init(&req->base,
  197. crypto_acomp_tfm(crypto_acomp_fb(tfm)));
  198. acomp_request_set_callback(req, acomp_request_flags(old), NULL, NULL);
  199. req->base.flags &= ~CRYPTO_ACOMP_REQ_PRIVATE;
  200. req->base.flags |= old->base.flags & CRYPTO_ACOMP_REQ_PRIVATE;
  201. req->src = old->src;
  202. req->dst = old->dst;
  203. req->slen = old->slen;
  204. req->dlen = old->dlen;
  205. return req;
  206. }
  207. #endif