diff options
-rw-r--r-- | drivers/infiniband/core/uverbs.h | 20 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_cmd.c | 56 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_main.c | 127 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/main.c | 6 | ||||
-rw-r--r-- | include/rdma/ib_verbs.h | 1 | ||||
-rw-r--r-- | include/uapi/rdma/ib_user_verbs.h | 23 |
6 files changed, 160 insertions, 73 deletions
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index 777954f67270..24adccbf92f9 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h | |||
@@ -47,6 +47,14 @@ | |||
47 | #include <rdma/ib_umem.h> | 47 | #include <rdma/ib_umem.h> |
48 | #include <rdma/ib_user_verbs.h> | 48 | #include <rdma/ib_user_verbs.h> |
49 | 49 | ||
50 | #define INIT_UDATA(udata, ibuf, obuf, ilen, olen) \ | ||
51 | do { \ | ||
52 | (udata)->inbuf = (void __user *) (ibuf); \ | ||
53 | (udata)->outbuf = (void __user *) (obuf); \ | ||
54 | (udata)->inlen = (ilen); \ | ||
55 | (udata)->outlen = (olen); \ | ||
56 | } while (0) | ||
57 | |||
50 | /* | 58 | /* |
51 | * Our lifetime rules for these structs are the following: | 59 | * Our lifetime rules for these structs are the following: |
52 | * | 60 | * |
@@ -233,9 +241,17 @@ IB_UVERBS_DECLARE_CMD(destroy_srq); | |||
233 | IB_UVERBS_DECLARE_CMD(create_xsrq); | 241 | IB_UVERBS_DECLARE_CMD(create_xsrq); |
234 | IB_UVERBS_DECLARE_CMD(open_xrcd); | 242 | IB_UVERBS_DECLARE_CMD(open_xrcd); |
235 | IB_UVERBS_DECLARE_CMD(close_xrcd); | 243 | IB_UVERBS_DECLARE_CMD(close_xrcd); |
244 | |||
236 | #ifdef CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING | 245 | #ifdef CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING |
237 | IB_UVERBS_DECLARE_CMD(create_flow); | 246 | |
238 | IB_UVERBS_DECLARE_CMD(destroy_flow); | 247 | #define IB_UVERBS_DECLARE_EX_CMD(name) \ |
248 | int ib_uverbs_ex_##name(struct ib_uverbs_file *file, \ | ||
249 | struct ib_udata *ucore, \ | ||
250 | struct ib_udata *uhw) | ||
251 | |||
252 | IB_UVERBS_DECLARE_EX_CMD(create_flow); | ||
253 | IB_UVERBS_DECLARE_EX_CMD(destroy_flow); | ||
254 | |||
239 | #endif /* CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING */ | 255 | #endif /* CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING */ |
240 | 256 | ||
241 | #endif /* UVERBS_H */ | 257 | #endif /* UVERBS_H */ |
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 19f14d82c988..33a52785f812 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
@@ -58,14 +58,6 @@ static struct uverbs_lock_class xrcd_lock_class = { .name = "XRCD-uobj" }; | |||
58 | static struct uverbs_lock_class rule_lock_class = { .name = "RULE-uobj" }; | 58 | static struct uverbs_lock_class rule_lock_class = { .name = "RULE-uobj" }; |
59 | #endif /* CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING */ | 59 | #endif /* CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING */ |
60 | 60 | ||
61 | #define INIT_UDATA(udata, ibuf, obuf, ilen, olen) \ | ||
62 | do { \ | ||
63 | (udata)->inbuf = (void __user *) (ibuf); \ | ||
64 | (udata)->outbuf = (void __user *) (obuf); \ | ||
65 | (udata)->inlen = (ilen); \ | ||
66 | (udata)->outlen = (olen); \ | ||
67 | } while (0) | ||
68 | |||
69 | /* | 61 | /* |
70 | * The ib_uobject locking scheme is as follows: | 62 | * The ib_uobject locking scheme is as follows: |
71 | * | 63 | * |
@@ -2642,9 +2634,9 @@ static int kern_spec_to_ib_spec(struct ib_uverbs_flow_spec *kern_spec, | |||
2642 | return 0; | 2634 | return 0; |
2643 | } | 2635 | } |
2644 | 2636 | ||
2645 | ssize_t ib_uverbs_create_flow(struct ib_uverbs_file *file, | 2637 | int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file, |
2646 | const char __user *buf, int in_len, | 2638 | struct ib_udata *ucore, |
2647 | int out_len) | 2639 | struct ib_udata *uhw) |
2648 | { | 2640 | { |
2649 | struct ib_uverbs_create_flow cmd; | 2641 | struct ib_uverbs_create_flow cmd; |
2650 | struct ib_uverbs_create_flow_resp resp; | 2642 | struct ib_uverbs_create_flow_resp resp; |
@@ -2658,11 +2650,15 @@ ssize_t ib_uverbs_create_flow(struct ib_uverbs_file *file, | |||
2658 | void *ib_spec; | 2650 | void *ib_spec; |
2659 | int i; | 2651 | int i; |
2660 | 2652 | ||
2661 | if (out_len < sizeof(resp)) | 2653 | if (ucore->outlen < sizeof(resp)) |
2662 | return -ENOSPC; | 2654 | return -ENOSPC; |
2663 | 2655 | ||
2664 | if (copy_from_user(&cmd, buf, sizeof(cmd))) | 2656 | err = ib_copy_from_udata(&cmd, ucore, sizeof(cmd)); |
2665 | return -EFAULT; | 2657 | if (err) |
2658 | return err; | ||
2659 | |||
2660 | ucore->inbuf += sizeof(cmd); | ||
2661 | ucore->inlen -= sizeof(cmd); | ||
2666 | 2662 | ||
2667 | if (cmd.comp_mask) | 2663 | if (cmd.comp_mask) |
2668 | return -EINVAL; | 2664 | return -EINVAL; |
@@ -2674,7 +2670,7 @@ ssize_t ib_uverbs_create_flow(struct ib_uverbs_file *file, | |||
2674 | if (cmd.flow_attr.num_of_specs > IB_FLOW_SPEC_SUPPORT_LAYERS) | 2670 | if (cmd.flow_attr.num_of_specs > IB_FLOW_SPEC_SUPPORT_LAYERS) |
2675 | return -EINVAL; | 2671 | return -EINVAL; |
2676 | 2672 | ||
2677 | if (cmd.flow_attr.size > (in_len - sizeof(cmd)) || | 2673 | if (cmd.flow_attr.size > ucore->inlen || |
2678 | cmd.flow_attr.size > | 2674 | cmd.flow_attr.size > |
2679 | (cmd.flow_attr.num_of_specs * sizeof(struct ib_uverbs_flow_spec))) | 2675 | (cmd.flow_attr.num_of_specs * sizeof(struct ib_uverbs_flow_spec))) |
2680 | return -EINVAL; | 2676 | return -EINVAL; |
@@ -2686,11 +2682,10 @@ ssize_t ib_uverbs_create_flow(struct ib_uverbs_file *file, | |||
2686 | return -ENOMEM; | 2682 | return -ENOMEM; |
2687 | 2683 | ||
2688 | memcpy(kern_flow_attr, &cmd.flow_attr, sizeof(*kern_flow_attr)); | 2684 | memcpy(kern_flow_attr, &cmd.flow_attr, sizeof(*kern_flow_attr)); |
2689 | if (copy_from_user(kern_flow_attr + 1, buf + sizeof(cmd), | 2685 | err = ib_copy_from_udata(kern_flow_attr + 1, ucore, |
2690 | cmd.flow_attr.size)) { | 2686 | cmd.flow_attr.size); |
2691 | err = -EFAULT; | 2687 | if (err) |
2692 | goto err_free_attr; | 2688 | goto err_free_attr; |
2693 | } | ||
2694 | } else { | 2689 | } else { |
2695 | kern_flow_attr = &cmd.flow_attr; | 2690 | kern_flow_attr = &cmd.flow_attr; |
2696 | } | 2691 | } |
@@ -2758,11 +2753,10 @@ ssize_t ib_uverbs_create_flow(struct ib_uverbs_file *file, | |||
2758 | memset(&resp, 0, sizeof(resp)); | 2753 | memset(&resp, 0, sizeof(resp)); |
2759 | resp.flow_handle = uobj->id; | 2754 | resp.flow_handle = uobj->id; |
2760 | 2755 | ||
2761 | if (copy_to_user((void __user *)(unsigned long) cmd.response, | 2756 | err = ib_copy_to_udata(ucore, |
2762 | &resp, sizeof(resp))) { | 2757 | &resp, sizeof(resp)); |
2763 | err = -EFAULT; | 2758 | if (err) |
2764 | goto err_copy; | 2759 | goto err_copy; |
2765 | } | ||
2766 | 2760 | ||
2767 | put_qp_read(qp); | 2761 | put_qp_read(qp); |
2768 | mutex_lock(&file->mutex); | 2762 | mutex_lock(&file->mutex); |
@@ -2775,7 +2769,7 @@ ssize_t ib_uverbs_create_flow(struct ib_uverbs_file *file, | |||
2775 | kfree(flow_attr); | 2769 | kfree(flow_attr); |
2776 | if (cmd.flow_attr.num_of_specs) | 2770 | if (cmd.flow_attr.num_of_specs) |
2777 | kfree(kern_flow_attr); | 2771 | kfree(kern_flow_attr); |
2778 | return in_len; | 2772 | return 0; |
2779 | err_copy: | 2773 | err_copy: |
2780 | idr_remove_uobj(&ib_uverbs_rule_idr, uobj); | 2774 | idr_remove_uobj(&ib_uverbs_rule_idr, uobj); |
2781 | destroy_flow: | 2775 | destroy_flow: |
@@ -2792,16 +2786,18 @@ err_free_attr: | |||
2792 | return err; | 2786 | return err; |
2793 | } | 2787 | } |
2794 | 2788 | ||
2795 | ssize_t ib_uverbs_destroy_flow(struct ib_uverbs_file *file, | 2789 | int ib_uverbs_ex_destroy_flow(struct ib_uverbs_file *file, |
2796 | const char __user *buf, int in_len, | 2790 | struct ib_udata *ucore, |
2797 | int out_len) { | 2791 | struct ib_udata *uhw) |
2792 | { | ||
2798 | struct ib_uverbs_destroy_flow cmd; | 2793 | struct ib_uverbs_destroy_flow cmd; |
2799 | struct ib_flow *flow_id; | 2794 | struct ib_flow *flow_id; |
2800 | struct ib_uobject *uobj; | 2795 | struct ib_uobject *uobj; |
2801 | int ret; | 2796 | int ret; |
2802 | 2797 | ||
2803 | if (copy_from_user(&cmd, buf, sizeof(cmd))) | 2798 | ret = ib_copy_from_udata(&cmd, ucore, sizeof(cmd)); |
2804 | return -EFAULT; | 2799 | if (ret) |
2800 | return ret; | ||
2805 | 2801 | ||
2806 | uobj = idr_write_uobj(&ib_uverbs_rule_idr, cmd.flow_handle, | 2802 | uobj = idr_write_uobj(&ib_uverbs_rule_idr, cmd.flow_handle, |
2807 | file->ucontext); | 2803 | file->ucontext); |
@@ -2823,7 +2819,7 @@ ssize_t ib_uverbs_destroy_flow(struct ib_uverbs_file *file, | |||
2823 | 2819 | ||
2824 | put_uobj(uobj); | 2820 | put_uobj(uobj); |
2825 | 2821 | ||
2826 | return ret ? ret : in_len; | 2822 | return ret; |
2827 | } | 2823 | } |
2828 | #endif /* CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING */ | 2824 | #endif /* CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING */ |
2829 | 2825 | ||
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 2df31f68ea09..189d99e76d9f 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
@@ -115,11 +115,16 @@ static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file, | |||
115 | [IB_USER_VERBS_CMD_CLOSE_XRCD] = ib_uverbs_close_xrcd, | 115 | [IB_USER_VERBS_CMD_CLOSE_XRCD] = ib_uverbs_close_xrcd, |
116 | [IB_USER_VERBS_CMD_CREATE_XSRQ] = ib_uverbs_create_xsrq, | 116 | [IB_USER_VERBS_CMD_CREATE_XSRQ] = ib_uverbs_create_xsrq, |
117 | [IB_USER_VERBS_CMD_OPEN_QP] = ib_uverbs_open_qp, | 117 | [IB_USER_VERBS_CMD_OPEN_QP] = ib_uverbs_open_qp, |
118 | }; | ||
119 | |||
118 | #ifdef CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING | 120 | #ifdef CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING |
119 | [IB_USER_VERBS_CMD_CREATE_FLOW] = ib_uverbs_create_flow, | 121 | static int (*uverbs_ex_cmd_table[])(struct ib_uverbs_file *file, |
120 | [IB_USER_VERBS_CMD_DESTROY_FLOW] = ib_uverbs_destroy_flow | 122 | struct ib_udata *ucore, |
121 | #endif /* CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING */ | 123 | struct ib_udata *uhw) = { |
124 | [IB_USER_VERBS_EX_CMD_CREATE_FLOW] = ib_uverbs_ex_create_flow, | ||
125 | [IB_USER_VERBS_EX_CMD_DESTROY_FLOW] = ib_uverbs_ex_destroy_flow | ||
122 | }; | 126 | }; |
127 | #endif /* CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING */ | ||
123 | 128 | ||
124 | static void ib_uverbs_add_one(struct ib_device *device); | 129 | static void ib_uverbs_add_one(struct ib_device *device); |
125 | static void ib_uverbs_remove_one(struct ib_device *device); | 130 | static void ib_uverbs_remove_one(struct ib_device *device); |
@@ -589,6 +594,7 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, | |||
589 | { | 594 | { |
590 | struct ib_uverbs_file *file = filp->private_data; | 595 | struct ib_uverbs_file *file = filp->private_data; |
591 | struct ib_uverbs_cmd_hdr hdr; | 596 | struct ib_uverbs_cmd_hdr hdr; |
597 | __u32 flags; | ||
592 | 598 | ||
593 | if (count < sizeof hdr) | 599 | if (count < sizeof hdr) |
594 | return -EINVAL; | 600 | return -EINVAL; |
@@ -596,45 +602,108 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, | |||
596 | if (copy_from_user(&hdr, buf, sizeof hdr)) | 602 | if (copy_from_user(&hdr, buf, sizeof hdr)) |
597 | return -EFAULT; | 603 | return -EFAULT; |
598 | 604 | ||
599 | if (hdr.command >= ARRAY_SIZE(uverbs_cmd_table) || | 605 | flags = (hdr.command & |
600 | !uverbs_cmd_table[hdr.command]) | 606 | IB_USER_VERBS_CMD_FLAGS_MASK) >> IB_USER_VERBS_CMD_FLAGS_SHIFT; |
601 | return -EINVAL; | ||
602 | 607 | ||
603 | if (!file->ucontext && | 608 | if (!flags) { |
604 | hdr.command != IB_USER_VERBS_CMD_GET_CONTEXT) | 609 | __u32 command; |
605 | return -EINVAL; | ||
606 | 610 | ||
607 | if (!(file->device->ib_dev->uverbs_cmd_mask & (1ull << hdr.command))) | 611 | if (hdr.command & ~(__u32)(IB_USER_VERBS_CMD_FLAGS_MASK | |
608 | return -ENOSYS; | 612 | IB_USER_VERBS_CMD_COMMAND_MASK)) |
613 | return -EINVAL; | ||
609 | 614 | ||
610 | #ifdef CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING | 615 | command = hdr.command & IB_USER_VERBS_CMD_COMMAND_MASK; |
611 | if (hdr.command >= IB_USER_VERBS_CMD_THRESHOLD) { | ||
612 | struct ib_uverbs_cmd_hdr_ex hdr_ex; | ||
613 | 616 | ||
614 | if (copy_from_user(&hdr_ex, buf, sizeof(hdr_ex))) | 617 | if (command >= ARRAY_SIZE(uverbs_cmd_table) || |
615 | return -EFAULT; | 618 | !uverbs_cmd_table[command]) |
619 | return -EINVAL; | ||
616 | 620 | ||
617 | if (((hdr_ex.in_words + hdr_ex.provider_in_words) * 4) != count) | 621 | if (!file->ucontext && |
622 | command != IB_USER_VERBS_CMD_GET_CONTEXT) | ||
618 | return -EINVAL; | 623 | return -EINVAL; |
619 | 624 | ||
620 | return uverbs_cmd_table[hdr.command](file, | 625 | if (!(file->device->ib_dev->uverbs_cmd_mask & (1ull << command))) |
621 | buf + sizeof(hdr_ex), | 626 | return -ENOSYS; |
622 | (hdr_ex.in_words + | 627 | |
623 | hdr_ex.provider_in_words) * 4, | ||
624 | (hdr_ex.out_words + | ||
625 | hdr_ex.provider_out_words) * 4); | ||
626 | } else { | ||
627 | #endif /* CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING */ | ||
628 | if (hdr.in_words * 4 != count) | 628 | if (hdr.in_words * 4 != count) |
629 | return -EINVAL; | 629 | return -EINVAL; |
630 | 630 | ||
631 | return uverbs_cmd_table[hdr.command](file, | 631 | return uverbs_cmd_table[command](file, |
632 | buf + sizeof(hdr), | 632 | buf + sizeof(hdr), |
633 | hdr.in_words * 4, | 633 | hdr.in_words * 4, |
634 | hdr.out_words * 4); | 634 | hdr.out_words * 4); |
635 | |||
635 | #ifdef CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING | 636 | #ifdef CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING |
637 | |||
638 | } else if (flags == IB_USER_VERBS_CMD_FLAG_EXTENDED) { | ||
639 | __u32 command; | ||
640 | |||
641 | struct ib_uverbs_ex_cmd_hdr ex_hdr; | ||
642 | struct ib_udata ucore; | ||
643 | struct ib_udata uhw; | ||
644 | int err; | ||
645 | size_t written_count = count; | ||
646 | |||
647 | if (hdr.command & ~(__u32)(IB_USER_VERBS_CMD_FLAGS_MASK | | ||
648 | IB_USER_VERBS_CMD_COMMAND_MASK)) | ||
649 | return -EINVAL; | ||
650 | |||
651 | command = hdr.command & IB_USER_VERBS_CMD_COMMAND_MASK; | ||
652 | |||
653 | if (command >= ARRAY_SIZE(uverbs_ex_cmd_table) || | ||
654 | !uverbs_ex_cmd_table[command]) | ||
655 | return -ENOSYS; | ||
656 | |||
657 | if (!file->ucontext) | ||
658 | return -EINVAL; | ||
659 | |||
660 | if (!(file->device->ib_dev->uverbs_ex_cmd_mask & (1ull << command))) | ||
661 | return -ENOSYS; | ||
662 | |||
663 | if (count < (sizeof(hdr) + sizeof(ex_hdr))) | ||
664 | return -EINVAL; | ||
665 | |||
666 | if (copy_from_user(&ex_hdr, buf + sizeof(hdr), sizeof(ex_hdr))) | ||
667 | return -EFAULT; | ||
668 | |||
669 | count -= sizeof(hdr) + sizeof(ex_hdr); | ||
670 | buf += sizeof(hdr) + sizeof(ex_hdr); | ||
671 | |||
672 | if ((hdr.in_words + ex_hdr.provider_in_words) * 8 != count) | ||
673 | return -EINVAL; | ||
674 | |||
675 | if (ex_hdr.response) { | ||
676 | if (!hdr.out_words && !ex_hdr.provider_out_words) | ||
677 | return -EINVAL; | ||
678 | } else { | ||
679 | if (hdr.out_words || ex_hdr.provider_out_words) | ||
680 | return -EINVAL; | ||
681 | } | ||
682 | |||
683 | INIT_UDATA(&ucore, | ||
684 | (hdr.in_words) ? buf : 0, | ||
685 | (unsigned long)ex_hdr.response, | ||
686 | hdr.in_words * 8, | ||
687 | hdr.out_words * 8); | ||
688 | |||
689 | INIT_UDATA(&uhw, | ||
690 | (ex_hdr.provider_in_words) ? buf + ucore.inlen : 0, | ||
691 | (ex_hdr.provider_out_words) ? (unsigned long)ex_hdr.response + ucore.outlen : 0, | ||
692 | ex_hdr.provider_in_words * 8, | ||
693 | ex_hdr.provider_out_words * 8); | ||
694 | |||
695 | err = uverbs_ex_cmd_table[command](file, | ||
696 | &ucore, | ||
697 | &uhw); | ||
698 | |||
699 | if (err) | ||
700 | return err; | ||
701 | |||
702 | return written_count; | ||
636 | } | 703 | } |
637 | #endif /* CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING */ | 704 | #endif /* CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING */ |
705 | |||
706 | return -ENOSYS; | ||
638 | } | 707 | } |
639 | 708 | ||
640 | static int ib_uverbs_mmap(struct file *filp, struct vm_area_struct *vma) | 709 | static int ib_uverbs_mmap(struct file *filp, struct vm_area_struct *vma) |
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index f0612645de99..4be29fef66d6 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
@@ -1692,9 +1692,9 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) | |||
1692 | ibdev->ib_dev.destroy_flow = mlx4_ib_destroy_flow; | 1692 | ibdev->ib_dev.destroy_flow = mlx4_ib_destroy_flow; |
1693 | 1693 | ||
1694 | #ifdef CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING | 1694 | #ifdef CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING |
1695 | ibdev->ib_dev.uverbs_cmd_mask |= | 1695 | ibdev->ib_dev.uverbs_ex_cmd_mask |= |
1696 | (1ull << IB_USER_VERBS_CMD_CREATE_FLOW) | | 1696 | (1ull << IB_USER_VERBS_EX_CMD_CREATE_FLOW) | |
1697 | (1ull << IB_USER_VERBS_CMD_DESTROY_FLOW); | 1697 | (1ull << IB_USER_VERBS_EX_CMD_DESTROY_FLOW); |
1698 | #endif /* CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING */ | 1698 | #endif /* CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING */ |
1699 | } | 1699 | } |
1700 | 1700 | ||
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index e393171e2fac..a06fc122f803 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h | |||
@@ -1436,6 +1436,7 @@ struct ib_device { | |||
1436 | 1436 | ||
1437 | int uverbs_abi_ver; | 1437 | int uverbs_abi_ver; |
1438 | u64 uverbs_cmd_mask; | 1438 | u64 uverbs_cmd_mask; |
1439 | u64 uverbs_ex_cmd_mask; | ||
1439 | 1440 | ||
1440 | char node_desc[64]; | 1441 | char node_desc[64]; |
1441 | __be64 node_guid; | 1442 | __be64 node_guid; |
diff --git a/include/uapi/rdma/ib_user_verbs.h b/include/uapi/rdma/ib_user_verbs.h index fc9bbe37cfce..6ace125e1af6 100644 --- a/include/uapi/rdma/ib_user_verbs.h +++ b/include/uapi/rdma/ib_user_verbs.h | |||
@@ -87,11 +87,14 @@ enum { | |||
87 | IB_USER_VERBS_CMD_CLOSE_XRCD, | 87 | IB_USER_VERBS_CMD_CLOSE_XRCD, |
88 | IB_USER_VERBS_CMD_CREATE_XSRQ, | 88 | IB_USER_VERBS_CMD_CREATE_XSRQ, |
89 | IB_USER_VERBS_CMD_OPEN_QP, | 89 | IB_USER_VERBS_CMD_OPEN_QP, |
90 | }; | ||
91 | |||
90 | #ifdef CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING | 92 | #ifdef CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING |
91 | IB_USER_VERBS_CMD_CREATE_FLOW = IB_USER_VERBS_CMD_THRESHOLD, | 93 | enum { |
92 | IB_USER_VERBS_CMD_DESTROY_FLOW | 94 | IB_USER_VERBS_EX_CMD_CREATE_FLOW = IB_USER_VERBS_CMD_THRESHOLD, |
93 | #endif /* CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING */ | 95 | IB_USER_VERBS_EX_CMD_DESTROY_FLOW |
94 | }; | 96 | }; |
97 | #endif /* CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING */ | ||
95 | 98 | ||
96 | /* | 99 | /* |
97 | * Make sure that all structs defined in this file remain laid out so | 100 | * Make sure that all structs defined in this file remain laid out so |
@@ -122,6 +125,12 @@ struct ib_uverbs_comp_event_desc { | |||
122 | * the rest of the command struct based on these value. | 125 | * the rest of the command struct based on these value. |
123 | */ | 126 | */ |
124 | 127 | ||
128 | #define IB_USER_VERBS_CMD_COMMAND_MASK 0xff | ||
129 | #define IB_USER_VERBS_CMD_FLAGS_MASK 0xff000000u | ||
130 | #define IB_USER_VERBS_CMD_FLAGS_SHIFT 24 | ||
131 | |||
132 | #define IB_USER_VERBS_CMD_FLAG_EXTENDED 0x80 | ||
133 | |||
125 | struct ib_uverbs_cmd_hdr { | 134 | struct ib_uverbs_cmd_hdr { |
126 | __u32 command; | 135 | __u32 command; |
127 | __u16 in_words; | 136 | __u16 in_words; |
@@ -129,10 +138,8 @@ struct ib_uverbs_cmd_hdr { | |||
129 | }; | 138 | }; |
130 | 139 | ||
131 | #ifdef CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING | 140 | #ifdef CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING |
132 | struct ib_uverbs_cmd_hdr_ex { | 141 | struct ib_uverbs_ex_cmd_hdr { |
133 | __u32 command; | 142 | __u64 response; |
134 | __u16 in_words; | ||
135 | __u16 out_words; | ||
136 | __u16 provider_in_words; | 143 | __u16 provider_in_words; |
137 | __u16 provider_out_words; | 144 | __u16 provider_out_words; |
138 | __u32 cmd_hdr_reserved; | 145 | __u32 cmd_hdr_reserved; |
@@ -782,8 +789,6 @@ struct ib_uverbs_flow_attr { | |||
782 | 789 | ||
783 | struct ib_uverbs_create_flow { | 790 | struct ib_uverbs_create_flow { |
784 | __u32 comp_mask; | 791 | __u32 comp_mask; |
785 | __u32 reserved; | ||
786 | __u64 response; | ||
787 | __u32 qp_handle; | 792 | __u32 qp_handle; |
788 | struct ib_uverbs_flow_attr flow_attr; | 793 | struct ib_uverbs_flow_attr flow_attr; |
789 | }; | 794 | }; |