Skip to content

Commit 459cc69

Browse files
Leon Romanovskyjgunthorpe
authored andcommitted
RDMA: Provide safe ib_alloc_device() function
All callers to ib_alloc_device() provide a larger size than struct ib_device and rely on the fact that struct ib_device is embedded in their driver specific structure as the first member. Provide a safer variant of ib_alloc_device() that checks and enforces this approach to make sure the drivers are using it right. Signed-off-by: Leon Romanovsky <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent e5c1bb4 commit 459cc69

File tree

19 files changed

+27
-21
lines changed

19 files changed

+27
-21
lines changed

drivers/infiniband/core/device.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ static struct class ib_class = {
268268
};
269269

270270
/**
271-
* ib_alloc_device - allocate an IB device struct
271+
* _ib_alloc_device - allocate an IB device struct
272272
* @size:size of structure to allocate
273273
*
274274
* Low-level drivers should use ib_alloc_device() to allocate &struct
@@ -277,7 +277,7 @@ static struct class ib_class = {
277277
* ib_dealloc_device() must be used to free structures allocated with
278278
* ib_alloc_device().
279279
*/
280-
struct ib_device *ib_alloc_device(size_t size)
280+
struct ib_device *_ib_alloc_device(size_t size)
281281
{
282282
struct ib_device *device;
283283

@@ -303,7 +303,7 @@ struct ib_device *ib_alloc_device(size_t size)
303303

304304
return device;
305305
}
306-
EXPORT_SYMBOL(ib_alloc_device);
306+
EXPORT_SYMBOL(_ib_alloc_device);
307307

308308
/**
309309
* ib_dealloc_device - free an IB device struct

drivers/infiniband/hw/bnxt_re/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,7 @@ static struct bnxt_re_dev *bnxt_re_dev_add(struct net_device *netdev,
688688
struct bnxt_re_dev *rdev;
689689

690690
/* Allocate bnxt_re_dev instance here */
691-
rdev = (struct bnxt_re_dev *)ib_alloc_device(sizeof(*rdev));
691+
rdev = ib_alloc_device(bnxt_re_dev, ibdev);
692692
if (!rdev) {
693693
dev_err(NULL, "%s: bnxt_re_dev allocation failure!",
694694
ROCE_DRV_MODULE_NAME);

drivers/infiniband/hw/cxgb3/iwch.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ static void open_rnic_dev(struct t3cdev *tdev)
146146

147147
pr_debug("%s t3cdev %p\n", __func__, tdev);
148148
pr_info_once("Chelsio T3 RDMA Driver - version %s\n", DRV_VERSION);
149-
rnicp = (struct iwch_dev *)ib_alloc_device(sizeof(*rnicp));
149+
rnicp = ib_alloc_device(iwch_dev, ibdev);
150150
if (!rnicp) {
151151
pr_err("Cannot allocate ib device\n");
152152
return;

drivers/infiniband/hw/cxgb4/device.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -966,7 +966,7 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop)
966966
pr_info("%s: On-Chip Queues not supported on this device\n",
967967
pci_name(infop->pdev));
968968

969-
devp = (struct c4iw_dev *)ib_alloc_device(sizeof(*devp));
969+
devp = ib_alloc_device(c4iw_dev, ibdev);
970970
if (!devp) {
971971
pr_err("Cannot allocate ib device\n");
972972
return ERR_PTR(-ENOMEM);

drivers/infiniband/hw/hns/hns_roce_hw_v1.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5002,7 +5002,7 @@ static int hns_roce_probe(struct platform_device *pdev)
50025002
struct hns_roce_dev *hr_dev;
50035003
struct device *dev = &pdev->dev;
50045004

5005-
hr_dev = (struct hns_roce_dev *)ib_alloc_device(sizeof(*hr_dev));
5005+
hr_dev = ib_alloc_device(hns_roce_dev, ib_dev);
50065006
if (!hr_dev)
50075007
return -ENOMEM;
50085008

drivers/infiniband/hw/hns/hns_roce_hw_v2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6059,7 +6059,7 @@ static int hns_roce_hw_v2_init_instance(struct hnae3_handle *handle)
60596059
struct hns_roce_dev *hr_dev;
60606060
int ret;
60616061

6062-
hr_dev = (struct hns_roce_dev *)ib_alloc_device(sizeof(*hr_dev));
6062+
hr_dev = ib_alloc_device(hns_roce_dev, ib_dev);
60636063
if (!hr_dev)
60646064
return -ENOMEM;
60656065

drivers/infiniband/hw/i40iw/i40iw_verbs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2762,7 +2762,7 @@ static struct i40iw_ib_device *i40iw_init_rdma_device(struct i40iw_device *iwdev
27622762
struct net_device *netdev = iwdev->netdev;
27632763
struct pci_dev *pcidev = (struct pci_dev *)iwdev->hw.dev_context;
27642764

2765-
iwibdev = (struct i40iw_ib_device *)ib_alloc_device(sizeof(*iwibdev));
2765+
iwibdev = ib_alloc_device(i40iw_ib_device, ibdev);
27662766
if (!iwibdev) {
27672767
i40iw_pr_err("iwdev == NULL\n");
27682768
return NULL;

drivers/infiniband/hw/mlx4/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2635,7 +2635,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
26352635
if (num_ports == 0)
26362636
return NULL;
26372637

2638-
ibdev = (struct mlx4_ib_dev *) ib_alloc_device(sizeof *ibdev);
2638+
ibdev = ib_alloc_device(mlx4_ib_dev, ib_dev);
26392639
if (!ibdev) {
26402640
dev_err(&dev->persist->pdev->dev,
26412641
"Device struct alloc failed\n");

drivers/infiniband/hw/mlx5/ib_rep.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ mlx5_ib_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
7070
{
7171
struct mlx5_ib_dev *ibdev;
7272

73-
ibdev = (struct mlx5_ib_dev *)ib_alloc_device(sizeof(*ibdev));
73+
ibdev = ib_alloc_device(mlx5_ib_dev, ib_dev);
7474
if (!ibdev)
7575
return -ENOMEM;
7676

drivers/infiniband/hw/mlx5/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6508,7 +6508,7 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
65086508
if (mlx5_core_is_mp_slave(mdev) && ll == IB_LINK_LAYER_ETHERNET)
65096509
return mlx5_ib_add_slave_port(mdev);
65106510

6511-
dev = (struct mlx5_ib_dev *)ib_alloc_device(sizeof(*dev));
6511+
dev = ib_alloc_device(mlx5_ib_dev, ib_dev);
65126512
if (!dev)
65136513
return NULL;
65146514

drivers/infiniband/hw/mthca/mthca_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -961,7 +961,7 @@ static int __mthca_init_one(struct pci_dev *pdev, int hca_type)
961961
/* We can handle large RDMA requests, so allow larger segments. */
962962
dma_set_max_seg_size(&pdev->dev, 1024 * 1024 * 1024);
963963

964-
mdev = (struct mthca_dev *) ib_alloc_device(sizeof *mdev);
964+
mdev = ib_alloc_device(mthca_dev, ib_dev);
965965
if (!mdev) {
966966
dev_err(&pdev->dev, "Device struct alloc failed, "
967967
"aborting.\n");

drivers/infiniband/hw/nes/nes_verbs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3669,7 +3669,7 @@ struct nes_ib_device *nes_init_ofa_device(struct net_device *netdev)
36693669
struct nes_vnic *nesvnic = netdev_priv(netdev);
36703670
struct nes_device *nesdev = nesvnic->nesdev;
36713671

3672-
nesibdev = (struct nes_ib_device *)ib_alloc_device(sizeof(struct nes_ib_device));
3672+
nesibdev = ib_alloc_device(nes_ib_device, ibdev);
36733673
if (nesibdev == NULL) {
36743674
return NULL;
36753675
}

drivers/infiniband/hw/ocrdma/ocrdma_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info)
297297
u8 lstate = 0;
298298
struct ocrdma_dev *dev;
299299

300-
dev = (struct ocrdma_dev *)ib_alloc_device(sizeof(struct ocrdma_dev));
300+
dev = ib_alloc_device(ocrdma_dev, ibdev);
301301
if (!dev) {
302302
pr_err("Unable to allocate ib device\n");
303303
return NULL;

drivers/infiniband/hw/qedr/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -853,7 +853,7 @@ static struct qedr_dev *qedr_add(struct qed_dev *cdev, struct pci_dev *pdev,
853853
struct qedr_dev *dev;
854854
int rc = 0;
855855

856-
dev = (struct qedr_dev *)ib_alloc_device(sizeof(*dev));
856+
dev = ib_alloc_device(qedr_dev, ibdev);
857857
if (!dev) {
858858
pr_err("Unable to allocate ib device\n");
859859
return NULL;

drivers/infiniband/hw/usnic/usnic_ib_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ static void *usnic_ib_device_add(struct pci_dev *dev)
372372
usnic_dbg("\n");
373373
netdev = pci_get_drvdata(dev);
374374

375-
us_ibdev = (struct usnic_ib_dev *)ib_alloc_device(sizeof(*us_ibdev));
375+
us_ibdev = ib_alloc_device(usnic_ib_dev, ib_dev);
376376
if (!us_ibdev) {
377377
usnic_err("Device %s context alloc failed\n",
378378
netdev_name(pci_get_drvdata(dev)));

drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -795,7 +795,7 @@ static int pvrdma_pci_probe(struct pci_dev *pdev,
795795
dev_dbg(&pdev->dev, "initializing driver %s\n", pci_name(pdev));
796796

797797
/* Allocate zero-out device */
798-
dev = (struct pvrdma_dev *)ib_alloc_device(sizeof(*dev));
798+
dev = ib_alloc_device(pvrdma_dev, ib_dev);
799799
if (!dev) {
800800
dev_err(&pdev->dev, "failed to allocate IB device\n");
801801
return -ENOMEM;

drivers/infiniband/sw/rdmavt/vt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ struct rvt_dev_info *rvt_alloc_device(size_t size, int nports)
9191
{
9292
struct rvt_dev_info *rdi;
9393

94-
rdi = (struct rvt_dev_info *)ib_alloc_device(size);
94+
rdi = container_of(_ib_alloc_device(size), struct rvt_dev_info, ibdev);
9595
if (!rdi)
9696
return rdi;
9797

drivers/infiniband/sw/rxe/rxe_net.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,7 @@ struct rxe_dev *rxe_net_add(struct net_device *ndev)
555555
int err;
556556
struct rxe_dev *rxe = NULL;
557557

558-
rxe = (struct rxe_dev *)ib_alloc_device(sizeof(*rxe));
558+
rxe = ib_alloc_device(rxe_dev, ib_dev);
559559
if (!rxe)
560560
return NULL;
561561

include/rdma/ib_verbs.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2621,7 +2621,13 @@ struct ib_client {
26212621
struct list_head list;
26222622
};
26232623

2624-
struct ib_device *ib_alloc_device(size_t size);
2624+
struct ib_device *_ib_alloc_device(size_t size);
2625+
#define ib_alloc_device(drv_struct, member) \
2626+
container_of(_ib_alloc_device(sizeof(struct drv_struct) + \
2627+
BUILD_BUG_ON_ZERO(offsetof( \
2628+
struct drv_struct, member))), \
2629+
struct drv_struct, member)
2630+
26252631
void ib_dealloc_device(struct ib_device *device);
26262632

26272633
void ib_get_device_fw_str(struct ib_device *device, char *str);

0 commit comments

Comments
 (0)