diff options
| -rw-r--r-- | drivers/infiniband/core/uverbs_cmd.c | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 89c4ce2da78b..87ffeebc0b28 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
| @@ -3488,8 +3488,8 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file, | |||
| 3488 | struct ib_flow_attr *flow_attr; | 3488 | struct ib_flow_attr *flow_attr; |
| 3489 | struct ib_qp *qp; | 3489 | struct ib_qp *qp; |
| 3490 | struct ib_uflow_resources *uflow_res; | 3490 | struct ib_uflow_resources *uflow_res; |
| 3491 | struct ib_uverbs_flow_spec_hdr *kern_spec; | ||
| 3491 | int err = 0; | 3492 | int err = 0; |
| 3492 | void *kern_spec; | ||
| 3493 | void *ib_spec; | 3493 | void *ib_spec; |
| 3494 | int i; | 3494 | int i; |
| 3495 | 3495 | ||
| @@ -3538,8 +3538,8 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file, | |||
| 3538 | if (!kern_flow_attr) | 3538 | if (!kern_flow_attr) |
| 3539 | return -ENOMEM; | 3539 | return -ENOMEM; |
| 3540 | 3540 | ||
| 3541 | memcpy(kern_flow_attr, &cmd.flow_attr, sizeof(*kern_flow_attr)); | 3541 | *kern_flow_attr = cmd.flow_attr; |
| 3542 | err = ib_copy_from_udata(kern_flow_attr + 1, ucore, | 3542 | err = ib_copy_from_udata(&kern_flow_attr->flow_specs, ucore, |
| 3543 | cmd.flow_attr.size); | 3543 | cmd.flow_attr.size); |
| 3544 | if (err) | 3544 | if (err) |
| 3545 | goto err_free_attr; | 3545 | goto err_free_attr; |
| @@ -3583,21 +3583,22 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file, | |||
| 3583 | flow_attr->flags = kern_flow_attr->flags; | 3583 | flow_attr->flags = kern_flow_attr->flags; |
| 3584 | flow_attr->size = sizeof(*flow_attr); | 3584 | flow_attr->size = sizeof(*flow_attr); |
| 3585 | 3585 | ||
| 3586 | kern_spec = kern_flow_attr + 1; | 3586 | kern_spec = kern_flow_attr->flow_specs; |
| 3587 | ib_spec = flow_attr + 1; | 3587 | ib_spec = flow_attr + 1; |
| 3588 | for (i = 0; i < flow_attr->num_of_specs && | 3588 | for (i = 0; i < flow_attr->num_of_specs && |
| 3589 | cmd.flow_attr.size > offsetof(struct ib_uverbs_flow_spec, reserved) && | 3589 | cmd.flow_attr.size > sizeof(*kern_spec) && |
| 3590 | cmd.flow_attr.size >= | 3590 | cmd.flow_attr.size >= kern_spec->size; |
| 3591 | ((struct ib_uverbs_flow_spec *)kern_spec)->size; i++) { | 3591 | i++) { |
| 3592 | err = kern_spec_to_ib_spec(file->ucontext, kern_spec, ib_spec, | 3592 | err = kern_spec_to_ib_spec( |
| 3593 | uflow_res); | 3593 | file->ucontext, (struct ib_uverbs_flow_spec *)kern_spec, |
| 3594 | ib_spec, uflow_res); | ||
| 3594 | if (err) | 3595 | if (err) |
| 3595 | goto err_free; | 3596 | goto err_free; |
| 3596 | 3597 | ||
| 3597 | flow_attr->size += | 3598 | flow_attr->size += |
| 3598 | ((union ib_flow_spec *) ib_spec)->size; | 3599 | ((union ib_flow_spec *) ib_spec)->size; |
| 3599 | cmd.flow_attr.size -= ((struct ib_uverbs_flow_spec *)kern_spec)->size; | 3600 | cmd.flow_attr.size -= kern_spec->size; |
| 3600 | kern_spec += ((struct ib_uverbs_flow_spec *) kern_spec)->size; | 3601 | kern_spec = ((void *)kern_spec) + kern_spec->size; |
| 3601 | ib_spec += ((union ib_flow_spec *) ib_spec)->size; | 3602 | ib_spec += ((union ib_flow_spec *) ib_spec)->size; |
| 3602 | } | 3603 | } |
| 3603 | if (cmd.flow_attr.size || (i != flow_attr->num_of_specs)) { | 3604 | if (cmd.flow_attr.size || (i != flow_attr->num_of_specs)) { |
