RDMA/uverbs: Check for NULL driver methods for every write call

Add annotations to the uverbs_api structure indicating which driver
methods are called by the implementation. If the required method
is NULL the write API will be not be callable.

This effectively duplicates the cmd_mask system, however it does it by
expressing invariants required by the core code, not by delegating
decision making to the driver. This is another step toward eliminating
cmd_mask.

Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
This commit is contained in:
Jason Gunthorpe 2018-11-12 22:59:58 +02:00
parent 1de751caf7
commit a140692a52
3 changed files with 174 additions and 97 deletions

View File

@ -991,11 +991,6 @@ static struct ib_ucq_object *create_cq(struct ib_uverbs_file *file,
if (IS_ERR(obj)) if (IS_ERR(obj))
return obj; return obj;
if (!ib_dev->create_cq) {
ret = -EOPNOTSUPP;
goto err;
}
if (cmd->comp_channel >= 0) { if (cmd->comp_channel >= 0) {
ev_file = ib_uverbs_lookup_comp_file(cmd->comp_channel, file); ev_file = ib_uverbs_lookup_comp_file(cmd->comp_channel, file);
if (IS_ERR(ev_file)) { if (IS_ERR(ev_file)) {
@ -2541,8 +2536,7 @@ static ssize_t ib_uverbs_post_srq_recv(struct ib_uverbs_file *file,
goto out; goto out;
resp.bad_wr = 0; resp.bad_wr = 0;
ret = srq->device->post_srq_recv ? ret = srq->device->post_srq_recv(srq, wr, &bad_wr);
srq->device->post_srq_recv(srq, wr, &bad_wr) : -EOPNOTSUPP;
uobj_put_obj_read(srq); uobj_put_obj_read(srq);
@ -3144,10 +3138,6 @@ static int ib_uverbs_ex_create_wq(struct ib_uverbs_file *file,
obj->uevent.events_reported = 0; obj->uevent.events_reported = 0;
INIT_LIST_HEAD(&obj->uevent.event_list); INIT_LIST_HEAD(&obj->uevent.event_list);
if (!pd->device->create_wq) {
err = -EOPNOTSUPP;
goto err_put_cq;
}
wq = pd->device->create_wq(pd, &wq_init_attr, uhw); wq = pd->device->create_wq(pd, &wq_init_attr, uhw);
if (IS_ERR(wq)) { if (IS_ERR(wq)) {
err = PTR_ERR(wq); err = PTR_ERR(wq);
@ -3277,12 +3267,7 @@ static int ib_uverbs_ex_modify_wq(struct ib_uverbs_file *file,
wq_attr.flags = cmd.flags; wq_attr.flags = cmd.flags;
wq_attr.flags_mask = cmd.flags_mask; wq_attr.flags_mask = cmd.flags_mask;
} }
if (!wq->device->modify_wq) {
ret = -EOPNOTSUPP;
goto out;
}
ret = wq->device->modify_wq(wq, &wq_attr, cmd.attr_mask, uhw); ret = wq->device->modify_wq(wq, &wq_attr, cmd.attr_mask, uhw);
out:
uobj_put_obj_read(wq); uobj_put_obj_read(wq);
return ret; return ret;
} }
@ -3380,10 +3365,6 @@ static int ib_uverbs_ex_create_rwq_ind_table(struct ib_uverbs_file *file,
init_attr.log_ind_tbl_size = cmd.log_ind_tbl_size; init_attr.log_ind_tbl_size = cmd.log_ind_tbl_size;
init_attr.ind_tbl = wqs; init_attr.ind_tbl = wqs;
if (!ib_dev->create_rwq_ind_table) {
err = -EOPNOTSUPP;
goto err_uobj;
}
rwq_ind_tbl = ib_dev->create_rwq_ind_table(ib_dev, &init_attr, uhw); rwq_ind_tbl = ib_dev->create_rwq_ind_table(ib_dev, &init_attr, uhw);
if (IS_ERR(rwq_ind_tbl)) { if (IS_ERR(rwq_ind_tbl)) {
@ -3548,11 +3529,6 @@ static int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file,
goto err_put; goto err_put;
} }
if (!qp->device->create_flow) {
err = -EOPNOTSUPP;
goto err_put;
}
flow_attr = kzalloc(struct_size(flow_attr, flows, flow_attr = kzalloc(struct_size(flow_attr, flows,
cmd.flow_attr.num_of_specs), GFP_KERNEL); cmd.flow_attr.num_of_specs), GFP_KERNEL);
if (!flow_attr) { if (!flow_attr) {
@ -3971,9 +3947,6 @@ static int ib_uverbs_ex_query_device(struct ib_uverbs_file *file,
return PTR_ERR(ucontext); return PTR_ERR(ucontext);
ib_dev = ucontext->device; ib_dev = ucontext->device;
if (!ib_dev->query_device)
return -EOPNOTSUPP;
if (ucore->inlen < sizeof(cmd)) if (ucore->inlen < sizeof(cmd))
return -EINVAL; return -EINVAL;
@ -4123,11 +4096,14 @@ static int ib_uverbs_ex_modify_cq(struct ib_uverbs_file *file,
} }
const struct uapi_definition uverbs_def_write_intf[] = { const struct uapi_definition uverbs_def_write_intf[] = {
DECLARE_UVERBS_OBJECT(UVERBS_OBJECT_AH, DECLARE_UVERBS_OBJECT(
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_CREATE_AH, UVERBS_OBJECT_AH,
ib_uverbs_create_ah), DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_CREATE_AH,
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_DESTROY_AH, ib_uverbs_create_ah,
ib_uverbs_destroy_ah)), UAPI_DEF_METHOD_NEEDS_FN(create_ah)),
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_DESTROY_AH,
ib_uverbs_destroy_ah,
UAPI_DEF_METHOD_NEEDS_FN(destroy_ah))),
DECLARE_UVERBS_OBJECT( DECLARE_UVERBS_OBJECT(
UVERBS_OBJECT_COMP_CHANNEL, UVERBS_OBJECT_COMP_CHANNEL,
@ -4137,19 +4113,26 @@ const struct uapi_definition uverbs_def_write_intf[] = {
DECLARE_UVERBS_OBJECT( DECLARE_UVERBS_OBJECT(
UVERBS_OBJECT_CQ, UVERBS_OBJECT_CQ,
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_CREATE_CQ, DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_CREATE_CQ,
ib_uverbs_create_cq), ib_uverbs_create_cq,
UAPI_DEF_METHOD_NEEDS_FN(create_cq)),
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_DESTROY_CQ, DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_DESTROY_CQ,
ib_uverbs_destroy_cq), ib_uverbs_destroy_cq,
UAPI_DEF_METHOD_NEEDS_FN(destroy_cq)),
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_POLL_CQ, DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_POLL_CQ,
ib_uverbs_poll_cq), ib_uverbs_poll_cq,
UAPI_DEF_METHOD_NEEDS_FN(poll_cq)),
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_REQ_NOTIFY_CQ, DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_REQ_NOTIFY_CQ,
ib_uverbs_req_notify_cq), ib_uverbs_req_notify_cq,
UAPI_DEF_METHOD_NEEDS_FN(req_notify_cq)),
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_RESIZE_CQ, DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_RESIZE_CQ,
ib_uverbs_resize_cq), ib_uverbs_resize_cq,
UAPI_DEF_METHOD_NEEDS_FN(resize_cq)),
DECLARE_UVERBS_WRITE_EX(IB_USER_VERBS_EX_CMD_CREATE_CQ, DECLARE_UVERBS_WRITE_EX(IB_USER_VERBS_EX_CMD_CREATE_CQ,
ib_uverbs_ex_create_cq), ib_uverbs_ex_create_cq,
UAPI_DEF_METHOD_NEEDS_FN(create_cq)),
DECLARE_UVERBS_WRITE_EX(IB_USER_VERBS_EX_CMD_MODIFY_CQ, DECLARE_UVERBS_WRITE_EX(IB_USER_VERBS_EX_CMD_MODIFY_CQ,
ib_uverbs_ex_modify_cq)), ib_uverbs_ex_modify_cq,
UAPI_DEF_METHOD_NEEDS_FN(create_cq))),
DECLARE_UVERBS_OBJECT( DECLARE_UVERBS_OBJECT(
UVERBS_OBJECT_DEVICE, UVERBS_OBJECT_DEVICE,
@ -4158,98 +4141,141 @@ const struct uapi_definition uverbs_def_write_intf[] = {
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_QUERY_DEVICE, DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_QUERY_DEVICE,
ib_uverbs_query_device), ib_uverbs_query_device),
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_QUERY_PORT, DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_QUERY_PORT,
ib_uverbs_query_port), ib_uverbs_query_port,
UAPI_DEF_METHOD_NEEDS_FN(query_port)),
DECLARE_UVERBS_WRITE_EX(IB_USER_VERBS_EX_CMD_QUERY_DEVICE, DECLARE_UVERBS_WRITE_EX(IB_USER_VERBS_EX_CMD_QUERY_DEVICE,
ib_uverbs_ex_query_device)), ib_uverbs_ex_query_device,
UAPI_DEF_METHOD_NEEDS_FN(query_device)),
UAPI_DEF_OBJ_NEEDS_FN(alloc_ucontext),
UAPI_DEF_OBJ_NEEDS_FN(dealloc_ucontext)),
DECLARE_UVERBS_OBJECT( DECLARE_UVERBS_OBJECT(
UVERBS_OBJECT_FLOW, UVERBS_OBJECT_FLOW,
DECLARE_UVERBS_WRITE_EX(IB_USER_VERBS_EX_CMD_CREATE_FLOW, DECLARE_UVERBS_WRITE_EX(IB_USER_VERBS_EX_CMD_CREATE_FLOW,
ib_uverbs_ex_create_flow), ib_uverbs_ex_create_flow,
UAPI_DEF_METHOD_NEEDS_FN(create_flow)),
DECLARE_UVERBS_WRITE_EX(IB_USER_VERBS_EX_CMD_DESTROY_FLOW, DECLARE_UVERBS_WRITE_EX(IB_USER_VERBS_EX_CMD_DESTROY_FLOW,
ib_uverbs_ex_destroy_flow)), ib_uverbs_ex_destroy_flow,
UAPI_DEF_METHOD_NEEDS_FN(destroy_flow))),
DECLARE_UVERBS_OBJECT(UVERBS_OBJECT_MR, DECLARE_UVERBS_OBJECT(
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_DEREG_MR, UVERBS_OBJECT_MR,
ib_uverbs_dereg_mr), DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_DEREG_MR,
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_REG_MR, ib_uverbs_dereg_mr,
ib_uverbs_reg_mr), UAPI_DEF_METHOD_NEEDS_FN(dereg_mr)),
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_REREG_MR, DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_REG_MR,
ib_uverbs_rereg_mr)), ib_uverbs_reg_mr,
UAPI_DEF_METHOD_NEEDS_FN(reg_user_mr)),
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_REREG_MR,
ib_uverbs_rereg_mr,
UAPI_DEF_METHOD_NEEDS_FN(rereg_user_mr))),
DECLARE_UVERBS_OBJECT(UVERBS_OBJECT_MW, DECLARE_UVERBS_OBJECT(
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_ALLOC_MW, UVERBS_OBJECT_MW,
ib_uverbs_alloc_mw), DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_ALLOC_MW,
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_DEALLOC_MW, ib_uverbs_alloc_mw,
ib_uverbs_dealloc_mw)), UAPI_DEF_METHOD_NEEDS_FN(alloc_mw)),
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_DEALLOC_MW,
ib_uverbs_dealloc_mw,
UAPI_DEF_METHOD_NEEDS_FN(dealloc_mw))),
DECLARE_UVERBS_OBJECT(UVERBS_OBJECT_PD, DECLARE_UVERBS_OBJECT(
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_ALLOC_PD, UVERBS_OBJECT_PD,
ib_uverbs_alloc_pd), DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_ALLOC_PD,
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_DEALLOC_PD, ib_uverbs_alloc_pd,
ib_uverbs_dealloc_pd)), UAPI_DEF_METHOD_NEEDS_FN(alloc_pd)),
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_DEALLOC_PD,
ib_uverbs_dealloc_pd,
UAPI_DEF_METHOD_NEEDS_FN(dealloc_pd))),
DECLARE_UVERBS_OBJECT( DECLARE_UVERBS_OBJECT(
UVERBS_OBJECT_QP, UVERBS_OBJECT_QP,
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_ATTACH_MCAST, DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_ATTACH_MCAST,
ib_uverbs_attach_mcast), ib_uverbs_attach_mcast,
UAPI_DEF_METHOD_NEEDS_FN(attach_mcast),
UAPI_DEF_METHOD_NEEDS_FN(detach_mcast)),
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_CREATE_QP, DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_CREATE_QP,
ib_uverbs_create_qp), ib_uverbs_create_qp,
UAPI_DEF_METHOD_NEEDS_FN(create_qp)),
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_DESTROY_QP, DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_DESTROY_QP,
ib_uverbs_destroy_qp), ib_uverbs_destroy_qp,
UAPI_DEF_METHOD_NEEDS_FN(destroy_qp)),
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_DETACH_MCAST, DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_DETACH_MCAST,
ib_uverbs_detach_mcast), ib_uverbs_detach_mcast,
UAPI_DEF_METHOD_NEEDS_FN(detach_mcast)),
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_MODIFY_QP, DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_MODIFY_QP,
ib_uverbs_modify_qp), ib_uverbs_modify_qp,
UAPI_DEF_METHOD_NEEDS_FN(modify_qp)),
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_POST_RECV, DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_POST_RECV,
ib_uverbs_post_recv), ib_uverbs_post_recv,
UAPI_DEF_METHOD_NEEDS_FN(post_recv)),
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_POST_SEND, DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_POST_SEND,
ib_uverbs_post_send), ib_uverbs_post_send,
UAPI_DEF_METHOD_NEEDS_FN(post_send)),
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_QUERY_QP, DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_QUERY_QP,
ib_uverbs_query_qp), ib_uverbs_query_qp,
UAPI_DEF_METHOD_NEEDS_FN(query_qp)),
DECLARE_UVERBS_WRITE_EX(IB_USER_VERBS_EX_CMD_CREATE_QP, DECLARE_UVERBS_WRITE_EX(IB_USER_VERBS_EX_CMD_CREATE_QP,
ib_uverbs_ex_create_qp), ib_uverbs_ex_create_qp,
UAPI_DEF_METHOD_NEEDS_FN(create_qp)),
DECLARE_UVERBS_WRITE_EX(IB_USER_VERBS_EX_CMD_MODIFY_QP, DECLARE_UVERBS_WRITE_EX(IB_USER_VERBS_EX_CMD_MODIFY_QP,
ib_uverbs_ex_modify_qp)), ib_uverbs_ex_modify_qp,
UAPI_DEF_METHOD_NEEDS_FN(modify_qp))),
DECLARE_UVERBS_OBJECT( DECLARE_UVERBS_OBJECT(
UVERBS_OBJECT_RWQ_IND_TBL, UVERBS_OBJECT_RWQ_IND_TBL,
DECLARE_UVERBS_WRITE_EX(IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL, DECLARE_UVERBS_WRITE_EX(
ib_uverbs_ex_create_rwq_ind_table), IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL,
DECLARE_UVERBS_WRITE_EX(IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL, ib_uverbs_ex_create_rwq_ind_table,
ib_uverbs_ex_destroy_rwq_ind_table)), UAPI_DEF_METHOD_NEEDS_FN(create_rwq_ind_table)),
DECLARE_UVERBS_WRITE_EX(
IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL,
ib_uverbs_ex_destroy_rwq_ind_table,
UAPI_DEF_METHOD_NEEDS_FN(destroy_rwq_ind_table))),
DECLARE_UVERBS_OBJECT( DECLARE_UVERBS_OBJECT(
UVERBS_OBJECT_WQ, UVERBS_OBJECT_WQ,
DECLARE_UVERBS_WRITE_EX(IB_USER_VERBS_EX_CMD_CREATE_WQ, DECLARE_UVERBS_WRITE_EX(IB_USER_VERBS_EX_CMD_CREATE_WQ,
ib_uverbs_ex_create_wq), ib_uverbs_ex_create_wq,
UAPI_DEF_METHOD_NEEDS_FN(create_wq)),
DECLARE_UVERBS_WRITE_EX(IB_USER_VERBS_EX_CMD_DESTROY_WQ, DECLARE_UVERBS_WRITE_EX(IB_USER_VERBS_EX_CMD_DESTROY_WQ,
ib_uverbs_ex_destroy_wq), ib_uverbs_ex_destroy_wq,
UAPI_DEF_METHOD_NEEDS_FN(destroy_wq)),
DECLARE_UVERBS_WRITE_EX(IB_USER_VERBS_EX_CMD_MODIFY_WQ, DECLARE_UVERBS_WRITE_EX(IB_USER_VERBS_EX_CMD_MODIFY_WQ,
ib_uverbs_ex_modify_wq)), ib_uverbs_ex_modify_wq,
UAPI_DEF_METHOD_NEEDS_FN(modify_wq))),
DECLARE_UVERBS_OBJECT( DECLARE_UVERBS_OBJECT(
UVERBS_OBJECT_SRQ, UVERBS_OBJECT_SRQ,
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_CREATE_SRQ, DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_CREATE_SRQ,
ib_uverbs_create_srq), ib_uverbs_create_srq,
UAPI_DEF_METHOD_NEEDS_FN(create_srq)),
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_CREATE_XSRQ, DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_CREATE_XSRQ,
ib_uverbs_create_xsrq), ib_uverbs_create_xsrq,
UAPI_DEF_METHOD_NEEDS_FN(create_srq)),
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_DESTROY_SRQ, DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_DESTROY_SRQ,
ib_uverbs_destroy_srq), ib_uverbs_destroy_srq,
UAPI_DEF_METHOD_NEEDS_FN(destroy_srq)),
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_MODIFY_SRQ, DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_MODIFY_SRQ,
ib_uverbs_modify_srq), ib_uverbs_modify_srq,
UAPI_DEF_METHOD_NEEDS_FN(modify_srq)),
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_POST_SRQ_RECV, DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_POST_SRQ_RECV,
ib_uverbs_post_srq_recv), ib_uverbs_post_srq_recv,
UAPI_DEF_METHOD_NEEDS_FN(post_srq_recv)),
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_QUERY_SRQ, DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_QUERY_SRQ,
ib_uverbs_query_srq)), ib_uverbs_query_srq,
UAPI_DEF_METHOD_NEEDS_FN(query_srq))),
DECLARE_UVERBS_OBJECT(UVERBS_OBJECT_XRCD, DECLARE_UVERBS_OBJECT(
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_CLOSE_XRCD, UVERBS_OBJECT_XRCD,
ib_uverbs_close_xrcd), DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_CLOSE_XRCD,
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_OPEN_QP, ib_uverbs_close_xrcd,
ib_uverbs_open_qp), UAPI_DEF_METHOD_NEEDS_FN(dealloc_xrcd)),
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_OPEN_XRCD, DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_OPEN_QP,
ib_uverbs_open_xrcd)), ib_uverbs_open_qp),
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_OPEN_XRCD,
ib_uverbs_open_xrcd,
UAPI_DEF_METHOD_NEEDS_FN(alloc_xrcd))),
{}, {},
}; };

View File

@ -60,8 +60,11 @@ static void *uapi_add_get_elm(struct uverbs_api *uapi, u32 key,
return elm; return elm;
} }
static int uapi_create_write(struct uverbs_api *uapi, struct ib_device *ibdev, static int uapi_create_write(struct uverbs_api *uapi,
const struct uapi_definition *def, u32 obj_key) struct ib_device *ibdev,
const struct uapi_definition *def,
u32 obj_key,
u32 *cur_method_key)
{ {
struct uverbs_api_write_method *method_elm; struct uverbs_api_write_method *method_elm;
u32 method_key = obj_key; u32 method_key = obj_key;
@ -93,6 +96,8 @@ static int uapi_create_write(struct uverbs_api *uapi, struct ib_device *ibdev,
method_elm->disabled = !(ibdev->uverbs_cmd_mask & method_elm->disabled = !(ibdev->uverbs_cmd_mask &
BIT_ULL(def->write.command_num)); BIT_ULL(def->write.command_num));
} }
*cur_method_key = method_key;
return 0; return 0;
} }
@ -218,7 +223,8 @@ static int uapi_merge_obj_tree(struct uverbs_api *uapi,
static int uapi_disable_elm(struct uverbs_api *uapi, static int uapi_disable_elm(struct uverbs_api *uapi,
const struct uapi_definition *def, const struct uapi_definition *def,
u32 obj_key) u32 obj_key,
u32 method_key)
{ {
bool exists; bool exists;
@ -233,6 +239,31 @@ static int uapi_disable_elm(struct uverbs_api *uapi,
return 0; return 0;
} }
if (def->scope == UAPI_SCOPE_METHOD &&
uapi_key_is_ioctl_method(method_key)) {
struct uverbs_api_ioctl_method *method_elm;
method_elm = uapi_add_get_elm(uapi, method_key,
sizeof(*method_elm), &exists);
if (IS_ERR(method_elm))
return PTR_ERR(method_elm);
method_elm->disabled = 1;
return 0;
}
if (def->scope == UAPI_SCOPE_METHOD &&
(uapi_key_is_write_method(method_key) ||
uapi_key_is_write_ex_method(method_key))) {
struct uverbs_api_write_method *write_elm;
write_elm = uapi_add_get_elm(uapi, method_key,
sizeof(*write_elm), &exists);
if (IS_ERR(write_elm))
return PTR_ERR(write_elm);
write_elm->disabled = 1;
return 0;
}
WARN_ON(true); WARN_ON(true);
return -EINVAL; return -EINVAL;
} }
@ -243,6 +274,7 @@ static int uapi_merge_def(struct uverbs_api *uapi, struct ib_device *ibdev,
{ {
const struct uapi_definition *def = def_list; const struct uapi_definition *def = def_list;
u32 cur_obj_key = UVERBS_API_KEY_ERR; u32 cur_obj_key = UVERBS_API_KEY_ERR;
u32 cur_method_key = UVERBS_API_KEY_ERR;
bool exists; bool exists;
int rc; int rc;
@ -277,7 +309,8 @@ static int uapi_merge_def(struct uverbs_api *uapi, struct ib_device *ibdev,
if (*ibdev_fn) if (*ibdev_fn)
continue; continue;
rc = uapi_disable_elm(uapi, def, cur_obj_key); rc = uapi_disable_elm(
uapi, def, cur_obj_key, cur_method_key);
if (rc) if (rc)
return rc; return rc;
continue; continue;
@ -286,7 +319,8 @@ static int uapi_merge_def(struct uverbs_api *uapi, struct ib_device *ibdev,
case UAPI_DEF_IS_SUPPORTED_FUNC: case UAPI_DEF_IS_SUPPORTED_FUNC:
if (def->func_is_supported(ibdev)) if (def->func_is_supported(ibdev))
continue; continue;
rc = uapi_disable_elm(uapi, def, cur_obj_key); rc = uapi_disable_elm(
uapi, def, cur_obj_key, cur_method_key);
if (rc) if (rc)
return rc; return rc;
continue; continue;
@ -303,7 +337,8 @@ static int uapi_merge_def(struct uverbs_api *uapi, struct ib_device *ibdev,
} }
case UAPI_DEF_WRITE: case UAPI_DEF_WRITE:
rc = uapi_create_write(uapi, ibdev, def, cur_obj_key); rc = uapi_create_write(
uapi, ibdev, def, cur_obj_key, &cur_method_key);
if (rc) if (rc)
return rc; return rc;
continue; continue;

View File

@ -350,6 +350,7 @@ enum uapi_definition_kind {
enum uapi_definition_scope { enum uapi_definition_scope {
UAPI_SCOPE_OBJECT = 1, UAPI_SCOPE_OBJECT = 1,
UAPI_SCOPE_METHOD = 2,
}; };
struct uapi_definition { struct uapi_definition {
@ -422,6 +423,21 @@ struct uapi_definition {
sizeof(void *)), \ sizeof(void *)), \
} }
/*
* Method is only supported if the function pointer named ibdev_fn in struct
* ib_device is not NULL.
*/
#define UAPI_DEF_METHOD_NEEDS_FN(ibdev_fn) \
{ \
.kind = UAPI_DEF_IS_SUPPORTED_DEV_FN, \
.scope = UAPI_SCOPE_METHOD, \
.needs_fn_offset = \
offsetof(struct ib_device, ibdev_fn) + \
BUILD_BUG_ON_ZERO( \
sizeof(((struct ib_device *)0)->ibdev_fn) != \
sizeof(void *)), \
}
/* Call a function to determine if the entire object is supported or not */ /* Call a function to determine if the entire object is supported or not */
#define UAPI_DEF_IS_OBJ_SUPPORTED(_func) \ #define UAPI_DEF_IS_OBJ_SUPPORTED(_func) \
{ \ { \