Skip to content

Commit

Permalink
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/rdma/rdma

Pull rdma updates from Jason Gunthorpe:
 "Nothing exciting this cycle, most of the diffstat is changing SPDX
  'or' to 'OR'.

  Summary:

   - Bugfixes for hns, mlx5, and hfi1

   - Hardening patches for size_*, counted_by, strscpy

   - rts fixes from static analysis

   - Dump SRQ objects in rdma netlink, with hns support

   - Fix a performance regression in mlx5 MR deregistration

   - New XDR (200Gb/lane) link speed

   - SRQ record doorbell latency optimization for hns

   - IPSEC support for mlx5 multi-port mode

   - ibv_rereg_mr() support for irdma

   - Affiliated event support for bnxt_re

   - Opt out for the spec compliant qkey security enforcement as we
     discovered SW that breaks under enforcement

   - Comment and trivial updates"

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: (50 commits)
  IB/mlx5: Fix init stage error handling to avoid double free of same QP and UAF
  RDMA/mlx5: Fix mkey cache WQ flush
  RDMA/hfi1: Workaround truncation compilation error
  IB/hfi1: Fix potential deadlock on &irq_src_lock and &dd->uctxt_lock
  RDMA/core: Remove NULL check before dev_{put, hold}
  RDMA/hfi1: Remove redundant assignment to pointer ppd
  RDMA/mlx5: Change the key being sent for MPV device affiliation
  RDMA/bnxt_re: Fix clang -Wimplicit-fallthrough in bnxt_re_handle_cq_async_error()
  RDMA/hns: Fix init failure of RoCE VF and HIP08
  RDMA/hns: Fix unnecessary port_num transition in HW stats allocation
  RDMA/hns: The UD mode can only be configured with DCQCN
  RDMA/hns: Add check for SL
  RDMA/hns: Fix signed-unsigned mixed comparisons
  RDMA/hns: Fix uninitialized ucmd in hns_roce_create_qp_common()
  RDMA/hns: Fix printing level of asynchronous events
  RDMA/core: Add support to set privileged QKEY parameter
  RDMA/bnxt_re: Do not report SRQ error in srq notification
  RDMA/bnxt_re: Report async events and errors
  RDMA/bnxt_re: Update HW interface headers
  IB/mlx5: Fix rdma counter binding for RAW QP
  ...
  • Loading branch information
Linus Torvalds committed Nov 3, 2023
2 parents 6ed92e5 + 2ef422f commit 4346845
Showing 194 changed files with 1,178 additions and 498 deletions.
2 changes: 1 addition & 1 deletion drivers/infiniband/core/cache.c
Original file line number Diff line number Diff line change
@@ -46,7 +46,7 @@

struct ib_pkey_cache {
int table_len;
u16 table[];
u16 table[] __counted_by(table_len);
};

struct ib_update_work {
1 change: 1 addition & 0 deletions drivers/infiniband/core/core_priv.h
Original file line number Diff line number Diff line change
@@ -373,4 +373,5 @@ void rdma_umap_priv_init(struct rdma_umap_priv *priv,

void ib_cq_pool_cleanup(struct ib_device *dev);

bool rdma_nl_get_privileged_qkey(void);
#endif /* _CORE_PRIV_H */
4 changes: 3 additions & 1 deletion drivers/infiniband/core/device.c
Original file line number Diff line number Diff line change
@@ -804,7 +804,7 @@ static int alloc_port_data(struct ib_device *device)
* empty slots at the beginning.
*/
pdata_rcu = kzalloc(struct_size(pdata_rcu, pdata,
rdma_end_port(device) + 1),
size_add(rdma_end_port(device), 1)),
GFP_KERNEL);
if (!pdata_rcu)
return -ENOMEM;
@@ -2651,6 +2651,8 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops)
SET_DEVICE_OP(dev_ops, fill_res_mr_entry_raw);
SET_DEVICE_OP(dev_ops, fill_res_qp_entry);
SET_DEVICE_OP(dev_ops, fill_res_qp_entry_raw);
SET_DEVICE_OP(dev_ops, fill_res_srq_entry);
SET_DEVICE_OP(dev_ops, fill_res_srq_entry_raw);
SET_DEVICE_OP(dev_ops, fill_stat_mr_entry);
SET_DEVICE_OP(dev_ops, get_dev_fw_str);
SET_DEVICE_OP(dev_ops, get_dma_mr);
3 changes: 1 addition & 2 deletions drivers/infiniband/core/lag.c
Original file line number Diff line number Diff line change
@@ -102,8 +102,7 @@ static struct net_device *rdma_get_xmit_slave_udp(struct ib_device *device,

void rdma_lag_put_ah_roce_slave(struct net_device *xmit_slave)
{
if (xmit_slave)
dev_put(xmit_slave);
dev_put(xmit_slave);
}

struct net_device *rdma_lag_get_ah_roce_slave(struct ib_device *device,
92 changes: 81 additions & 11 deletions drivers/infiniband/core/nldev.c
Original file line number Diff line number Diff line change
@@ -43,6 +43,13 @@
#include "restrack.h"
#include "uverbs.h"

/*
* This determines whether a non-privileged user is allowed to specify a
* controlled QKEY or not, when true non-privileged user is allowed to specify
* a controlled QKEY.
*/
static bool privileged_qkey;

typedef int (*res_fill_func_t)(struct sk_buff*, bool,
struct rdma_restrack_entry*, uint32_t);

@@ -156,6 +163,7 @@ static const struct nla_policy nldev_policy[RDMA_NLDEV_ATTR_MAX] = {
[RDMA_NLDEV_SYS_ATTR_COPY_ON_FORK] = { .type = NLA_U8 },
[RDMA_NLDEV_ATTR_STAT_HWCOUNTER_INDEX] = { .type = NLA_U32 },
[RDMA_NLDEV_ATTR_STAT_HWCOUNTER_DYNAMIC] = { .type = NLA_U8 },
[RDMA_NLDEV_SYS_ATTR_PRIVILEGED_QKEY_MODE] = { .type = NLA_U8 },
};

static int put_driver_name_print_type(struct sk_buff *msg, const char *name,
@@ -237,6 +245,12 @@ int rdma_nl_put_driver_u64_hex(struct sk_buff *msg, const char *name, u64 value)
}
EXPORT_SYMBOL(rdma_nl_put_driver_u64_hex);

bool rdma_nl_get_privileged_qkey(void)
{
return privileged_qkey || capable(CAP_NET_RAW);
}
EXPORT_SYMBOL(rdma_nl_get_privileged_qkey);

static int fill_nldev_handle(struct sk_buff *msg, struct ib_device *device)
{
if (nla_put_u32(msg, RDMA_NLDEV_ATTR_DEV_INDEX, device->index))
@@ -357,8 +371,7 @@ static int fill_port_info(struct sk_buff *msg,
}

out:
if (netdev)
dev_put(netdev);
dev_put(netdev);
return ret;
}

@@ -818,6 +831,7 @@ static int fill_res_srq_entry(struct sk_buff *msg, bool has_cap_net_admin,
struct rdma_restrack_entry *res, uint32_t port)
{
struct ib_srq *srq = container_of(res, struct ib_srq, res);
struct ib_device *dev = srq->device;

if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_SRQN, srq->res.id))
goto err;
@@ -837,12 +851,29 @@ static int fill_res_srq_entry(struct sk_buff *msg, bool has_cap_net_admin,
if (fill_res_srq_qps(msg, srq))
goto err;

return fill_res_name_pid(msg, res);
if (fill_res_name_pid(msg, res))
goto err;

if (dev->ops.fill_res_srq_entry)
return dev->ops.fill_res_srq_entry(msg, srq);

return 0;

err:
return -EMSGSIZE;
}

static int fill_res_srq_raw_entry(struct sk_buff *msg, bool has_cap_net_admin,
struct rdma_restrack_entry *res, uint32_t port)
{
struct ib_srq *srq = container_of(res, struct ib_srq, res);
struct ib_device *dev = srq->device;

if (!dev->ops.fill_res_srq_entry_raw)
return -EINVAL;
return dev->ops.fill_res_srq_entry_raw(msg, srq);
}

static int fill_stat_counter_mode(struct sk_buff *msg,
struct rdma_counter *counter)
{
@@ -1652,6 +1683,7 @@ RES_GET_FUNCS(mr_raw, RDMA_RESTRACK_MR);
RES_GET_FUNCS(counter, RDMA_RESTRACK_COUNTER);
RES_GET_FUNCS(ctx, RDMA_RESTRACK_CTX);
RES_GET_FUNCS(srq, RDMA_RESTRACK_SRQ);
RES_GET_FUNCS(srq_raw, RDMA_RESTRACK_SRQ);

static LIST_HEAD(link_ops);
static DECLARE_RWSEM(link_ops_rwsem);
@@ -1882,6 +1914,12 @@ static int nldev_sys_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
return err;
}

err = nla_put_u8(msg, RDMA_NLDEV_SYS_ATTR_PRIVILEGED_QKEY_MODE,
(u8)privileged_qkey);
if (err) {
nlmsg_free(msg);
return err;
}
/*
* Copy-on-fork is supported.
* See commits:
@@ -1898,18 +1936,11 @@ static int nldev_sys_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
return rdma_nl_unicast(sock_net(skb->sk), msg, NETLINK_CB(skb).portid);
}

static int nldev_set_sys_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
struct netlink_ext_ack *extack)
static int nldev_set_sys_set_netns_doit(struct nlattr *tb[])
{
struct nlattr *tb[RDMA_NLDEV_ATTR_MAX];
u8 enable;
int err;

err = nlmsg_parse(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
nldev_policy, extack);
if (err || !tb[RDMA_NLDEV_SYS_ATTR_NETNS_MODE])
return -EINVAL;

enable = nla_get_u8(tb[RDMA_NLDEV_SYS_ATTR_NETNS_MODE]);
/* Only 0 and 1 are supported */
if (enable > 1)
@@ -1919,6 +1950,40 @@ static int nldev_set_sys_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
return err;
}

static int nldev_set_sys_set_pqkey_doit(struct nlattr *tb[])
{
u8 enable;

enable = nla_get_u8(tb[RDMA_NLDEV_SYS_ATTR_PRIVILEGED_QKEY_MODE]);
/* Only 0 and 1 are supported */
if (enable > 1)
return -EINVAL;

privileged_qkey = enable;
return 0;
}

static int nldev_set_sys_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
struct netlink_ext_ack *extack)
{
struct nlattr *tb[RDMA_NLDEV_ATTR_MAX];
int err;

err = nlmsg_parse(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
nldev_policy, extack);
if (err)
return -EINVAL;

if (tb[RDMA_NLDEV_SYS_ATTR_NETNS_MODE])
return nldev_set_sys_set_netns_doit(tb);

if (tb[RDMA_NLDEV_SYS_ATTR_PRIVILEGED_QKEY_MODE])
return nldev_set_sys_set_pqkey_doit(tb);

return -EINVAL;
}


static int nldev_stat_set_mode_doit(struct sk_buff *msg,
struct netlink_ext_ack *extack,
struct nlattr *tb[],
@@ -2558,6 +2623,11 @@ static const struct rdma_nl_cbs nldev_cb_table[RDMA_NLDEV_NUM_OPS] = {
.dump = nldev_res_get_mr_raw_dumpit,
.flags = RDMA_NL_ADMIN_PERM,
},
[RDMA_NLDEV_CMD_RES_SRQ_GET_RAW] = {
.doit = nldev_res_get_srq_raw_doit,
.dump = nldev_res_get_srq_raw_dumpit,
.flags = RDMA_NL_ADMIN_PERM,
},
[RDMA_NLDEV_CMD_STAT_GET_STATUS] = {
.doit = nldev_stat_get_counter_status_doit,
},
2 changes: 1 addition & 1 deletion drivers/infiniband/core/rw.c
Original file line number Diff line number Diff line change
@@ -666,7 +666,7 @@ void rdma_rw_init_qp(struct ib_device *dev, struct ib_qp_init_attr *attr)
factor = 1;

/*
* If the devices needs MRs to perform RDMA READ or WRITE operations,
* If the device needs MRs to perform RDMA READ or WRITE operations,
* we'll need two additional MRs for the registrations and the
* invalidation.
*/
4 changes: 3 additions & 1 deletion drivers/infiniband/core/sa_query.c
Original file line number Diff line number Diff line change
@@ -2159,7 +2159,9 @@ static int ib_sa_add_one(struct ib_device *device)
s = rdma_start_port(device);
e = rdma_end_port(device);

sa_dev = kzalloc(struct_size(sa_dev, port, e - s + 1), GFP_KERNEL);
sa_dev = kzalloc(struct_size(sa_dev, port,
size_add(size_sub(e, s), 1)),
GFP_KERNEL);
if (!sa_dev)
return -ENOMEM;

14 changes: 9 additions & 5 deletions drivers/infiniband/core/sysfs.c
Original file line number Diff line number Diff line change
@@ -342,6 +342,10 @@ static ssize_t rate_show(struct ib_device *ibdev, u32 port_num,
speed = " NDR";
rate = 1000;
break;
case IB_SPEED_XDR:
speed = " XDR";
rate = 2000;
break;
case IB_SPEED_SDR:
default: /* default to SDR for invalid rates */
speed = " SDR";
@@ -903,7 +907,7 @@ alloc_hw_stats_device(struct ib_device *ibdev)
* Two extra attribue elements here, one for the lifespan entry and
* one to NULL terminate the list for the sysfs core code
*/
data = kzalloc(struct_size(data, attrs, stats->num_counters + 1),
data = kzalloc(struct_size(data, attrs, size_add(stats->num_counters, 1)),
GFP_KERNEL);
if (!data)
goto err_free_stats;
@@ -1009,7 +1013,7 @@ alloc_hw_stats_port(struct ib_port *port, struct attribute_group *group)
* Two extra attribue elements here, one for the lifespan entry and
* one to NULL terminate the list for the sysfs core code
*/
data = kzalloc(struct_size(data, attrs, stats->num_counters + 1),
data = kzalloc(struct_size(data, attrs, size_add(stats->num_counters, 1)),
GFP_KERNEL);
if (!data)
goto err_free_stats;
@@ -1140,7 +1144,7 @@ static int setup_gid_attrs(struct ib_port *port,
int ret;

gid_attr_group = kzalloc(struct_size(gid_attr_group, attrs_list,
attr->gid_tbl_len * 2),
size_mul(attr->gid_tbl_len, 2)),
GFP_KERNEL);
if (!gid_attr_group)
return -ENOMEM;
@@ -1205,8 +1209,8 @@ static struct ib_port *setup_port(struct ib_core_device *coredev, int port_num,
int ret;

p = kvzalloc(struct_size(p, attrs_list,
attr->gid_tbl_len + attr->pkey_tbl_len),
GFP_KERNEL);
size_add(attr->gid_tbl_len, attr->pkey_tbl_len)),
GFP_KERNEL);
if (!p)
return ERR_PTR(-ENOMEM);
p->ibdev = device;
4 changes: 3 additions & 1 deletion drivers/infiniband/core/user_mad.c
Original file line number Diff line number Diff line change
@@ -1378,7 +1378,9 @@ static int ib_umad_add_one(struct ib_device *device)
s = rdma_start_port(device);
e = rdma_end_port(device);

umad_dev = kzalloc(struct_size(umad_dev, ports, e - s + 1), GFP_KERNEL);
umad_dev = kzalloc(struct_size(umad_dev, ports,
size_add(size_sub(e, s), 1)),
GFP_KERNEL);
if (!umad_dev)
return -ENOMEM;

3 changes: 2 additions & 1 deletion drivers/infiniband/core/uverbs_cmd.c
Original file line number Diff line number Diff line change
@@ -1851,7 +1851,8 @@ static int modify_qp(struct uverbs_attr_bundle *attrs,
if (cmd->base.attr_mask & IB_QP_PATH_MIG_STATE)
attr->path_mig_state = cmd->base.path_mig_state;
if (cmd->base.attr_mask & IB_QP_QKEY) {
if (cmd->base.qkey & IB_QP_SET_QKEY && !capable(CAP_NET_RAW)) {
if (cmd->base.qkey & IB_QP_SET_QKEY &&
!rdma_nl_get_privileged_qkey()) {
ret = -EPERM;
goto release_qp;
}
3 changes: 2 additions & 1 deletion drivers/infiniband/core/uverbs_std_types_device.c
Original file line number Diff line number Diff line change
@@ -203,6 +203,7 @@ static int UVERBS_HANDLER(UVERBS_METHOD_QUERY_PORT)(

copy_port_attr_to_resp(&attr, &resp.legacy_resp, ib_dev, port_num);
resp.port_cap_flags2 = attr.port_cap_flags2;
resp.active_speed_ex = attr.active_speed;

return uverbs_copy_to_struct_or_zero(attrs, UVERBS_ATTR_QUERY_PORT_RESP,
&resp, sizeof(resp));
@@ -461,7 +462,7 @@ DECLARE_UVERBS_NAMED_METHOD(
UVERBS_ATTR_PTR_OUT(
UVERBS_ATTR_QUERY_PORT_RESP,
UVERBS_ATTR_STRUCT(struct ib_uverbs_query_port_resp_ex,
reserved),
active_speed_ex),
UA_MANDATORY));

DECLARE_UVERBS_NAMED_METHOD(
7 changes: 5 additions & 2 deletions drivers/infiniband/core/verbs.c
Original file line number Diff line number Diff line change
@@ -147,6 +147,7 @@ __attribute_const__ int ib_rate_to_mult(enum ib_rate rate)
case IB_RATE_50_GBPS: return 20;
case IB_RATE_400_GBPS: return 160;
case IB_RATE_600_GBPS: return 240;
case IB_RATE_800_GBPS: return 320;
default: return -1;
}
}
@@ -176,6 +177,7 @@ __attribute_const__ enum ib_rate mult_to_ib_rate(int mult)
case 20: return IB_RATE_50_GBPS;
case 160: return IB_RATE_400_GBPS;
case 240: return IB_RATE_600_GBPS;
case 320: return IB_RATE_800_GBPS;
default: return IB_RATE_PORT_CURRENT;
}
}
@@ -205,6 +207,7 @@ __attribute_const__ int ib_rate_to_mbps(enum ib_rate rate)
case IB_RATE_50_GBPS: return 53125;
case IB_RATE_400_GBPS: return 425000;
case IB_RATE_600_GBPS: return 637500;
case IB_RATE_800_GBPS: return 850000;
default: return -1;
}
}
@@ -366,7 +369,7 @@ void rdma_copy_ah_attr(struct rdma_ah_attr *dest,
EXPORT_SYMBOL(rdma_copy_ah_attr);

/**
* rdma_replace_ah_attr - Replace valid ah_attr with new new one.
* rdma_replace_ah_attr - Replace valid ah_attr with new one.
* @old: Pointer to existing ah_attr which needs to be replaced.
* old is assumed to be valid or zero'd
* @new: Pointer to the new ah_attr.
@@ -744,7 +747,7 @@ EXPORT_SYMBOL(ib_get_gids_from_rdma_hdr);

/* Resolve destination mac address and hop limit for unicast destination
* GID entry, considering the source GID entry as well.
* ah_attribute must have have valid port_num, sgid_index.
* ah_attribute must have valid port_num, sgid_index.
*/
static int ib_resolve_unicast_gid_dmac(struct ib_device *device,
struct rdma_ah_attr *ah_attr)
Loading

0 comments on commit 4346845

Please sign in to comment.