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