]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
RDMA: Provide safe ib_alloc_device() function
authorLeon Romanovsky <leonro@mellanox.com>
Wed, 30 Jan 2019 10:49:11 +0000 (12:49 +0200)
committerJason Gunthorpe <jgg@mellanox.com>
Wed, 30 Jan 2019 22:52:30 +0000 (15:52 -0700)
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 <leonro@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
19 files changed:
drivers/infiniband/core/device.c
drivers/infiniband/hw/bnxt_re/main.c
drivers/infiniband/hw/cxgb3/iwch.c
drivers/infiniband/hw/cxgb4/device.c
drivers/infiniband/hw/hns/hns_roce_hw_v1.c
drivers/infiniband/hw/hns/hns_roce_hw_v2.c
drivers/infiniband/hw/i40iw/i40iw_verbs.c
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx5/ib_rep.c
drivers/infiniband/hw/mlx5/main.c
drivers/infiniband/hw/mthca/mthca_main.c
drivers/infiniband/hw/nes/nes_verbs.c
drivers/infiniband/hw/ocrdma/ocrdma_main.c
drivers/infiniband/hw/qedr/main.c
drivers/infiniband/hw/usnic/usnic_ib_main.c
drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c
drivers/infiniband/sw/rdmavt/vt.c
drivers/infiniband/sw/rxe/rxe_net.c
include/rdma/ib_verbs.h

index 200431c540f22a784b8a37b5b98895d1c75d49a9..b511cfa00bdb6b2768cd0856a8466d4c19e9ad08 100644 (file)
@@ -268,7 +268,7 @@ static struct class ib_class = {
 };
 
 /**
- * ib_alloc_device - allocate an IB device struct
+ * _ib_alloc_device - allocate an IB device struct
  * @size:size of structure to allocate
  *
  * Low-level drivers should use ib_alloc_device() to allocate &struct
@@ -277,7 +277,7 @@ static struct class ib_class = {
  * ib_dealloc_device() must be used to free structures allocated with
  * ib_alloc_device().
  */
-struct ib_device *ib_alloc_device(size_t size)
+struct ib_device *_ib_alloc_device(size_t size)
 {
        struct ib_device *device;
 
@@ -303,7 +303,7 @@ struct ib_device *ib_alloc_device(size_t size)
 
        return device;
 }
-EXPORT_SYMBOL(ib_alloc_device);
+EXPORT_SYMBOL(_ib_alloc_device);
 
 /**
  * ib_dealloc_device - free an IB device struct
index 16eecfa5882c008469913fc9b0de204233652e6a..08777506d0b1bd930034030b06f9dd62c38feb8e 100644 (file)
@@ -688,7 +688,7 @@ static struct bnxt_re_dev *bnxt_re_dev_add(struct net_device *netdev,
        struct bnxt_re_dev *rdev;
 
        /* Allocate bnxt_re_dev instance here */
-       rdev = (struct bnxt_re_dev *)ib_alloc_device(sizeof(*rdev));
+       rdev = ib_alloc_device(bnxt_re_dev, ibdev);
        if (!rdev) {
                dev_err(NULL, "%s: bnxt_re_dev allocation failure!",
                        ROCE_DRV_MODULE_NAME);
index 591de319c1788712251fcb14933a12dba899f5d7..fb03bc492ef7733236a37d24f40d0323e382033d 100644 (file)
@@ -146,7 +146,7 @@ static void open_rnic_dev(struct t3cdev *tdev)
 
        pr_debug("%s t3cdev %p\n", __func__,  tdev);
        pr_info_once("Chelsio T3 RDMA Driver - version %s\n", DRV_VERSION);
-       rnicp = (struct iwch_dev *)ib_alloc_device(sizeof(*rnicp));
+       rnicp = ib_alloc_device(iwch_dev, ibdev);
        if (!rnicp) {
                pr_err("Cannot allocate ib device\n");
                return;
index 9c10fff6dcfbe62532aeb2345c3951ddf1111012..4b4e2464b70513fcb5bf5be43c410e1605402949 100644 (file)
@@ -966,7 +966,7 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop)
                pr_info("%s: On-Chip Queues not supported on this device\n",
                        pci_name(infop->pdev));
 
-       devp = (struct c4iw_dev *)ib_alloc_device(sizeof(*devp));
+       devp = ib_alloc_device(c4iw_dev, ibdev);
        if (!devp) {
                pr_err("Cannot allocate ib device\n");
                return ERR_PTR(-ENOMEM);
index b74c742b000c711d66673774983d12f8a344b058..fa08c22aad66b8aebd4b17ae81b4f67ac53fdf7c 100644 (file)
@@ -5002,7 +5002,7 @@ static int hns_roce_probe(struct platform_device *pdev)
        struct hns_roce_dev *hr_dev;
        struct device *dev = &pdev->dev;
 
-       hr_dev = (struct hns_roce_dev *)ib_alloc_device(sizeof(*hr_dev));
+       hr_dev = ib_alloc_device(hns_roce_dev, ib_dev);
        if (!hr_dev)
                return -ENOMEM;
 
index 5c483b437bdda6d25d5159d4b688154e6a1a3463..48a5d6548cd470148b756f5711d57ec5b05a3017 100644 (file)
@@ -6059,7 +6059,7 @@ static int hns_roce_hw_v2_init_instance(struct hnae3_handle *handle)
        struct hns_roce_dev *hr_dev;
        int ret;
 
-       hr_dev = (struct hns_roce_dev *)ib_alloc_device(sizeof(*hr_dev));
+       hr_dev = ib_alloc_device(hns_roce_dev, ib_dev);
        if (!hr_dev)
                return -ENOMEM;
 
index 12b31a8440be5e932adecab49e975070992d92d9..d4ab46dd9e6c7ebfec5b371528c9ccfefbe3362f 100644 (file)
@@ -2762,7 +2762,7 @@ static struct i40iw_ib_device *i40iw_init_rdma_device(struct i40iw_device *iwdev
        struct net_device *netdev = iwdev->netdev;
        struct pci_dev *pcidev = (struct pci_dev *)iwdev->hw.dev_context;
 
-       iwibdev = (struct i40iw_ib_device *)ib_alloc_device(sizeof(*iwibdev));
+       iwibdev = ib_alloc_device(i40iw_ib_device, ibdev);
        if (!iwibdev) {
                i40iw_pr_err("iwdev == NULL\n");
                return NULL;
index dc2ffd293a1137e4c9dfac31202888d87233b783..d66002a3100072ea597ebf65bad0d31da320e976 100644 (file)
@@ -2635,7 +2635,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
        if (num_ports == 0)
                return NULL;
 
-       ibdev = (struct mlx4_ib_dev *) ib_alloc_device(sizeof *ibdev);
+       ibdev = ib_alloc_device(mlx4_ib_dev, ib_dev);
        if (!ibdev) {
                dev_err(&dev->persist->pdev->dev,
                        "Device struct alloc failed\n");
index 46a9ddc8ca56ccfc8d7b5c3b3e4049f91ab288f1..6d7b8bad4b610a0233885e8a5cc092b41a76d69d 100644 (file)
@@ -70,7 +70,7 @@ mlx5_ib_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
 {
        struct mlx5_ib_dev *ibdev;
 
-       ibdev = (struct mlx5_ib_dev *)ib_alloc_device(sizeof(*ibdev));
+       ibdev = ib_alloc_device(mlx5_ib_dev, ib_dev);
        if (!ibdev)
                return -ENOMEM;
 
index 96bf1b2f9dd734f66a903ff3832aff1833790f78..8161acda64e6bfd503ac860b8459fba8e6b3c03e 100644 (file)
@@ -6508,7 +6508,7 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
        if (mlx5_core_is_mp_slave(mdev) && ll == IB_LINK_LAYER_ETHERNET)
                return mlx5_ib_add_slave_port(mdev);
 
-       dev = (struct mlx5_ib_dev *)ib_alloc_device(sizeof(*dev));
+       dev = ib_alloc_device(mlx5_ib_dev, ib_dev);
        if (!dev)
                return NULL;
 
index 92c49bff22bc31d9cd7d023ee64d08a135108264..fe9654a7af713a30f562699f81521dffbcf1727e 100644 (file)
@@ -961,7 +961,7 @@ static int __mthca_init_one(struct pci_dev *pdev, int hca_type)
        /* We can handle large RDMA requests, so allow larger segments. */
        dma_set_max_seg_size(&pdev->dev, 1024 * 1024 * 1024);
 
-       mdev = (struct mthca_dev *) ib_alloc_device(sizeof *mdev);
+       mdev = ib_alloc_device(mthca_dev, ib_dev);
        if (!mdev) {
                dev_err(&pdev->dev, "Device struct alloc failed, "
                        "aborting.\n");
index 034156f7e9ed6e2bb216379cd30d4858aacb2688..6eb991d4003581a9e413a1d4d935ef3686265958 100644 (file)
@@ -3669,7 +3669,7 @@ struct nes_ib_device *nes_init_ofa_device(struct net_device *netdev)
        struct nes_vnic *nesvnic = netdev_priv(netdev);
        struct nes_device *nesdev = nesvnic->nesdev;
 
-       nesibdev = (struct nes_ib_device *)ib_alloc_device(sizeof(struct nes_ib_device));
+       nesibdev = ib_alloc_device(nes_ib_device, ibdev);
        if (nesibdev == NULL) {
                return NULL;
        }
index b0491b9ecfe41cb1eb19bba6294278f045c849f8..88970a6bb555792a4f6061bd12c676c884eb74c1 100644 (file)
@@ -297,7 +297,7 @@ static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info)
        u8 lstate = 0;
        struct ocrdma_dev *dev;
 
-       dev = (struct ocrdma_dev *)ib_alloc_device(sizeof(struct ocrdma_dev));
+       dev = ib_alloc_device(ocrdma_dev, ibdev);
        if (!dev) {
                pr_err("Unable to allocate ib device\n");
                return NULL;
index f85e72b65a100cca4545c85439271ea74ee38812..878e9e23652bf0168db86a8e3bdfc9e0dc004510 100644 (file)
@@ -853,7 +853,7 @@ static struct qedr_dev *qedr_add(struct qed_dev *cdev, struct pci_dev *pdev,
        struct qedr_dev *dev;
        int rc = 0;
 
-       dev = (struct qedr_dev *)ib_alloc_device(sizeof(*dev));
+       dev = ib_alloc_device(qedr_dev, ibdev);
        if (!dev) {
                pr_err("Unable to allocate ib device\n");
                return NULL;
index 3201dd1899c7a63afb8ee73a657e6ce4c257b8a3..0c0a288cb585b00f756dd6c41e158fb71c1152e7 100644 (file)
@@ -372,7 +372,7 @@ static void *usnic_ib_device_add(struct pci_dev *dev)
        usnic_dbg("\n");
        netdev = pci_get_drvdata(dev);
 
-       us_ibdev = (struct usnic_ib_dev *)ib_alloc_device(sizeof(*us_ibdev));
+       us_ibdev = ib_alloc_device(usnic_ib_dev, ib_dev);
        if (!us_ibdev) {
                usnic_err("Device %s context alloc failed\n",
                                netdev_name(pci_get_drvdata(dev)));
index a5f02276d90327af0c23d11d13d5fc9a005414b1..e582beaf94305c61f7cbc30e5f7a68cf9eac0f8c 100644 (file)
@@ -795,7 +795,7 @@ static int pvrdma_pci_probe(struct pci_dev *pdev,
        dev_dbg(&pdev->dev, "initializing driver %s\n", pci_name(pdev));
 
        /* Allocate zero-out device */
-       dev = (struct pvrdma_dev *)ib_alloc_device(sizeof(*dev));
+       dev = ib_alloc_device(pvrdma_dev, ib_dev);
        if (!dev) {
                dev_err(&pdev->dev, "failed to allocate IB device\n");
                return -ENOMEM;
index 7de7389d02350cda023adb74e11eee446001ac4f..b3f0c557892515630d0ffbf592186855b25c5505 100644 (file)
@@ -91,7 +91,7 @@ struct rvt_dev_info *rvt_alloc_device(size_t size, int nports)
 {
        struct rvt_dev_info *rdi;
 
-       rdi = (struct rvt_dev_info *)ib_alloc_device(size);
+       rdi = container_of(_ib_alloc_device(size), struct rvt_dev_info, ibdev);
        if (!rdi)
                return rdi;
 
index 8fd03ae20efc1735c269a6086db71191b4e02518..19f3c69916b19aef77c4d621a919490d2c6c9446 100644 (file)
@@ -555,7 +555,7 @@ struct rxe_dev *rxe_net_add(struct net_device *ndev)
        int err;
        struct rxe_dev *rxe = NULL;
 
-       rxe = (struct rxe_dev *)ib_alloc_device(sizeof(*rxe));
+       rxe = ib_alloc_device(rxe_dev, ib_dev);
        if (!rxe)
                return NULL;
 
index 71ea144ec823a2c1eedbf6a8c056dbb3c3f4873c..a1a1e710642cbf528235461bccc800951145ad35 100644 (file)
@@ -2621,7 +2621,13 @@ struct ib_client {
        struct list_head list;
 };
 
-struct ib_device *ib_alloc_device(size_t size);
+struct ib_device *_ib_alloc_device(size_t size);
+#define ib_alloc_device(drv_struct, member)                                    \
+       container_of(_ib_alloc_device(sizeof(struct drv_struct) +              \
+                                     BUILD_BUG_ON_ZERO(offsetof(              \
+                                             struct drv_struct, member))),    \
+                    struct drv_struct, member)
+
 void ib_dealloc_device(struct ib_device *device);
 
 void ib_get_device_fw_str(struct ib_device *device, char *str);