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