@@ -306,6 +306,14 @@ err_free:
static void set_lib_ops(struct verbs_context *vctx)
{
vctx->create_cq_ex = __lib_ibv_create_cq_ex;
+
+ /*
+ * The compat symver entry point behaves identically to what used to
+ * be pointed to by _compat_query_port.
+ */
+#undef ibv_query_port
+ vctx->context.ops._compat_query_port = ibv_query_port;
+ vctx->query_port = __lib_query_port;
}
struct ibv_context *verbs_open_device(struct ibv_device *device, void *private_data)
@@ -616,7 +616,7 @@ void verbs_set_ops(struct verbs_context *vctx,
SET_OP(ctx, post_srq_recv);
SET_PRIV_OP(ctx, query_device);
SET_OP(vctx, query_device_ex);
- SET_PRIV_OP(ctx, query_port);
+ SET_PRIV_OP_IC(ctx, query_port);
SET_PRIV_OP(ctx, query_qp);
SET_OP(vctx, query_rt_values);
SET_OP(vctx, read_counters);
@@ -58,6 +58,8 @@ int ibverbs_get_device_list(struct list_head *list);
int ibverbs_init(void);
void ibverbs_device_put(struct ibv_device *dev);
void ibverbs_device_hold(struct ibv_device *dev);
+int __lib_query_port(struct ibv_context *context, uint8_t port_num,
+ struct ibv_port_attr *port_attr, size_t port_attr_len);
#ifdef _STATIC_LIBRARY_BUILD_
static inline void load_drivers(void)
@@ -145,12 +145,61 @@ LATEST_SYMVER_FUNC(ibv_query_device, 1_1, "IBVERBS_1.1",
return get_ops(context)->query_device(context, device_attr);
}
+int __lib_query_port(struct ibv_context *context, uint8_t port_num,
+ struct ibv_port_attr *port_attr, size_t port_attr_len)
+{
+ /* Don't expose this mess to the provider, provide a large enough
+ * temporary buffer if the user buffer is too small.
+ */
+ if (port_attr_len < sizeof(struct ibv_port_attr)) {
+ struct ibv_port_attr tmp_attr = {};
+ int rc;
+
+ rc = get_ops(context)->query_port(context, port_num,
+ &tmp_attr);
+ if (rc)
+ return rc;
+
+ memcpy(port_attr, &tmp_attr, port_attr_len);
+ return 0;
+ }
+
+ memset(port_attr, 0, port_attr_len);
+ return get_ops(context)->query_port(context, port_num, port_attr);
+}
+
+struct _compat_ibv_port_attr {
+ enum ibv_port_state state;
+ enum ibv_mtu max_mtu;
+ enum ibv_mtu active_mtu;
+ int gid_tbl_len;
+ uint32_t port_cap_flags;
+ uint32_t max_msg_sz;
+ uint32_t bad_pkey_cntr;
+ uint32_t qkey_viol_cntr;
+ uint16_t pkey_tbl_len;
+ uint16_t lid;
+ uint16_t sm_lid;
+ uint8_t lmc;
+ uint8_t max_vl_num;
+ uint8_t sm_sl;
+ uint8_t subnet_timeout;
+ uint8_t init_type_reply;
+ uint8_t active_width;
+ uint8_t active_speed;
+ uint8_t phys_state;
+ uint8_t link_layer;
+ uint8_t flags;
+};
+
LATEST_SYMVER_FUNC(ibv_query_port, 1_1, "IBVERBS_1.1",
int,
struct ibv_context *context, uint8_t port_num,
- struct ibv_port_attr *port_attr)
+ struct _compat_ibv_port_attr *port_attr)
{
- return get_ops(context)->query_port(context, port_num, port_attr);
+ return __lib_query_port(context, port_num,
+ (struct ibv_port_attr *)port_attr,
+ sizeof(*port_attr));
}
LATEST_SYMVER_FUNC(ibv_query_gid, 1_1, "IBVERBS_1.1",
@@ -1661,9 +1661,12 @@ struct ibv_device {
char ibdev_path[IBV_SYSFS_PATH_MAX];
};
+struct _compat_ibv_port_attr;
struct ibv_context_ops {
void *(*_compat_query_device)(void);
- void *(*_compat_query_port)(void);
+ int (*_compat_query_port)(struct ibv_context *context,
+ uint8_t port_num,
+ struct _compat_ibv_port_attr *port_attr);
void *(*_compat_alloc_pd)(void);
void *(*_compat_dealloc_pd)(void);
void *(*_compat_reg_mr)(void);
@@ -1786,6 +1789,9 @@ struct ibv_values_ex {
struct verbs_context {
/* "grows up" - new fields go here */
+ int (*query_port)(struct ibv_context *context, uint8_t port_num,
+ struct ibv_port_attr *port_attr,
+ size_t port_attr_len);
int (*advise_mr)(struct ibv_pd *pd,
enum ibv_advise_mr_advice advice,
uint32_t flags,
@@ -1997,17 +2003,26 @@ int ibv_query_device(struct ibv_context *context,
* ibv_query_port - Get port properties
*/
int ibv_query_port(struct ibv_context *context, uint8_t port_num,
- struct ibv_port_attr *port_attr);
+ struct _compat_ibv_port_attr *port_attr);
static inline int ___ibv_query_port(struct ibv_context *context,
uint8_t port_num,
struct ibv_port_attr *port_attr)
{
- /* For compatibility when running with old libibverbs */
- port_attr->link_layer = IBV_LINK_LAYER_UNSPECIFIED;
- port_attr->flags = 0;
+ struct verbs_context *vctx = verbs_get_ctx_op(context, query_port);
- return ibv_query_port(context, port_num, port_attr);
+ if (!vctx) {
+ int rc;
+
+ memset(port_attr, 0, sizeof(*port_attr));
+
+ rc = ibv_query_port(context, port_num,
+ (struct _compat_ibv_port_attr *)port_attr);
+ return rc;
+ }
+
+ return vctx->query_port(context, port_num, port_attr,
+ sizeof(*port_attr));
}
#define ibv_query_port(context, port_num, port_attr) \
@@ -74,7 +74,6 @@ int bnxt_re_query_port(struct ibv_context *ibvctx, uint8_t port,
{
struct ibv_query_port cmd;
- memset(port_attr, 0, sizeof(struct ibv_port_attr));
return ibv_cmd_query_port(ibvctx, port, port_attr, &cmd, sizeof(cmd));
}