xref: /spdk/module/bdev/crypto/vbdev_crypto.c (revision c2e288a62534eb6f0def595f2745ca7e8d98555c)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2018 Intel Corporation.
3  *   All rights reserved.
4  *   Copyright (c) 2022, 2023 NVIDIA CORPORATION & AFFILIATES.
5  *   All rights reserved.
6  */
7 
8 #include "vbdev_crypto.h"
9 
10 #include "spdk_internal/assert.h"
11 #include "spdk/thread.h"
12 #include "spdk/bdev_module.h"
13 #include "spdk/likely.h"
14 
15 struct bdev_names {
16 	struct vbdev_crypto_opts	*opts;
17 	TAILQ_ENTRY(bdev_names)		link;
18 };
19 
20 /* List of crypto_bdev names and their base bdevs via configuration file. */
21 static TAILQ_HEAD(, bdev_names) g_bdev_names = TAILQ_HEAD_INITIALIZER(g_bdev_names);
22 
23 struct vbdev_crypto {
24 	struct spdk_bdev		*base_bdev;		/* the thing we're attaching to */
25 	struct spdk_bdev_desc		*base_desc;		/* its descriptor we get from open */
26 	struct spdk_bdev		crypto_bdev;		/* the crypto virtual bdev */
27 	struct vbdev_crypto_opts	*opts;			/* crypto options such as names and DEK */
28 	TAILQ_ENTRY(vbdev_crypto)	link;
29 	struct spdk_thread		*thread;		/* thread where base device is opened */
30 };
31 
32 /* List of virtual bdevs and associated info for each. We keep the device friendly name here even
33  * though its also in the device struct because we use it early on.
34  */
35 static TAILQ_HEAD(, vbdev_crypto) g_vbdev_crypto = TAILQ_HEAD_INITIALIZER(g_vbdev_crypto);
36 
37 /* The crypto vbdev channel struct. It is allocated and freed on my behalf by the io channel code.
38  * We store things in here that are needed on per thread basis like the base_channel for this thread.
39  */
40 struct crypto_io_channel {
41 	struct spdk_io_channel		*base_ch;	/* IO channel of base device */
42 	struct spdk_io_channel		*accel_channel;	/* Accel engine channel used for crypto ops */
43 	struct spdk_accel_crypto_key	*crypto_key;
44 };
45 
46 enum crypto_io_resubmit_state {
47 	CRYPTO_IO_NEW,		/* Resubmit IO from the scratch */
48 	CRYPTO_IO_DECRYPT_DONE,	/* Appended decrypt, need to read */
49 	CRYPTO_IO_ENCRYPT_DONE,	/* Need to write */
50 };
51 
52 /* This is the crypto per IO context that the bdev layer allocates for us opaquely and attaches to
53  * each IO for us.
54  */
55 struct crypto_bdev_io {
56 	struct crypto_io_channel *crypto_ch;		/* need to store for crypto completion handling */
57 	struct vbdev_crypto *crypto_bdev;		/* the crypto node struct associated with this IO */
58 	/* Used for the single contiguous buffer that serves as the crypto destination target for writes */
59 	uint64_t aux_num_blocks;			/* num of blocks for the contiguous buffer */
60 	uint64_t aux_offset_blocks;			/* block offset on media */
61 	void *aux_buf_raw;				/* raw buffer that the bdev layer gave us for write buffer */
62 	struct iovec aux_buf_iov;			/* iov representing aligned contig write buffer */
63 	struct spdk_memory_domain *aux_domain;		/* memory domain of the aux buf */
64 	void *aux_domain_ctx;				/* memory domain ctx of the aux buf */
65 	struct spdk_accel_sequence *seq;		/* sequence of accel operations */
66 
67 	/* for bdev_io_wait */
68 	struct spdk_bdev_io_wait_entry bdev_io_wait;
69 	enum crypto_io_resubmit_state resubmit_state;
70 };
71 
72 static void vbdev_crypto_queue_io(struct spdk_bdev_io *bdev_io,
73 				  enum crypto_io_resubmit_state state);
74 static void _complete_internal_io(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg);
75 static void vbdev_crypto_examine(struct spdk_bdev *bdev);
76 static int vbdev_crypto_claim(const char *bdev_name);
77 static void vbdev_crypto_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io);
78 
79 static void
80 crypto_io_fail(struct crypto_bdev_io *crypto_io)
81 {
82 	struct spdk_bdev_io *bdev_io = spdk_bdev_io_from_ctx(crypto_io);
83 
84 	/* This function can only be used to fail an IO that hasn't been sent to the base bdev,
85 	 * otherwise accel sequence might have already been executed/aborted. */
86 	spdk_accel_sequence_abort(crypto_io->seq);
87 	spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED);
88 }
89 
90 static void
91 crypto_write(struct crypto_io_channel *crypto_ch, struct spdk_bdev_io *bdev_io)
92 {
93 	struct vbdev_crypto *crypto_bdev = SPDK_CONTAINEROF(bdev_io->bdev, struct vbdev_crypto,
94 					   crypto_bdev);
95 	struct crypto_bdev_io *crypto_io = (struct crypto_bdev_io *)bdev_io->driver_ctx;
96 	struct spdk_bdev_ext_io_opts opts = {};
97 	int rc;
98 
99 	opts.size = sizeof(opts);
100 	opts.accel_sequence = crypto_io->seq;
101 	opts.memory_domain = crypto_io->aux_domain;
102 	opts.memory_domain_ctx = crypto_io->aux_domain_ctx;
103 
104 	/* Write the encrypted data. */
105 	rc = spdk_bdev_writev_blocks_ext(crypto_bdev->base_desc, crypto_ch->base_ch,
106 					 &crypto_io->aux_buf_iov, 1, crypto_io->aux_offset_blocks,
107 					 crypto_io->aux_num_blocks, _complete_internal_io,
108 					 bdev_io, &opts);
109 	if (spdk_unlikely(rc != 0)) {
110 		if (rc == -ENOMEM) {
111 			SPDK_DEBUGLOG(vbdev_crypto, "No memory, queue the IO.\n");
112 			vbdev_crypto_queue_io(bdev_io, CRYPTO_IO_ENCRYPT_DONE);
113 		} else {
114 			SPDK_ERRLOG("Failed to submit bdev_io!\n");
115 			crypto_io_fail(crypto_io);
116 		}
117 	}
118 }
119 
120 static void
121 crypto_encrypt_cb(void *cb_arg)
122 {
123 	struct crypto_bdev_io *crypto_io = cb_arg;
124 	struct crypto_io_channel *crypto_ch = crypto_io->crypto_ch;
125 
126 	spdk_accel_put_buf(crypto_ch->accel_channel, crypto_io->aux_buf_raw,
127 			   crypto_io->aux_domain, crypto_io->aux_domain_ctx);
128 }
129 
130 /* We're either encrypting on the way down or decrypting on the way back. */
131 static void
132 crypto_encrypt(struct crypto_io_channel *crypto_ch, struct spdk_bdev_io *bdev_io)
133 {
134 	struct crypto_bdev_io *crypto_io = (struct crypto_bdev_io *)bdev_io->driver_ctx;
135 	uint32_t crypto_len = crypto_io->crypto_bdev->crypto_bdev.blocklen;
136 	uint64_t total_length;
137 	uint64_t alignment;
138 	void *aux_buf = crypto_io->aux_buf_raw;
139 	int rc;
140 
141 	/* For encryption, we need to prepare a single contiguous buffer as the encryption
142 	 * destination, we'll then pass that along for the write after encryption is done.
143 	 * This is done to avoiding encrypting the provided write buffer which may be
144 	 * undesirable in some use cases.
145 	 */
146 	total_length = bdev_io->u.bdev.num_blocks * crypto_len;
147 	alignment = spdk_bdev_get_buf_align(&crypto_io->crypto_bdev->crypto_bdev);
148 	crypto_io->aux_buf_iov.iov_len = total_length;
149 	crypto_io->aux_buf_iov.iov_base  = (void *)(((uintptr_t)aux_buf + (alignment - 1)) & ~
150 					   (alignment - 1));
151 	crypto_io->aux_offset_blocks = bdev_io->u.bdev.offset_blocks;
152 	crypto_io->aux_num_blocks = bdev_io->u.bdev.num_blocks;
153 
154 	rc = spdk_accel_append_encrypt(&crypto_io->seq, crypto_ch->accel_channel,
155 				       crypto_ch->crypto_key, &crypto_io->aux_buf_iov, 1,
156 				       crypto_io->aux_domain, crypto_io->aux_domain_ctx,
157 				       bdev_io->u.bdev.iovs, bdev_io->u.bdev.iovcnt,
158 				       bdev_io->u.bdev.memory_domain,
159 				       bdev_io->u.bdev.memory_domain_ctx,
160 				       bdev_io->u.bdev.offset_blocks, crypto_len, 0,
161 				       crypto_encrypt_cb, crypto_io);
162 	if (spdk_unlikely(rc != 0)) {
163 		spdk_accel_put_buf(crypto_ch->accel_channel, crypto_io->aux_buf_raw,
164 				   crypto_io->aux_domain, crypto_io->aux_domain_ctx);
165 		if (rc == -ENOMEM) {
166 			SPDK_DEBUGLOG(vbdev_crypto, "No memory, queue the IO.\n");
167 			vbdev_crypto_queue_io(bdev_io, CRYPTO_IO_NEW);
168 		} else {
169 			SPDK_ERRLOG("Failed to submit bdev_io!\n");
170 			crypto_io_fail(crypto_io);
171 		}
172 
173 		return;
174 	}
175 
176 	crypto_write(crypto_ch, bdev_io);
177 }
178 
179 static void
180 _complete_internal_io(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
181 {
182 	struct spdk_bdev_io *orig_io = cb_arg;
183 	int status = success ? SPDK_BDEV_IO_STATUS_SUCCESS : SPDK_BDEV_IO_STATUS_FAILED;
184 
185 	spdk_bdev_io_complete(orig_io, status);
186 	spdk_bdev_free_io(bdev_io);
187 }
188 
189 static void crypto_read(struct crypto_io_channel *crypto_ch, struct spdk_bdev_io *bdev_io);
190 
191 static void
192 vbdev_crypto_resubmit_io(void *arg)
193 {
194 	struct spdk_bdev_io *bdev_io = (struct spdk_bdev_io *)arg;
195 	struct crypto_bdev_io *crypto_io = (struct crypto_bdev_io *)bdev_io->driver_ctx;
196 	struct spdk_io_channel *ch;
197 
198 	switch (crypto_io->resubmit_state) {
199 	case CRYPTO_IO_NEW:
200 		assert(crypto_io->crypto_ch);
201 		ch = spdk_io_channel_from_ctx(crypto_io->crypto_ch);
202 		vbdev_crypto_submit_request(ch, bdev_io);
203 		break;
204 	case CRYPTO_IO_ENCRYPT_DONE:
205 		crypto_write(crypto_io->crypto_ch, bdev_io);
206 		break;
207 	case CRYPTO_IO_DECRYPT_DONE:
208 		crypto_read(crypto_io->crypto_ch, bdev_io);
209 		break;
210 	default:
211 		SPDK_UNREACHABLE();
212 	}
213 }
214 
215 static void
216 vbdev_crypto_queue_io(struct spdk_bdev_io *bdev_io, enum crypto_io_resubmit_state state)
217 {
218 	struct crypto_bdev_io *crypto_io = (struct crypto_bdev_io *)bdev_io->driver_ctx;
219 	int rc;
220 
221 	crypto_io->bdev_io_wait.bdev = bdev_io->bdev;
222 	crypto_io->bdev_io_wait.cb_fn = vbdev_crypto_resubmit_io;
223 	crypto_io->bdev_io_wait.cb_arg = bdev_io;
224 	crypto_io->resubmit_state = state;
225 
226 	/* TODO: We shouldn't use spdk_bdev_queue_io_wait() for queueing IOs due to receiving ENOMEM
227 	 * from anything other than one of the bdev functions (e.g. accel).  We should have a
228 	 * different mechanism for handling such requests. */
229 	rc = spdk_bdev_queue_io_wait(bdev_io->bdev, crypto_io->crypto_ch->base_ch,
230 				     &crypto_io->bdev_io_wait);
231 	if (rc != 0) {
232 		SPDK_ERRLOG("Queue io failed in vbdev_crypto_queue_io, rc=%d.\n", rc);
233 		crypto_io_fail(crypto_io);
234 	}
235 }
236 
237 static void
238 crypto_read(struct crypto_io_channel *crypto_ch, struct spdk_bdev_io *bdev_io)
239 {
240 	struct crypto_bdev_io *crypto_io = (struct crypto_bdev_io *)bdev_io->driver_ctx;
241 	struct vbdev_crypto *crypto_bdev = SPDK_CONTAINEROF(bdev_io->bdev, struct vbdev_crypto,
242 					   crypto_bdev);
243 	struct spdk_bdev_ext_io_opts opts = {};
244 	int rc;
245 
246 	opts.size = sizeof(opts);
247 	opts.accel_sequence = crypto_io->seq;
248 	opts.memory_domain = bdev_io->u.bdev.memory_domain;
249 	opts.memory_domain_ctx = bdev_io->u.bdev.memory_domain_ctx;
250 
251 	rc = spdk_bdev_readv_blocks_ext(crypto_bdev->base_desc, crypto_ch->base_ch,
252 					bdev_io->u.bdev.iovs, bdev_io->u.bdev.iovcnt,
253 					bdev_io->u.bdev.offset_blocks, bdev_io->u.bdev.num_blocks,
254 					_complete_internal_io, bdev_io, &opts);
255 	if (rc != 0) {
256 		if (rc == -ENOMEM) {
257 			SPDK_DEBUGLOG(vbdev_crypto, "No memory, queue the IO.\n");
258 			vbdev_crypto_queue_io(bdev_io, CRYPTO_IO_DECRYPT_DONE);
259 		} else {
260 			SPDK_ERRLOG("Failed to submit bdev_io!\n");
261 			crypto_io_fail(crypto_io);
262 		}
263 	}
264 }
265 
266 /* Callback for getting a buf from the bdev pool in the event that the caller passed
267  * in NULL, we need to own the buffer so it doesn't get freed by another vbdev module
268  * beneath us before we're done with it.
269  */
270 static void
271 crypto_read_get_buf_cb(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io,
272 		       bool success)
273 {
274 	struct crypto_io_channel *crypto_ch = spdk_io_channel_get_ctx(ch);
275 	struct crypto_bdev_io *crypto_io = (struct crypto_bdev_io *)bdev_io->driver_ctx;
276 	uint32_t blocklen = crypto_io->crypto_bdev->crypto_bdev.blocklen;
277 	int rc;
278 
279 	if (!success) {
280 		crypto_io_fail(crypto_io);
281 		return;
282 	}
283 
284 	rc = spdk_accel_append_decrypt(&crypto_io->seq, crypto_ch->accel_channel,
285 				       crypto_ch->crypto_key,
286 				       bdev_io->u.bdev.iovs, bdev_io->u.bdev.iovcnt,
287 				       bdev_io->u.bdev.memory_domain,
288 				       bdev_io->u.bdev.memory_domain_ctx,
289 				       bdev_io->u.bdev.iovs, bdev_io->u.bdev.iovcnt,
290 				       bdev_io->u.bdev.memory_domain,
291 				       bdev_io->u.bdev.memory_domain_ctx,
292 				       bdev_io->u.bdev.offset_blocks, blocklen, 0,
293 				       NULL, NULL);
294 	if (rc != 0) {
295 		if (rc == -ENOMEM) {
296 			SPDK_DEBUGLOG(vbdev_crypto, "No memory, queue the IO.\n");
297 			vbdev_crypto_queue_io(bdev_io, CRYPTO_IO_NEW);
298 		} else {
299 			SPDK_ERRLOG("Failed to submit bdev_io!\n");
300 			crypto_io_fail(crypto_io);
301 		}
302 
303 		return;
304 	}
305 
306 	crypto_read(crypto_ch, bdev_io);
307 }
308 
309 /* Called when someone submits IO to this crypto vbdev. For IO's not relevant to crypto,
310  * we're simply passing it on here via SPDK IO calls which in turn allocate another bdev IO
311  * and call our cpl callback provided below along with the original bdev_io so that we can
312  * complete it once this IO completes. For crypto operations, we'll either encrypt it first
313  * (writes) then call back into bdev to submit it or we'll submit a read and then catch it
314  * on the way back for decryption.
315  */
316 static void
317 vbdev_crypto_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io)
318 {
319 	struct vbdev_crypto *crypto_bdev = SPDK_CONTAINEROF(bdev_io->bdev, struct vbdev_crypto,
320 					   crypto_bdev);
321 	struct crypto_io_channel *crypto_ch = spdk_io_channel_get_ctx(ch);
322 	struct crypto_bdev_io *crypto_io = (struct crypto_bdev_io *)bdev_io->driver_ctx;
323 	int rc = 0;
324 
325 	memset(crypto_io, 0, sizeof(struct crypto_bdev_io));
326 	crypto_io->crypto_bdev = crypto_bdev;
327 	crypto_io->crypto_ch = crypto_ch;
328 	crypto_io->seq = bdev_io->u.bdev.accel_sequence;
329 
330 	switch (bdev_io->type) {
331 	case SPDK_BDEV_IO_TYPE_READ:
332 		spdk_bdev_io_get_buf(bdev_io, crypto_read_get_buf_cb,
333 				     bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen);
334 		break;
335 	case SPDK_BDEV_IO_TYPE_WRITE:
336 		/* For encryption we don't want to encrypt the data in place as the host isn't
337 		 * expecting us to mangle its data buffers so we need to encrypt into the aux accel
338 		 * buffer, then we can use that as the source for the disk data transfer.
339 		 */
340 		rc = spdk_accel_get_buf(crypto_ch->accel_channel,
341 					bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen,
342 					&crypto_io->aux_buf_raw, &crypto_io->aux_domain,
343 					&crypto_io->aux_domain_ctx);
344 		if (rc == 0) {
345 			crypto_encrypt(crypto_ch, bdev_io);
346 		}
347 		break;
348 	case SPDK_BDEV_IO_TYPE_UNMAP:
349 		rc = spdk_bdev_unmap_blocks(crypto_bdev->base_desc, crypto_ch->base_ch,
350 					    bdev_io->u.bdev.offset_blocks,
351 					    bdev_io->u.bdev.num_blocks,
352 					    _complete_internal_io, bdev_io);
353 		break;
354 	case SPDK_BDEV_IO_TYPE_FLUSH:
355 		rc = spdk_bdev_flush_blocks(crypto_bdev->base_desc, crypto_ch->base_ch,
356 					    bdev_io->u.bdev.offset_blocks,
357 					    bdev_io->u.bdev.num_blocks,
358 					    _complete_internal_io, bdev_io);
359 		break;
360 	case SPDK_BDEV_IO_TYPE_RESET:
361 		rc = spdk_bdev_reset(crypto_bdev->base_desc, crypto_ch->base_ch,
362 				     _complete_internal_io, bdev_io);
363 		break;
364 	case SPDK_BDEV_IO_TYPE_WRITE_ZEROES:
365 	default:
366 		SPDK_ERRLOG("crypto: unknown I/O type %d\n", bdev_io->type);
367 		rc = -EINVAL;
368 		break;
369 	}
370 
371 	if (rc != 0) {
372 		if (rc == -ENOMEM) {
373 			SPDK_DEBUGLOG(vbdev_crypto, "No memory, queue the IO.\n");
374 			vbdev_crypto_queue_io(bdev_io, CRYPTO_IO_NEW);
375 		} else {
376 			SPDK_ERRLOG("Failed to submit bdev_io!\n");
377 			crypto_io_fail(crypto_io);
378 		}
379 	}
380 }
381 
382 /* We'll just call the base bdev and let it answer except for WZ command which
383  * we always say we don't support so that the bdev layer will actually send us
384  * real writes that we can encrypt.
385  */
386 static bool
387 vbdev_crypto_io_type_supported(void *ctx, enum spdk_bdev_io_type io_type)
388 {
389 	struct vbdev_crypto *crypto_bdev = (struct vbdev_crypto *)ctx;
390 
391 	switch (io_type) {
392 	case SPDK_BDEV_IO_TYPE_WRITE:
393 	case SPDK_BDEV_IO_TYPE_UNMAP:
394 	case SPDK_BDEV_IO_TYPE_RESET:
395 	case SPDK_BDEV_IO_TYPE_READ:
396 	case SPDK_BDEV_IO_TYPE_FLUSH:
397 		return spdk_bdev_io_type_supported(crypto_bdev->base_bdev, io_type);
398 	case SPDK_BDEV_IO_TYPE_WRITE_ZEROES:
399 	/* Force the bdev layer to issue actual writes of zeroes so we can
400 	 * encrypt them as regular writes.
401 	 */
402 	default:
403 		return false;
404 	}
405 }
406 
407 /* Callback for unregistering the IO device. */
408 static void
409 _device_unregister_cb(void *io_device)
410 {
411 	struct vbdev_crypto *crypto_bdev = io_device;
412 
413 	/* Done with this crypto_bdev. */
414 	crypto_bdev->opts = NULL;
415 
416 	spdk_bdev_destruct_done(&crypto_bdev->crypto_bdev, 0);
417 	free(crypto_bdev->crypto_bdev.name);
418 	free(crypto_bdev);
419 }
420 
421 /* Wrapper for the bdev close operation. */
422 static void
423 _vbdev_crypto_destruct(void *ctx)
424 {
425 	struct spdk_bdev_desc *desc = ctx;
426 
427 	spdk_bdev_close(desc);
428 }
429 
430 /* Called after we've unregistered following a hot remove callback.
431  * Our finish entry point will be called next.
432  */
433 static int
434 vbdev_crypto_destruct(void *ctx)
435 {
436 	struct vbdev_crypto *crypto_bdev = (struct vbdev_crypto *)ctx;
437 
438 	/* Remove this device from the internal list */
439 	TAILQ_REMOVE(&g_vbdev_crypto, crypto_bdev, link);
440 
441 	/* Unclaim the underlying bdev. */
442 	spdk_bdev_module_release_bdev(crypto_bdev->base_bdev);
443 
444 	/* Close the underlying bdev on its same opened thread. */
445 	if (crypto_bdev->thread && crypto_bdev->thread != spdk_get_thread()) {
446 		spdk_thread_send_msg(crypto_bdev->thread, _vbdev_crypto_destruct, crypto_bdev->base_desc);
447 	} else {
448 		spdk_bdev_close(crypto_bdev->base_desc);
449 	}
450 
451 	/* Unregister the io_device. */
452 	spdk_io_device_unregister(crypto_bdev, _device_unregister_cb);
453 
454 	return 1;
455 }
456 
457 /* We supplied this as an entry point for upper layers who want to communicate to this
458  * bdev.  This is how they get a channel. We are passed the same context we provided when
459  * we created our crypto vbdev in examine() which, for this bdev, is the address of one of
460  * our context nodes. From here we'll ask the SPDK channel code to fill out our channel
461  * struct and we'll keep it in our crypto node.
462  */
463 static struct spdk_io_channel *
464 vbdev_crypto_get_io_channel(void *ctx)
465 {
466 	struct vbdev_crypto *crypto_bdev = (struct vbdev_crypto *)ctx;
467 
468 	/* The IO channel code will allocate a channel for us which consists of
469 	 * the SPDK channel structure plus the size of our crypto_io_channel struct
470 	 * that we passed in when we registered our IO device. It will then call
471 	 * our channel create callback to populate any elements that we need to
472 	 * update.
473 	 */
474 	return spdk_get_io_channel(crypto_bdev);
475 }
476 
477 /* This is the output for bdev_get_bdevs() for this vbdev */
478 static int
479 vbdev_crypto_dump_info_json(void *ctx, struct spdk_json_write_ctx *w)
480 {
481 	struct vbdev_crypto *crypto_bdev = (struct vbdev_crypto *)ctx;
482 
483 	spdk_json_write_name(w, "crypto");
484 	spdk_json_write_object_begin(w);
485 	spdk_json_write_named_string(w, "base_bdev_name", spdk_bdev_get_name(crypto_bdev->base_bdev));
486 	spdk_json_write_named_string(w, "name", spdk_bdev_get_name(&crypto_bdev->crypto_bdev));
487 	spdk_json_write_named_string(w, "key_name", crypto_bdev->opts->key->param.key_name);
488 	spdk_json_write_object_end(w);
489 
490 	return 0;
491 }
492 
493 static int
494 vbdev_crypto_config_json(struct spdk_json_write_ctx *w)
495 {
496 	struct vbdev_crypto *crypto_bdev;
497 
498 	TAILQ_FOREACH(crypto_bdev, &g_vbdev_crypto, link) {
499 		spdk_json_write_object_begin(w);
500 		spdk_json_write_named_string(w, "method", "bdev_crypto_create");
501 		spdk_json_write_named_object_begin(w, "params");
502 		spdk_json_write_named_string(w, "base_bdev_name", spdk_bdev_get_name(crypto_bdev->base_bdev));
503 		spdk_json_write_named_string(w, "name", spdk_bdev_get_name(&crypto_bdev->crypto_bdev));
504 		spdk_json_write_named_string(w, "key_name", crypto_bdev->opts->key->param.key_name);
505 		spdk_json_write_object_end(w);
506 		spdk_json_write_object_end(w);
507 	}
508 	return 0;
509 }
510 
511 /* We provide this callback for the SPDK channel code to create a channel using
512  * the channel struct we provided in our module get_io_channel() entry point. Here
513  * we get and save off an underlying base channel of the device below us so that
514  * we can communicate with the base bdev on a per channel basis. We also register the
515  * poller used to complete crypto operations from the device.
516  */
517 static int
518 crypto_bdev_ch_create_cb(void *io_device, void *ctx_buf)
519 {
520 	struct crypto_io_channel *crypto_ch = ctx_buf;
521 	struct vbdev_crypto *crypto_bdev = io_device;
522 
523 	crypto_ch->base_ch = spdk_bdev_get_io_channel(crypto_bdev->base_desc);
524 	crypto_ch->accel_channel = spdk_accel_get_io_channel();
525 	crypto_ch->crypto_key = crypto_bdev->opts->key;
526 
527 	return 0;
528 }
529 
530 /* We provide this callback for the SPDK channel code to destroy a channel
531  * created with our create callback. We just need to undo anything we did
532  * when we created.
533  */
534 static void
535 crypto_bdev_ch_destroy_cb(void *io_device, void *ctx_buf)
536 {
537 	struct crypto_io_channel *crypto_ch = ctx_buf;
538 
539 	spdk_put_io_channel(crypto_ch->base_ch);
540 	spdk_put_io_channel(crypto_ch->accel_channel);
541 }
542 
543 /* Create the association from the bdev and vbdev name and insert
544  * on the global list. */
545 static int
546 vbdev_crypto_insert_name(struct vbdev_crypto_opts *opts, struct bdev_names **out)
547 {
548 	struct bdev_names *name;
549 
550 	assert(opts);
551 	assert(out);
552 
553 	TAILQ_FOREACH(name, &g_bdev_names, link) {
554 		if (strcmp(opts->vbdev_name, name->opts->vbdev_name) == 0) {
555 			SPDK_ERRLOG("Crypto bdev %s already exists\n", opts->vbdev_name);
556 			return -EEXIST;
557 		}
558 	}
559 
560 	name = calloc(1, sizeof(struct bdev_names));
561 	if (!name) {
562 		SPDK_ERRLOG("Failed to allocate memory for bdev_names.\n");
563 		return -ENOMEM;
564 	}
565 
566 	name->opts = opts;
567 	TAILQ_INSERT_TAIL(&g_bdev_names, name, link);
568 	*out = name;
569 
570 	return 0;
571 }
572 
573 void
574 free_crypto_opts(struct vbdev_crypto_opts *opts)
575 {
576 	free(opts->bdev_name);
577 	free(opts->vbdev_name);
578 	free(opts);
579 }
580 
581 static void
582 vbdev_crypto_delete_name(struct bdev_names *name)
583 {
584 	TAILQ_REMOVE(&g_bdev_names, name, link);
585 	if (name->opts) {
586 		if (name->opts->key_owner && name->opts->key) {
587 			spdk_accel_crypto_key_destroy(name->opts->key);
588 		}
589 		free_crypto_opts(name->opts);
590 		name->opts = NULL;
591 	}
592 	free(name);
593 }
594 
595 /* RPC entry point for crypto creation. */
596 int
597 create_crypto_disk(struct vbdev_crypto_opts *opts)
598 {
599 	struct bdev_names *name = NULL;
600 	int rc;
601 
602 	rc = vbdev_crypto_insert_name(opts, &name);
603 	if (rc) {
604 		return rc;
605 	}
606 
607 	rc = vbdev_crypto_claim(opts->bdev_name);
608 	if (rc == -ENODEV) {
609 		SPDK_NOTICELOG("vbdev creation deferred pending base bdev arrival\n");
610 		rc = 0;
611 	}
612 
613 	if (rc) {
614 		assert(name != NULL);
615 		/* In case of error we let the caller function to deallocate @opts
616 		 * since it is its responsibility. Setting name->opts = NULL let's
617 		 * vbdev_crypto_delete_name() know it does not have to do anything
618 		 * about @opts.
619 		 */
620 		name->opts = NULL;
621 		vbdev_crypto_delete_name(name);
622 	}
623 	return rc;
624 }
625 
626 /* Called at driver init time, parses config file to prepare for examine calls,
627  * also fully initializes the crypto drivers.
628  */
629 static int
630 vbdev_crypto_init(void)
631 {
632 	return 0;
633 }
634 
635 /* Called when the entire module is being torn down. */
636 static void
637 vbdev_crypto_finish(void)
638 {
639 	struct bdev_names *name;
640 
641 	while ((name = TAILQ_FIRST(&g_bdev_names))) {
642 		vbdev_crypto_delete_name(name);
643 	}
644 }
645 
646 /* During init we'll be asked how much memory we'd like passed to us
647  * in bev_io structures as context. Here's where we specify how
648  * much context we want per IO.
649  */
650 static int
651 vbdev_crypto_get_ctx_size(void)
652 {
653 	return sizeof(struct crypto_bdev_io);
654 }
655 
656 static void
657 vbdev_crypto_base_bdev_hotremove_cb(struct spdk_bdev *bdev_find)
658 {
659 	struct vbdev_crypto *crypto_bdev, *tmp;
660 
661 	TAILQ_FOREACH_SAFE(crypto_bdev, &g_vbdev_crypto, link, tmp) {
662 		if (bdev_find == crypto_bdev->base_bdev) {
663 			spdk_bdev_unregister(&crypto_bdev->crypto_bdev, NULL, NULL);
664 		}
665 	}
666 }
667 
668 /* Called when the underlying base bdev triggers asynchronous event such as bdev removal. */
669 static void
670 vbdev_crypto_base_bdev_event_cb(enum spdk_bdev_event_type type, struct spdk_bdev *bdev,
671 				void *event_ctx)
672 {
673 	switch (type) {
674 	case SPDK_BDEV_EVENT_REMOVE:
675 		vbdev_crypto_base_bdev_hotremove_cb(bdev);
676 		break;
677 	default:
678 		SPDK_NOTICELOG("Unsupported bdev event: type %d\n", type);
679 		break;
680 	}
681 }
682 
683 static int
684 vbdev_crypto_get_memory_domains(void *ctx, struct spdk_memory_domain **domains, int array_size)
685 {
686 	struct vbdev_crypto *crypto_bdev = ctx;
687 	int num_domains;
688 
689 	/* Report base bdev's memory domains plus accel memory domain */
690 	num_domains = spdk_bdev_get_memory_domains(crypto_bdev->base_bdev, domains, array_size);
691 	if (domains != NULL && num_domains < array_size) {
692 		domains[num_domains] = spdk_accel_get_memory_domain();
693 	}
694 
695 	return num_domains + 1;
696 }
697 
698 static bool
699 vbdev_crypto_sequence_supported(void *ctx, enum spdk_bdev_io_type type)
700 {
701 	switch (type) {
702 	case SPDK_BDEV_IO_TYPE_READ:
703 	case SPDK_BDEV_IO_TYPE_WRITE:
704 		return true;
705 	default:
706 		return false;
707 	}
708 }
709 
710 /* When we register our bdev this is how we specify our entry points. */
711 static const struct spdk_bdev_fn_table vbdev_crypto_fn_table = {
712 	.destruct			= vbdev_crypto_destruct,
713 	.submit_request			= vbdev_crypto_submit_request,
714 	.io_type_supported		= vbdev_crypto_io_type_supported,
715 	.get_io_channel			= vbdev_crypto_get_io_channel,
716 	.dump_info_json			= vbdev_crypto_dump_info_json,
717 	.get_memory_domains		= vbdev_crypto_get_memory_domains,
718 	.accel_sequence_supported	= vbdev_crypto_sequence_supported,
719 };
720 
721 static struct spdk_bdev_module crypto_if = {
722 	.name = "crypto",
723 	.module_init = vbdev_crypto_init,
724 	.get_ctx_size = vbdev_crypto_get_ctx_size,
725 	.examine_config = vbdev_crypto_examine,
726 	.module_fini = vbdev_crypto_finish,
727 	.config_json = vbdev_crypto_config_json
728 };
729 
730 SPDK_BDEV_MODULE_REGISTER(crypto, &crypto_if)
731 
732 static int
733 vbdev_crypto_claim(const char *bdev_name)
734 {
735 	struct bdev_names *name;
736 	struct vbdev_crypto *vbdev;
737 	struct spdk_bdev *bdev;
738 	struct spdk_iobuf_opts iobuf_opts;
739 	int rc = 0;
740 
741 	/* Limit the max IO size by some reasonable value. Since in write operation we use aux buffer,
742 	 * let's set the limit to the large_bufsize value */
743 	spdk_iobuf_get_opts(&iobuf_opts);
744 
745 	/* Check our list of names from config versus this bdev and if
746 	 * there's a match, create the crypto_bdev & bdev accordingly.
747 	 */
748 	TAILQ_FOREACH(name, &g_bdev_names, link) {
749 		if (strcmp(name->opts->bdev_name, bdev_name) != 0) {
750 			continue;
751 		}
752 		SPDK_DEBUGLOG(vbdev_crypto, "Match on %s\n", bdev_name);
753 
754 		vbdev = calloc(1, sizeof(struct vbdev_crypto));
755 		if (!vbdev) {
756 			SPDK_ERRLOG("Failed to allocate memory for crypto_bdev.\n");
757 			return -ENOMEM;
758 		}
759 		vbdev->crypto_bdev.product_name = "crypto";
760 
761 		vbdev->crypto_bdev.name = strdup(name->opts->vbdev_name);
762 		if (!vbdev->crypto_bdev.name) {
763 			SPDK_ERRLOG("Failed to allocate memory for crypto_bdev name.\n");
764 			rc = -ENOMEM;
765 			goto error_bdev_name;
766 		}
767 
768 		rc = spdk_bdev_open_ext(bdev_name, true, vbdev_crypto_base_bdev_event_cb,
769 					NULL, &vbdev->base_desc);
770 		if (rc) {
771 			if (rc != -ENODEV) {
772 				SPDK_ERRLOG("Failed to open bdev %s: error %d\n", bdev_name, rc);
773 			}
774 			goto error_open;
775 		}
776 
777 		bdev = spdk_bdev_desc_get_bdev(vbdev->base_desc);
778 		vbdev->base_bdev = bdev;
779 
780 		vbdev->crypto_bdev.write_cache = bdev->write_cache;
781 		if (bdev->optimal_io_boundary > 0) {
782 			vbdev->crypto_bdev.optimal_io_boundary =
783 				spdk_min((iobuf_opts.large_bufsize / bdev->blocklen), bdev->optimal_io_boundary);
784 		} else {
785 			vbdev->crypto_bdev.optimal_io_boundary = (iobuf_opts.large_bufsize / bdev->blocklen);
786 		}
787 		vbdev->crypto_bdev.split_on_optimal_io_boundary = true;
788 		if (bdev->required_alignment > 0) {
789 			vbdev->crypto_bdev.required_alignment = bdev->required_alignment;
790 		} else {
791 			/* Some accel modules may not support SGL input or output, if this module works with physical
792 			 * addresses, unaligned buffer may cross huge page boundary which leads to scattered payload.
793 			 * To avoid such cases, set required_alignment to the block size */
794 			vbdev->crypto_bdev.required_alignment = spdk_u32log2(bdev->blocklen);
795 		}
796 		vbdev->crypto_bdev.blocklen = bdev->blocklen;
797 		vbdev->crypto_bdev.blockcnt = bdev->blockcnt;
798 
799 		/* This is the context that is passed to us when the bdev
800 		 * layer calls in so we'll save our crypto_bdev node here.
801 		 */
802 		vbdev->crypto_bdev.ctxt = vbdev;
803 		vbdev->crypto_bdev.fn_table = &vbdev_crypto_fn_table;
804 		vbdev->crypto_bdev.module = &crypto_if;
805 
806 		/* Assign crypto opts from the name. The pointer is valid up to the point
807 		 * the module is unloaded and all names removed from the list. */
808 		vbdev->opts = name->opts;
809 
810 		TAILQ_INSERT_TAIL(&g_vbdev_crypto, vbdev, link);
811 
812 		spdk_io_device_register(vbdev, crypto_bdev_ch_create_cb, crypto_bdev_ch_destroy_cb,
813 					sizeof(struct crypto_io_channel), vbdev->crypto_bdev.name);
814 
815 		/* Save the thread where the base device is opened */
816 		vbdev->thread = spdk_get_thread();
817 
818 		rc = spdk_bdev_module_claim_bdev(bdev, vbdev->base_desc, vbdev->crypto_bdev.module);
819 		if (rc) {
820 			SPDK_ERRLOG("Failed to claim bdev %s\n", spdk_bdev_get_name(bdev));
821 			goto error_claim;
822 		}
823 
824 		rc = spdk_bdev_register(&vbdev->crypto_bdev);
825 		if (rc < 0) {
826 			SPDK_ERRLOG("Failed to register vbdev: error %d\n", rc);
827 			rc = -EINVAL;
828 			goto error_bdev_register;
829 		}
830 		SPDK_DEBUGLOG(vbdev_crypto, "Registered io_device and virtual bdev for: %s\n",
831 			      vbdev->opts->vbdev_name);
832 		break;
833 	}
834 
835 	return rc;
836 
837 	/* Error cleanup paths. */
838 error_bdev_register:
839 	spdk_bdev_module_release_bdev(vbdev->base_bdev);
840 error_claim:
841 	TAILQ_REMOVE(&g_vbdev_crypto, vbdev, link);
842 	spdk_io_device_unregister(vbdev, NULL);
843 	spdk_bdev_close(vbdev->base_desc);
844 error_open:
845 	free(vbdev->crypto_bdev.name);
846 error_bdev_name:
847 	free(vbdev);
848 
849 	return rc;
850 }
851 
852 struct crypto_delete_disk_ctx {
853 	spdk_delete_crypto_complete cb_fn;
854 	void *cb_arg;
855 	char *bdev_name;
856 };
857 
858 static void
859 delete_crypto_disk_bdev_name(void *ctx, int rc)
860 {
861 	struct bdev_names *name;
862 	struct crypto_delete_disk_ctx *disk_ctx = ctx;
863 
864 	/* Remove the association (vbdev, bdev) from g_bdev_names. This is required so that the
865 	 * vbdev does not get re-created if the same bdev is constructed at some other time,
866 	 * unless the underlying bdev was hot-removed. */
867 	TAILQ_FOREACH(name, &g_bdev_names, link) {
868 		if (strcmp(name->opts->vbdev_name, disk_ctx->bdev_name) == 0) {
869 			vbdev_crypto_delete_name(name);
870 			break;
871 		}
872 	}
873 
874 	disk_ctx->cb_fn(disk_ctx->cb_arg, rc);
875 
876 	free(disk_ctx->bdev_name);
877 	free(disk_ctx);
878 }
879 
880 /* RPC entry for deleting a crypto vbdev. */
881 void
882 delete_crypto_disk(const char *bdev_name, spdk_delete_crypto_complete cb_fn,
883 		   void *cb_arg)
884 {
885 	int rc;
886 	struct crypto_delete_disk_ctx *ctx;
887 
888 	ctx = calloc(1, sizeof(struct crypto_delete_disk_ctx));
889 	if (!ctx) {
890 		SPDK_ERRLOG("Failed to allocate delete crypto disk ctx\n");
891 		cb_fn(cb_arg, -ENOMEM);
892 		return;
893 	}
894 
895 	ctx->bdev_name = strdup(bdev_name);
896 	if (!ctx->bdev_name) {
897 		SPDK_ERRLOG("Failed to copy bdev_name\n");
898 		free(ctx);
899 		cb_fn(cb_arg, -ENOMEM);
900 		return;
901 	}
902 	ctx->cb_arg = cb_arg;
903 	ctx->cb_fn = cb_fn;
904 	/* Some cleanup happens in the destruct callback. */
905 	rc = spdk_bdev_unregister_by_name(bdev_name, &crypto_if, delete_crypto_disk_bdev_name, ctx);
906 	if (rc != 0) {
907 		SPDK_ERRLOG("Encountered an error during bdev unregistration\n");
908 		cb_fn(cb_arg, rc);
909 		free(ctx->bdev_name);
910 		free(ctx);
911 	}
912 }
913 
914 /* Because we specified this function in our crypto bdev function table when we
915  * registered our crypto bdev, we'll get this call anytime a new bdev shows up.
916  * Here we need to decide if we care about it and if so what to do. We
917  * parsed the config file at init so we check the new bdev against the list
918  * we built up at that time and if the user configured us to attach to this
919  * bdev, here's where we do it.
920  */
921 static void
922 vbdev_crypto_examine(struct spdk_bdev *bdev)
923 {
924 	vbdev_crypto_claim(spdk_bdev_get_name(bdev));
925 	spdk_bdev_module_examine_done(&crypto_if);
926 }
927 
928 SPDK_LOG_REGISTER_COMPONENT(vbdev_crypto)
929