xref: /spdk/lib/vhost/vhost_scsi.c (revision 94a84ae98590bea46939eb1dcd7a9876bd393b54)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include "spdk/stdinc.h"
35 
36 #include <linux/virtio_scsi.h>
37 
38 #include "spdk/env.h"
39 #include "spdk/thread.h"
40 #include "spdk/scsi.h"
41 #include "spdk/scsi_spec.h"
42 #include "spdk/conf.h"
43 #include "spdk/event.h"
44 #include "spdk/util.h"
45 #include "spdk/likely.h"
46 
47 #include "spdk/vhost.h"
48 #include "vhost_internal.h"
49 
50 /* Features supported by SPDK VHOST lib. */
51 #define SPDK_VHOST_SCSI_FEATURES	(SPDK_VHOST_FEATURES | \
52 					(1ULL << VIRTIO_SCSI_F_INOUT) | \
53 					(1ULL << VIRTIO_SCSI_F_HOTPLUG) | \
54 					(1ULL << VIRTIO_SCSI_F_CHANGE ) | \
55 					(1ULL << VIRTIO_SCSI_F_T10_PI ))
56 
57 /* Features that are specified in VIRTIO SCSI but currently not supported:
58  * - Live migration not supported yet
59  * - T10 PI
60  */
61 #define SPDK_VHOST_SCSI_DISABLED_FEATURES	(SPDK_VHOST_DISABLED_FEATURES | \
62 						(1ULL << VIRTIO_SCSI_F_T10_PI ))
63 
64 #define MGMT_POLL_PERIOD_US (1000 * 5)
65 
66 #define VIRTIO_SCSI_CONTROLQ   0
67 #define VIRTIO_SCSI_EVENTQ   1
68 #define VIRTIO_SCSI_REQUESTQ   2
69 
70 enum spdk_scsi_dev_vhost_status {
71 	/* Target ID is empty. */
72 	VHOST_SCSI_DEV_EMPTY,
73 
74 	/* Target is still being added. */
75 	VHOST_SCSI_DEV_ADDING,
76 
77 	/* Target ID occupied. */
78 	VHOST_SCSI_DEV_PRESENT,
79 
80 	/* Target ID is occupied but removal is in progress. */
81 	VHOST_SCSI_DEV_REMOVING,
82 
83 	/* In session - device (SCSI target) seen but removed. */
84 	VHOST_SCSI_DEV_REMOVED,
85 };
86 
87 /** Context for a SCSI target in a vhost device */
88 struct spdk_scsi_dev_vhost_state {
89 	struct spdk_scsi_dev *dev;
90 	enum spdk_scsi_dev_vhost_status status;
91 	spdk_vhost_event_fn remove_cb;
92 	void *remove_ctx;
93 };
94 
95 struct spdk_vhost_scsi_dev {
96 	int ref;
97 	bool registered;
98 	struct spdk_vhost_dev vdev;
99 	struct spdk_scsi_dev_vhost_state scsi_dev_state[SPDK_VHOST_SCSI_CTRLR_MAX_DEVS];
100 };
101 
102 /** Context for a SCSI target in a vhost session */
103 struct spdk_scsi_dev_session_state {
104 	struct spdk_scsi_dev *dev;
105 	enum spdk_scsi_dev_vhost_status status;
106 };
107 
108 struct spdk_vhost_scsi_session {
109 	struct spdk_vhost_session vsession;
110 
111 	struct spdk_vhost_scsi_dev *svdev;
112 	/** Local copy of the device state */
113 	struct spdk_scsi_dev_session_state scsi_dev_state[SPDK_VHOST_SCSI_CTRLR_MAX_DEVS];
114 	struct spdk_poller *requestq_poller;
115 	struct spdk_poller *mgmt_poller;
116 	struct spdk_poller *stop_poller;
117 };
118 
119 struct spdk_vhost_scsi_task {
120 	struct spdk_scsi_task	scsi;
121 	struct iovec iovs[SPDK_VHOST_IOVS_MAX];
122 
123 	union {
124 		struct virtio_scsi_cmd_resp *resp;
125 		struct virtio_scsi_ctrl_tmf_resp *tmf_resp;
126 	};
127 
128 	struct spdk_vhost_scsi_session *svsession;
129 	struct spdk_scsi_dev *scsi_dev;
130 
131 	/** Number of bytes that were written. */
132 	uint32_t used_len;
133 
134 	int req_idx;
135 
136 	/* If set, the task is currently used for I/O processing. */
137 	bool used;
138 
139 	struct spdk_vhost_virtqueue *vq;
140 };
141 
142 static int vhost_scsi_start(struct spdk_vhost_session *vsession);
143 static int vhost_scsi_stop(struct spdk_vhost_session *vsession);
144 static void vhost_scsi_dump_info_json(struct spdk_vhost_dev *vdev,
145 				      struct spdk_json_write_ctx *w);
146 static void vhost_scsi_write_config_json(struct spdk_vhost_dev *vdev,
147 		struct spdk_json_write_ctx *w);
148 static int vhost_scsi_dev_remove(struct spdk_vhost_dev *vdev);
149 
150 const struct spdk_vhost_dev_backend spdk_vhost_scsi_device_backend = {
151 	.session_ctx_size = sizeof(struct spdk_vhost_scsi_session) - sizeof(struct spdk_vhost_session),
152 	.start_session =  vhost_scsi_start,
153 	.stop_session = vhost_scsi_stop,
154 	.dump_info_json = vhost_scsi_dump_info_json,
155 	.write_config_json = vhost_scsi_write_config_json,
156 	.remove_device = vhost_scsi_dev_remove,
157 };
158 
159 static void
160 vhost_scsi_task_put(struct spdk_vhost_scsi_task *task)
161 {
162 	spdk_scsi_task_put(&task->scsi);
163 }
164 
165 static void
166 vhost_scsi_task_free_cb(struct spdk_scsi_task *scsi_task)
167 {
168 	struct spdk_vhost_scsi_task *task = SPDK_CONTAINEROF(scsi_task, struct spdk_vhost_scsi_task, scsi);
169 	struct spdk_vhost_session *vsession = &task->svsession->vsession;
170 
171 	assert(vsession->task_cnt > 0);
172 	vsession->task_cnt--;
173 	task->used = false;
174 }
175 
176 static void
177 remove_scsi_tgt(struct spdk_vhost_scsi_dev *svdev,
178 		unsigned scsi_tgt_num)
179 {
180 	struct spdk_scsi_dev_vhost_state *state;
181 	struct spdk_scsi_dev *dev;
182 
183 	state = &svdev->scsi_dev_state[scsi_tgt_num];
184 	dev = state->dev;
185 	state->dev = NULL;
186 	assert(state->status == VHOST_SCSI_DEV_REMOVING);
187 	state->status = VHOST_SCSI_DEV_EMPTY;
188 	spdk_scsi_dev_destruct(dev, NULL, NULL);
189 	if (state->remove_cb) {
190 		state->remove_cb(&svdev->vdev, state->remove_ctx);
191 		state->remove_cb = NULL;
192 	}
193 	SPDK_INFOLOG(SPDK_LOG_VHOST, "%s: removed target 'Target %u'\n",
194 		     svdev->vdev.name, scsi_tgt_num);
195 
196 	if (--svdev->ref == 0 && svdev->registered == false) {
197 		free(svdev);
198 	}
199 }
200 
201 static void
202 vhost_scsi_dev_process_removed_cpl_cb(struct spdk_vhost_dev *vdev, void *ctx)
203 {
204 	unsigned scsi_tgt_num = (unsigned)(uintptr_t)ctx;
205 	struct spdk_vhost_scsi_dev *svdev = SPDK_CONTAINEROF(vdev,
206 					    struct spdk_vhost_scsi_dev, vdev);
207 
208 	/* all sessions have already detached the device */
209 	if (svdev->scsi_dev_state[scsi_tgt_num].status != VHOST_SCSI_DEV_REMOVING) {
210 		/* device was already removed in the meantime */
211 		return;
212 	}
213 
214 	remove_scsi_tgt(svdev, scsi_tgt_num);
215 }
216 
217 static int
218 vhost_scsi_session_process_removed(struct spdk_vhost_dev *vdev,
219 				   struct spdk_vhost_session *vsession, void *ctx)
220 {
221 	unsigned scsi_tgt_num = (unsigned)(uintptr_t)ctx;
222 	struct spdk_vhost_scsi_session *svsession = (struct spdk_vhost_scsi_session *)vsession;
223 	struct spdk_scsi_dev_session_state *state = &svsession->scsi_dev_state[scsi_tgt_num];
224 
225 	if (state->dev != NULL) {
226 		/* there's still a session that references this device,
227 		 * so abort our foreach chain here. We'll be called
228 		 * again from this session's management poller after it
229 		 * is removed in there
230 		 */
231 		return -1;
232 	}
233 
234 	return 0;
235 }
236 
237 static void
238 process_removed_devs(struct spdk_vhost_scsi_session *svsession)
239 {
240 	struct spdk_scsi_dev *dev;
241 	struct spdk_scsi_dev_session_state *state;
242 	int i;
243 
244 	for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; ++i) {
245 		state = &svsession->scsi_dev_state[i];
246 		dev = state->dev;
247 
248 		if (dev && state->status == VHOST_SCSI_DEV_REMOVING &&
249 		    !spdk_scsi_dev_has_pending_tasks(dev, NULL)) {
250 			/* detach the device from this session */
251 			spdk_scsi_dev_free_io_channels(dev);
252 			state->dev = NULL;
253 			state->status = VHOST_SCSI_DEV_REMOVED;
254 			/* try to detach it globally */
255 			spdk_vhost_lock();
256 			vhost_dev_foreach_session(&svsession->svdev->vdev,
257 						  vhost_scsi_session_process_removed,
258 						  vhost_scsi_dev_process_removed_cpl_cb,
259 						  (void *)(uintptr_t)i);
260 			spdk_vhost_unlock();
261 		}
262 	}
263 }
264 
265 static void
266 eventq_enqueue(struct spdk_vhost_scsi_session *svsession, unsigned scsi_dev_num,
267 	       uint32_t event, uint32_t reason)
268 {
269 	struct spdk_vhost_session *vsession = &svsession->vsession;
270 	struct spdk_vhost_virtqueue *vq;
271 	struct vring_desc *desc, *desc_table;
272 	struct virtio_scsi_event *desc_ev;
273 	uint32_t desc_table_size, req_size = 0;
274 	uint16_t req;
275 	int rc;
276 
277 	assert(scsi_dev_num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS);
278 	vq = &vsession->virtqueue[VIRTIO_SCSI_EVENTQ];
279 
280 	if (vq->vring.desc == NULL || vhost_vq_avail_ring_get(vq, &req, 1) != 1) {
281 		SPDK_ERRLOG("%s: failed to send virtio event (no avail ring entries?).\n",
282 			    vsession->name);
283 		return;
284 	}
285 
286 	rc = vhost_vq_get_desc(vsession, vq, req, &desc, &desc_table, &desc_table_size);
287 	if (rc != 0 || desc->len < sizeof(*desc_ev)) {
288 		SPDK_ERRLOG("%s: invalid eventq descriptor at index %"PRIu16".\n",
289 			    vsession->name, req);
290 		goto out;
291 	}
292 
293 	desc_ev = vhost_gpa_to_vva(vsession, desc->addr, sizeof(*desc_ev));
294 	if (desc_ev == NULL) {
295 		SPDK_ERRLOG("%s: eventq descriptor at index %"PRIu16" points "
296 			    "to unmapped guest memory address %p.\n",
297 			    vsession->name, req, (void *)(uintptr_t)desc->addr);
298 		goto out;
299 	}
300 
301 	desc_ev->event = event;
302 	desc_ev->lun[0] = 1;
303 	desc_ev->lun[1] = scsi_dev_num;
304 	/* virtio LUN id 0 can refer either to the entire device
305 	 * or actual LUN 0 (the only supported by vhost for now)
306 	 */
307 	desc_ev->lun[2] = 0 >> 8;
308 	desc_ev->lun[3] = 0 & 0xFF;
309 	/* virtio doesn't specify any strict format for LUN id (bytes 2 and 3)
310 	 * current implementation relies on linux kernel sources
311 	 */
312 	memset(&desc_ev->lun[4], 0, 4);
313 	desc_ev->reason = reason;
314 	req_size = sizeof(*desc_ev);
315 
316 out:
317 	vhost_vq_used_ring_enqueue(vsession, vq, req, req_size);
318 }
319 
320 static void
321 submit_completion(struct spdk_vhost_scsi_task *task)
322 {
323 	struct spdk_vhost_session *vsession = &task->svsession->vsession;
324 
325 	vhost_vq_used_ring_enqueue(vsession, task->vq, task->req_idx,
326 				   task->used_len);
327 	SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI, "Finished task (%p) req_idx=%d\n", task, task->req_idx);
328 
329 	vhost_scsi_task_put(task);
330 }
331 
332 static void
333 vhost_scsi_task_mgmt_cpl(struct spdk_scsi_task *scsi_task)
334 {
335 	struct spdk_vhost_scsi_task *task = SPDK_CONTAINEROF(scsi_task, struct spdk_vhost_scsi_task, scsi);
336 
337 	submit_completion(task);
338 }
339 
340 static void
341 vhost_scsi_task_cpl(struct spdk_scsi_task *scsi_task)
342 {
343 	struct spdk_vhost_scsi_task *task = SPDK_CONTAINEROF(scsi_task, struct spdk_vhost_scsi_task, scsi);
344 
345 	/* The SCSI task has completed.  Do final processing and then post
346 	   notification to the virtqueue's "used" ring.
347 	 */
348 	task->resp->status = task->scsi.status;
349 
350 	if (task->scsi.status != SPDK_SCSI_STATUS_GOOD) {
351 		memcpy(task->resp->sense, task->scsi.sense_data, task->scsi.sense_data_len);
352 		task->resp->sense_len = task->scsi.sense_data_len;
353 		SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI, "Task (%p) req_idx=%d failed - status=%u\n", task, task->req_idx,
354 			      task->scsi.status);
355 	}
356 	assert(task->scsi.transfer_len == task->scsi.length);
357 	task->resp->resid = task->scsi.length - task->scsi.data_transferred;
358 
359 	submit_completion(task);
360 }
361 
362 static void
363 task_submit(struct spdk_vhost_scsi_task *task)
364 {
365 	task->resp->response = VIRTIO_SCSI_S_OK;
366 	spdk_scsi_dev_queue_task(task->scsi_dev, &task->scsi);
367 }
368 
369 static void
370 mgmt_task_submit(struct spdk_vhost_scsi_task *task, enum spdk_scsi_task_func func)
371 {
372 	task->tmf_resp->response = VIRTIO_SCSI_S_OK;
373 	task->scsi.function = func;
374 	spdk_scsi_dev_queue_mgmt_task(task->scsi_dev, &task->scsi);
375 }
376 
377 static void
378 invalid_request(struct spdk_vhost_scsi_task *task)
379 {
380 	struct spdk_vhost_session *vsession = &task->svsession->vsession;
381 
382 	vhost_vq_used_ring_enqueue(vsession, task->vq, task->req_idx,
383 				   task->used_len);
384 	vhost_scsi_task_put(task);
385 
386 	SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI, "Invalid request (status=%" PRIu8")\n",
387 		      task->resp ? task->resp->response : -1);
388 }
389 
390 static int
391 vhost_scsi_task_init_target(struct spdk_vhost_scsi_task *task, const __u8 *lun)
392 {
393 	struct spdk_vhost_scsi_session *svsession = task->svsession;
394 	struct spdk_scsi_dev_session_state *state;
395 	uint16_t lun_id = (((uint16_t)lun[2] << 8) | lun[3]) & 0x3FFF;
396 
397 	SPDK_LOGDUMP(SPDK_LOG_VHOST_SCSI_QUEUE, "LUN", lun, 8);
398 
399 	/* First byte must be 1 and second is target */
400 	if (lun[0] != 1 || lun[1] >= SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
401 		return -1;
402 	}
403 
404 	state = &svsession->scsi_dev_state[lun[1]];
405 	task->scsi_dev = state->dev;
406 	if (state->dev == NULL || state->status != VHOST_SCSI_DEV_PRESENT) {
407 		/* If dev has been hotdetached, return 0 to allow sending
408 		 * additional hotremove event via sense codes.
409 		 */
410 		return state->status != VHOST_SCSI_DEV_EMPTY ? 0 : -1;
411 	}
412 
413 	task->scsi.target_port = spdk_scsi_dev_find_port_by_id(task->scsi_dev, 0);
414 	task->scsi.lun = spdk_scsi_dev_get_lun(state->dev, lun_id);
415 	return 0;
416 }
417 
418 static void
419 process_ctrl_request(struct spdk_vhost_scsi_task *task)
420 {
421 	struct spdk_vhost_session *vsession = &task->svsession->vsession;
422 	struct vring_desc *desc, *desc_table;
423 	struct virtio_scsi_ctrl_tmf_req *ctrl_req;
424 	struct virtio_scsi_ctrl_an_resp *an_resp;
425 	uint32_t desc_table_size, used_len = 0;
426 	int rc;
427 
428 	spdk_scsi_task_construct(&task->scsi, vhost_scsi_task_mgmt_cpl, vhost_scsi_task_free_cb);
429 	rc = vhost_vq_get_desc(vsession, task->vq, task->req_idx, &desc, &desc_table,
430 			       &desc_table_size);
431 	if (spdk_unlikely(rc != 0)) {
432 		SPDK_ERRLOG("%s: invalid controlq descriptor at index %d.\n",
433 			    vsession->name, task->req_idx);
434 		goto out;
435 	}
436 
437 	ctrl_req = vhost_gpa_to_vva(vsession, desc->addr, sizeof(*ctrl_req));
438 	if (ctrl_req == NULL) {
439 		SPDK_ERRLOG("%s: invalid task management request at index %d.\n",
440 			    vsession->name, task->req_idx);
441 		goto out;
442 	}
443 
444 	SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI_QUEUE,
445 		      "Processing controlq descriptor: desc %d/%p, desc_addr %p, len %d, flags %d, last_used_idx %d; kickfd %d; size %d\n",
446 		      task->req_idx, desc, (void *)desc->addr, desc->len, desc->flags, task->vq->last_used_idx,
447 		      task->vq->vring.kickfd, task->vq->vring.size);
448 	SPDK_LOGDUMP(SPDK_LOG_VHOST_SCSI_QUEUE, "Request descriptor", (uint8_t *)ctrl_req, desc->len);
449 
450 	vhost_scsi_task_init_target(task, ctrl_req->lun);
451 
452 	vhost_vring_desc_get_next(&desc, desc_table, desc_table_size);
453 	if (spdk_unlikely(desc == NULL)) {
454 		SPDK_ERRLOG("%s: no response descriptor for controlq request %d.\n",
455 			    vsession->name, task->req_idx);
456 		goto out;
457 	}
458 
459 	/* Process the TMF request */
460 	switch (ctrl_req->type) {
461 	case VIRTIO_SCSI_T_TMF:
462 		task->tmf_resp = vhost_gpa_to_vva(vsession, desc->addr, sizeof(*task->tmf_resp));
463 		if (spdk_unlikely(desc->len < sizeof(struct virtio_scsi_ctrl_tmf_resp) || task->tmf_resp == NULL)) {
464 			SPDK_ERRLOG("%s: TMF response descriptor at index %d points to invalid guest memory region\n",
465 				    vsession->name, task->req_idx);
466 			goto out;
467 		}
468 
469 		/* Check if we are processing a valid request */
470 		if (task->scsi_dev == NULL) {
471 			task->tmf_resp->response = VIRTIO_SCSI_S_BAD_TARGET;
472 			break;
473 		}
474 
475 		switch (ctrl_req->subtype) {
476 		case VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET:
477 			/* Handle LUN reset */
478 			SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI_QUEUE, "%s: LUN reset\n", vsession->name);
479 
480 			mgmt_task_submit(task, SPDK_SCSI_TASK_FUNC_LUN_RESET);
481 			return;
482 		default:
483 			task->tmf_resp->response = VIRTIO_SCSI_S_ABORTED;
484 			/* Unsupported command */
485 			SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI_QUEUE, "%s: unsupported TMF command %x\n",
486 				      vsession->name, ctrl_req->subtype);
487 			break;
488 		}
489 		break;
490 	case VIRTIO_SCSI_T_AN_QUERY:
491 	case VIRTIO_SCSI_T_AN_SUBSCRIBE: {
492 		an_resp = vhost_gpa_to_vva(vsession, desc->addr, sizeof(*an_resp));
493 		if (spdk_unlikely(desc->len < sizeof(struct virtio_scsi_ctrl_an_resp) || an_resp == NULL)) {
494 			SPDK_WARNLOG("%s: asynchronous response descriptor points to invalid guest memory region\n",
495 				     vsession->name);
496 			goto out;
497 		}
498 
499 		an_resp->response = VIRTIO_SCSI_S_ABORTED;
500 		break;
501 	}
502 	default:
503 		SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI_QUEUE, "%s: Unsupported control command %x\n",
504 			      vsession->name, ctrl_req->type);
505 		break;
506 	}
507 
508 	used_len = sizeof(struct virtio_scsi_ctrl_tmf_resp);
509 out:
510 	vhost_vq_used_ring_enqueue(vsession, task->vq, task->req_idx, used_len);
511 	vhost_scsi_task_put(task);
512 }
513 
514 /*
515  * Process task's descriptor chain and setup data related fields.
516  * Return
517  *   -1 if request is invalid and must be aborted,
518  *    0 if all data are set.
519  */
520 static int
521 task_data_setup(struct spdk_vhost_scsi_task *task,
522 		struct virtio_scsi_cmd_req **req)
523 {
524 	struct spdk_vhost_session *vsession = &task->svsession->vsession;
525 	struct vring_desc *desc, *desc_table;
526 	struct iovec *iovs = task->iovs;
527 	uint16_t iovcnt = 0;
528 	uint32_t desc_table_len, len = 0;
529 	int rc;
530 
531 	spdk_scsi_task_construct(&task->scsi, vhost_scsi_task_cpl, vhost_scsi_task_free_cb);
532 
533 	rc = vhost_vq_get_desc(vsession, task->vq, task->req_idx, &desc, &desc_table, &desc_table_len);
534 	/* First descriptor must be readable */
535 	if (spdk_unlikely(rc != 0  || vhost_vring_desc_is_wr(desc) ||
536 			  desc->len < sizeof(struct virtio_scsi_cmd_req))) {
537 		SPDK_WARNLOG("%s: invalid first request descriptor at index %"PRIu16".\n",
538 			     vsession->name, task->req_idx);
539 		goto invalid_task;
540 	}
541 
542 	*req = vhost_gpa_to_vva(vsession, desc->addr, sizeof(**req));
543 	if (spdk_unlikely(*req == NULL)) {
544 		SPDK_WARNLOG("%s: request descriptor at index %d points to invalid guest memory region\n",
545 			     vsession->name, task->req_idx);
546 		goto invalid_task;
547 	}
548 
549 	/* Each request must have at least 2 descriptors (e.g. request and response) */
550 	vhost_vring_desc_get_next(&desc, desc_table, desc_table_len);
551 	if (desc == NULL) {
552 		SPDK_WARNLOG("%s: descriptor chain at index %d contains neither payload nor response buffer.\n",
553 			     vsession->name, task->req_idx);
554 		goto invalid_task;
555 	}
556 	task->scsi.dxfer_dir = vhost_vring_desc_is_wr(desc) ? SPDK_SCSI_DIR_FROM_DEV :
557 			       SPDK_SCSI_DIR_TO_DEV;
558 	task->scsi.iovs = iovs;
559 
560 	if (task->scsi.dxfer_dir == SPDK_SCSI_DIR_FROM_DEV) {
561 		/*
562 		 * FROM_DEV (READ): [RD_req][WR_resp][WR_buf0]...[WR_bufN]
563 		 */
564 		task->resp = vhost_gpa_to_vva(vsession, desc->addr, sizeof(*task->resp));
565 		if (spdk_unlikely(desc->len < sizeof(struct virtio_scsi_cmd_resp) || task->resp == NULL)) {
566 			SPDK_WARNLOG("%s: response descriptor at index %d points to invalid guest memory region\n",
567 				     vsession->name, task->req_idx);
568 			goto invalid_task;
569 		}
570 		rc = vhost_vring_desc_get_next(&desc, desc_table, desc_table_len);
571 		if (spdk_unlikely(rc != 0)) {
572 			SPDK_WARNLOG("%s: invalid descriptor chain at request index %d (descriptor id overflow?).\n",
573 				     vsession->name, task->req_idx);
574 			goto invalid_task;
575 		}
576 
577 		if (desc == NULL) {
578 			/*
579 			 * TEST UNIT READY command and some others might not contain any payload and this is not an error.
580 			 */
581 			SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI_DATA,
582 				      "No payload descriptors for FROM DEV command req_idx=%"PRIu16".\n", task->req_idx);
583 			SPDK_LOGDUMP(SPDK_LOG_VHOST_SCSI_DATA, "CDB=", (*req)->cdb, VIRTIO_SCSI_CDB_SIZE);
584 			task->used_len = sizeof(struct virtio_scsi_cmd_resp);
585 			task->scsi.iovcnt = 1;
586 			task->scsi.iovs[0].iov_len = 0;
587 			task->scsi.length = 0;
588 			task->scsi.transfer_len = 0;
589 			return 0;
590 		}
591 
592 		/* All remaining descriptors are data. */
593 		while (desc) {
594 			if (spdk_unlikely(!vhost_vring_desc_is_wr(desc))) {
595 				SPDK_WARNLOG("%s: FROM DEV cmd: descriptor nr %" PRIu16" in payload chain is read only.\n",
596 					     vsession->name, iovcnt);
597 				goto invalid_task;
598 			}
599 
600 			if (spdk_unlikely(vhost_vring_desc_to_iov(vsession, iovs, &iovcnt, desc))) {
601 				goto invalid_task;
602 			}
603 			len += desc->len;
604 
605 			rc = vhost_vring_desc_get_next(&desc, desc_table, desc_table_len);
606 			if (spdk_unlikely(rc != 0)) {
607 				SPDK_WARNLOG("%s: invalid payload in descriptor chain starting at index %d.\n",
608 					     vsession->name, task->req_idx);
609 				goto invalid_task;
610 			}
611 		}
612 
613 		task->used_len = sizeof(struct virtio_scsi_cmd_resp) + len;
614 	} else {
615 		SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI_DATA, "TO DEV");
616 		/*
617 		 * TO_DEV (WRITE):[RD_req][RD_buf0]...[RD_bufN][WR_resp]
618 		 * No need to check descriptor WR flag as this is done while setting scsi.dxfer_dir.
619 		 */
620 
621 		/* Process descriptors up to response. */
622 		while (!vhost_vring_desc_is_wr(desc)) {
623 			if (spdk_unlikely(vhost_vring_desc_to_iov(vsession, iovs, &iovcnt, desc))) {
624 				goto invalid_task;
625 			}
626 			len += desc->len;
627 
628 			vhost_vring_desc_get_next(&desc, desc_table, desc_table_len);
629 			if (spdk_unlikely(desc == NULL)) {
630 				SPDK_WARNLOG("%s: TO_DEV cmd: no response descriptor.\n", vsession->name);
631 				goto invalid_task;
632 			}
633 		}
634 
635 		task->resp = vhost_gpa_to_vva(vsession, desc->addr, sizeof(*task->resp));
636 		if (spdk_unlikely(desc->len < sizeof(struct virtio_scsi_cmd_resp) || task->resp == NULL)) {
637 			SPDK_WARNLOG("%s: response descriptor at index %d points to invalid guest memory region\n",
638 				     vsession->name, task->req_idx);
639 			goto invalid_task;
640 		}
641 
642 		task->used_len = sizeof(struct virtio_scsi_cmd_resp);
643 	}
644 
645 	task->scsi.iovcnt = iovcnt;
646 	task->scsi.length = len;
647 	task->scsi.transfer_len = len;
648 	return 0;
649 
650 invalid_task:
651 	SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI_DATA, "%s: Invalid task at index %"PRIu16".\n",
652 		      vsession->name, task->req_idx);
653 	return -1;
654 }
655 
656 static int
657 process_request(struct spdk_vhost_scsi_task *task)
658 {
659 	struct virtio_scsi_cmd_req *req;
660 	int result;
661 
662 	result = task_data_setup(task, &req);
663 	if (result) {
664 		return result;
665 	}
666 
667 	result = vhost_scsi_task_init_target(task, req->lun);
668 	if (spdk_unlikely(result != 0)) {
669 		task->resp->response = VIRTIO_SCSI_S_BAD_TARGET;
670 		return -1;
671 	}
672 
673 	task->scsi.cdb = req->cdb;
674 	SPDK_LOGDUMP(SPDK_LOG_VHOST_SCSI_DATA, "request CDB", req->cdb, VIRTIO_SCSI_CDB_SIZE);
675 
676 	if (spdk_unlikely(task->scsi.lun == NULL)) {
677 		spdk_scsi_task_process_null_lun(&task->scsi);
678 		task->resp->response = VIRTIO_SCSI_S_OK;
679 		return 1;
680 	}
681 
682 	return 0;
683 }
684 
685 static void
686 process_controlq(struct spdk_vhost_scsi_session *svsession, struct spdk_vhost_virtqueue *vq)
687 {
688 	struct spdk_vhost_session *vsession = &svsession->vsession;
689 	struct spdk_vhost_scsi_task *task;
690 	uint16_t reqs[32];
691 	uint16_t reqs_cnt, i;
692 
693 	reqs_cnt = vhost_vq_avail_ring_get(vq, reqs, SPDK_COUNTOF(reqs));
694 	for (i = 0; i < reqs_cnt; i++) {
695 		if (spdk_unlikely(reqs[i] >= vq->vring.size)) {
696 			SPDK_ERRLOG("%s: invalid entry in avail ring. Buffer '%"PRIu16"' exceeds virtqueue size (%"PRIu16")\n",
697 				    vsession->name, reqs[i], vq->vring.size);
698 			vhost_vq_used_ring_enqueue(vsession, vq, reqs[i], 0);
699 			continue;
700 		}
701 
702 		task = &((struct spdk_vhost_scsi_task *)vq->tasks)[reqs[i]];
703 		if (spdk_unlikely(task->used)) {
704 			SPDK_ERRLOG("%s: invalid entry in avail ring. Buffer '%"PRIu16"' is still in use!\n",
705 				    vsession->name, reqs[i]);
706 			vhost_vq_used_ring_enqueue(vsession, vq, reqs[i], 0);
707 			continue;
708 		}
709 
710 		vsession->task_cnt++;
711 		memset(&task->scsi, 0, sizeof(task->scsi));
712 		task->tmf_resp = NULL;
713 		task->used = true;
714 		process_ctrl_request(task);
715 	}
716 }
717 
718 static void
719 process_requestq(struct spdk_vhost_scsi_session *svsession, struct spdk_vhost_virtqueue *vq)
720 {
721 	struct spdk_vhost_session *vsession = &svsession->vsession;
722 	struct spdk_vhost_scsi_task *task;
723 	uint16_t reqs[32];
724 	uint16_t reqs_cnt, i;
725 	int result;
726 
727 	reqs_cnt = vhost_vq_avail_ring_get(vq, reqs, SPDK_COUNTOF(reqs));
728 	assert(reqs_cnt <= 32);
729 
730 	for (i = 0; i < reqs_cnt; i++) {
731 		SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI, "====== Starting processing request idx %"PRIu16"======\n",
732 			      reqs[i]);
733 
734 		if (spdk_unlikely(reqs[i] >= vq->vring.size)) {
735 			SPDK_ERRLOG("%s: request idx '%"PRIu16"' exceeds virtqueue size (%"PRIu16").\n",
736 				    vsession->name, reqs[i], vq->vring.size);
737 			vhost_vq_used_ring_enqueue(vsession, vq, reqs[i], 0);
738 			continue;
739 		}
740 
741 		task = &((struct spdk_vhost_scsi_task *)vq->tasks)[reqs[i]];
742 		if (spdk_unlikely(task->used)) {
743 			SPDK_ERRLOG("%s: request with idx '%"PRIu16"' is already pending.\n",
744 				    vsession->name, reqs[i]);
745 			vhost_vq_used_ring_enqueue(vsession, vq, reqs[i], 0);
746 			continue;
747 		}
748 
749 		vsession->task_cnt++;
750 		memset(&task->scsi, 0, sizeof(task->scsi));
751 		task->resp = NULL;
752 		task->used = true;
753 		task->used_len = 0;
754 		result = process_request(task);
755 		if (likely(result == 0)) {
756 			task_submit(task);
757 			SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI, "====== Task %p req_idx %d submitted ======\n", task,
758 				      task->req_idx);
759 		} else if (result > 0) {
760 			vhost_scsi_task_cpl(&task->scsi);
761 			SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI, "====== Task %p req_idx %d finished early ======\n", task,
762 				      task->req_idx);
763 		} else {
764 			invalid_request(task);
765 			SPDK_DEBUGLOG(SPDK_LOG_VHOST_SCSI, "====== Task %p req_idx %d failed ======\n", task,
766 				      task->req_idx);
767 		}
768 	}
769 }
770 
771 static int
772 vdev_mgmt_worker(void *arg)
773 {
774 	struct spdk_vhost_scsi_session *svsession = arg;
775 	struct spdk_vhost_session *vsession = &svsession->vsession;
776 
777 	process_removed_devs(svsession);
778 	vhost_vq_used_signal(vsession, &vsession->virtqueue[VIRTIO_SCSI_EVENTQ]);
779 
780 	process_controlq(svsession, &vsession->virtqueue[VIRTIO_SCSI_CONTROLQ]);
781 	vhost_vq_used_signal(vsession, &vsession->virtqueue[VIRTIO_SCSI_CONTROLQ]);
782 
783 	return -1;
784 }
785 
786 static int
787 vdev_worker(void *arg)
788 {
789 	struct spdk_vhost_scsi_session *svsession = arg;
790 	struct spdk_vhost_session *vsession = &svsession->vsession;
791 	uint32_t q_idx;
792 
793 	for (q_idx = VIRTIO_SCSI_REQUESTQ; q_idx < vsession->max_queues; q_idx++) {
794 		process_requestq(svsession, &vsession->virtqueue[q_idx]);
795 	}
796 
797 	vhost_session_used_signal(vsession);
798 
799 	return -1;
800 }
801 
802 static struct spdk_vhost_scsi_dev *
803 to_scsi_dev(struct spdk_vhost_dev *ctrlr)
804 {
805 	if (ctrlr == NULL) {
806 		return NULL;
807 	}
808 
809 	if (ctrlr->backend != &spdk_vhost_scsi_device_backend) {
810 		SPDK_ERRLOG("%s: not a vhost-scsi device.\n", ctrlr->name);
811 		return NULL;
812 	}
813 
814 	return SPDK_CONTAINEROF(ctrlr, struct spdk_vhost_scsi_dev, vdev);
815 }
816 
817 static struct spdk_vhost_scsi_session *
818 to_scsi_session(struct spdk_vhost_session *vsession)
819 {
820 	assert(vsession->vdev->backend == &spdk_vhost_scsi_device_backend);
821 	return (struct spdk_vhost_scsi_session *)vsession;
822 }
823 
824 int
825 spdk_vhost_scsi_dev_construct(const char *name, const char *cpumask)
826 {
827 	struct spdk_vhost_scsi_dev *svdev = calloc(1, sizeof(*svdev));
828 	int rc;
829 
830 	if (svdev == NULL) {
831 		return -ENOMEM;
832 	}
833 
834 	svdev->vdev.virtio_features = SPDK_VHOST_SCSI_FEATURES;
835 	svdev->vdev.disabled_features = SPDK_VHOST_SCSI_DISABLED_FEATURES;
836 
837 	spdk_vhost_lock();
838 	rc = vhost_dev_register(&svdev->vdev, name, cpumask,
839 				&spdk_vhost_scsi_device_backend);
840 
841 	if (rc) {
842 		free(svdev);
843 		spdk_vhost_unlock();
844 		return rc;
845 	}
846 
847 	svdev->registered = true;
848 
849 	spdk_vhost_unlock();
850 	return rc;
851 }
852 
853 static int
854 vhost_scsi_dev_remove(struct spdk_vhost_dev *vdev)
855 {
856 	struct spdk_vhost_scsi_dev *svdev = to_scsi_dev(vdev);
857 	int rc, i;
858 
859 	assert(svdev != NULL);
860 	for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; ++i) {
861 		if (svdev->scsi_dev_state[i].dev) {
862 			if (vdev->registered) {
863 				SPDK_ERRLOG("%s: SCSI target %d is still present.\n", vdev->name, i);
864 				return -EBUSY;
865 			}
866 
867 			rc = spdk_vhost_scsi_dev_remove_tgt(vdev, i, NULL, NULL);
868 			if (rc != 0) {
869 				SPDK_ERRLOG("%s: failed to force-remove target %d\n", vdev->name, i);
870 				return rc;
871 			}
872 		}
873 	}
874 
875 	rc = vhost_dev_unregister(vdev);
876 	if (rc != 0) {
877 		return rc;
878 	}
879 	svdev->registered = false;
880 
881 	if (svdev->ref == 0) {
882 		free(svdev);
883 	}
884 
885 	return 0;
886 }
887 
888 struct spdk_scsi_dev *
889 spdk_vhost_scsi_dev_get_tgt(struct spdk_vhost_dev *vdev, uint8_t num)
890 {
891 	struct spdk_vhost_scsi_dev *svdev;
892 
893 	assert(num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS);
894 	svdev = to_scsi_dev(vdev);
895 	assert(svdev != NULL);
896 	if (svdev->scsi_dev_state[num].status != VHOST_SCSI_DEV_PRESENT) {
897 		return NULL;
898 	}
899 
900 	assert(svdev->scsi_dev_state[num].dev != NULL);
901 	return svdev->scsi_dev_state[num].dev;
902 }
903 
904 static void
905 vhost_scsi_lun_hotremove(const struct spdk_scsi_lun *lun, void *arg)
906 {
907 	struct spdk_vhost_scsi_dev *svdev = arg;
908 	const struct spdk_scsi_dev *scsi_dev;
909 	unsigned scsi_dev_num;
910 
911 	assert(lun != NULL);
912 	assert(svdev != NULL);
913 	scsi_dev = spdk_scsi_lun_get_dev(lun);
914 	for (scsi_dev_num = 0; scsi_dev_num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; scsi_dev_num++) {
915 		if (svdev->scsi_dev_state[scsi_dev_num].dev == scsi_dev) {
916 			break;
917 		}
918 	}
919 
920 	if (scsi_dev_num == SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
921 		/* The entire device has been already removed. */
922 		return;
923 	}
924 
925 	/* remove entire device */
926 	spdk_vhost_scsi_dev_remove_tgt(&svdev->vdev, scsi_dev_num, NULL, NULL);
927 }
928 
929 static void
930 vhost_scsi_dev_add_tgt_cpl_cb(struct spdk_vhost_dev *vdev, void *ctx)
931 {
932 	unsigned scsi_tgt_num = (unsigned)(uintptr_t)ctx;
933 	struct spdk_vhost_scsi_dev *svdev = SPDK_CONTAINEROF(vdev,
934 					    struct spdk_vhost_scsi_dev, vdev);
935 	struct spdk_scsi_dev_vhost_state *vhost_sdev;
936 
937 	vhost_sdev = &svdev->scsi_dev_state[scsi_tgt_num];
938 
939 	/* All sessions have added the target */
940 	assert(vhost_sdev->status == VHOST_SCSI_DEV_ADDING);
941 	vhost_sdev->status = VHOST_SCSI_DEV_PRESENT;
942 	svdev->ref++;
943 }
944 
945 static int
946 vhost_scsi_session_add_tgt(struct spdk_vhost_dev *vdev,
947 			   struct spdk_vhost_session *vsession, void *ctx)
948 {
949 	unsigned scsi_tgt_num = (unsigned)(uintptr_t)ctx;
950 	struct spdk_vhost_scsi_session *svsession = (struct spdk_vhost_scsi_session *)vsession;
951 	struct spdk_scsi_dev_session_state *session_sdev = &svsession->scsi_dev_state[scsi_tgt_num];
952 	struct spdk_scsi_dev_vhost_state *vhost_sdev;
953 	int rc;
954 
955 	if (!vsession->started || session_sdev->dev != NULL) {
956 		/* Nothing to do. */
957 		return 0;
958 	}
959 
960 	vhost_sdev = &svsession->svdev->scsi_dev_state[scsi_tgt_num];
961 	session_sdev->dev = vhost_sdev->dev;
962 	session_sdev->status = VHOST_SCSI_DEV_PRESENT;
963 
964 	rc = spdk_scsi_dev_allocate_io_channels(svsession->scsi_dev_state[scsi_tgt_num].dev);
965 	if (rc != 0) {
966 		SPDK_ERRLOG("%s: Couldn't allocate io channnel for SCSI target %u.\n",
967 			    vsession->name, scsi_tgt_num);
968 
969 		/* unset the SCSI target so that all I/O to it will be rejected */
970 		session_sdev->dev = NULL;
971 		/* Set status to EMPTY so that we won't reply with SCSI hotremove
972 		 * sense codes - the device hasn't ever been added.
973 		 */
974 		session_sdev->status = VHOST_SCSI_DEV_EMPTY;
975 
976 		/* Return with no error. We'll continue allocating io_channels for
977 		 * other sessions on this device in hopes they succeed. The sessions
978 		 * that failed to allocate io_channels simply won't be able to
979 		 * detect the SCSI target, nor do any I/O to it.
980 		 */
981 		return 0;
982 	}
983 
984 	if (vhost_dev_has_feature(vsession, VIRTIO_SCSI_F_HOTPLUG)) {
985 		eventq_enqueue(svsession, scsi_tgt_num,
986 			       VIRTIO_SCSI_T_TRANSPORT_RESET, VIRTIO_SCSI_EVT_RESET_RESCAN);
987 	} else {
988 		SPDK_NOTICELOG("%s: driver does not support hotplug. "
989 			       "Please restart it or perform a rescan.\n",
990 			       vsession->name);
991 	}
992 
993 	return 0;
994 }
995 
996 int
997 spdk_vhost_scsi_dev_add_tgt(struct spdk_vhost_dev *vdev, int scsi_tgt_num,
998 			    const char *bdev_name)
999 {
1000 	struct spdk_vhost_scsi_dev *svdev;
1001 	struct spdk_scsi_dev_vhost_state *state;
1002 	char target_name[SPDK_SCSI_DEV_MAX_NAME];
1003 	int lun_id_list[1];
1004 	const char *bdev_names_list[1];
1005 
1006 	svdev = to_scsi_dev(vdev);
1007 	assert(svdev != NULL);
1008 	if (scsi_tgt_num < 0) {
1009 		for (scsi_tgt_num = 0; scsi_tgt_num < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; scsi_tgt_num++) {
1010 			if (svdev->scsi_dev_state[scsi_tgt_num].dev == NULL) {
1011 				break;
1012 			}
1013 		}
1014 
1015 		if (scsi_tgt_num == SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
1016 			SPDK_ERRLOG("%s: all SCSI target slots are already in use.\n", vdev->name);
1017 			return -ENOSPC;
1018 		}
1019 	} else {
1020 		if (scsi_tgt_num >= SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
1021 			SPDK_ERRLOG("%s: SCSI target number is too big (got %d, max %d)\n",
1022 				    vdev->name, scsi_tgt_num, SPDK_VHOST_SCSI_CTRLR_MAX_DEVS);
1023 			return -EINVAL;
1024 		}
1025 	}
1026 
1027 	if (bdev_name == NULL) {
1028 		SPDK_ERRLOG("No lun name specified\n");
1029 		return -EINVAL;
1030 	}
1031 
1032 	state = &svdev->scsi_dev_state[scsi_tgt_num];
1033 	if (state->dev != NULL) {
1034 		SPDK_ERRLOG("%s: SCSI target %u already occupied\n", vdev->name, scsi_tgt_num);
1035 		return -EEXIST;
1036 	}
1037 
1038 	/*
1039 	 * At this stage only one LUN per target
1040 	 */
1041 	snprintf(target_name, sizeof(target_name), "Target %u", scsi_tgt_num);
1042 	lun_id_list[0] = 0;
1043 	bdev_names_list[0] = (char *)bdev_name;
1044 
1045 	state->status = VHOST_SCSI_DEV_ADDING;
1046 	state->dev = spdk_scsi_dev_construct(target_name, bdev_names_list, lun_id_list, 1,
1047 					     SPDK_SPC_PROTOCOL_IDENTIFIER_SAS,
1048 					     vhost_scsi_lun_hotremove, svdev);
1049 
1050 	if (state->dev == NULL) {
1051 		state->status = VHOST_SCSI_DEV_EMPTY;
1052 		SPDK_ERRLOG("%s: couldn't create SCSI target %u using bdev '%s'\n",
1053 			    vdev->name, scsi_tgt_num, bdev_name);
1054 		return -EINVAL;
1055 	}
1056 	spdk_scsi_dev_add_port(state->dev, 0, "vhost");
1057 
1058 	SPDK_INFOLOG(SPDK_LOG_VHOST, "%s: added SCSI target %u using bdev '%s'\n",
1059 		     vdev->name, scsi_tgt_num, bdev_name);
1060 
1061 	vhost_dev_foreach_session(vdev, vhost_scsi_session_add_tgt,
1062 				  vhost_scsi_dev_add_tgt_cpl_cb,
1063 				  (void *)(uintptr_t)scsi_tgt_num);
1064 	return scsi_tgt_num;
1065 }
1066 
1067 struct scsi_tgt_hotplug_ctx {
1068 	unsigned scsi_tgt_num;
1069 	bool async_fini;
1070 };
1071 
1072 static void
1073 vhost_scsi_dev_remove_tgt_cpl_cb(struct spdk_vhost_dev *vdev, void *_ctx)
1074 {
1075 	struct scsi_tgt_hotplug_ctx *ctx = _ctx;
1076 	struct spdk_vhost_scsi_dev *svdev = SPDK_CONTAINEROF(vdev,
1077 					    struct spdk_vhost_scsi_dev, vdev);
1078 
1079 	if (!ctx->async_fini) {
1080 		/* there aren't any active sessions, so remove the dev and exit */
1081 		remove_scsi_tgt(svdev, ctx->scsi_tgt_num);
1082 	}
1083 
1084 	free(ctx);
1085 }
1086 
1087 static int
1088 vhost_scsi_session_remove_tgt(struct spdk_vhost_dev *vdev,
1089 			      struct spdk_vhost_session *vsession, void *_ctx)
1090 {
1091 	struct scsi_tgt_hotplug_ctx *ctx = _ctx;
1092 	unsigned scsi_tgt_num = ctx->scsi_tgt_num;
1093 	struct spdk_vhost_scsi_session *svsession = (struct spdk_vhost_scsi_session *)vsession;
1094 	struct spdk_scsi_dev_session_state *state = &svsession->scsi_dev_state[scsi_tgt_num];
1095 
1096 	if (!vsession->started || state->dev == NULL) {
1097 		/* Nothing to do */
1098 		return 0;
1099 	}
1100 
1101 	/* Mark the target for removal */
1102 	assert(state->status == VHOST_SCSI_DEV_PRESENT);
1103 	state->status = VHOST_SCSI_DEV_REMOVING;
1104 
1105 	/* Send a hotremove Virtio event */
1106 	if (vhost_dev_has_feature(vsession, VIRTIO_SCSI_F_HOTPLUG)) {
1107 		eventq_enqueue(svsession, scsi_tgt_num,
1108 			       VIRTIO_SCSI_T_TRANSPORT_RESET, VIRTIO_SCSI_EVT_RESET_REMOVED);
1109 	}
1110 
1111 	/* Wait for the session's management poller to remove the target after
1112 	 * all its pending I/O has finished.
1113 	 */
1114 	ctx->async_fini = true;
1115 	return 0;
1116 }
1117 
1118 int
1119 spdk_vhost_scsi_dev_remove_tgt(struct spdk_vhost_dev *vdev, unsigned scsi_tgt_num,
1120 			       spdk_vhost_event_fn cb_fn, void *cb_arg)
1121 {
1122 	struct spdk_vhost_scsi_dev *svdev;
1123 	struct spdk_scsi_dev_vhost_state *scsi_dev_state;
1124 	struct scsi_tgt_hotplug_ctx *ctx;
1125 
1126 	if (scsi_tgt_num >= SPDK_VHOST_SCSI_CTRLR_MAX_DEVS) {
1127 		SPDK_ERRLOG("%s: invalid SCSI target number %d\n", vdev->name, scsi_tgt_num);
1128 		return -EINVAL;
1129 	}
1130 
1131 	svdev = to_scsi_dev(vdev);
1132 	assert(svdev != NULL);
1133 	scsi_dev_state = &svdev->scsi_dev_state[scsi_tgt_num];
1134 	if (scsi_dev_state->dev == NULL || scsi_dev_state->status == VHOST_SCSI_DEV_ADDING) {
1135 		SPDK_ERRLOG("%s: SCSI target %u is not occupied\n", vdev->name, scsi_tgt_num);
1136 		return -ENODEV;
1137 	}
1138 
1139 	assert(scsi_dev_state->status != VHOST_SCSI_DEV_EMPTY);
1140 	if (scsi_dev_state->status != VHOST_SCSI_DEV_PRESENT) {
1141 		SPDK_WARNLOG("%s: SCSI target %u has been already marked for hotremoval.\n",
1142 			     vdev->name, scsi_tgt_num);
1143 		return -EBUSY;
1144 	}
1145 
1146 	ctx = calloc(1, sizeof(*ctx));
1147 	if (ctx == NULL) {
1148 		SPDK_ERRLOG("calloc failed\n");
1149 		return -ENOMEM;
1150 	}
1151 
1152 	ctx->scsi_tgt_num = scsi_tgt_num;
1153 	ctx->async_fini = false;
1154 
1155 	scsi_dev_state->remove_cb = cb_fn;
1156 	scsi_dev_state->remove_ctx = cb_arg;
1157 	scsi_dev_state->status = VHOST_SCSI_DEV_REMOVING;
1158 
1159 	vhost_dev_foreach_session(vdev, vhost_scsi_session_remove_tgt,
1160 				  vhost_scsi_dev_remove_tgt_cpl_cb, ctx);
1161 	return 0;
1162 }
1163 
1164 int
1165 vhost_scsi_controller_construct(void)
1166 {
1167 	struct spdk_conf_section *sp = spdk_conf_first_section(NULL);
1168 	struct spdk_vhost_dev *vdev;
1169 	int i, dev_num;
1170 	unsigned ctrlr_num = 0;
1171 	char *bdev_name, *tgt_num_str;
1172 	char *cpumask;
1173 	char *name;
1174 	char *tgt = NULL;
1175 
1176 	while (sp != NULL) {
1177 		if (!spdk_conf_section_match_prefix(sp, "VhostScsi")) {
1178 			sp = spdk_conf_next_section(sp);
1179 			continue;
1180 		}
1181 
1182 		if (sscanf(spdk_conf_section_get_name(sp), "VhostScsi%u", &ctrlr_num) != 1) {
1183 			SPDK_ERRLOG("Section '%s' has non-numeric suffix.\n",
1184 				    spdk_conf_section_get_name(sp));
1185 			return -1;
1186 		}
1187 
1188 		name =  spdk_conf_section_get_val(sp, "Name");
1189 		cpumask = spdk_conf_section_get_val(sp, "Cpumask");
1190 
1191 		if (spdk_vhost_scsi_dev_construct(name, cpumask) < 0) {
1192 			return -1;
1193 		}
1194 
1195 		vdev = spdk_vhost_dev_find(name);
1196 		assert(vdev);
1197 
1198 		for (i = 0; ; i++) {
1199 
1200 			tgt = spdk_conf_section_get_nval(sp, "Target", i);
1201 			if (tgt == NULL) {
1202 				break;
1203 			}
1204 
1205 			tgt_num_str = spdk_conf_section_get_nmval(sp, "Target", i, 0);
1206 			if (tgt_num_str == NULL) {
1207 				SPDK_ERRLOG("%s: invalid or missing SCSI target number\n", name);
1208 				return -1;
1209 			}
1210 
1211 			dev_num = (int)strtol(tgt_num_str, NULL, 10);
1212 			bdev_name = spdk_conf_section_get_nmval(sp, "Target", i, 1);
1213 			if (bdev_name == NULL) {
1214 				SPDK_ERRLOG("%s: invalid or missing bdev name for SCSI target %d\n", name, dev_num);
1215 				return -1;
1216 			} else if (spdk_conf_section_get_nmval(sp, "Target", i, 2)) {
1217 				SPDK_ERRLOG("%s: only one LUN per SCSI target is supported\n", name);
1218 				return -1;
1219 			}
1220 
1221 			if (spdk_vhost_scsi_dev_add_tgt(vdev, dev_num, bdev_name) < 0) {
1222 				return -1;
1223 			}
1224 		}
1225 
1226 		sp = spdk_conf_next_section(sp);
1227 	}
1228 
1229 	return 0;
1230 }
1231 
1232 static void
1233 free_task_pool(struct spdk_vhost_scsi_session *svsession)
1234 {
1235 	struct spdk_vhost_session *vsession = &svsession->vsession;
1236 	struct spdk_vhost_virtqueue *vq;
1237 	uint16_t i;
1238 
1239 	for (i = 0; i < vsession->max_queues; i++) {
1240 		vq = &vsession->virtqueue[i];
1241 		if (vq->tasks == NULL) {
1242 			continue;
1243 		}
1244 
1245 		spdk_free(vq->tasks);
1246 		vq->tasks = NULL;
1247 	}
1248 }
1249 
1250 static int
1251 alloc_task_pool(struct spdk_vhost_scsi_session *svsession)
1252 {
1253 	struct spdk_vhost_session *vsession = &svsession->vsession;
1254 	struct spdk_vhost_virtqueue *vq;
1255 	struct spdk_vhost_scsi_task *task;
1256 	uint32_t task_cnt;
1257 	uint16_t i;
1258 	uint32_t j;
1259 
1260 	for (i = 0; i < vsession->max_queues; i++) {
1261 		vq = &vsession->virtqueue[i];
1262 		if (vq->vring.desc == NULL) {
1263 			continue;
1264 		}
1265 
1266 		task_cnt = vq->vring.size;
1267 		if (task_cnt > SPDK_VHOST_MAX_VQ_SIZE) {
1268 			/* sanity check */
1269 			SPDK_ERRLOG("%s: virtuque %"PRIu16" is too big. (size = %"PRIu32", max = %"PRIu32")\n",
1270 				    vsession->name, i, task_cnt, SPDK_VHOST_MAX_VQ_SIZE);
1271 			free_task_pool(svsession);
1272 			return -1;
1273 		}
1274 		vq->tasks = spdk_zmalloc(sizeof(struct spdk_vhost_scsi_task) * task_cnt,
1275 					 SPDK_CACHE_LINE_SIZE, NULL,
1276 					 SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
1277 		if (vq->tasks == NULL) {
1278 			SPDK_ERRLOG("%s: failed to allocate %"PRIu32" tasks for virtqueue %"PRIu16"\n",
1279 				    vsession->name, task_cnt, i);
1280 			free_task_pool(svsession);
1281 			return -1;
1282 		}
1283 
1284 		for (j = 0; j < task_cnt; j++) {
1285 			task = &((struct spdk_vhost_scsi_task *)vq->tasks)[j];
1286 			task->svsession = svsession;
1287 			task->vq = vq;
1288 			task->req_idx = j;
1289 		}
1290 	}
1291 
1292 	return 0;
1293 }
1294 
1295 static int
1296 vhost_scsi_start_cb(struct spdk_vhost_dev *vdev,
1297 		    struct spdk_vhost_session *vsession, void *unused)
1298 {
1299 	struct spdk_vhost_scsi_session *svsession = to_scsi_session(vsession);
1300 	struct spdk_vhost_scsi_dev *svdev = svsession->svdev;
1301 	struct spdk_scsi_dev_vhost_state *state;
1302 	uint32_t i;
1303 	int rc;
1304 
1305 	/* validate all I/O queues are in a contiguous index range */
1306 	for (i = VIRTIO_SCSI_REQUESTQ; i < vsession->max_queues; i++) {
1307 		if (vsession->virtqueue[i].vring.desc == NULL) {
1308 			SPDK_ERRLOG("%s: queue %"PRIu32" is empty\n", vsession->name, i);
1309 			rc = -1;
1310 			goto out;
1311 		}
1312 	}
1313 
1314 	rc = alloc_task_pool(svsession);
1315 	if (rc != 0) {
1316 		SPDK_ERRLOG("%s: failed to alloc task pool.\n", vsession->name);
1317 		goto out;
1318 	}
1319 
1320 	for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) {
1321 		state = &svdev->scsi_dev_state[i];
1322 		if (state->dev == NULL || state->status == VHOST_SCSI_DEV_REMOVING) {
1323 			continue;
1324 		}
1325 
1326 		assert(svsession->scsi_dev_state[i].status == VHOST_SCSI_DEV_EMPTY);
1327 		svsession->scsi_dev_state[i].dev = state->dev;
1328 		svsession->scsi_dev_state[i].status = VHOST_SCSI_DEV_PRESENT;
1329 		rc = spdk_scsi_dev_allocate_io_channels(state->dev);
1330 		if (rc != 0) {
1331 			SPDK_ERRLOG("%s: failed to alloc io_channel for SCSI target %"PRIu32"\n",
1332 				    vsession->name, i);
1333 			/* unset the SCSI target so that all I/O to it will be rejected */
1334 			svsession->scsi_dev_state[i].dev = NULL;
1335 			/* set EMPTY state so that we won't reply with SCSI hotremove
1336 			 * sense codes - the device hasn't ever been added.
1337 			 */
1338 			svsession->scsi_dev_state[i].status = VHOST_SCSI_DEV_EMPTY;
1339 			continue;
1340 		}
1341 	}
1342 	SPDK_INFOLOG(SPDK_LOG_VHOST, "%s: started poller on lcore %d\n",
1343 		     vsession->name, spdk_env_get_current_core());
1344 
1345 	svsession->requestq_poller = spdk_poller_register(vdev_worker, svsession, 0);
1346 	if (vsession->virtqueue[VIRTIO_SCSI_CONTROLQ].vring.desc &&
1347 	    vsession->virtqueue[VIRTIO_SCSI_EVENTQ].vring.desc) {
1348 		svsession->mgmt_poller = spdk_poller_register(vdev_mgmt_worker, svsession,
1349 					 MGMT_POLL_PERIOD_US);
1350 	}
1351 out:
1352 	vhost_session_start_done(vsession, rc);
1353 	return rc;
1354 }
1355 
1356 static int
1357 vhost_scsi_start(struct spdk_vhost_session *vsession)
1358 {
1359 	struct spdk_vhost_scsi_session *svsession = to_scsi_session(vsession);
1360 	struct spdk_vhost_scsi_dev *svdev;
1361 
1362 	svdev = to_scsi_dev(vsession->vdev);
1363 	assert(svdev != NULL);
1364 	svsession->svdev = svdev;
1365 
1366 	return vhost_session_send_event(vsession, vhost_scsi_start_cb,
1367 					3, "start session");
1368 }
1369 
1370 static int
1371 destroy_session_poller_cb(void *arg)
1372 {
1373 	struct spdk_vhost_scsi_session *svsession = arg;
1374 	struct spdk_vhost_session *vsession = &svsession->vsession;
1375 	struct spdk_scsi_dev_session_state *state;
1376 	uint32_t i;
1377 
1378 	if (vsession->task_cnt > 0) {
1379 		return -1;
1380 	}
1381 
1382 	if (spdk_vhost_trylock() != 0) {
1383 		return -1;
1384 	}
1385 
1386 	for (i = 0; i < vsession->max_queues; i++) {
1387 		vhost_vq_used_signal(vsession, &vsession->virtqueue[i]);
1388 	}
1389 
1390 	for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) {
1391 		enum spdk_scsi_dev_vhost_status prev_status;
1392 
1393 		state = &svsession->scsi_dev_state[i];
1394 		/* clear the REMOVED status so that we won't send hotremove events anymore */
1395 		prev_status = state->status;
1396 		state->status = VHOST_SCSI_DEV_EMPTY;
1397 		if (state->dev == NULL) {
1398 			continue;
1399 		}
1400 
1401 		spdk_scsi_dev_free_io_channels(state->dev);
1402 
1403 		state->dev = NULL;
1404 
1405 		if (prev_status == VHOST_SCSI_DEV_REMOVING) {
1406 			/* try to detach it globally */
1407 			vhost_dev_foreach_session(vsession->vdev,
1408 						  vhost_scsi_session_process_removed,
1409 						  vhost_scsi_dev_process_removed_cpl_cb,
1410 						  (void *)(uintptr_t)i);
1411 		}
1412 	}
1413 
1414 	SPDK_INFOLOG(SPDK_LOG_VHOST, "%s: stopping poller on lcore %d\n",
1415 		     vsession->name, spdk_env_get_current_core());
1416 
1417 	free_task_pool(svsession);
1418 
1419 	spdk_poller_unregister(&svsession->stop_poller);
1420 	vhost_session_stop_done(vsession, 0);
1421 
1422 	spdk_vhost_unlock();
1423 	return -1;
1424 }
1425 
1426 static int
1427 vhost_scsi_stop_cb(struct spdk_vhost_dev *vdev,
1428 		   struct spdk_vhost_session *vsession, void *unused)
1429 {
1430 	struct spdk_vhost_scsi_session *svsession = to_scsi_session(vsession);
1431 
1432 	/* Stop receiving new I/O requests */
1433 	spdk_poller_unregister(&svsession->requestq_poller);
1434 
1435 	/* Stop receiving controlq requests, also stop processing the
1436 	 * asynchronous hotremove events. All the remaining events
1437 	 * will be finalized by the stop_poller below.
1438 	 */
1439 	spdk_poller_unregister(&svsession->mgmt_poller);
1440 
1441 	/* Wait for all pending I/Os to complete, then process all the
1442 	 * remaining hotremove events one last time.
1443 	 */
1444 	svsession->stop_poller = spdk_poller_register(destroy_session_poller_cb,
1445 				 svsession, 1000);
1446 
1447 	return 0;
1448 }
1449 
1450 static int
1451 vhost_scsi_stop(struct spdk_vhost_session *vsession)
1452 {
1453 	return vhost_session_send_event(vsession, vhost_scsi_stop_cb,
1454 					3, "stop session");
1455 }
1456 
1457 static void
1458 vhost_scsi_dump_info_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w)
1459 {
1460 	struct spdk_scsi_dev *sdev;
1461 	struct spdk_scsi_lun *lun;
1462 	uint32_t dev_idx;
1463 	uint32_t lun_idx;
1464 
1465 	assert(vdev != NULL);
1466 	spdk_json_write_named_array_begin(w, "scsi");
1467 	for (dev_idx = 0; dev_idx < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; dev_idx++) {
1468 		sdev = spdk_vhost_scsi_dev_get_tgt(vdev, dev_idx);
1469 		if (!sdev) {
1470 			continue;
1471 		}
1472 
1473 		spdk_json_write_object_begin(w);
1474 
1475 		spdk_json_write_named_uint32(w, "scsi_dev_num", dev_idx);
1476 
1477 		spdk_json_write_named_uint32(w, "id", spdk_scsi_dev_get_id(sdev));
1478 
1479 		spdk_json_write_named_string(w, "target_name", spdk_scsi_dev_get_name(sdev));
1480 
1481 		spdk_json_write_named_array_begin(w, "luns");
1482 
1483 		for (lun_idx = 0; lun_idx < SPDK_SCSI_DEV_MAX_LUN; lun_idx++) {
1484 			lun = spdk_scsi_dev_get_lun(sdev, lun_idx);
1485 			if (!lun) {
1486 				continue;
1487 			}
1488 
1489 			spdk_json_write_object_begin(w);
1490 
1491 			spdk_json_write_named_int32(w, "id", spdk_scsi_lun_get_id(lun));
1492 
1493 			spdk_json_write_named_string(w, "bdev_name", spdk_scsi_lun_get_bdev_name(lun));
1494 
1495 			spdk_json_write_object_end(w);
1496 		}
1497 
1498 		spdk_json_write_array_end(w);
1499 		spdk_json_write_object_end(w);
1500 	}
1501 
1502 	spdk_json_write_array_end(w);
1503 }
1504 
1505 static void
1506 vhost_scsi_write_config_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w)
1507 {
1508 	struct spdk_scsi_dev *scsi_dev;
1509 	struct spdk_scsi_lun *lun;
1510 	uint32_t i;
1511 
1512 	spdk_json_write_object_begin(w);
1513 	spdk_json_write_named_string(w, "method", "vhost_create_scsi_controller");
1514 
1515 	spdk_json_write_named_object_begin(w, "params");
1516 	spdk_json_write_named_string(w, "ctrlr", vdev->name);
1517 	spdk_json_write_named_string(w, "cpumask",
1518 				     spdk_cpuset_fmt(spdk_thread_get_cpumask(vdev->thread)));
1519 	spdk_json_write_object_end(w);
1520 
1521 	spdk_json_write_object_end(w);
1522 
1523 	for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) {
1524 		scsi_dev = spdk_vhost_scsi_dev_get_tgt(vdev, i);
1525 		if (scsi_dev == NULL) {
1526 			continue;
1527 		}
1528 
1529 		lun = spdk_scsi_dev_get_lun(scsi_dev, 0);
1530 
1531 		spdk_json_write_object_begin(w);
1532 		spdk_json_write_named_string(w, "method", "vhost_scsi_controller_add_target");
1533 
1534 		spdk_json_write_named_object_begin(w, "params");
1535 		spdk_json_write_named_string(w, "ctrlr", vdev->name);
1536 		spdk_json_write_named_uint32(w, "scsi_target_num", i);
1537 
1538 		spdk_json_write_named_string(w, "bdev_name", spdk_scsi_lun_get_bdev_name(lun));
1539 		spdk_json_write_object_end(w);
1540 
1541 		spdk_json_write_object_end(w);
1542 	}
1543 }
1544 
1545 SPDK_LOG_REGISTER_COMPONENT("vhost_scsi", SPDK_LOG_VHOST_SCSI)
1546 SPDK_LOG_REGISTER_COMPONENT("vhost_scsi_queue", SPDK_LOG_VHOST_SCSI_QUEUE)
1547 SPDK_LOG_REGISTER_COMPONENT("vhost_scsi_data", SPDK_LOG_VHOST_SCSI_DATA)
1548