diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-10 17:48:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-10 17:48:50 -0400 |
commit | 8d10aae2741ec9ffd53c8d214f7ada6d543b3a46 (patch) | |
tree | 08e8cc6a787484589e22d1d7c1b58300a763d9ef | |
parent | 6664565681a1c0c95607ae2e30070352d9a563d0 (diff) | |
parent | 09a34c8404c1d4c5782de319c02e1d742c57875c (diff) |
Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
Pull vhost fixes and cleanups from Michael S Tsirkin:
"This includes some fixes and cleanups for vhost net and scsi drivers"
* tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost:
vhost/test: update test after vhost cleanups
vhost: Make local function static
vhost: Make vhost a separate module
vhost-scsi: Rename struct tcm_vhost_cmd *tv_cmd to *cmd
vhost-scsi: Rename struct tcm_vhost_tpg *tv_tpg to *tpg
vhost-scsi: Make func indention more consistent
vhost-scsi: Rename struct vhost_scsi *s to *vs
vhost-scsi: Remove unnecessary forward struct vhost_scsi declaration
vhost: Simplify dev->vqs[i] access
vhost-net: fix use-after-free in vhost_net_flush
-rw-r--r-- | drivers/vhost/Kconfig | 8 | ||||
-rw-r--r-- | drivers/vhost/Makefile | 3 | ||||
-rw-r--r-- | drivers/vhost/net.c | 4 | ||||
-rw-r--r-- | drivers/vhost/scsi.c | 472 | ||||
-rw-r--r-- | drivers/vhost/test.c | 33 | ||||
-rw-r--r-- | drivers/vhost/vhost.c | 86 | ||||
-rw-r--r-- | drivers/vhost/vhost.h | 2 |
7 files changed, 349 insertions, 259 deletions
diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig index 8b9226da3f54..017a1e8a8f6f 100644 --- a/drivers/vhost/Kconfig +++ b/drivers/vhost/Kconfig | |||
@@ -1,6 +1,7 @@ | |||
1 | config VHOST_NET | 1 | config VHOST_NET |
2 | tristate "Host kernel accelerator for virtio net" | 2 | tristate "Host kernel accelerator for virtio net" |
3 | depends on NET && EVENTFD && (TUN || !TUN) && (MACVTAP || !MACVTAP) | 3 | depends on NET && EVENTFD && (TUN || !TUN) && (MACVTAP || !MACVTAP) |
4 | select VHOST | ||
4 | select VHOST_RING | 5 | select VHOST_RING |
5 | ---help--- | 6 | ---help--- |
6 | This kernel module can be loaded in host kernel to accelerate | 7 | This kernel module can be loaded in host kernel to accelerate |
@@ -13,6 +14,7 @@ config VHOST_NET | |||
13 | config VHOST_SCSI | 14 | config VHOST_SCSI |
14 | tristate "VHOST_SCSI TCM fabric driver" | 15 | tristate "VHOST_SCSI TCM fabric driver" |
15 | depends on TARGET_CORE && EVENTFD && m | 16 | depends on TARGET_CORE && EVENTFD && m |
17 | select VHOST | ||
16 | select VHOST_RING | 18 | select VHOST_RING |
17 | default n | 19 | default n |
18 | ---help--- | 20 | ---help--- |
@@ -24,3 +26,9 @@ config VHOST_RING | |||
24 | ---help--- | 26 | ---help--- |
25 | This option is selected by any driver which needs to access | 27 | This option is selected by any driver which needs to access |
26 | the host side of a virtio ring. | 28 | the host side of a virtio ring. |
29 | |||
30 | config VHOST | ||
31 | tristate | ||
32 | ---help--- | ||
33 | This option is selected by any driver which needs to access | ||
34 | the core of vhost. | ||
diff --git a/drivers/vhost/Makefile b/drivers/vhost/Makefile index 654e9afb11f5..e0441c34db1c 100644 --- a/drivers/vhost/Makefile +++ b/drivers/vhost/Makefile | |||
@@ -1,7 +1,8 @@ | |||
1 | obj-$(CONFIG_VHOST_NET) += vhost_net.o | 1 | obj-$(CONFIG_VHOST_NET) += vhost_net.o |
2 | vhost_net-y := vhost.o net.o | 2 | vhost_net-y := net.o |
3 | 3 | ||
4 | obj-$(CONFIG_VHOST_SCSI) += vhost_scsi.o | 4 | obj-$(CONFIG_VHOST_SCSI) += vhost_scsi.o |
5 | vhost_scsi-y := scsi.o | 5 | vhost_scsi-y := scsi.o |
6 | 6 | ||
7 | obj-$(CONFIG_VHOST_RING) += vringh.o | 7 | obj-$(CONFIG_VHOST_RING) += vringh.o |
8 | obj-$(CONFIG_VHOST) += vhost.o | ||
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 8ca5ac71b845..027be91db139 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c | |||
@@ -168,7 +168,7 @@ static void vhost_net_clear_ubuf_info(struct vhost_net *n) | |||
168 | } | 168 | } |
169 | } | 169 | } |
170 | 170 | ||
171 | int vhost_net_set_ubuf_info(struct vhost_net *n) | 171 | static int vhost_net_set_ubuf_info(struct vhost_net *n) |
172 | { | 172 | { |
173 | bool zcopy; | 173 | bool zcopy; |
174 | int i; | 174 | int i; |
@@ -189,7 +189,7 @@ err: | |||
189 | return -ENOMEM; | 189 | return -ENOMEM; |
190 | } | 190 | } |
191 | 191 | ||
192 | void vhost_net_vq_reset(struct vhost_net *n) | 192 | static void vhost_net_vq_reset(struct vhost_net *n) |
193 | { | 193 | { |
194 | int i; | 194 | int i; |
195 | 195 | ||
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 701420297225..4264840ef7dc 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c | |||
@@ -49,7 +49,6 @@ | |||
49 | #include <linux/llist.h> | 49 | #include <linux/llist.h> |
50 | #include <linux/bitmap.h> | 50 | #include <linux/bitmap.h> |
51 | 51 | ||
52 | #include "vhost.c" | ||
53 | #include "vhost.h" | 52 | #include "vhost.h" |
54 | 53 | ||
55 | #define TCM_VHOST_VERSION "v0.1" | 54 | #define TCM_VHOST_VERSION "v0.1" |
@@ -116,7 +115,6 @@ struct tcm_vhost_nacl { | |||
116 | struct se_node_acl se_node_acl; | 115 | struct se_node_acl se_node_acl; |
117 | }; | 116 | }; |
118 | 117 | ||
119 | struct vhost_scsi; | ||
120 | struct tcm_vhost_tpg { | 118 | struct tcm_vhost_tpg { |
121 | /* Vhost port target portal group tag for TCM */ | 119 | /* Vhost port target portal group tag for TCM */ |
122 | u16 tport_tpgt; | 120 | u16 tport_tpgt; |
@@ -218,7 +216,7 @@ static int iov_num_pages(struct iovec *iov) | |||
218 | ((unsigned long)iov->iov_base & PAGE_MASK)) >> PAGE_SHIFT; | 216 | ((unsigned long)iov->iov_base & PAGE_MASK)) >> PAGE_SHIFT; |
219 | } | 217 | } |
220 | 218 | ||
221 | void tcm_vhost_done_inflight(struct kref *kref) | 219 | static void tcm_vhost_done_inflight(struct kref *kref) |
222 | { | 220 | { |
223 | struct vhost_scsi_inflight *inflight; | 221 | struct vhost_scsi_inflight *inflight; |
224 | 222 | ||
@@ -329,11 +327,12 @@ static u32 tcm_vhost_get_default_depth(struct se_portal_group *se_tpg) | |||
329 | return 1; | 327 | return 1; |
330 | } | 328 | } |
331 | 329 | ||
332 | static u32 tcm_vhost_get_pr_transport_id(struct se_portal_group *se_tpg, | 330 | static u32 |
333 | struct se_node_acl *se_nacl, | 331 | tcm_vhost_get_pr_transport_id(struct se_portal_group *se_tpg, |
334 | struct t10_pr_registration *pr_reg, | 332 | struct se_node_acl *se_nacl, |
335 | int *format_code, | 333 | struct t10_pr_registration *pr_reg, |
336 | unsigned char *buf) | 334 | int *format_code, |
335 | unsigned char *buf) | ||
337 | { | 336 | { |
338 | struct tcm_vhost_tpg *tpg = container_of(se_tpg, | 337 | struct tcm_vhost_tpg *tpg = container_of(se_tpg, |
339 | struct tcm_vhost_tpg, se_tpg); | 338 | struct tcm_vhost_tpg, se_tpg); |
@@ -359,10 +358,11 @@ static u32 tcm_vhost_get_pr_transport_id(struct se_portal_group *se_tpg, | |||
359 | format_code, buf); | 358 | format_code, buf); |
360 | } | 359 | } |
361 | 360 | ||
362 | static u32 tcm_vhost_get_pr_transport_id_len(struct se_portal_group *se_tpg, | 361 | static u32 |
363 | struct se_node_acl *se_nacl, | 362 | tcm_vhost_get_pr_transport_id_len(struct se_portal_group *se_tpg, |
364 | struct t10_pr_registration *pr_reg, | 363 | struct se_node_acl *se_nacl, |
365 | int *format_code) | 364 | struct t10_pr_registration *pr_reg, |
365 | int *format_code) | ||
366 | { | 366 | { |
367 | struct tcm_vhost_tpg *tpg = container_of(se_tpg, | 367 | struct tcm_vhost_tpg *tpg = container_of(se_tpg, |
368 | struct tcm_vhost_tpg, se_tpg); | 368 | struct tcm_vhost_tpg, se_tpg); |
@@ -388,10 +388,11 @@ static u32 tcm_vhost_get_pr_transport_id_len(struct se_portal_group *se_tpg, | |||
388 | format_code); | 388 | format_code); |
389 | } | 389 | } |
390 | 390 | ||
391 | static char *tcm_vhost_parse_pr_out_transport_id(struct se_portal_group *se_tpg, | 391 | static char * |
392 | const char *buf, | 392 | tcm_vhost_parse_pr_out_transport_id(struct se_portal_group *se_tpg, |
393 | u32 *out_tid_len, | 393 | const char *buf, |
394 | char **port_nexus_ptr) | 394 | u32 *out_tid_len, |
395 | char **port_nexus_ptr) | ||
395 | { | 396 | { |
396 | struct tcm_vhost_tpg *tpg = container_of(se_tpg, | 397 | struct tcm_vhost_tpg *tpg = container_of(se_tpg, |
397 | struct tcm_vhost_tpg, se_tpg); | 398 | struct tcm_vhost_tpg, se_tpg); |
@@ -417,8 +418,8 @@ static char *tcm_vhost_parse_pr_out_transport_id(struct se_portal_group *se_tpg, | |||
417 | port_nexus_ptr); | 418 | port_nexus_ptr); |
418 | } | 419 | } |
419 | 420 | ||
420 | static struct se_node_acl *tcm_vhost_alloc_fabric_acl( | 421 | static struct se_node_acl * |
421 | struct se_portal_group *se_tpg) | 422 | tcm_vhost_alloc_fabric_acl(struct se_portal_group *se_tpg) |
422 | { | 423 | { |
423 | struct tcm_vhost_nacl *nacl; | 424 | struct tcm_vhost_nacl *nacl; |
424 | 425 | ||
@@ -431,8 +432,9 @@ static struct se_node_acl *tcm_vhost_alloc_fabric_acl( | |||
431 | return &nacl->se_node_acl; | 432 | return &nacl->se_node_acl; |
432 | } | 433 | } |
433 | 434 | ||
434 | static void tcm_vhost_release_fabric_acl(struct se_portal_group *se_tpg, | 435 | static void |
435 | struct se_node_acl *se_nacl) | 436 | tcm_vhost_release_fabric_acl(struct se_portal_group *se_tpg, |
437 | struct se_node_acl *se_nacl) | ||
436 | { | 438 | { |
437 | struct tcm_vhost_nacl *nacl = container_of(se_nacl, | 439 | struct tcm_vhost_nacl *nacl = container_of(se_nacl, |
438 | struct tcm_vhost_nacl, se_node_acl); | 440 | struct tcm_vhost_nacl, se_node_acl); |
@@ -491,28 +493,28 @@ static int tcm_vhost_get_cmd_state(struct se_cmd *se_cmd) | |||
491 | return 0; | 493 | return 0; |
492 | } | 494 | } |
493 | 495 | ||
494 | static void vhost_scsi_complete_cmd(struct tcm_vhost_cmd *tv_cmd) | 496 | static void vhost_scsi_complete_cmd(struct tcm_vhost_cmd *cmd) |
495 | { | 497 | { |
496 | struct vhost_scsi *vs = tv_cmd->tvc_vhost; | 498 | struct vhost_scsi *vs = cmd->tvc_vhost; |
497 | 499 | ||
498 | llist_add(&tv_cmd->tvc_completion_list, &vs->vs_completion_list); | 500 | llist_add(&cmd->tvc_completion_list, &vs->vs_completion_list); |
499 | 501 | ||
500 | vhost_work_queue(&vs->dev, &vs->vs_completion_work); | 502 | vhost_work_queue(&vs->dev, &vs->vs_completion_work); |
501 | } | 503 | } |
502 | 504 | ||
503 | static int tcm_vhost_queue_data_in(struct se_cmd *se_cmd) | 505 | static int tcm_vhost_queue_data_in(struct se_cmd *se_cmd) |
504 | { | 506 | { |
505 | struct tcm_vhost_cmd *tv_cmd = container_of(se_cmd, | 507 | struct tcm_vhost_cmd *cmd = container_of(se_cmd, |
506 | struct tcm_vhost_cmd, tvc_se_cmd); | 508 | struct tcm_vhost_cmd, tvc_se_cmd); |
507 | vhost_scsi_complete_cmd(tv_cmd); | 509 | vhost_scsi_complete_cmd(cmd); |
508 | return 0; | 510 | return 0; |
509 | } | 511 | } |
510 | 512 | ||
511 | static int tcm_vhost_queue_status(struct se_cmd *se_cmd) | 513 | static int tcm_vhost_queue_status(struct se_cmd *se_cmd) |
512 | { | 514 | { |
513 | struct tcm_vhost_cmd *tv_cmd = container_of(se_cmd, | 515 | struct tcm_vhost_cmd *cmd = container_of(se_cmd, |
514 | struct tcm_vhost_cmd, tvc_se_cmd); | 516 | struct tcm_vhost_cmd, tvc_se_cmd); |
515 | vhost_scsi_complete_cmd(tv_cmd); | 517 | vhost_scsi_complete_cmd(cmd); |
516 | return 0; | 518 | return 0; |
517 | } | 519 | } |
518 | 520 | ||
@@ -527,8 +529,9 @@ static void tcm_vhost_free_evt(struct vhost_scsi *vs, struct tcm_vhost_evt *evt) | |||
527 | kfree(evt); | 529 | kfree(evt); |
528 | } | 530 | } |
529 | 531 | ||
530 | static struct tcm_vhost_evt *tcm_vhost_allocate_evt(struct vhost_scsi *vs, | 532 | static struct tcm_vhost_evt * |
531 | u32 event, u32 reason) | 533 | tcm_vhost_allocate_evt(struct vhost_scsi *vs, |
534 | u32 event, u32 reason) | ||
532 | { | 535 | { |
533 | struct vhost_virtqueue *vq = &vs->vqs[VHOST_SCSI_VQ_EVT].vq; | 536 | struct vhost_virtqueue *vq = &vs->vqs[VHOST_SCSI_VQ_EVT].vq; |
534 | struct tcm_vhost_evt *evt; | 537 | struct tcm_vhost_evt *evt; |
@@ -552,28 +555,28 @@ static struct tcm_vhost_evt *tcm_vhost_allocate_evt(struct vhost_scsi *vs, | |||
552 | return evt; | 555 | return evt; |
553 | } | 556 | } |
554 | 557 | ||
555 | static void vhost_scsi_free_cmd(struct tcm_vhost_cmd *tv_cmd) | 558 | static void vhost_scsi_free_cmd(struct tcm_vhost_cmd *cmd) |
556 | { | 559 | { |
557 | struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd; | 560 | struct se_cmd *se_cmd = &cmd->tvc_se_cmd; |
558 | 561 | ||
559 | /* TODO locking against target/backend threads? */ | 562 | /* TODO locking against target/backend threads? */ |
560 | transport_generic_free_cmd(se_cmd, 1); | 563 | transport_generic_free_cmd(se_cmd, 1); |
561 | 564 | ||
562 | if (tv_cmd->tvc_sgl_count) { | 565 | if (cmd->tvc_sgl_count) { |
563 | u32 i; | 566 | u32 i; |
564 | for (i = 0; i < tv_cmd->tvc_sgl_count; i++) | 567 | for (i = 0; i < cmd->tvc_sgl_count; i++) |
565 | put_page(sg_page(&tv_cmd->tvc_sgl[i])); | 568 | put_page(sg_page(&cmd->tvc_sgl[i])); |
566 | 569 | ||
567 | kfree(tv_cmd->tvc_sgl); | 570 | kfree(cmd->tvc_sgl); |
568 | } | 571 | } |
569 | 572 | ||
570 | tcm_vhost_put_inflight(tv_cmd->inflight); | 573 | tcm_vhost_put_inflight(cmd->inflight); |
571 | 574 | ||
572 | kfree(tv_cmd); | 575 | kfree(cmd); |
573 | } | 576 | } |
574 | 577 | ||
575 | static void tcm_vhost_do_evt_work(struct vhost_scsi *vs, | 578 | static void |
576 | struct tcm_vhost_evt *evt) | 579 | tcm_vhost_do_evt_work(struct vhost_scsi *vs, struct tcm_vhost_evt *evt) |
577 | { | 580 | { |
578 | struct vhost_virtqueue *vq = &vs->vqs[VHOST_SCSI_VQ_EVT].vq; | 581 | struct vhost_virtqueue *vq = &vs->vqs[VHOST_SCSI_VQ_EVT].vq; |
579 | struct virtio_scsi_event *event = &evt->event; | 582 | struct virtio_scsi_event *event = &evt->event; |
@@ -652,7 +655,7 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work *work) | |||
652 | vs_completion_work); | 655 | vs_completion_work); |
653 | DECLARE_BITMAP(signal, VHOST_SCSI_MAX_VQ); | 656 | DECLARE_BITMAP(signal, VHOST_SCSI_MAX_VQ); |
654 | struct virtio_scsi_cmd_resp v_rsp; | 657 | struct virtio_scsi_cmd_resp v_rsp; |
655 | struct tcm_vhost_cmd *tv_cmd; | 658 | struct tcm_vhost_cmd *cmd; |
656 | struct llist_node *llnode; | 659 | struct llist_node *llnode; |
657 | struct se_cmd *se_cmd; | 660 | struct se_cmd *se_cmd; |
658 | int ret, vq; | 661 | int ret, vq; |
@@ -660,32 +663,32 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work *work) | |||
660 | bitmap_zero(signal, VHOST_SCSI_MAX_VQ); | 663 | bitmap_zero(signal, VHOST_SCSI_MAX_VQ); |
661 | llnode = llist_del_all(&vs->vs_completion_list); | 664 | llnode = llist_del_all(&vs->vs_completion_list); |
662 | while (llnode) { | 665 | while (llnode) { |
663 | tv_cmd = llist_entry(llnode, struct tcm_vhost_cmd, | 666 | cmd = llist_entry(llnode, struct tcm_vhost_cmd, |
664 | tvc_completion_list); | 667 | tvc_completion_list); |
665 | llnode = llist_next(llnode); | 668 | llnode = llist_next(llnode); |
666 | se_cmd = &tv_cmd->tvc_se_cmd; | 669 | se_cmd = &cmd->tvc_se_cmd; |
667 | 670 | ||
668 | pr_debug("%s tv_cmd %p resid %u status %#02x\n", __func__, | 671 | pr_debug("%s tv_cmd %p resid %u status %#02x\n", __func__, |
669 | tv_cmd, se_cmd->residual_count, se_cmd->scsi_status); | 672 | cmd, se_cmd->residual_count, se_cmd->scsi_status); |
670 | 673 | ||
671 | memset(&v_rsp, 0, sizeof(v_rsp)); | 674 | memset(&v_rsp, 0, sizeof(v_rsp)); |
672 | v_rsp.resid = se_cmd->residual_count; | 675 | v_rsp.resid = se_cmd->residual_count; |
673 | /* TODO is status_qualifier field needed? */ | 676 | /* TODO is status_qualifier field needed? */ |
674 | v_rsp.status = se_cmd->scsi_status; | 677 | v_rsp.status = se_cmd->scsi_status; |
675 | v_rsp.sense_len = se_cmd->scsi_sense_length; | 678 | v_rsp.sense_len = se_cmd->scsi_sense_length; |
676 | memcpy(v_rsp.sense, tv_cmd->tvc_sense_buf, | 679 | memcpy(v_rsp.sense, cmd->tvc_sense_buf, |
677 | v_rsp.sense_len); | 680 | v_rsp.sense_len); |
678 | ret = copy_to_user(tv_cmd->tvc_resp, &v_rsp, sizeof(v_rsp)); | 681 | ret = copy_to_user(cmd->tvc_resp, &v_rsp, sizeof(v_rsp)); |
679 | if (likely(ret == 0)) { | 682 | if (likely(ret == 0)) { |
680 | struct vhost_scsi_virtqueue *q; | 683 | struct vhost_scsi_virtqueue *q; |
681 | vhost_add_used(tv_cmd->tvc_vq, tv_cmd->tvc_vq_desc, 0); | 684 | vhost_add_used(cmd->tvc_vq, cmd->tvc_vq_desc, 0); |
682 | q = container_of(tv_cmd->tvc_vq, struct vhost_scsi_virtqueue, vq); | 685 | q = container_of(cmd->tvc_vq, struct vhost_scsi_virtqueue, vq); |
683 | vq = q - vs->vqs; | 686 | vq = q - vs->vqs; |
684 | __set_bit(vq, signal); | 687 | __set_bit(vq, signal); |
685 | } else | 688 | } else |
686 | pr_err("Faulted on virtio_scsi_cmd_resp\n"); | 689 | pr_err("Faulted on virtio_scsi_cmd_resp\n"); |
687 | 690 | ||
688 | vhost_scsi_free_cmd(tv_cmd); | 691 | vhost_scsi_free_cmd(cmd); |
689 | } | 692 | } |
690 | 693 | ||
691 | vq = -1; | 694 | vq = -1; |
@@ -694,35 +697,35 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work *work) | |||
694 | vhost_signal(&vs->dev, &vs->vqs[vq].vq); | 697 | vhost_signal(&vs->dev, &vs->vqs[vq].vq); |
695 | } | 698 | } |
696 | 699 | ||
697 | static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd( | 700 | static struct tcm_vhost_cmd * |
698 | struct vhost_virtqueue *vq, | 701 | vhost_scsi_allocate_cmd(struct vhost_virtqueue *vq, |
699 | struct tcm_vhost_tpg *tv_tpg, | 702 | struct tcm_vhost_tpg *tpg, |
700 | struct virtio_scsi_cmd_req *v_req, | 703 | struct virtio_scsi_cmd_req *v_req, |
701 | u32 exp_data_len, | 704 | u32 exp_data_len, |
702 | int data_direction) | 705 | int data_direction) |
703 | { | 706 | { |
704 | struct tcm_vhost_cmd *tv_cmd; | 707 | struct tcm_vhost_cmd *cmd; |
705 | struct tcm_vhost_nexus *tv_nexus; | 708 | struct tcm_vhost_nexus *tv_nexus; |
706 | 709 | ||
707 | tv_nexus = tv_tpg->tpg_nexus; | 710 | tv_nexus = tpg->tpg_nexus; |
708 | if (!tv_nexus) { | 711 | if (!tv_nexus) { |
709 | pr_err("Unable to locate active struct tcm_vhost_nexus\n"); | 712 | pr_err("Unable to locate active struct tcm_vhost_nexus\n"); |
710 | return ERR_PTR(-EIO); | 713 | return ERR_PTR(-EIO); |
711 | } | 714 | } |
712 | 715 | ||
713 | tv_cmd = kzalloc(sizeof(struct tcm_vhost_cmd), GFP_ATOMIC); | 716 | cmd = kzalloc(sizeof(struct tcm_vhost_cmd), GFP_ATOMIC); |
714 | if (!tv_cmd) { | 717 | if (!cmd) { |
715 | pr_err("Unable to allocate struct tcm_vhost_cmd\n"); | 718 | pr_err("Unable to allocate struct tcm_vhost_cmd\n"); |
716 | return ERR_PTR(-ENOMEM); | 719 | return ERR_PTR(-ENOMEM); |
717 | } | 720 | } |
718 | tv_cmd->tvc_tag = v_req->tag; | 721 | cmd->tvc_tag = v_req->tag; |
719 | tv_cmd->tvc_task_attr = v_req->task_attr; | 722 | cmd->tvc_task_attr = v_req->task_attr; |
720 | tv_cmd->tvc_exp_data_len = exp_data_len; | 723 | cmd->tvc_exp_data_len = exp_data_len; |
721 | tv_cmd->tvc_data_direction = data_direction; | 724 | cmd->tvc_data_direction = data_direction; |
722 | tv_cmd->tvc_nexus = tv_nexus; | 725 | cmd->tvc_nexus = tv_nexus; |
723 | tv_cmd->inflight = tcm_vhost_get_inflight(vq); | 726 | cmd->inflight = tcm_vhost_get_inflight(vq); |
724 | 727 | ||
725 | return tv_cmd; | 728 | return cmd; |
726 | } | 729 | } |
727 | 730 | ||
728 | /* | 731 | /* |
@@ -730,8 +733,11 @@ static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd( | |||
730 | * | 733 | * |
731 | * Returns the number of scatterlist entries used or -errno on error. | 734 | * Returns the number of scatterlist entries used or -errno on error. |
732 | */ | 735 | */ |
733 | static int vhost_scsi_map_to_sgl(struct scatterlist *sgl, | 736 | static int |
734 | unsigned int sgl_count, struct iovec *iov, int write) | 737 | vhost_scsi_map_to_sgl(struct scatterlist *sgl, |
738 | unsigned int sgl_count, | ||
739 | struct iovec *iov, | ||
740 | int write) | ||
735 | { | 741 | { |
736 | unsigned int npages = 0, pages_nr, offset, nbytes; | 742 | unsigned int npages = 0, pages_nr, offset, nbytes; |
737 | struct scatterlist *sg = sgl; | 743 | struct scatterlist *sg = sgl; |
@@ -775,8 +781,11 @@ out: | |||
775 | return ret; | 781 | return ret; |
776 | } | 782 | } |
777 | 783 | ||
778 | static int vhost_scsi_map_iov_to_sgl(struct tcm_vhost_cmd *tv_cmd, | 784 | static int |
779 | struct iovec *iov, unsigned int niov, int write) | 785 | vhost_scsi_map_iov_to_sgl(struct tcm_vhost_cmd *cmd, |
786 | struct iovec *iov, | ||
787 | unsigned int niov, | ||
788 | int write) | ||
780 | { | 789 | { |
781 | int ret; | 790 | int ret; |
782 | unsigned int i; | 791 | unsigned int i; |
@@ -792,25 +801,25 @@ static int vhost_scsi_map_iov_to_sgl(struct tcm_vhost_cmd *tv_cmd, | |||
792 | 801 | ||
793 | /* TODO overflow checking */ | 802 | /* TODO overflow checking */ |
794 | 803 | ||
795 | sg = kmalloc(sizeof(tv_cmd->tvc_sgl[0]) * sgl_count, GFP_ATOMIC); | 804 | sg = kmalloc(sizeof(cmd->tvc_sgl[0]) * sgl_count, GFP_ATOMIC); |
796 | if (!sg) | 805 | if (!sg) |
797 | return -ENOMEM; | 806 | return -ENOMEM; |
798 | pr_debug("%s sg %p sgl_count %u is_err %d\n", __func__, | 807 | pr_debug("%s sg %p sgl_count %u is_err %d\n", __func__, |
799 | sg, sgl_count, !sg); | 808 | sg, sgl_count, !sg); |
800 | sg_init_table(sg, sgl_count); | 809 | sg_init_table(sg, sgl_count); |
801 | 810 | ||
802 | tv_cmd->tvc_sgl = sg; | 811 | cmd->tvc_sgl = sg; |
803 | tv_cmd->tvc_sgl_count = sgl_count; | 812 | cmd->tvc_sgl_count = sgl_count; |
804 | 813 | ||
805 | pr_debug("Mapping %u iovecs for %u pages\n", niov, sgl_count); | 814 | pr_debug("Mapping %u iovecs for %u pages\n", niov, sgl_count); |
806 | for (i = 0; i < niov; i++) { | 815 | for (i = 0; i < niov; i++) { |
807 | ret = vhost_scsi_map_to_sgl(sg, sgl_count, &iov[i], write); | 816 | ret = vhost_scsi_map_to_sgl(sg, sgl_count, &iov[i], write); |
808 | if (ret < 0) { | 817 | if (ret < 0) { |
809 | for (i = 0; i < tv_cmd->tvc_sgl_count; i++) | 818 | for (i = 0; i < cmd->tvc_sgl_count; i++) |
810 | put_page(sg_page(&tv_cmd->tvc_sgl[i])); | 819 | put_page(sg_page(&cmd->tvc_sgl[i])); |
811 | kfree(tv_cmd->tvc_sgl); | 820 | kfree(cmd->tvc_sgl); |
812 | tv_cmd->tvc_sgl = NULL; | 821 | cmd->tvc_sgl = NULL; |
813 | tv_cmd->tvc_sgl_count = 0; | 822 | cmd->tvc_sgl_count = 0; |
814 | return ret; | 823 | return ret; |
815 | } | 824 | } |
816 | 825 | ||
@@ -822,15 +831,15 @@ static int vhost_scsi_map_iov_to_sgl(struct tcm_vhost_cmd *tv_cmd, | |||
822 | 831 | ||
823 | static void tcm_vhost_submission_work(struct work_struct *work) | 832 | static void tcm_vhost_submission_work(struct work_struct *work) |
824 | { | 833 | { |
825 | struct tcm_vhost_cmd *tv_cmd = | 834 | struct tcm_vhost_cmd *cmd = |
826 | container_of(work, struct tcm_vhost_cmd, work); | 835 | container_of(work, struct tcm_vhost_cmd, work); |
827 | struct tcm_vhost_nexus *tv_nexus; | 836 | struct tcm_vhost_nexus *tv_nexus; |
828 | struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd; | 837 | struct se_cmd *se_cmd = &cmd->tvc_se_cmd; |
829 | struct scatterlist *sg_ptr, *sg_bidi_ptr = NULL; | 838 | struct scatterlist *sg_ptr, *sg_bidi_ptr = NULL; |
830 | int rc, sg_no_bidi = 0; | 839 | int rc, sg_no_bidi = 0; |
831 | 840 | ||
832 | if (tv_cmd->tvc_sgl_count) { | 841 | if (cmd->tvc_sgl_count) { |
833 | sg_ptr = tv_cmd->tvc_sgl; | 842 | sg_ptr = cmd->tvc_sgl; |
834 | /* FIXME: Fix BIDI operation in tcm_vhost_submission_work() */ | 843 | /* FIXME: Fix BIDI operation in tcm_vhost_submission_work() */ |
835 | #if 0 | 844 | #if 0 |
836 | if (se_cmd->se_cmd_flags & SCF_BIDI) { | 845 | if (se_cmd->se_cmd_flags & SCF_BIDI) { |
@@ -841,13 +850,13 @@ static void tcm_vhost_submission_work(struct work_struct *work) | |||
841 | } else { | 850 | } else { |
842 | sg_ptr = NULL; | 851 | sg_ptr = NULL; |
843 | } | 852 | } |
844 | tv_nexus = tv_cmd->tvc_nexus; | 853 | tv_nexus = cmd->tvc_nexus; |
845 | 854 | ||
846 | rc = target_submit_cmd_map_sgls(se_cmd, tv_nexus->tvn_se_sess, | 855 | rc = target_submit_cmd_map_sgls(se_cmd, tv_nexus->tvn_se_sess, |
847 | tv_cmd->tvc_cdb, &tv_cmd->tvc_sense_buf[0], | 856 | cmd->tvc_cdb, &cmd->tvc_sense_buf[0], |
848 | tv_cmd->tvc_lun, tv_cmd->tvc_exp_data_len, | 857 | cmd->tvc_lun, cmd->tvc_exp_data_len, |
849 | tv_cmd->tvc_task_attr, tv_cmd->tvc_data_direction, | 858 | cmd->tvc_task_attr, cmd->tvc_data_direction, |
850 | 0, sg_ptr, tv_cmd->tvc_sgl_count, | 859 | 0, sg_ptr, cmd->tvc_sgl_count, |
851 | sg_bidi_ptr, sg_no_bidi); | 860 | sg_bidi_ptr, sg_no_bidi); |
852 | if (rc < 0) { | 861 | if (rc < 0) { |
853 | transport_send_check_condition_and_sense(se_cmd, | 862 | transport_send_check_condition_and_sense(se_cmd, |
@@ -856,8 +865,10 @@ static void tcm_vhost_submission_work(struct work_struct *work) | |||
856 | } | 865 | } |
857 | } | 866 | } |
858 | 867 | ||
859 | static void vhost_scsi_send_bad_target(struct vhost_scsi *vs, | 868 | static void |
860 | struct vhost_virtqueue *vq, int head, unsigned out) | 869 | vhost_scsi_send_bad_target(struct vhost_scsi *vs, |
870 | struct vhost_virtqueue *vq, | ||
871 | int head, unsigned out) | ||
861 | { | 872 | { |
862 | struct virtio_scsi_cmd_resp __user *resp; | 873 | struct virtio_scsi_cmd_resp __user *resp; |
863 | struct virtio_scsi_cmd_resp rsp; | 874 | struct virtio_scsi_cmd_resp rsp; |
@@ -873,13 +884,13 @@ static void vhost_scsi_send_bad_target(struct vhost_scsi *vs, | |||
873 | pr_err("Faulted on virtio_scsi_cmd_resp\n"); | 884 | pr_err("Faulted on virtio_scsi_cmd_resp\n"); |
874 | } | 885 | } |
875 | 886 | ||
876 | static void vhost_scsi_handle_vq(struct vhost_scsi *vs, | 887 | static void |
877 | struct vhost_virtqueue *vq) | 888 | vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq) |
878 | { | 889 | { |
879 | struct tcm_vhost_tpg **vs_tpg; | 890 | struct tcm_vhost_tpg **vs_tpg; |
880 | struct virtio_scsi_cmd_req v_req; | 891 | struct virtio_scsi_cmd_req v_req; |
881 | struct tcm_vhost_tpg *tv_tpg; | 892 | struct tcm_vhost_tpg *tpg; |
882 | struct tcm_vhost_cmd *tv_cmd; | 893 | struct tcm_vhost_cmd *cmd; |
883 | u32 exp_data_len, data_first, data_num, data_direction; | 894 | u32 exp_data_len, data_first, data_num, data_direction; |
884 | unsigned out, in, i; | 895 | unsigned out, in, i; |
885 | int head, ret; | 896 | int head, ret; |
@@ -964,10 +975,10 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs, | |||
964 | 975 | ||
965 | /* Extract the tpgt */ | 976 | /* Extract the tpgt */ |
966 | target = v_req.lun[1]; | 977 | target = v_req.lun[1]; |
967 | tv_tpg = ACCESS_ONCE(vs_tpg[target]); | 978 | tpg = ACCESS_ONCE(vs_tpg[target]); |
968 | 979 | ||
969 | /* Target does not exist, fail the request */ | 980 | /* Target does not exist, fail the request */ |
970 | if (unlikely(!tv_tpg)) { | 981 | if (unlikely(!tpg)) { |
971 | vhost_scsi_send_bad_target(vs, vq, head, out); | 982 | vhost_scsi_send_bad_target(vs, vq, head, out); |
972 | continue; | 983 | continue; |
973 | } | 984 | } |
@@ -976,46 +987,46 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs, | |||
976 | for (i = 0; i < data_num; i++) | 987 | for (i = 0; i < data_num; i++) |
977 | exp_data_len += vq->iov[data_first + i].iov_len; | 988 | exp_data_len += vq->iov[data_first + i].iov_len; |
978 | 989 | ||
979 | tv_cmd = vhost_scsi_allocate_cmd(vq, tv_tpg, &v_req, | 990 | cmd = vhost_scsi_allocate_cmd(vq, tpg, &v_req, |
980 | exp_data_len, data_direction); | 991 | exp_data_len, data_direction); |
981 | if (IS_ERR(tv_cmd)) { | 992 | if (IS_ERR(cmd)) { |
982 | vq_err(vq, "vhost_scsi_allocate_cmd failed %ld\n", | 993 | vq_err(vq, "vhost_scsi_allocate_cmd failed %ld\n", |
983 | PTR_ERR(tv_cmd)); | 994 | PTR_ERR(cmd)); |
984 | goto err_cmd; | 995 | goto err_cmd; |
985 | } | 996 | } |
986 | pr_debug("Allocated tv_cmd: %p exp_data_len: %d, data_direction" | 997 | pr_debug("Allocated tv_cmd: %p exp_data_len: %d, data_direction" |
987 | ": %d\n", tv_cmd, exp_data_len, data_direction); | 998 | ": %d\n", cmd, exp_data_len, data_direction); |
988 | 999 | ||
989 | tv_cmd->tvc_vhost = vs; | 1000 | cmd->tvc_vhost = vs; |
990 | tv_cmd->tvc_vq = vq; | 1001 | cmd->tvc_vq = vq; |
991 | tv_cmd->tvc_resp = vq->iov[out].iov_base; | 1002 | cmd->tvc_resp = vq->iov[out].iov_base; |
992 | 1003 | ||
993 | /* | 1004 | /* |
994 | * Copy in the recieved CDB descriptor into tv_cmd->tvc_cdb | 1005 | * Copy in the recieved CDB descriptor into cmd->tvc_cdb |
995 | * that will be used by tcm_vhost_new_cmd_map() and down into | 1006 | * that will be used by tcm_vhost_new_cmd_map() and down into |
996 | * target_setup_cmd_from_cdb() | 1007 | * target_setup_cmd_from_cdb() |
997 | */ | 1008 | */ |
998 | memcpy(tv_cmd->tvc_cdb, v_req.cdb, TCM_VHOST_MAX_CDB_SIZE); | 1009 | memcpy(cmd->tvc_cdb, v_req.cdb, TCM_VHOST_MAX_CDB_SIZE); |
999 | /* | 1010 | /* |
1000 | * Check that the recieved CDB size does not exceeded our | 1011 | * Check that the recieved CDB size does not exceeded our |
1001 | * hardcoded max for tcm_vhost | 1012 | * hardcoded max for tcm_vhost |
1002 | */ | 1013 | */ |
1003 | /* TODO what if cdb was too small for varlen cdb header? */ | 1014 | /* TODO what if cdb was too small for varlen cdb header? */ |
1004 | if (unlikely(scsi_command_size(tv_cmd->tvc_cdb) > | 1015 | if (unlikely(scsi_command_size(cmd->tvc_cdb) > |
1005 | TCM_VHOST_MAX_CDB_SIZE)) { | 1016 | TCM_VHOST_MAX_CDB_SIZE)) { |
1006 | vq_err(vq, "Received SCSI CDB with command_size: %d that" | 1017 | vq_err(vq, "Received SCSI CDB with command_size: %d that" |
1007 | " exceeds SCSI_MAX_VARLEN_CDB_SIZE: %d\n", | 1018 | " exceeds SCSI_MAX_VARLEN_CDB_SIZE: %d\n", |
1008 | scsi_command_size(tv_cmd->tvc_cdb), | 1019 | scsi_command_size(cmd->tvc_cdb), |
1009 | TCM_VHOST_MAX_CDB_SIZE); | 1020 | TCM_VHOST_MAX_CDB_SIZE); |
1010 | goto err_free; | 1021 | goto err_free; |
1011 | } | 1022 | } |
1012 | tv_cmd->tvc_lun = ((v_req.lun[2] << 8) | v_req.lun[3]) & 0x3FFF; | 1023 | cmd->tvc_lun = ((v_req.lun[2] << 8) | v_req.lun[3]) & 0x3FFF; |
1013 | 1024 | ||
1014 | pr_debug("vhost_scsi got command opcode: %#02x, lun: %d\n", | 1025 | pr_debug("vhost_scsi got command opcode: %#02x, lun: %d\n", |
1015 | tv_cmd->tvc_cdb[0], tv_cmd->tvc_lun); | 1026 | cmd->tvc_cdb[0], cmd->tvc_lun); |
1016 | 1027 | ||
1017 | if (data_direction != DMA_NONE) { | 1028 | if (data_direction != DMA_NONE) { |
1018 | ret = vhost_scsi_map_iov_to_sgl(tv_cmd, | 1029 | ret = vhost_scsi_map_iov_to_sgl(cmd, |
1019 | &vq->iov[data_first], data_num, | 1030 | &vq->iov[data_first], data_num, |
1020 | data_direction == DMA_TO_DEVICE); | 1031 | data_direction == DMA_TO_DEVICE); |
1021 | if (unlikely(ret)) { | 1032 | if (unlikely(ret)) { |
@@ -1029,22 +1040,22 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs, | |||
1029 | * complete the virtio-scsi request in TCM callback context via | 1040 | * complete the virtio-scsi request in TCM callback context via |
1030 | * tcm_vhost_queue_data_in() and tcm_vhost_queue_status() | 1041 | * tcm_vhost_queue_data_in() and tcm_vhost_queue_status() |
1031 | */ | 1042 | */ |
1032 | tv_cmd->tvc_vq_desc = head; | 1043 | cmd->tvc_vq_desc = head; |
1033 | /* | 1044 | /* |
1034 | * Dispatch tv_cmd descriptor for cmwq execution in process | 1045 | * Dispatch tv_cmd descriptor for cmwq execution in process |
1035 | * context provided by tcm_vhost_workqueue. This also ensures | 1046 | * context provided by tcm_vhost_workqueue. This also ensures |
1036 | * tv_cmd is executed on the same kworker CPU as this vhost | 1047 | * tv_cmd is executed on the same kworker CPU as this vhost |
1037 | * thread to gain positive L2 cache locality effects.. | 1048 | * thread to gain positive L2 cache locality effects.. |
1038 | */ | 1049 | */ |
1039 | INIT_WORK(&tv_cmd->work, tcm_vhost_submission_work); | 1050 | INIT_WORK(&cmd->work, tcm_vhost_submission_work); |
1040 | queue_work(tcm_vhost_workqueue, &tv_cmd->work); | 1051 | queue_work(tcm_vhost_workqueue, &cmd->work); |
1041 | } | 1052 | } |
1042 | 1053 | ||
1043 | mutex_unlock(&vq->mutex); | 1054 | mutex_unlock(&vq->mutex); |
1044 | return; | 1055 | return; |
1045 | 1056 | ||
1046 | err_free: | 1057 | err_free: |
1047 | vhost_scsi_free_cmd(tv_cmd); | 1058 | vhost_scsi_free_cmd(cmd); |
1048 | err_cmd: | 1059 | err_cmd: |
1049 | vhost_scsi_send_bad_target(vs, vq, head, out); | 1060 | vhost_scsi_send_bad_target(vs, vq, head, out); |
1050 | mutex_unlock(&vq->mutex); | 1061 | mutex_unlock(&vq->mutex); |
@@ -1055,8 +1066,12 @@ static void vhost_scsi_ctl_handle_kick(struct vhost_work *work) | |||
1055 | pr_debug("%s: The handling func for control queue.\n", __func__); | 1066 | pr_debug("%s: The handling func for control queue.\n", __func__); |
1056 | } | 1067 | } |
1057 | 1068 | ||
1058 | static void tcm_vhost_send_evt(struct vhost_scsi *vs, struct tcm_vhost_tpg *tpg, | 1069 | static void |
1059 | struct se_lun *lun, u32 event, u32 reason) | 1070 | tcm_vhost_send_evt(struct vhost_scsi *vs, |
1071 | struct tcm_vhost_tpg *tpg, | ||
1072 | struct se_lun *lun, | ||
1073 | u32 event, | ||
1074 | u32 reason) | ||
1060 | { | 1075 | { |
1061 | struct tcm_vhost_evt *evt; | 1076 | struct tcm_vhost_evt *evt; |
1062 | 1077 | ||
@@ -1146,12 +1161,12 @@ static void vhost_scsi_flush(struct vhost_scsi *vs) | |||
1146 | * The lock nesting rule is: | 1161 | * The lock nesting rule is: |
1147 | * tcm_vhost_mutex -> vs->dev.mutex -> tpg->tv_tpg_mutex -> vq->mutex | 1162 | * tcm_vhost_mutex -> vs->dev.mutex -> tpg->tv_tpg_mutex -> vq->mutex |
1148 | */ | 1163 | */ |
1149 | static int vhost_scsi_set_endpoint( | 1164 | static int |
1150 | struct vhost_scsi *vs, | 1165 | vhost_scsi_set_endpoint(struct vhost_scsi *vs, |
1151 | struct vhost_scsi_target *t) | 1166 | struct vhost_scsi_target *t) |
1152 | { | 1167 | { |
1153 | struct tcm_vhost_tport *tv_tport; | 1168 | struct tcm_vhost_tport *tv_tport; |
1154 | struct tcm_vhost_tpg *tv_tpg; | 1169 | struct tcm_vhost_tpg *tpg; |
1155 | struct tcm_vhost_tpg **vs_tpg; | 1170 | struct tcm_vhost_tpg **vs_tpg; |
1156 | struct vhost_virtqueue *vq; | 1171 | struct vhost_virtqueue *vq; |
1157 | int index, ret, i, len; | 1172 | int index, ret, i, len; |
@@ -1178,32 +1193,32 @@ static int vhost_scsi_set_endpoint( | |||
1178 | if (vs->vs_tpg) | 1193 | if (vs->vs_tpg) |
1179 | memcpy(vs_tpg, vs->vs_tpg, len); | 1194 | memcpy(vs_tpg, vs->vs_tpg, len); |
1180 | 1195 | ||
1181 | list_for_each_entry(tv_tpg, &tcm_vhost_list, tv_tpg_list) { | 1196 | list_for_each_entry(tpg, &tcm_vhost_list, tv_tpg_list) { |
1182 | mutex_lock(&tv_tpg->tv_tpg_mutex); | 1197 | mutex_lock(&tpg->tv_tpg_mutex); |
1183 | if (!tv_tpg->tpg_nexus) { | 1198 | if (!tpg->tpg_nexus) { |
1184 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | 1199 | mutex_unlock(&tpg->tv_tpg_mutex); |
1185 | continue; | 1200 | continue; |
1186 | } | 1201 | } |
1187 | if (tv_tpg->tv_tpg_vhost_count != 0) { | 1202 | if (tpg->tv_tpg_vhost_count != 0) { |
1188 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | 1203 | mutex_unlock(&tpg->tv_tpg_mutex); |
1189 | continue; | 1204 | continue; |
1190 | } | 1205 | } |
1191 | tv_tport = tv_tpg->tport; | 1206 | tv_tport = tpg->tport; |
1192 | 1207 | ||
1193 | if (!strcmp(tv_tport->tport_name, t->vhost_wwpn)) { | 1208 | if (!strcmp(tv_tport->tport_name, t->vhost_wwpn)) { |
1194 | if (vs->vs_tpg && vs->vs_tpg[tv_tpg->tport_tpgt]) { | 1209 | if (vs->vs_tpg && vs->vs_tpg[tpg->tport_tpgt]) { |
1195 | kfree(vs_tpg); | 1210 | kfree(vs_tpg); |
1196 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | 1211 | mutex_unlock(&tpg->tv_tpg_mutex); |
1197 | ret = -EEXIST; | 1212 | ret = -EEXIST; |
1198 | goto out; | 1213 | goto out; |
1199 | } | 1214 | } |
1200 | tv_tpg->tv_tpg_vhost_count++; | 1215 | tpg->tv_tpg_vhost_count++; |
1201 | tv_tpg->vhost_scsi = vs; | 1216 | tpg->vhost_scsi = vs; |
1202 | vs_tpg[tv_tpg->tport_tpgt] = tv_tpg; | 1217 | vs_tpg[tpg->tport_tpgt] = tpg; |
1203 | smp_mb__after_atomic_inc(); | 1218 | smp_mb__after_atomic_inc(); |
1204 | match = true; | 1219 | match = true; |
1205 | } | 1220 | } |
1206 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | 1221 | mutex_unlock(&tpg->tv_tpg_mutex); |
1207 | } | 1222 | } |
1208 | 1223 | ||
1209 | if (match) { | 1224 | if (match) { |
@@ -1236,12 +1251,12 @@ out: | |||
1236 | return ret; | 1251 | return ret; |
1237 | } | 1252 | } |
1238 | 1253 | ||
1239 | static int vhost_scsi_clear_endpoint( | 1254 | static int |
1240 | struct vhost_scsi *vs, | 1255 | vhost_scsi_clear_endpoint(struct vhost_scsi *vs, |
1241 | struct vhost_scsi_target *t) | 1256 | struct vhost_scsi_target *t) |
1242 | { | 1257 | { |
1243 | struct tcm_vhost_tport *tv_tport; | 1258 | struct tcm_vhost_tport *tv_tport; |
1244 | struct tcm_vhost_tpg *tv_tpg; | 1259 | struct tcm_vhost_tpg *tpg; |
1245 | struct vhost_virtqueue *vq; | 1260 | struct vhost_virtqueue *vq; |
1246 | bool match = false; | 1261 | bool match = false; |
1247 | int index, ret, i; | 1262 | int index, ret, i; |
@@ -1264,30 +1279,30 @@ static int vhost_scsi_clear_endpoint( | |||
1264 | 1279 | ||
1265 | for (i = 0; i < VHOST_SCSI_MAX_TARGET; i++) { | 1280 | for (i = 0; i < VHOST_SCSI_MAX_TARGET; i++) { |
1266 | target = i; | 1281 | target = i; |
1267 | tv_tpg = vs->vs_tpg[target]; | 1282 | tpg = vs->vs_tpg[target]; |
1268 | if (!tv_tpg) | 1283 | if (!tpg) |
1269 | continue; | 1284 | continue; |
1270 | 1285 | ||
1271 | mutex_lock(&tv_tpg->tv_tpg_mutex); | 1286 | mutex_lock(&tpg->tv_tpg_mutex); |
1272 | tv_tport = tv_tpg->tport; | 1287 | tv_tport = tpg->tport; |
1273 | if (!tv_tport) { | 1288 | if (!tv_tport) { |
1274 | ret = -ENODEV; | 1289 | ret = -ENODEV; |
1275 | goto err_tpg; | 1290 | goto err_tpg; |
1276 | } | 1291 | } |
1277 | 1292 | ||
1278 | if (strcmp(tv_tport->tport_name, t->vhost_wwpn)) { | 1293 | if (strcmp(tv_tport->tport_name, t->vhost_wwpn)) { |
1279 | pr_warn("tv_tport->tport_name: %s, tv_tpg->tport_tpgt: %hu" | 1294 | pr_warn("tv_tport->tport_name: %s, tpg->tport_tpgt: %hu" |
1280 | " does not match t->vhost_wwpn: %s, t->vhost_tpgt: %hu\n", | 1295 | " does not match t->vhost_wwpn: %s, t->vhost_tpgt: %hu\n", |
1281 | tv_tport->tport_name, tv_tpg->tport_tpgt, | 1296 | tv_tport->tport_name, tpg->tport_tpgt, |
1282 | t->vhost_wwpn, t->vhost_tpgt); | 1297 | t->vhost_wwpn, t->vhost_tpgt); |
1283 | ret = -EINVAL; | 1298 | ret = -EINVAL; |
1284 | goto err_tpg; | 1299 | goto err_tpg; |
1285 | } | 1300 | } |
1286 | tv_tpg->tv_tpg_vhost_count--; | 1301 | tpg->tv_tpg_vhost_count--; |
1287 | tv_tpg->vhost_scsi = NULL; | 1302 | tpg->vhost_scsi = NULL; |
1288 | vs->vs_tpg[target] = NULL; | 1303 | vs->vs_tpg[target] = NULL; |
1289 | match = true; | 1304 | match = true; |
1290 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | 1305 | mutex_unlock(&tpg->tv_tpg_mutex); |
1291 | } | 1306 | } |
1292 | if (match) { | 1307 | if (match) { |
1293 | for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) { | 1308 | for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) { |
@@ -1311,7 +1326,7 @@ static int vhost_scsi_clear_endpoint( | |||
1311 | return 0; | 1326 | return 0; |
1312 | 1327 | ||
1313 | err_tpg: | 1328 | err_tpg: |
1314 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | 1329 | mutex_unlock(&tpg->tv_tpg_mutex); |
1315 | err_dev: | 1330 | err_dev: |
1316 | mutex_unlock(&vs->dev.mutex); | 1331 | mutex_unlock(&vs->dev.mutex); |
1317 | mutex_unlock(&tcm_vhost_mutex); | 1332 | mutex_unlock(&tcm_vhost_mutex); |
@@ -1338,68 +1353,70 @@ static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features) | |||
1338 | 1353 | ||
1339 | static int vhost_scsi_open(struct inode *inode, struct file *f) | 1354 | static int vhost_scsi_open(struct inode *inode, struct file *f) |
1340 | { | 1355 | { |
1341 | struct vhost_scsi *s; | 1356 | struct vhost_scsi *vs; |
1342 | struct vhost_virtqueue **vqs; | 1357 | struct vhost_virtqueue **vqs; |
1343 | int r, i; | 1358 | int r, i; |
1344 | 1359 | ||
1345 | s = kzalloc(sizeof(*s), GFP_KERNEL); | 1360 | vs = kzalloc(sizeof(*vs), GFP_KERNEL); |
1346 | if (!s) | 1361 | if (!vs) |
1347 | return -ENOMEM; | 1362 | return -ENOMEM; |
1348 | 1363 | ||
1349 | vqs = kmalloc(VHOST_SCSI_MAX_VQ * sizeof(*vqs), GFP_KERNEL); | 1364 | vqs = kmalloc(VHOST_SCSI_MAX_VQ * sizeof(*vqs), GFP_KERNEL); |
1350 | if (!vqs) { | 1365 | if (!vqs) { |
1351 | kfree(s); | 1366 | kfree(vs); |
1352 | return -ENOMEM; | 1367 | return -ENOMEM; |
1353 | } | 1368 | } |
1354 | 1369 | ||
1355 | vhost_work_init(&s->vs_completion_work, vhost_scsi_complete_cmd_work); | 1370 | vhost_work_init(&vs->vs_completion_work, vhost_scsi_complete_cmd_work); |
1356 | vhost_work_init(&s->vs_event_work, tcm_vhost_evt_work); | 1371 | vhost_work_init(&vs->vs_event_work, tcm_vhost_evt_work); |
1357 | 1372 | ||
1358 | s->vs_events_nr = 0; | 1373 | vs->vs_events_nr = 0; |
1359 | s->vs_events_missed = false; | 1374 | vs->vs_events_missed = false; |
1360 | 1375 | ||
1361 | vqs[VHOST_SCSI_VQ_CTL] = &s->vqs[VHOST_SCSI_VQ_CTL].vq; | 1376 | vqs[VHOST_SCSI_VQ_CTL] = &vs->vqs[VHOST_SCSI_VQ_CTL].vq; |
1362 | vqs[VHOST_SCSI_VQ_EVT] = &s->vqs[VHOST_SCSI_VQ_EVT].vq; | 1377 | vqs[VHOST_SCSI_VQ_EVT] = &vs->vqs[VHOST_SCSI_VQ_EVT].vq; |
1363 | s->vqs[VHOST_SCSI_VQ_CTL].vq.handle_kick = vhost_scsi_ctl_handle_kick; | 1378 | vs->vqs[VHOST_SCSI_VQ_CTL].vq.handle_kick = vhost_scsi_ctl_handle_kick; |
1364 | s->vqs[VHOST_SCSI_VQ_EVT].vq.handle_kick = vhost_scsi_evt_handle_kick; | 1379 | vs->vqs[VHOST_SCSI_VQ_EVT].vq.handle_kick = vhost_scsi_evt_handle_kick; |
1365 | for (i = VHOST_SCSI_VQ_IO; i < VHOST_SCSI_MAX_VQ; i++) { | 1380 | for (i = VHOST_SCSI_VQ_IO; i < VHOST_SCSI_MAX_VQ; i++) { |
1366 | vqs[i] = &s->vqs[i].vq; | 1381 | vqs[i] = &vs->vqs[i].vq; |
1367 | s->vqs[i].vq.handle_kick = vhost_scsi_handle_kick; | 1382 | vs->vqs[i].vq.handle_kick = vhost_scsi_handle_kick; |
1368 | } | 1383 | } |
1369 | r = vhost_dev_init(&s->dev, vqs, VHOST_SCSI_MAX_VQ); | 1384 | r = vhost_dev_init(&vs->dev, vqs, VHOST_SCSI_MAX_VQ); |
1370 | 1385 | ||
1371 | tcm_vhost_init_inflight(s, NULL); | 1386 | tcm_vhost_init_inflight(vs, NULL); |
1372 | 1387 | ||
1373 | if (r < 0) { | 1388 | if (r < 0) { |
1374 | kfree(vqs); | 1389 | kfree(vqs); |
1375 | kfree(s); | 1390 | kfree(vs); |
1376 | return r; | 1391 | return r; |
1377 | } | 1392 | } |
1378 | 1393 | ||
1379 | f->private_data = s; | 1394 | f->private_data = vs; |
1380 | return 0; | 1395 | return 0; |
1381 | } | 1396 | } |
1382 | 1397 | ||
1383 | static int vhost_scsi_release(struct inode *inode, struct file *f) | 1398 | static int vhost_scsi_release(struct inode *inode, struct file *f) |
1384 | { | 1399 | { |
1385 | struct vhost_scsi *s = f->private_data; | 1400 | struct vhost_scsi *vs = f->private_data; |
1386 | struct vhost_scsi_target t; | 1401 | struct vhost_scsi_target t; |
1387 | 1402 | ||
1388 | mutex_lock(&s->dev.mutex); | 1403 | mutex_lock(&vs->dev.mutex); |
1389 | memcpy(t.vhost_wwpn, s->vs_vhost_wwpn, sizeof(t.vhost_wwpn)); | 1404 | memcpy(t.vhost_wwpn, vs->vs_vhost_wwpn, sizeof(t.vhost_wwpn)); |
1390 | mutex_unlock(&s->dev.mutex); | 1405 | mutex_unlock(&vs->dev.mutex); |
1391 | vhost_scsi_clear_endpoint(s, &t); | 1406 | vhost_scsi_clear_endpoint(vs, &t); |
1392 | vhost_dev_stop(&s->dev); | 1407 | vhost_dev_stop(&vs->dev); |
1393 | vhost_dev_cleanup(&s->dev, false); | 1408 | vhost_dev_cleanup(&vs->dev, false); |
1394 | /* Jobs can re-queue themselves in evt kick handler. Do extra flush. */ | 1409 | /* Jobs can re-queue themselves in evt kick handler. Do extra flush. */ |
1395 | vhost_scsi_flush(s); | 1410 | vhost_scsi_flush(vs); |
1396 | kfree(s->dev.vqs); | 1411 | kfree(vs->dev.vqs); |
1397 | kfree(s); | 1412 | kfree(vs); |
1398 | return 0; | 1413 | return 0; |
1399 | } | 1414 | } |
1400 | 1415 | ||
1401 | static long vhost_scsi_ioctl(struct file *f, unsigned int ioctl, | 1416 | static long |
1402 | unsigned long arg) | 1417 | vhost_scsi_ioctl(struct file *f, |
1418 | unsigned int ioctl, | ||
1419 | unsigned long arg) | ||
1403 | { | 1420 | { |
1404 | struct vhost_scsi *vs = f->private_data; | 1421 | struct vhost_scsi *vs = f->private_data; |
1405 | struct vhost_scsi_target backend; | 1422 | struct vhost_scsi_target backend; |
@@ -1515,8 +1532,9 @@ static char *tcm_vhost_dump_proto_id(struct tcm_vhost_tport *tport) | |||
1515 | return "Unknown"; | 1532 | return "Unknown"; |
1516 | } | 1533 | } |
1517 | 1534 | ||
1518 | static void tcm_vhost_do_plug(struct tcm_vhost_tpg *tpg, | 1535 | static void |
1519 | struct se_lun *lun, bool plug) | 1536 | tcm_vhost_do_plug(struct tcm_vhost_tpg *tpg, |
1537 | struct se_lun *lun, bool plug) | ||
1520 | { | 1538 | { |
1521 | 1539 | ||
1522 | struct vhost_scsi *vs = tpg->vhost_scsi; | 1540 | struct vhost_scsi *vs = tpg->vhost_scsi; |
@@ -1556,18 +1574,18 @@ static void tcm_vhost_hotunplug(struct tcm_vhost_tpg *tpg, struct se_lun *lun) | |||
1556 | } | 1574 | } |
1557 | 1575 | ||
1558 | static int tcm_vhost_port_link(struct se_portal_group *se_tpg, | 1576 | static int tcm_vhost_port_link(struct se_portal_group *se_tpg, |
1559 | struct se_lun *lun) | 1577 | struct se_lun *lun) |
1560 | { | 1578 | { |
1561 | struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg, | 1579 | struct tcm_vhost_tpg *tpg = container_of(se_tpg, |
1562 | struct tcm_vhost_tpg, se_tpg); | 1580 | struct tcm_vhost_tpg, se_tpg); |
1563 | 1581 | ||
1564 | mutex_lock(&tcm_vhost_mutex); | 1582 | mutex_lock(&tcm_vhost_mutex); |
1565 | 1583 | ||
1566 | mutex_lock(&tv_tpg->tv_tpg_mutex); | 1584 | mutex_lock(&tpg->tv_tpg_mutex); |
1567 | tv_tpg->tv_tpg_port_count++; | 1585 | tpg->tv_tpg_port_count++; |
1568 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | 1586 | mutex_unlock(&tpg->tv_tpg_mutex); |
1569 | 1587 | ||
1570 | tcm_vhost_hotplug(tv_tpg, lun); | 1588 | tcm_vhost_hotplug(tpg, lun); |
1571 | 1589 | ||
1572 | mutex_unlock(&tcm_vhost_mutex); | 1590 | mutex_unlock(&tcm_vhost_mutex); |
1573 | 1591 | ||
@@ -1575,26 +1593,26 @@ static int tcm_vhost_port_link(struct se_portal_group *se_tpg, | |||
1575 | } | 1593 | } |
1576 | 1594 | ||
1577 | static void tcm_vhost_port_unlink(struct se_portal_group *se_tpg, | 1595 | static void tcm_vhost_port_unlink(struct se_portal_group *se_tpg, |
1578 | struct se_lun *lun) | 1596 | struct se_lun *lun) |
1579 | { | 1597 | { |
1580 | struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg, | 1598 | struct tcm_vhost_tpg *tpg = container_of(se_tpg, |
1581 | struct tcm_vhost_tpg, se_tpg); | 1599 | struct tcm_vhost_tpg, se_tpg); |
1582 | 1600 | ||
1583 | mutex_lock(&tcm_vhost_mutex); | 1601 | mutex_lock(&tcm_vhost_mutex); |
1584 | 1602 | ||
1585 | mutex_lock(&tv_tpg->tv_tpg_mutex); | 1603 | mutex_lock(&tpg->tv_tpg_mutex); |
1586 | tv_tpg->tv_tpg_port_count--; | 1604 | tpg->tv_tpg_port_count--; |
1587 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | 1605 | mutex_unlock(&tpg->tv_tpg_mutex); |
1588 | 1606 | ||
1589 | tcm_vhost_hotunplug(tv_tpg, lun); | 1607 | tcm_vhost_hotunplug(tpg, lun); |
1590 | 1608 | ||
1591 | mutex_unlock(&tcm_vhost_mutex); | 1609 | mutex_unlock(&tcm_vhost_mutex); |
1592 | } | 1610 | } |
1593 | 1611 | ||
1594 | static struct se_node_acl *tcm_vhost_make_nodeacl( | 1612 | static struct se_node_acl * |
1595 | struct se_portal_group *se_tpg, | 1613 | tcm_vhost_make_nodeacl(struct se_portal_group *se_tpg, |
1596 | struct config_group *group, | 1614 | struct config_group *group, |
1597 | const char *name) | 1615 | const char *name) |
1598 | { | 1616 | { |
1599 | struct se_node_acl *se_nacl, *se_nacl_new; | 1617 | struct se_node_acl *se_nacl, *se_nacl_new; |
1600 | struct tcm_vhost_nacl *nacl; | 1618 | struct tcm_vhost_nacl *nacl; |
@@ -1635,23 +1653,23 @@ static void tcm_vhost_drop_nodeacl(struct se_node_acl *se_acl) | |||
1635 | kfree(nacl); | 1653 | kfree(nacl); |
1636 | } | 1654 | } |
1637 | 1655 | ||
1638 | static int tcm_vhost_make_nexus(struct tcm_vhost_tpg *tv_tpg, | 1656 | static int tcm_vhost_make_nexus(struct tcm_vhost_tpg *tpg, |
1639 | const char *name) | 1657 | const char *name) |
1640 | { | 1658 | { |
1641 | struct se_portal_group *se_tpg; | 1659 | struct se_portal_group *se_tpg; |
1642 | struct tcm_vhost_nexus *tv_nexus; | 1660 | struct tcm_vhost_nexus *tv_nexus; |
1643 | 1661 | ||
1644 | mutex_lock(&tv_tpg->tv_tpg_mutex); | 1662 | mutex_lock(&tpg->tv_tpg_mutex); |
1645 | if (tv_tpg->tpg_nexus) { | 1663 | if (tpg->tpg_nexus) { |
1646 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | 1664 | mutex_unlock(&tpg->tv_tpg_mutex); |
1647 | pr_debug("tv_tpg->tpg_nexus already exists\n"); | 1665 | pr_debug("tpg->tpg_nexus already exists\n"); |
1648 | return -EEXIST; | 1666 | return -EEXIST; |
1649 | } | 1667 | } |
1650 | se_tpg = &tv_tpg->se_tpg; | 1668 | se_tpg = &tpg->se_tpg; |
1651 | 1669 | ||
1652 | tv_nexus = kzalloc(sizeof(struct tcm_vhost_nexus), GFP_KERNEL); | 1670 | tv_nexus = kzalloc(sizeof(struct tcm_vhost_nexus), GFP_KERNEL); |
1653 | if (!tv_nexus) { | 1671 | if (!tv_nexus) { |
1654 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | 1672 | mutex_unlock(&tpg->tv_tpg_mutex); |
1655 | pr_err("Unable to allocate struct tcm_vhost_nexus\n"); | 1673 | pr_err("Unable to allocate struct tcm_vhost_nexus\n"); |
1656 | return -ENOMEM; | 1674 | return -ENOMEM; |
1657 | } | 1675 | } |
@@ -1660,7 +1678,7 @@ static int tcm_vhost_make_nexus(struct tcm_vhost_tpg *tv_tpg, | |||
1660 | */ | 1678 | */ |
1661 | tv_nexus->tvn_se_sess = transport_init_session(); | 1679 | tv_nexus->tvn_se_sess = transport_init_session(); |
1662 | if (IS_ERR(tv_nexus->tvn_se_sess)) { | 1680 | if (IS_ERR(tv_nexus->tvn_se_sess)) { |
1663 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | 1681 | mutex_unlock(&tpg->tv_tpg_mutex); |
1664 | kfree(tv_nexus); | 1682 | kfree(tv_nexus); |
1665 | return -ENOMEM; | 1683 | return -ENOMEM; |
1666 | } | 1684 | } |
@@ -1672,7 +1690,7 @@ static int tcm_vhost_make_nexus(struct tcm_vhost_tpg *tv_tpg, | |||
1672 | tv_nexus->tvn_se_sess->se_node_acl = core_tpg_check_initiator_node_acl( | 1690 | tv_nexus->tvn_se_sess->se_node_acl = core_tpg_check_initiator_node_acl( |
1673 | se_tpg, (unsigned char *)name); | 1691 | se_tpg, (unsigned char *)name); |
1674 | if (!tv_nexus->tvn_se_sess->se_node_acl) { | 1692 | if (!tv_nexus->tvn_se_sess->se_node_acl) { |
1675 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | 1693 | mutex_unlock(&tpg->tv_tpg_mutex); |
1676 | pr_debug("core_tpg_check_initiator_node_acl() failed" | 1694 | pr_debug("core_tpg_check_initiator_node_acl() failed" |
1677 | " for %s\n", name); | 1695 | " for %s\n", name); |
1678 | transport_free_session(tv_nexus->tvn_se_sess); | 1696 | transport_free_session(tv_nexus->tvn_se_sess); |
@@ -1685,9 +1703,9 @@ static int tcm_vhost_make_nexus(struct tcm_vhost_tpg *tv_tpg, | |||
1685 | */ | 1703 | */ |
1686 | __transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl, | 1704 | __transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl, |
1687 | tv_nexus->tvn_se_sess, tv_nexus); | 1705 | tv_nexus->tvn_se_sess, tv_nexus); |
1688 | tv_tpg->tpg_nexus = tv_nexus; | 1706 | tpg->tpg_nexus = tv_nexus; |
1689 | 1707 | ||
1690 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | 1708 | mutex_unlock(&tpg->tv_tpg_mutex); |
1691 | return 0; | 1709 | return 0; |
1692 | } | 1710 | } |
1693 | 1711 | ||
@@ -1740,40 +1758,40 @@ static int tcm_vhost_drop_nexus(struct tcm_vhost_tpg *tpg) | |||
1740 | } | 1758 | } |
1741 | 1759 | ||
1742 | static ssize_t tcm_vhost_tpg_show_nexus(struct se_portal_group *se_tpg, | 1760 | static ssize_t tcm_vhost_tpg_show_nexus(struct se_portal_group *se_tpg, |
1743 | char *page) | 1761 | char *page) |
1744 | { | 1762 | { |
1745 | struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg, | 1763 | struct tcm_vhost_tpg *tpg = container_of(se_tpg, |
1746 | struct tcm_vhost_tpg, se_tpg); | 1764 | struct tcm_vhost_tpg, se_tpg); |
1747 | struct tcm_vhost_nexus *tv_nexus; | 1765 | struct tcm_vhost_nexus *tv_nexus; |
1748 | ssize_t ret; | 1766 | ssize_t ret; |
1749 | 1767 | ||
1750 | mutex_lock(&tv_tpg->tv_tpg_mutex); | 1768 | mutex_lock(&tpg->tv_tpg_mutex); |
1751 | tv_nexus = tv_tpg->tpg_nexus; | 1769 | tv_nexus = tpg->tpg_nexus; |
1752 | if (!tv_nexus) { | 1770 | if (!tv_nexus) { |
1753 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | 1771 | mutex_unlock(&tpg->tv_tpg_mutex); |
1754 | return -ENODEV; | 1772 | return -ENODEV; |
1755 | } | 1773 | } |
1756 | ret = snprintf(page, PAGE_SIZE, "%s\n", | 1774 | ret = snprintf(page, PAGE_SIZE, "%s\n", |
1757 | tv_nexus->tvn_se_sess->se_node_acl->initiatorname); | 1775 | tv_nexus->tvn_se_sess->se_node_acl->initiatorname); |
1758 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | 1776 | mutex_unlock(&tpg->tv_tpg_mutex); |
1759 | 1777 | ||
1760 | return ret; | 1778 | return ret; |
1761 | } | 1779 | } |
1762 | 1780 | ||
1763 | static ssize_t tcm_vhost_tpg_store_nexus(struct se_portal_group *se_tpg, | 1781 | static ssize_t tcm_vhost_tpg_store_nexus(struct se_portal_group *se_tpg, |
1764 | const char *page, | 1782 | const char *page, |
1765 | size_t count) | 1783 | size_t count) |
1766 | { | 1784 | { |
1767 | struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg, | 1785 | struct tcm_vhost_tpg *tpg = container_of(se_tpg, |
1768 | struct tcm_vhost_tpg, se_tpg); | 1786 | struct tcm_vhost_tpg, se_tpg); |
1769 | struct tcm_vhost_tport *tport_wwn = tv_tpg->tport; | 1787 | struct tcm_vhost_tport *tport_wwn = tpg->tport; |
1770 | unsigned char i_port[TCM_VHOST_NAMELEN], *ptr, *port_ptr; | 1788 | unsigned char i_port[TCM_VHOST_NAMELEN], *ptr, *port_ptr; |
1771 | int ret; | 1789 | int ret; |
1772 | /* | 1790 | /* |
1773 | * Shutdown the active I_T nexus if 'NULL' is passed.. | 1791 | * Shutdown the active I_T nexus if 'NULL' is passed.. |
1774 | */ | 1792 | */ |
1775 | if (!strncmp(page, "NULL", 4)) { | 1793 | if (!strncmp(page, "NULL", 4)) { |
1776 | ret = tcm_vhost_drop_nexus(tv_tpg); | 1794 | ret = tcm_vhost_drop_nexus(tpg); |
1777 | return (!ret) ? count : ret; | 1795 | return (!ret) ? count : ret; |
1778 | } | 1796 | } |
1779 | /* | 1797 | /* |
@@ -1831,7 +1849,7 @@ check_newline: | |||
1831 | if (i_port[strlen(i_port)-1] == '\n') | 1849 | if (i_port[strlen(i_port)-1] == '\n') |
1832 | i_port[strlen(i_port)-1] = '\0'; | 1850 | i_port[strlen(i_port)-1] = '\0'; |
1833 | 1851 | ||
1834 | ret = tcm_vhost_make_nexus(tv_tpg, port_ptr); | 1852 | ret = tcm_vhost_make_nexus(tpg, port_ptr); |
1835 | if (ret < 0) | 1853 | if (ret < 0) |
1836 | return ret; | 1854 | return ret; |
1837 | 1855 | ||
@@ -1845,9 +1863,10 @@ static struct configfs_attribute *tcm_vhost_tpg_attrs[] = { | |||
1845 | NULL, | 1863 | NULL, |
1846 | }; | 1864 | }; |
1847 | 1865 | ||
1848 | static struct se_portal_group *tcm_vhost_make_tpg(struct se_wwn *wwn, | 1866 | static struct se_portal_group * |
1849 | struct config_group *group, | 1867 | tcm_vhost_make_tpg(struct se_wwn *wwn, |
1850 | const char *name) | 1868 | struct config_group *group, |
1869 | const char *name) | ||
1851 | { | 1870 | { |
1852 | struct tcm_vhost_tport *tport = container_of(wwn, | 1871 | struct tcm_vhost_tport *tport = container_of(wwn, |
1853 | struct tcm_vhost_tport, tport_wwn); | 1872 | struct tcm_vhost_tport, tport_wwn); |
@@ -1903,9 +1922,10 @@ static void tcm_vhost_drop_tpg(struct se_portal_group *se_tpg) | |||
1903 | kfree(tpg); | 1922 | kfree(tpg); |
1904 | } | 1923 | } |
1905 | 1924 | ||
1906 | static struct se_wwn *tcm_vhost_make_tport(struct target_fabric_configfs *tf, | 1925 | static struct se_wwn * |
1907 | struct config_group *group, | 1926 | tcm_vhost_make_tport(struct target_fabric_configfs *tf, |
1908 | const char *name) | 1927 | struct config_group *group, |
1928 | const char *name) | ||
1909 | { | 1929 | { |
1910 | struct tcm_vhost_tport *tport; | 1930 | struct tcm_vhost_tport *tport; |
1911 | char *ptr; | 1931 | char *ptr; |
@@ -1975,9 +1995,9 @@ static void tcm_vhost_drop_tport(struct se_wwn *wwn) | |||
1975 | kfree(tport); | 1995 | kfree(tport); |
1976 | } | 1996 | } |
1977 | 1997 | ||
1978 | static ssize_t tcm_vhost_wwn_show_attr_version( | 1998 | static ssize_t |
1979 | struct target_fabric_configfs *tf, | 1999 | tcm_vhost_wwn_show_attr_version(struct target_fabric_configfs *tf, |
1980 | char *page) | 2000 | char *page) |
1981 | { | 2001 | { |
1982 | return sprintf(page, "TCM_VHOST fabric module %s on %s/%s" | 2002 | return sprintf(page, "TCM_VHOST fabric module %s on %s/%s" |
1983 | "on "UTS_RELEASE"\n", TCM_VHOST_VERSION, utsname()->sysname, | 2003 | "on "UTS_RELEASE"\n", TCM_VHOST_VERSION, utsname()->sysname, |
diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c index 1ee45bc85f67..a73ea217f24d 100644 --- a/drivers/vhost/test.c +++ b/drivers/vhost/test.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | 19 | ||
20 | #include "test.h" | 20 | #include "test.h" |
21 | #include "vhost.c" | 21 | #include "vhost.h" |
22 | 22 | ||
23 | /* Max number of bytes transferred before requeueing the job. | 23 | /* Max number of bytes transferred before requeueing the job. |
24 | * Using this limit prevents one virtqueue from starving others. */ | 24 | * Using this limit prevents one virtqueue from starving others. */ |
@@ -38,17 +38,19 @@ struct vhost_test { | |||
38 | * read-size critical section for our kind of RCU. */ | 38 | * read-size critical section for our kind of RCU. */ |
39 | static void handle_vq(struct vhost_test *n) | 39 | static void handle_vq(struct vhost_test *n) |
40 | { | 40 | { |
41 | struct vhost_virtqueue *vq = &n->dev.vqs[VHOST_TEST_VQ]; | 41 | struct vhost_virtqueue *vq = &n->vqs[VHOST_TEST_VQ]; |
42 | unsigned out, in; | 42 | unsigned out, in; |
43 | int head; | 43 | int head; |
44 | size_t len, total_len = 0; | 44 | size_t len, total_len = 0; |
45 | void *private; | 45 | void *private; |
46 | 46 | ||
47 | private = rcu_dereference_check(vq->private_data, 1); | 47 | mutex_lock(&vq->mutex); |
48 | if (!private) | 48 | private = vq->private_data; |
49 | if (!private) { | ||
50 | mutex_unlock(&vq->mutex); | ||
49 | return; | 51 | return; |
52 | } | ||
50 | 53 | ||
51 | mutex_lock(&vq->mutex); | ||
52 | vhost_disable_notify(&n->dev, vq); | 54 | vhost_disable_notify(&n->dev, vq); |
53 | 55 | ||
54 | for (;;) { | 56 | for (;;) { |
@@ -102,15 +104,23 @@ static int vhost_test_open(struct inode *inode, struct file *f) | |||
102 | { | 104 | { |
103 | struct vhost_test *n = kmalloc(sizeof *n, GFP_KERNEL); | 105 | struct vhost_test *n = kmalloc(sizeof *n, GFP_KERNEL); |
104 | struct vhost_dev *dev; | 106 | struct vhost_dev *dev; |
107 | struct vhost_virtqueue **vqs; | ||
105 | int r; | 108 | int r; |
106 | 109 | ||
107 | if (!n) | 110 | if (!n) |
108 | return -ENOMEM; | 111 | return -ENOMEM; |
112 | vqs = kmalloc(VHOST_TEST_VQ_MAX * sizeof(*vqs), GFP_KERNEL); | ||
113 | if (!vqs) { | ||
114 | kfree(n); | ||
115 | return -ENOMEM; | ||
116 | } | ||
109 | 117 | ||
110 | dev = &n->dev; | 118 | dev = &n->dev; |
119 | vqs[VHOST_TEST_VQ] = &n->vqs[VHOST_TEST_VQ]; | ||
111 | n->vqs[VHOST_TEST_VQ].handle_kick = handle_vq_kick; | 120 | n->vqs[VHOST_TEST_VQ].handle_kick = handle_vq_kick; |
112 | r = vhost_dev_init(dev, n->vqs, VHOST_TEST_VQ_MAX); | 121 | r = vhost_dev_init(dev, vqs, VHOST_TEST_VQ_MAX); |
113 | if (r < 0) { | 122 | if (r < 0) { |
123 | kfree(vqs); | ||
114 | kfree(n); | 124 | kfree(n); |
115 | return r; | 125 | return r; |
116 | } | 126 | } |
@@ -126,9 +136,8 @@ static void *vhost_test_stop_vq(struct vhost_test *n, | |||
126 | void *private; | 136 | void *private; |
127 | 137 | ||
128 | mutex_lock(&vq->mutex); | 138 | mutex_lock(&vq->mutex); |
129 | private = rcu_dereference_protected(vq->private_data, | 139 | private = vq->private_data; |
130 | lockdep_is_held(&vq->mutex)); | 140 | vq->private_data = NULL; |
131 | rcu_assign_pointer(vq->private_data, NULL); | ||
132 | mutex_unlock(&vq->mutex); | 141 | mutex_unlock(&vq->mutex); |
133 | return private; | 142 | return private; |
134 | } | 143 | } |
@@ -140,7 +149,7 @@ static void vhost_test_stop(struct vhost_test *n, void **privatep) | |||
140 | 149 | ||
141 | static void vhost_test_flush_vq(struct vhost_test *n, int index) | 150 | static void vhost_test_flush_vq(struct vhost_test *n, int index) |
142 | { | 151 | { |
143 | vhost_poll_flush(&n->dev.vqs[index].poll); | 152 | vhost_poll_flush(&n->vqs[index].poll); |
144 | } | 153 | } |
145 | 154 | ||
146 | static void vhost_test_flush(struct vhost_test *n) | 155 | static void vhost_test_flush(struct vhost_test *n) |
@@ -268,14 +277,14 @@ static long vhost_test_ioctl(struct file *f, unsigned int ioctl, | |||
268 | return -EFAULT; | 277 | return -EFAULT; |
269 | return vhost_test_run(n, test); | 278 | return vhost_test_run(n, test); |
270 | case VHOST_GET_FEATURES: | 279 | case VHOST_GET_FEATURES: |
271 | features = VHOST_NET_FEATURES; | 280 | features = VHOST_FEATURES; |
272 | if (copy_to_user(featurep, &features, sizeof features)) | 281 | if (copy_to_user(featurep, &features, sizeof features)) |
273 | return -EFAULT; | 282 | return -EFAULT; |
274 | return 0; | 283 | return 0; |
275 | case VHOST_SET_FEATURES: | 284 | case VHOST_SET_FEATURES: |
276 | if (copy_from_user(&features, featurep, sizeof features)) | 285 | if (copy_from_user(&features, featurep, sizeof features)) |
277 | return -EFAULT; | 286 | return -EFAULT; |
278 | if (features & ~VHOST_NET_FEATURES) | 287 | if (features & ~VHOST_FEATURES) |
279 | return -EOPNOTSUPP; | 288 | return -EOPNOTSUPP; |
280 | return vhost_test_set_features(n, features); | 289 | return vhost_test_set_features(n, features); |
281 | case VHOST_RESET_OWNER: | 290 | case VHOST_RESET_OWNER: |
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 60aa5ad09a2f..e58cf0001cee 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/kthread.h> | 26 | #include <linux/kthread.h> |
27 | #include <linux/cgroup.h> | 27 | #include <linux/cgroup.h> |
28 | #include <linux/module.h> | ||
28 | 29 | ||
29 | #include "vhost.h" | 30 | #include "vhost.h" |
30 | 31 | ||
@@ -66,6 +67,7 @@ void vhost_work_init(struct vhost_work *work, vhost_work_fn_t fn) | |||
66 | work->flushing = 0; | 67 | work->flushing = 0; |
67 | work->queue_seq = work->done_seq = 0; | 68 | work->queue_seq = work->done_seq = 0; |
68 | } | 69 | } |
70 | EXPORT_SYMBOL_GPL(vhost_work_init); | ||
69 | 71 | ||
70 | /* Init poll structure */ | 72 | /* Init poll structure */ |
71 | void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn, | 73 | void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn, |
@@ -79,6 +81,7 @@ void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn, | |||
79 | 81 | ||
80 | vhost_work_init(&poll->work, fn); | 82 | vhost_work_init(&poll->work, fn); |
81 | } | 83 | } |
84 | EXPORT_SYMBOL_GPL(vhost_poll_init); | ||
82 | 85 | ||
83 | /* Start polling a file. We add ourselves to file's wait queue. The caller must | 86 | /* Start polling a file. We add ourselves to file's wait queue. The caller must |
84 | * keep a reference to a file until after vhost_poll_stop is called. */ | 87 | * keep a reference to a file until after vhost_poll_stop is called. */ |
@@ -101,6 +104,7 @@ int vhost_poll_start(struct vhost_poll *poll, struct file *file) | |||
101 | 104 | ||
102 | return ret; | 105 | return ret; |
103 | } | 106 | } |
107 | EXPORT_SYMBOL_GPL(vhost_poll_start); | ||
104 | 108 | ||
105 | /* Stop polling a file. After this function returns, it becomes safe to drop the | 109 | /* Stop polling a file. After this function returns, it becomes safe to drop the |
106 | * file reference. You must also flush afterwards. */ | 110 | * file reference. You must also flush afterwards. */ |
@@ -111,6 +115,7 @@ void vhost_poll_stop(struct vhost_poll *poll) | |||
111 | poll->wqh = NULL; | 115 | poll->wqh = NULL; |
112 | } | 116 | } |
113 | } | 117 | } |
118 | EXPORT_SYMBOL_GPL(vhost_poll_stop); | ||
114 | 119 | ||
115 | static bool vhost_work_seq_done(struct vhost_dev *dev, struct vhost_work *work, | 120 | static bool vhost_work_seq_done(struct vhost_dev *dev, struct vhost_work *work, |
116 | unsigned seq) | 121 | unsigned seq) |
@@ -123,7 +128,7 @@ static bool vhost_work_seq_done(struct vhost_dev *dev, struct vhost_work *work, | |||
123 | return left <= 0; | 128 | return left <= 0; |
124 | } | 129 | } |
125 | 130 | ||
126 | static void vhost_work_flush(struct vhost_dev *dev, struct vhost_work *work) | 131 | void vhost_work_flush(struct vhost_dev *dev, struct vhost_work *work) |
127 | { | 132 | { |
128 | unsigned seq; | 133 | unsigned seq; |
129 | int flushing; | 134 | int flushing; |
@@ -138,6 +143,7 @@ static void vhost_work_flush(struct vhost_dev *dev, struct vhost_work *work) | |||
138 | spin_unlock_irq(&dev->work_lock); | 143 | spin_unlock_irq(&dev->work_lock); |
139 | BUG_ON(flushing < 0); | 144 | BUG_ON(flushing < 0); |
140 | } | 145 | } |
146 | EXPORT_SYMBOL_GPL(vhost_work_flush); | ||
141 | 147 | ||
142 | /* Flush any work that has been scheduled. When calling this, don't hold any | 148 | /* Flush any work that has been scheduled. When calling this, don't hold any |
143 | * locks that are also used by the callback. */ | 149 | * locks that are also used by the callback. */ |
@@ -145,6 +151,7 @@ void vhost_poll_flush(struct vhost_poll *poll) | |||
145 | { | 151 | { |
146 | vhost_work_flush(poll->dev, &poll->work); | 152 | vhost_work_flush(poll->dev, &poll->work); |
147 | } | 153 | } |
154 | EXPORT_SYMBOL_GPL(vhost_poll_flush); | ||
148 | 155 | ||
149 | void vhost_work_queue(struct vhost_dev *dev, struct vhost_work *work) | 156 | void vhost_work_queue(struct vhost_dev *dev, struct vhost_work *work) |
150 | { | 157 | { |
@@ -158,11 +165,13 @@ void vhost_work_queue(struct vhost_dev *dev, struct vhost_work *work) | |||
158 | } | 165 | } |
159 | spin_unlock_irqrestore(&dev->work_lock, flags); | 166 | spin_unlock_irqrestore(&dev->work_lock, flags); |
160 | } | 167 | } |
168 | EXPORT_SYMBOL_GPL(vhost_work_queue); | ||
161 | 169 | ||
162 | void vhost_poll_queue(struct vhost_poll *poll) | 170 | void vhost_poll_queue(struct vhost_poll *poll) |
163 | { | 171 | { |
164 | vhost_work_queue(poll->dev, &poll->work); | 172 | vhost_work_queue(poll->dev, &poll->work); |
165 | } | 173 | } |
174 | EXPORT_SYMBOL_GPL(vhost_poll_queue); | ||
166 | 175 | ||
167 | static void vhost_vq_reset(struct vhost_dev *dev, | 176 | static void vhost_vq_reset(struct vhost_dev *dev, |
168 | struct vhost_virtqueue *vq) | 177 | struct vhost_virtqueue *vq) |
@@ -251,17 +260,16 @@ static void vhost_vq_free_iovecs(struct vhost_virtqueue *vq) | |||
251 | /* Helper to allocate iovec buffers for all vqs. */ | 260 | /* Helper to allocate iovec buffers for all vqs. */ |
252 | static long vhost_dev_alloc_iovecs(struct vhost_dev *dev) | 261 | static long vhost_dev_alloc_iovecs(struct vhost_dev *dev) |
253 | { | 262 | { |
263 | struct vhost_virtqueue *vq; | ||
254 | int i; | 264 | int i; |
255 | 265 | ||
256 | for (i = 0; i < dev->nvqs; ++i) { | 266 | for (i = 0; i < dev->nvqs; ++i) { |
257 | dev->vqs[i]->indirect = kmalloc(sizeof *dev->vqs[i]->indirect * | 267 | vq = dev->vqs[i]; |
258 | UIO_MAXIOV, GFP_KERNEL); | 268 | vq->indirect = kmalloc(sizeof *vq->indirect * UIO_MAXIOV, |
259 | dev->vqs[i]->log = kmalloc(sizeof *dev->vqs[i]->log * UIO_MAXIOV, | 269 | GFP_KERNEL); |
260 | GFP_KERNEL); | 270 | vq->log = kmalloc(sizeof *vq->log * UIO_MAXIOV, GFP_KERNEL); |
261 | dev->vqs[i]->heads = kmalloc(sizeof *dev->vqs[i]->heads * | 271 | vq->heads = kmalloc(sizeof *vq->heads * UIO_MAXIOV, GFP_KERNEL); |
262 | UIO_MAXIOV, GFP_KERNEL); | 272 | if (!vq->indirect || !vq->log || !vq->heads) |
263 | if (!dev->vqs[i]->indirect || !dev->vqs[i]->log || | ||
264 | !dev->vqs[i]->heads) | ||
265 | goto err_nomem; | 273 | goto err_nomem; |
266 | } | 274 | } |
267 | return 0; | 275 | return 0; |
@@ -283,6 +291,7 @@ static void vhost_dev_free_iovecs(struct vhost_dev *dev) | |||
283 | long vhost_dev_init(struct vhost_dev *dev, | 291 | long vhost_dev_init(struct vhost_dev *dev, |
284 | struct vhost_virtqueue **vqs, int nvqs) | 292 | struct vhost_virtqueue **vqs, int nvqs) |
285 | { | 293 | { |
294 | struct vhost_virtqueue *vq; | ||
286 | int i; | 295 | int i; |
287 | 296 | ||
288 | dev->vqs = vqs; | 297 | dev->vqs = vqs; |
@@ -297,19 +306,21 @@ long vhost_dev_init(struct vhost_dev *dev, | |||
297 | dev->worker = NULL; | 306 | dev->worker = NULL; |
298 | 307 | ||
299 | for (i = 0; i < dev->nvqs; ++i) { | 308 | for (i = 0; i < dev->nvqs; ++i) { |
300 | dev->vqs[i]->log = NULL; | 309 | vq = dev->vqs[i]; |
301 | dev->vqs[i]->indirect = NULL; | 310 | vq->log = NULL; |
302 | dev->vqs[i]->heads = NULL; | 311 | vq->indirect = NULL; |
303 | dev->vqs[i]->dev = dev; | 312 | vq->heads = NULL; |
304 | mutex_init(&dev->vqs[i]->mutex); | 313 | vq->dev = dev; |
305 | vhost_vq_reset(dev, dev->vqs[i]); | 314 | mutex_init(&vq->mutex); |
306 | if (dev->vqs[i]->handle_kick) | 315 | vhost_vq_reset(dev, vq); |
307 | vhost_poll_init(&dev->vqs[i]->poll, | 316 | if (vq->handle_kick) |
308 | dev->vqs[i]->handle_kick, POLLIN, dev); | 317 | vhost_poll_init(&vq->poll, vq->handle_kick, |
318 | POLLIN, dev); | ||
309 | } | 319 | } |
310 | 320 | ||
311 | return 0; | 321 | return 0; |
312 | } | 322 | } |
323 | EXPORT_SYMBOL_GPL(vhost_dev_init); | ||
313 | 324 | ||
314 | /* Caller should have device mutex */ | 325 | /* Caller should have device mutex */ |
315 | long vhost_dev_check_owner(struct vhost_dev *dev) | 326 | long vhost_dev_check_owner(struct vhost_dev *dev) |
@@ -317,6 +328,7 @@ long vhost_dev_check_owner(struct vhost_dev *dev) | |||
317 | /* Are you the owner? If not, I don't think you mean to do that */ | 328 | /* Are you the owner? If not, I don't think you mean to do that */ |
318 | return dev->mm == current->mm ? 0 : -EPERM; | 329 | return dev->mm == current->mm ? 0 : -EPERM; |
319 | } | 330 | } |
331 | EXPORT_SYMBOL_GPL(vhost_dev_check_owner); | ||
320 | 332 | ||
321 | struct vhost_attach_cgroups_struct { | 333 | struct vhost_attach_cgroups_struct { |
322 | struct vhost_work work; | 334 | struct vhost_work work; |
@@ -348,6 +360,7 @@ bool vhost_dev_has_owner(struct vhost_dev *dev) | |||
348 | { | 360 | { |
349 | return dev->mm; | 361 | return dev->mm; |
350 | } | 362 | } |
363 | EXPORT_SYMBOL_GPL(vhost_dev_has_owner); | ||
351 | 364 | ||
352 | /* Caller should have device mutex */ | 365 | /* Caller should have device mutex */ |
353 | long vhost_dev_set_owner(struct vhost_dev *dev) | 366 | long vhost_dev_set_owner(struct vhost_dev *dev) |
@@ -391,11 +404,13 @@ err_worker: | |||
391 | err_mm: | 404 | err_mm: |
392 | return err; | 405 | return err; |
393 | } | 406 | } |
407 | EXPORT_SYMBOL_GPL(vhost_dev_set_owner); | ||
394 | 408 | ||
395 | struct vhost_memory *vhost_dev_reset_owner_prepare(void) | 409 | struct vhost_memory *vhost_dev_reset_owner_prepare(void) |
396 | { | 410 | { |
397 | return kmalloc(offsetof(struct vhost_memory, regions), GFP_KERNEL); | 411 | return kmalloc(offsetof(struct vhost_memory, regions), GFP_KERNEL); |
398 | } | 412 | } |
413 | EXPORT_SYMBOL_GPL(vhost_dev_reset_owner_prepare); | ||
399 | 414 | ||
400 | /* Caller should have device mutex */ | 415 | /* Caller should have device mutex */ |
401 | void vhost_dev_reset_owner(struct vhost_dev *dev, struct vhost_memory *memory) | 416 | void vhost_dev_reset_owner(struct vhost_dev *dev, struct vhost_memory *memory) |
@@ -406,6 +421,7 @@ void vhost_dev_reset_owner(struct vhost_dev *dev, struct vhost_memory *memory) | |||
406 | memory->nregions = 0; | 421 | memory->nregions = 0; |
407 | RCU_INIT_POINTER(dev->memory, memory); | 422 | RCU_INIT_POINTER(dev->memory, memory); |
408 | } | 423 | } |
424 | EXPORT_SYMBOL_GPL(vhost_dev_reset_owner); | ||
409 | 425 | ||
410 | void vhost_dev_stop(struct vhost_dev *dev) | 426 | void vhost_dev_stop(struct vhost_dev *dev) |
411 | { | 427 | { |
@@ -418,6 +434,7 @@ void vhost_dev_stop(struct vhost_dev *dev) | |||
418 | } | 434 | } |
419 | } | 435 | } |
420 | } | 436 | } |
437 | EXPORT_SYMBOL_GPL(vhost_dev_stop); | ||
421 | 438 | ||
422 | /* Caller should have device mutex if and only if locked is set */ | 439 | /* Caller should have device mutex if and only if locked is set */ |
423 | void vhost_dev_cleanup(struct vhost_dev *dev, bool locked) | 440 | void vhost_dev_cleanup(struct vhost_dev *dev, bool locked) |
@@ -458,6 +475,7 @@ void vhost_dev_cleanup(struct vhost_dev *dev, bool locked) | |||
458 | mmput(dev->mm); | 475 | mmput(dev->mm); |
459 | dev->mm = NULL; | 476 | dev->mm = NULL; |
460 | } | 477 | } |
478 | EXPORT_SYMBOL_GPL(vhost_dev_cleanup); | ||
461 | 479 | ||
462 | static int log_access_ok(void __user *log_base, u64 addr, unsigned long sz) | 480 | static int log_access_ok(void __user *log_base, u64 addr, unsigned long sz) |
463 | { | 481 | { |
@@ -543,6 +561,7 @@ int vhost_log_access_ok(struct vhost_dev *dev) | |||
543 | lockdep_is_held(&dev->mutex)); | 561 | lockdep_is_held(&dev->mutex)); |
544 | return memory_access_ok(dev, mp, 1); | 562 | return memory_access_ok(dev, mp, 1); |
545 | } | 563 | } |
564 | EXPORT_SYMBOL_GPL(vhost_log_access_ok); | ||
546 | 565 | ||
547 | /* Verify access for write logging. */ | 566 | /* Verify access for write logging. */ |
548 | /* Caller should have vq mutex and device mutex */ | 567 | /* Caller should have vq mutex and device mutex */ |
@@ -568,6 +587,7 @@ int vhost_vq_access_ok(struct vhost_virtqueue *vq) | |||
568 | return vq_access_ok(vq->dev, vq->num, vq->desc, vq->avail, vq->used) && | 587 | return vq_access_ok(vq->dev, vq->num, vq->desc, vq->avail, vq->used) && |
569 | vq_log_access_ok(vq->dev, vq, vq->log_base); | 588 | vq_log_access_ok(vq->dev, vq, vq->log_base); |
570 | } | 589 | } |
590 | EXPORT_SYMBOL_GPL(vhost_vq_access_ok); | ||
571 | 591 | ||
572 | static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m) | 592 | static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m) |
573 | { | 593 | { |
@@ -797,6 +817,7 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp) | |||
797 | vhost_poll_flush(&vq->poll); | 817 | vhost_poll_flush(&vq->poll); |
798 | return r; | 818 | return r; |
799 | } | 819 | } |
820 | EXPORT_SYMBOL_GPL(vhost_vring_ioctl); | ||
800 | 821 | ||
801 | /* Caller must have device mutex */ | 822 | /* Caller must have device mutex */ |
802 | long vhost_dev_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *argp) | 823 | long vhost_dev_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *argp) |
@@ -877,6 +898,7 @@ long vhost_dev_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *argp) | |||
877 | done: | 898 | done: |
878 | return r; | 899 | return r; |
879 | } | 900 | } |
901 | EXPORT_SYMBOL_GPL(vhost_dev_ioctl); | ||
880 | 902 | ||
881 | static const struct vhost_memory_region *find_region(struct vhost_memory *mem, | 903 | static const struct vhost_memory_region *find_region(struct vhost_memory *mem, |
882 | __u64 addr, __u32 len) | 904 | __u64 addr, __u32 len) |
@@ -968,6 +990,7 @@ int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log, | |||
968 | BUG(); | 990 | BUG(); |
969 | return 0; | 991 | return 0; |
970 | } | 992 | } |
993 | EXPORT_SYMBOL_GPL(vhost_log_write); | ||
971 | 994 | ||
972 | static int vhost_update_used_flags(struct vhost_virtqueue *vq) | 995 | static int vhost_update_used_flags(struct vhost_virtqueue *vq) |
973 | { | 996 | { |
@@ -1019,6 +1042,7 @@ int vhost_init_used(struct vhost_virtqueue *vq) | |||
1019 | vq->signalled_used_valid = false; | 1042 | vq->signalled_used_valid = false; |
1020 | return get_user(vq->last_used_idx, &vq->used->idx); | 1043 | return get_user(vq->last_used_idx, &vq->used->idx); |
1021 | } | 1044 | } |
1045 | EXPORT_SYMBOL_GPL(vhost_init_used); | ||
1022 | 1046 | ||
1023 | static int translate_desc(struct vhost_dev *dev, u64 addr, u32 len, | 1047 | static int translate_desc(struct vhost_dev *dev, u64 addr, u32 len, |
1024 | struct iovec iov[], int iov_size) | 1048 | struct iovec iov[], int iov_size) |
@@ -1295,12 +1319,14 @@ int vhost_get_vq_desc(struct vhost_dev *dev, struct vhost_virtqueue *vq, | |||
1295 | BUG_ON(!(vq->used_flags & VRING_USED_F_NO_NOTIFY)); | 1319 | BUG_ON(!(vq->used_flags & VRING_USED_F_NO_NOTIFY)); |
1296 | return head; | 1320 | return head; |
1297 | } | 1321 | } |
1322 | EXPORT_SYMBOL_GPL(vhost_get_vq_desc); | ||
1298 | 1323 | ||
1299 | /* Reverse the effect of vhost_get_vq_desc. Useful for error handling. */ | 1324 | /* Reverse the effect of vhost_get_vq_desc. Useful for error handling. */ |
1300 | void vhost_discard_vq_desc(struct vhost_virtqueue *vq, int n) | 1325 | void vhost_discard_vq_desc(struct vhost_virtqueue *vq, int n) |
1301 | { | 1326 | { |
1302 | vq->last_avail_idx -= n; | 1327 | vq->last_avail_idx -= n; |
1303 | } | 1328 | } |
1329 | EXPORT_SYMBOL_GPL(vhost_discard_vq_desc); | ||
1304 | 1330 | ||
1305 | /* After we've used one of their buffers, we tell them about it. We'll then | 1331 | /* After we've used one of their buffers, we tell them about it. We'll then |
1306 | * want to notify the guest, using eventfd. */ | 1332 | * want to notify the guest, using eventfd. */ |
@@ -1349,6 +1375,7 @@ int vhost_add_used(struct vhost_virtqueue *vq, unsigned int head, int len) | |||
1349 | vq->signalled_used_valid = false; | 1375 | vq->signalled_used_valid = false; |
1350 | return 0; | 1376 | return 0; |
1351 | } | 1377 | } |
1378 | EXPORT_SYMBOL_GPL(vhost_add_used); | ||
1352 | 1379 | ||
1353 | static int __vhost_add_used_n(struct vhost_virtqueue *vq, | 1380 | static int __vhost_add_used_n(struct vhost_virtqueue *vq, |
1354 | struct vring_used_elem *heads, | 1381 | struct vring_used_elem *heads, |
@@ -1418,6 +1445,7 @@ int vhost_add_used_n(struct vhost_virtqueue *vq, struct vring_used_elem *heads, | |||
1418 | } | 1445 | } |
1419 | return r; | 1446 | return r; |
1420 | } | 1447 | } |
1448 | EXPORT_SYMBOL_GPL(vhost_add_used_n); | ||
1421 | 1449 | ||
1422 | static bool vhost_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq) | 1450 | static bool vhost_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq) |
1423 | { | 1451 | { |
@@ -1462,6 +1490,7 @@ void vhost_signal(struct vhost_dev *dev, struct vhost_virtqueue *vq) | |||
1462 | if (vq->call_ctx && vhost_notify(dev, vq)) | 1490 | if (vq->call_ctx && vhost_notify(dev, vq)) |
1463 | eventfd_signal(vq->call_ctx, 1); | 1491 | eventfd_signal(vq->call_ctx, 1); |
1464 | } | 1492 | } |
1493 | EXPORT_SYMBOL_GPL(vhost_signal); | ||
1465 | 1494 | ||
1466 | /* And here's the combo meal deal. Supersize me! */ | 1495 | /* And here's the combo meal deal. Supersize me! */ |
1467 | void vhost_add_used_and_signal(struct vhost_dev *dev, | 1496 | void vhost_add_used_and_signal(struct vhost_dev *dev, |
@@ -1471,6 +1500,7 @@ void vhost_add_used_and_signal(struct vhost_dev *dev, | |||
1471 | vhost_add_used(vq, head, len); | 1500 | vhost_add_used(vq, head, len); |
1472 | vhost_signal(dev, vq); | 1501 | vhost_signal(dev, vq); |
1473 | } | 1502 | } |
1503 | EXPORT_SYMBOL_GPL(vhost_add_used_and_signal); | ||
1474 | 1504 | ||
1475 | /* multi-buffer version of vhost_add_used_and_signal */ | 1505 | /* multi-buffer version of vhost_add_used_and_signal */ |
1476 | void vhost_add_used_and_signal_n(struct vhost_dev *dev, | 1506 | void vhost_add_used_and_signal_n(struct vhost_dev *dev, |
@@ -1480,6 +1510,7 @@ void vhost_add_used_and_signal_n(struct vhost_dev *dev, | |||
1480 | vhost_add_used_n(vq, heads, count); | 1510 | vhost_add_used_n(vq, heads, count); |
1481 | vhost_signal(dev, vq); | 1511 | vhost_signal(dev, vq); |
1482 | } | 1512 | } |
1513 | EXPORT_SYMBOL_GPL(vhost_add_used_and_signal_n); | ||
1483 | 1514 | ||
1484 | /* OK, now we need to know about added descriptors. */ | 1515 | /* OK, now we need to know about added descriptors. */ |
1485 | bool vhost_enable_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq) | 1516 | bool vhost_enable_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq) |
@@ -1517,6 +1548,7 @@ bool vhost_enable_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq) | |||
1517 | 1548 | ||
1518 | return avail_idx != vq->avail_idx; | 1549 | return avail_idx != vq->avail_idx; |
1519 | } | 1550 | } |
1551 | EXPORT_SYMBOL_GPL(vhost_enable_notify); | ||
1520 | 1552 | ||
1521 | /* We don't need to be notified again. */ | 1553 | /* We don't need to be notified again. */ |
1522 | void vhost_disable_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq) | 1554 | void vhost_disable_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq) |
@@ -1533,3 +1565,21 @@ void vhost_disable_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq) | |||
1533 | &vq->used->flags, r); | 1565 | &vq->used->flags, r); |
1534 | } | 1566 | } |
1535 | } | 1567 | } |
1568 | EXPORT_SYMBOL_GPL(vhost_disable_notify); | ||
1569 | |||
1570 | static int __init vhost_init(void) | ||
1571 | { | ||
1572 | return 0; | ||
1573 | } | ||
1574 | |||
1575 | static void __exit vhost_exit(void) | ||
1576 | { | ||
1577 | } | ||
1578 | |||
1579 | module_init(vhost_init); | ||
1580 | module_exit(vhost_exit); | ||
1581 | |||
1582 | MODULE_VERSION("0.0.1"); | ||
1583 | MODULE_LICENSE("GPL v2"); | ||
1584 | MODULE_AUTHOR("Michael S. Tsirkin"); | ||
1585 | MODULE_DESCRIPTION("Host kernel accelerator for virtio"); | ||
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index 64adcf99ff33..42298cd23c73 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h | |||
@@ -46,6 +46,8 @@ int vhost_poll_start(struct vhost_poll *poll, struct file *file); | |||
46 | void vhost_poll_stop(struct vhost_poll *poll); | 46 | void vhost_poll_stop(struct vhost_poll *poll); |
47 | void vhost_poll_flush(struct vhost_poll *poll); | 47 | void vhost_poll_flush(struct vhost_poll *poll); |
48 | void vhost_poll_queue(struct vhost_poll *poll); | 48 | void vhost_poll_queue(struct vhost_poll *poll); |
49 | void vhost_work_flush(struct vhost_dev *dev, struct vhost_work *work); | ||
50 | long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp); | ||
49 | 51 | ||
50 | struct vhost_log { | 52 | struct vhost_log { |
51 | u64 addr; | 53 | u64 addr; |