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