0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #ifndef UVERBS_H
0038 #define UVERBS_H
0039
0040 #include <linux/kref.h>
0041 #include <linux/idr.h>
0042 #include <linux/mutex.h>
0043 #include <linux/completion.h>
0044 #include <linux/cdev.h>
0045
0046 #include <rdma/ib_verbs.h>
0047 #include <rdma/ib_umem.h>
0048 #include <rdma/ib_user_verbs.h>
0049 #include <rdma/uverbs_std_types.h>
0050
0051 #define UVERBS_MODULE_NAME ib_uverbs
0052 #include <rdma/uverbs_named_ioctl.h>
0053
0054 static inline void
0055 ib_uverbs_init_udata(struct ib_udata *udata,
0056 const void __user *ibuf,
0057 void __user *obuf,
0058 size_t ilen, size_t olen)
0059 {
0060 udata->inbuf = ibuf;
0061 udata->outbuf = obuf;
0062 udata->inlen = ilen;
0063 udata->outlen = olen;
0064 }
0065
0066 static inline void
0067 ib_uverbs_init_udata_buf_or_null(struct ib_udata *udata,
0068 const void __user *ibuf,
0069 void __user *obuf,
0070 size_t ilen, size_t olen)
0071 {
0072 ib_uverbs_init_udata(udata,
0073 ilen ? ibuf : NULL, olen ? obuf : NULL,
0074 ilen, olen);
0075 }
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099 struct ib_uverbs_device {
0100 refcount_t refcount;
0101 u32 num_comp_vectors;
0102 struct completion comp;
0103 struct device dev;
0104
0105 const struct attribute_group *groups[2];
0106 struct ib_device __rcu *ib_dev;
0107 int devnum;
0108 struct cdev cdev;
0109 struct rb_root xrcd_tree;
0110 struct mutex xrcd_tree_mutex;
0111 struct srcu_struct disassociate_srcu;
0112 struct mutex lists_mutex;
0113 struct list_head uverbs_file_list;
0114 struct uverbs_api *uapi;
0115 };
0116
0117 struct ib_uverbs_event_queue {
0118 spinlock_t lock;
0119 int is_closed;
0120 wait_queue_head_t poll_wait;
0121 struct fasync_struct *async_queue;
0122 struct list_head event_list;
0123 };
0124
0125 struct ib_uverbs_async_event_file {
0126 struct ib_uobject uobj;
0127 struct ib_uverbs_event_queue ev_queue;
0128 struct ib_event_handler event_handler;
0129 };
0130
0131 struct ib_uverbs_completion_event_file {
0132 struct ib_uobject uobj;
0133 struct ib_uverbs_event_queue ev_queue;
0134 };
0135
0136 struct ib_uverbs_file {
0137 struct kref ref;
0138 struct ib_uverbs_device *device;
0139 struct mutex ucontext_lock;
0140
0141
0142
0143
0144 struct ib_ucontext *ucontext;
0145 struct ib_uverbs_async_event_file *default_async_file;
0146 struct list_head list;
0147
0148
0149
0150
0151
0152
0153
0154 struct rw_semaphore hw_destroy_rwsem;
0155 spinlock_t uobjects_lock;
0156 struct list_head uobjects;
0157
0158 struct mutex umap_lock;
0159 struct list_head umaps;
0160 struct page *disassociate_page;
0161
0162 struct xarray idr;
0163 };
0164
0165 struct ib_uverbs_event {
0166 union {
0167 struct ib_uverbs_async_event_desc async;
0168 struct ib_uverbs_comp_event_desc comp;
0169 } desc;
0170 struct list_head list;
0171 struct list_head obj_list;
0172 u32 *counter;
0173 };
0174
0175 struct ib_uverbs_mcast_entry {
0176 struct list_head list;
0177 union ib_gid gid;
0178 u16 lid;
0179 };
0180
0181 struct ib_uevent_object {
0182 struct ib_uobject uobject;
0183 struct ib_uverbs_async_event_file *event_file;
0184
0185 struct list_head event_list;
0186 u32 events_reported;
0187 };
0188
0189 struct ib_uxrcd_object {
0190 struct ib_uobject uobject;
0191 atomic_t refcnt;
0192 };
0193
0194 struct ib_usrq_object {
0195 struct ib_uevent_object uevent;
0196 struct ib_uxrcd_object *uxrcd;
0197 };
0198
0199 struct ib_uqp_object {
0200 struct ib_uevent_object uevent;
0201
0202 struct mutex mcast_lock;
0203 struct list_head mcast_list;
0204 struct ib_uxrcd_object *uxrcd;
0205 };
0206
0207 struct ib_uwq_object {
0208 struct ib_uevent_object uevent;
0209 };
0210
0211 struct ib_ucq_object {
0212 struct ib_uevent_object uevent;
0213 struct list_head comp_list;
0214 u32 comp_events_reported;
0215 };
0216
0217 extern const struct file_operations uverbs_event_fops;
0218 extern const struct file_operations uverbs_async_event_fops;
0219 void ib_uverbs_init_event_queue(struct ib_uverbs_event_queue *ev_queue);
0220 void ib_uverbs_init_async_event_file(struct ib_uverbs_async_event_file *ev_file);
0221 void ib_uverbs_free_event_queue(struct ib_uverbs_event_queue *event_queue);
0222 void ib_uverbs_flow_resources_free(struct ib_uflow_resources *uflow_res);
0223 int uverbs_async_event_release(struct inode *inode, struct file *filp);
0224
0225 int ib_alloc_ucontext(struct uverbs_attr_bundle *attrs);
0226 int ib_init_ucontext(struct uverbs_attr_bundle *attrs);
0227
0228 void ib_uverbs_release_ucq(struct ib_uverbs_completion_event_file *ev_file,
0229 struct ib_ucq_object *uobj);
0230 void ib_uverbs_release_uevent(struct ib_uevent_object *uobj);
0231 void ib_uverbs_release_file(struct kref *ref);
0232 void ib_uverbs_async_handler(struct ib_uverbs_async_event_file *async_file,
0233 __u64 element, __u64 event,
0234 struct list_head *obj_list, u32 *counter);
0235
0236 void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context);
0237 void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr);
0238 void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr);
0239 void ib_uverbs_wq_event_handler(struct ib_event *event, void *context_ptr);
0240 void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr);
0241 int ib_uverbs_dealloc_xrcd(struct ib_uobject *uobject, struct ib_xrcd *xrcd,
0242 enum rdma_remove_reason why,
0243 struct uverbs_attr_bundle *attrs);
0244
0245 int uverbs_dealloc_mw(struct ib_mw *mw);
0246 void ib_uverbs_detach_umcast(struct ib_qp *qp,
0247 struct ib_uqp_object *uobj);
0248
0249 long ib_uverbs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
0250
0251 struct ib_uverbs_flow_spec {
0252 union {
0253 union {
0254 struct ib_uverbs_flow_spec_hdr hdr;
0255 struct {
0256 __u32 type;
0257 __u16 size;
0258 __u16 reserved;
0259 };
0260 };
0261 struct ib_uverbs_flow_spec_eth eth;
0262 struct ib_uverbs_flow_spec_ipv4 ipv4;
0263 struct ib_uverbs_flow_spec_esp esp;
0264 struct ib_uverbs_flow_spec_tcp_udp tcp_udp;
0265 struct ib_uverbs_flow_spec_ipv6 ipv6;
0266 struct ib_uverbs_flow_spec_action_tag flow_tag;
0267 struct ib_uverbs_flow_spec_action_drop drop;
0268 struct ib_uverbs_flow_spec_action_handle action;
0269 struct ib_uverbs_flow_spec_action_count flow_count;
0270 };
0271 };
0272
0273 int ib_uverbs_kern_spec_to_ib_spec_filter(enum ib_flow_spec_type type,
0274 const void *kern_spec_mask,
0275 const void *kern_spec_val,
0276 size_t kern_filter_sz,
0277 union ib_flow_spec *ib_spec);
0278
0279
0280
0281
0282
0283 static inline u32 make_port_cap_flags(const struct ib_port_attr *attr)
0284 {
0285 u32 res;
0286
0287
0288
0289
0290
0291
0292 res = attr->port_cap_flags & ~(u32)IB_UVERBS_PCF_IP_BASED_GIDS;
0293
0294 if (attr->ip_gids)
0295 res |= IB_UVERBS_PCF_IP_BASED_GIDS;
0296
0297 return res;
0298 }
0299
0300 static inline struct ib_uverbs_async_event_file *
0301 ib_uverbs_get_async_event(struct uverbs_attr_bundle *attrs,
0302 u16 id)
0303 {
0304 struct ib_uobject *async_ev_file_uobj;
0305 struct ib_uverbs_async_event_file *async_ev_file;
0306
0307 async_ev_file_uobj = uverbs_attr_get_uobject(attrs, id);
0308 if (IS_ERR(async_ev_file_uobj))
0309 async_ev_file = READ_ONCE(attrs->ufile->default_async_file);
0310 else
0311 async_ev_file = container_of(async_ev_file_uobj,
0312 struct ib_uverbs_async_event_file,
0313 uobj);
0314 if (async_ev_file)
0315 uverbs_uobject_get(&async_ev_file->uobj);
0316 return async_ev_file;
0317 }
0318
0319 void copy_port_attr_to_resp(struct ib_port_attr *attr,
0320 struct ib_uverbs_query_port_resp *resp,
0321 struct ib_device *ib_dev, u8 port_num);
0322 #endif