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