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