Skip to content

Commit 4346845

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/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 ...
2 parents 6ed92e5 + 2ef422f commit 4346845

File tree

194 files changed

+1178
-498
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

194 files changed

+1178
-498
lines changed

drivers/infiniband/core/cache.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646

4747
struct ib_pkey_cache {
4848
int table_len;
49-
u16 table[];
49+
u16 table[] __counted_by(table_len);
5050
};
5151

5252
struct ib_update_work {

drivers/infiniband/core/core_priv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,4 +373,5 @@ void rdma_umap_priv_init(struct rdma_umap_priv *priv,
373373

374374
void ib_cq_pool_cleanup(struct ib_device *dev);
375375

376+
bool rdma_nl_get_privileged_qkey(void);
376377
#endif /* _CORE_PRIV_H */

drivers/infiniband/core/device.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -804,7 +804,7 @@ static int alloc_port_data(struct ib_device *device)
804804
* empty slots at the beginning.
805805
*/
806806
pdata_rcu = kzalloc(struct_size(pdata_rcu, pdata,
807-
rdma_end_port(device) + 1),
807+
size_add(rdma_end_port(device), 1)),
808808
GFP_KERNEL);
809809
if (!pdata_rcu)
810810
return -ENOMEM;
@@ -2651,6 +2651,8 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops)
26512651
SET_DEVICE_OP(dev_ops, fill_res_mr_entry_raw);
26522652
SET_DEVICE_OP(dev_ops, fill_res_qp_entry);
26532653
SET_DEVICE_OP(dev_ops, fill_res_qp_entry_raw);
2654+
SET_DEVICE_OP(dev_ops, fill_res_srq_entry);
2655+
SET_DEVICE_OP(dev_ops, fill_res_srq_entry_raw);
26542656
SET_DEVICE_OP(dev_ops, fill_stat_mr_entry);
26552657
SET_DEVICE_OP(dev_ops, get_dev_fw_str);
26562658
SET_DEVICE_OP(dev_ops, get_dma_mr);

drivers/infiniband/core/lag.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,7 @@ static struct net_device *rdma_get_xmit_slave_udp(struct ib_device *device,
102102

103103
void rdma_lag_put_ah_roce_slave(struct net_device *xmit_slave)
104104
{
105-
if (xmit_slave)
106-
dev_put(xmit_slave);
105+
dev_put(xmit_slave);
107106
}
108107

109108
struct net_device *rdma_lag_get_ah_roce_slave(struct ib_device *device,

drivers/infiniband/core/nldev.c

Lines changed: 81 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@
4343
#include "restrack.h"
4444
#include "uverbs.h"
4545

46+
/*
47+
* This determines whether a non-privileged user is allowed to specify a
48+
* controlled QKEY or not, when true non-privileged user is allowed to specify
49+
* a controlled QKEY.
50+
*/
51+
static bool privileged_qkey;
52+
4653
typedef int (*res_fill_func_t)(struct sk_buff*, bool,
4754
struct rdma_restrack_entry*, uint32_t);
4855

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

161169
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)
237245
}
238246
EXPORT_SYMBOL(rdma_nl_put_driver_u64_hex);
239247

248+
bool rdma_nl_get_privileged_qkey(void)
249+
{
250+
return privileged_qkey || capable(CAP_NET_RAW);
251+
}
252+
EXPORT_SYMBOL(rdma_nl_get_privileged_qkey);
253+
240254
static int fill_nldev_handle(struct sk_buff *msg, struct ib_device *device)
241255
{
242256
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,
357371
}
358372

359373
out:
360-
if (netdev)
361-
dev_put(netdev);
374+
dev_put(netdev);
362375
return ret;
363376
}
364377

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

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

840-
return fill_res_name_pid(msg, res);
854+
if (fill_res_name_pid(msg, res))
855+
goto err;
856+
857+
if (dev->ops.fill_res_srq_entry)
858+
return dev->ops.fill_res_srq_entry(msg, srq);
859+
860+
return 0;
841861

842862
err:
843863
return -EMSGSIZE;
844864
}
845865

866+
static int fill_res_srq_raw_entry(struct sk_buff *msg, bool has_cap_net_admin,
867+
struct rdma_restrack_entry *res, uint32_t port)
868+
{
869+
struct ib_srq *srq = container_of(res, struct ib_srq, res);
870+
struct ib_device *dev = srq->device;
871+
872+
if (!dev->ops.fill_res_srq_entry_raw)
873+
return -EINVAL;
874+
return dev->ops.fill_res_srq_entry_raw(msg, srq);
875+
}
876+
846877
static int fill_stat_counter_mode(struct sk_buff *msg,
847878
struct rdma_counter *counter)
848879
{
@@ -1652,6 +1683,7 @@ RES_GET_FUNCS(mr_raw, RDMA_RESTRACK_MR);
16521683
RES_GET_FUNCS(counter, RDMA_RESTRACK_COUNTER);
16531684
RES_GET_FUNCS(ctx, RDMA_RESTRACK_CTX);
16541685
RES_GET_FUNCS(srq, RDMA_RESTRACK_SRQ);
1686+
RES_GET_FUNCS(srq_raw, RDMA_RESTRACK_SRQ);
16551687

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

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

1901-
static int nldev_set_sys_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
1902-
struct netlink_ext_ack *extack)
1939+
static int nldev_set_sys_set_netns_doit(struct nlattr *tb[])
19031940
{
1904-
struct nlattr *tb[RDMA_NLDEV_ATTR_MAX];
19051941
u8 enable;
19061942
int err;
19071943

1908-
err = nlmsg_parse(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
1909-
nldev_policy, extack);
1910-
if (err || !tb[RDMA_NLDEV_SYS_ATTR_NETNS_MODE])
1911-
return -EINVAL;
1912-
19131944
enable = nla_get_u8(tb[RDMA_NLDEV_SYS_ATTR_NETNS_MODE]);
19141945
/* Only 0 and 1 are supported */
19151946
if (enable > 1)
@@ -1919,6 +1950,40 @@ static int nldev_set_sys_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
19191950
return err;
19201951
}
19211952

1953+
static int nldev_set_sys_set_pqkey_doit(struct nlattr *tb[])
1954+
{
1955+
u8 enable;
1956+
1957+
enable = nla_get_u8(tb[RDMA_NLDEV_SYS_ATTR_PRIVILEGED_QKEY_MODE]);
1958+
/* Only 0 and 1 are supported */
1959+
if (enable > 1)
1960+
return -EINVAL;
1961+
1962+
privileged_qkey = enable;
1963+
return 0;
1964+
}
1965+
1966+
static int nldev_set_sys_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
1967+
struct netlink_ext_ack *extack)
1968+
{
1969+
struct nlattr *tb[RDMA_NLDEV_ATTR_MAX];
1970+
int err;
1971+
1972+
err = nlmsg_parse(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
1973+
nldev_policy, extack);
1974+
if (err)
1975+
return -EINVAL;
1976+
1977+
if (tb[RDMA_NLDEV_SYS_ATTR_NETNS_MODE])
1978+
return nldev_set_sys_set_netns_doit(tb);
1979+
1980+
if (tb[RDMA_NLDEV_SYS_ATTR_PRIVILEGED_QKEY_MODE])
1981+
return nldev_set_sys_set_pqkey_doit(tb);
1982+
1983+
return -EINVAL;
1984+
}
1985+
1986+
19221987
static int nldev_stat_set_mode_doit(struct sk_buff *msg,
19231988
struct netlink_ext_ack *extack,
19241989
struct nlattr *tb[],
@@ -2558,6 +2623,11 @@ static const struct rdma_nl_cbs nldev_cb_table[RDMA_NLDEV_NUM_OPS] = {
25582623
.dump = nldev_res_get_mr_raw_dumpit,
25592624
.flags = RDMA_NL_ADMIN_PERM,
25602625
},
2626+
[RDMA_NLDEV_CMD_RES_SRQ_GET_RAW] = {
2627+
.doit = nldev_res_get_srq_raw_doit,
2628+
.dump = nldev_res_get_srq_raw_dumpit,
2629+
.flags = RDMA_NL_ADMIN_PERM,
2630+
},
25612631
[RDMA_NLDEV_CMD_STAT_GET_STATUS] = {
25622632
.doit = nldev_stat_get_counter_status_doit,
25632633
},

drivers/infiniband/core/rw.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,7 @@ void rdma_rw_init_qp(struct ib_device *dev, struct ib_qp_init_attr *attr)
666666
factor = 1;
667667

668668
/*
669-
* If the devices needs MRs to perform RDMA READ or WRITE operations,
669+
* If the device needs MRs to perform RDMA READ or WRITE operations,
670670
* we'll need two additional MRs for the registrations and the
671671
* invalidation.
672672
*/

drivers/infiniband/core/sa_query.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2159,7 +2159,9 @@ static int ib_sa_add_one(struct ib_device *device)
21592159
s = rdma_start_port(device);
21602160
e = rdma_end_port(device);
21612161

2162-
sa_dev = kzalloc(struct_size(sa_dev, port, e - s + 1), GFP_KERNEL);
2162+
sa_dev = kzalloc(struct_size(sa_dev, port,
2163+
size_add(size_sub(e, s), 1)),
2164+
GFP_KERNEL);
21632165
if (!sa_dev)
21642166
return -ENOMEM;
21652167

drivers/infiniband/core/sysfs.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,10 @@ static ssize_t rate_show(struct ib_device *ibdev, u32 port_num,
342342
speed = " NDR";
343343
rate = 1000;
344344
break;
345+
case IB_SPEED_XDR:
346+
speed = " XDR";
347+
rate = 2000;
348+
break;
345349
case IB_SPEED_SDR:
346350
default: /* default to SDR for invalid rates */
347351
speed = " SDR";
@@ -903,7 +907,7 @@ alloc_hw_stats_device(struct ib_device *ibdev)
903907
* Two extra attribue elements here, one for the lifespan entry and
904908
* one to NULL terminate the list for the sysfs core code
905909
*/
906-
data = kzalloc(struct_size(data, attrs, stats->num_counters + 1),
910+
data = kzalloc(struct_size(data, attrs, size_add(stats->num_counters, 1)),
907911
GFP_KERNEL);
908912
if (!data)
909913
goto err_free_stats;
@@ -1009,7 +1013,7 @@ alloc_hw_stats_port(struct ib_port *port, struct attribute_group *group)
10091013
* Two extra attribue elements here, one for the lifespan entry and
10101014
* one to NULL terminate the list for the sysfs core code
10111015
*/
1012-
data = kzalloc(struct_size(data, attrs, stats->num_counters + 1),
1016+
data = kzalloc(struct_size(data, attrs, size_add(stats->num_counters, 1)),
10131017
GFP_KERNEL);
10141018
if (!data)
10151019
goto err_free_stats;
@@ -1140,7 +1144,7 @@ static int setup_gid_attrs(struct ib_port *port,
11401144
int ret;
11411145

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

12071211
p = kvzalloc(struct_size(p, attrs_list,
1208-
attr->gid_tbl_len + attr->pkey_tbl_len),
1209-
GFP_KERNEL);
1212+
size_add(attr->gid_tbl_len, attr->pkey_tbl_len)),
1213+
GFP_KERNEL);
12101214
if (!p)
12111215
return ERR_PTR(-ENOMEM);
12121216
p->ibdev = device;

drivers/infiniband/core/user_mad.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1378,7 +1378,9 @@ static int ib_umad_add_one(struct ib_device *device)
13781378
s = rdma_start_port(device);
13791379
e = rdma_end_port(device);
13801380

1381-
umad_dev = kzalloc(struct_size(umad_dev, ports, e - s + 1), GFP_KERNEL);
1381+
umad_dev = kzalloc(struct_size(umad_dev, ports,
1382+
size_add(size_sub(e, s), 1)),
1383+
GFP_KERNEL);
13821384
if (!umad_dev)
13831385
return -ENOMEM;
13841386

drivers/infiniband/core/uverbs_cmd.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1851,7 +1851,8 @@ static int modify_qp(struct uverbs_attr_bundle *attrs,
18511851
if (cmd->base.attr_mask & IB_QP_PATH_MIG_STATE)
18521852
attr->path_mig_state = cmd->base.path_mig_state;
18531853
if (cmd->base.attr_mask & IB_QP_QKEY) {
1854-
if (cmd->base.qkey & IB_QP_SET_QKEY && !capable(CAP_NET_RAW)) {
1854+
if (cmd->base.qkey & IB_QP_SET_QKEY &&
1855+
!rdma_nl_get_privileged_qkey()) {
18551856
ret = -EPERM;
18561857
goto release_qp;
18571858
}

0 commit comments

Comments
 (0)