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