Commit 459cc69f authored by Leon Romanovsky's avatar Leon Romanovsky Committed by Jason Gunthorpe

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: default avatarLeon Romanovsky <leonro@mellanox.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent e5c1bb47
...@@ -268,7 +268,7 @@ static struct class ib_class = { ...@@ -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 * @size:size of structure to allocate
* *
* Low-level drivers should use ib_alloc_device() to allocate &struct * Low-level drivers should use ib_alloc_device() to allocate &struct
...@@ -277,7 +277,7 @@ static struct class ib_class = { ...@@ -277,7 +277,7 @@ static struct class ib_class = {
* ib_dealloc_device() must be used to free structures allocated with * ib_dealloc_device() must be used to free structures allocated with
* ib_alloc_device(). * 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; struct ib_device *device;
...@@ -303,7 +303,7 @@ struct ib_device *ib_alloc_device(size_t size) ...@@ -303,7 +303,7 @@ struct ib_device *ib_alloc_device(size_t size)
return device; return device;
} }
EXPORT_SYMBOL(ib_alloc_device); EXPORT_SYMBOL(_ib_alloc_device);
/** /**
* ib_dealloc_device - free an IB device struct * ib_dealloc_device - free an IB device struct
......
...@@ -688,7 +688,7 @@ static struct bnxt_re_dev *bnxt_re_dev_add(struct net_device *netdev, ...@@ -688,7 +688,7 @@ static struct bnxt_re_dev *bnxt_re_dev_add(struct net_device *netdev,
struct bnxt_re_dev *rdev; struct bnxt_re_dev *rdev;
/* Allocate bnxt_re_dev instance here */ /* 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) { if (!rdev) {
dev_err(NULL, "%s: bnxt_re_dev allocation failure!", dev_err(NULL, "%s: bnxt_re_dev allocation failure!",
ROCE_DRV_MODULE_NAME); ROCE_DRV_MODULE_NAME);
......
...@@ -146,7 +146,7 @@ static void open_rnic_dev(struct t3cdev *tdev) ...@@ -146,7 +146,7 @@ static void open_rnic_dev(struct t3cdev *tdev)
pr_debug("%s t3cdev %p\n", __func__, tdev); pr_debug("%s t3cdev %p\n", __func__, tdev);
pr_info_once("Chelsio T3 RDMA Driver - version %s\n", DRV_VERSION); 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) { if (!rnicp) {
pr_err("Cannot allocate ib device\n"); pr_err("Cannot allocate ib device\n");
return; return;
......
...@@ -966,7 +966,7 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop) ...@@ -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", pr_info("%s: On-Chip Queues not supported on this device\n",
pci_name(infop->pdev)); pci_name(infop->pdev));
devp = (struct c4iw_dev *)ib_alloc_device(sizeof(*devp)); devp = ib_alloc_device(c4iw_dev, ibdev);
if (!devp) { if (!devp) {
pr_err("Cannot allocate ib device\n"); pr_err("Cannot allocate ib device\n");
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
......
...@@ -5002,7 +5002,7 @@ static int hns_roce_probe(struct platform_device *pdev) ...@@ -5002,7 +5002,7 @@ static int hns_roce_probe(struct platform_device *pdev)
struct hns_roce_dev *hr_dev; struct hns_roce_dev *hr_dev;
struct device *dev = &pdev->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) if (!hr_dev)
return -ENOMEM; return -ENOMEM;
......
...@@ -6059,7 +6059,7 @@ static int hns_roce_hw_v2_init_instance(struct hnae3_handle *handle) ...@@ -6059,7 +6059,7 @@ static int hns_roce_hw_v2_init_instance(struct hnae3_handle *handle)
struct hns_roce_dev *hr_dev; struct hns_roce_dev *hr_dev;
int ret; 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) if (!hr_dev)
return -ENOMEM; return -ENOMEM;
......
...@@ -2762,7 +2762,7 @@ static struct i40iw_ib_device *i40iw_init_rdma_device(struct i40iw_device *iwdev ...@@ -2762,7 +2762,7 @@ static struct i40iw_ib_device *i40iw_init_rdma_device(struct i40iw_device *iwdev
struct net_device *netdev = iwdev->netdev; struct net_device *netdev = iwdev->netdev;
struct pci_dev *pcidev = (struct pci_dev *)iwdev->hw.dev_context; 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) { if (!iwibdev) {
i40iw_pr_err("iwdev == NULL\n"); i40iw_pr_err("iwdev == NULL\n");
return NULL; return NULL;
......
...@@ -2635,7 +2635,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) ...@@ -2635,7 +2635,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
if (num_ports == 0) if (num_ports == 0)
return NULL; return NULL;
ibdev = (struct mlx4_ib_dev *) ib_alloc_device(sizeof *ibdev); ibdev = ib_alloc_device(mlx4_ib_dev, ib_dev);
if (!ibdev) { if (!ibdev) {
dev_err(&dev->persist->pdev->dev, dev_err(&dev->persist->pdev->dev,
"Device struct alloc failed\n"); "Device struct alloc failed\n");
......
...@@ -70,7 +70,7 @@ mlx5_ib_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) ...@@ -70,7 +70,7 @@ mlx5_ib_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
{ {
struct mlx5_ib_dev *ibdev; 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) if (!ibdev)
return -ENOMEM; return -ENOMEM;
......
...@@ -6508,7 +6508,7 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev) ...@@ -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) if (mlx5_core_is_mp_slave(mdev) && ll == IB_LINK_LAYER_ETHERNET)
return mlx5_ib_add_slave_port(mdev); 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) if (!dev)
return NULL; return NULL;
......
...@@ -961,7 +961,7 @@ static int __mthca_init_one(struct pci_dev *pdev, int hca_type) ...@@ -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. */ /* We can handle large RDMA requests, so allow larger segments. */
dma_set_max_seg_size(&pdev->dev, 1024 * 1024 * 1024); 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) { if (!mdev) {
dev_err(&pdev->dev, "Device struct alloc failed, " dev_err(&pdev->dev, "Device struct alloc failed, "
"aborting.\n"); "aborting.\n");
......
...@@ -3669,7 +3669,7 @@ struct nes_ib_device *nes_init_ofa_device(struct net_device *netdev) ...@@ -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_vnic *nesvnic = netdev_priv(netdev);
struct nes_device *nesdev = nesvnic->nesdev; 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) { if (nesibdev == NULL) {
return NULL; return NULL;
} }
......
...@@ -297,7 +297,7 @@ static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info) ...@@ -297,7 +297,7 @@ static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info)
u8 lstate = 0; u8 lstate = 0;
struct ocrdma_dev *dev; struct ocrdma_dev *dev;
dev = (struct ocrdma_dev *)ib_alloc_device(sizeof(struct ocrdma_dev)); dev = ib_alloc_device(ocrdma_dev, ibdev);
if (!dev) { if (!dev) {
pr_err("Unable to allocate ib device\n"); pr_err("Unable to allocate ib device\n");
return NULL; return NULL;
......
...@@ -853,7 +853,7 @@ static struct qedr_dev *qedr_add(struct qed_dev *cdev, struct pci_dev *pdev, ...@@ -853,7 +853,7 @@ static struct qedr_dev *qedr_add(struct qed_dev *cdev, struct pci_dev *pdev,
struct qedr_dev *dev; struct qedr_dev *dev;
int rc = 0; int rc = 0;
dev = (struct qedr_dev *)ib_alloc_device(sizeof(*dev)); dev = ib_alloc_device(qedr_dev, ibdev);
if (!dev) { if (!dev) {
pr_err("Unable to allocate ib device\n"); pr_err("Unable to allocate ib device\n");
return NULL; return NULL;
......
...@@ -372,7 +372,7 @@ static void *usnic_ib_device_add(struct pci_dev *dev) ...@@ -372,7 +372,7 @@ static void *usnic_ib_device_add(struct pci_dev *dev)
usnic_dbg("\n"); usnic_dbg("\n");
netdev = pci_get_drvdata(dev); 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) { if (!us_ibdev) {
usnic_err("Device %s context alloc failed\n", usnic_err("Device %s context alloc failed\n",
netdev_name(pci_get_drvdata(dev))); netdev_name(pci_get_drvdata(dev)));
......
...@@ -795,7 +795,7 @@ static int pvrdma_pci_probe(struct pci_dev *pdev, ...@@ -795,7 +795,7 @@ static int pvrdma_pci_probe(struct pci_dev *pdev,
dev_dbg(&pdev->dev, "initializing driver %s\n", pci_name(pdev)); dev_dbg(&pdev->dev, "initializing driver %s\n", pci_name(pdev));
/* Allocate zero-out device */ /* Allocate zero-out device */
dev = (struct pvrdma_dev *)ib_alloc_device(sizeof(*dev)); dev = ib_alloc_device(pvrdma_dev, ib_dev);
if (!dev) { if (!dev) {
dev_err(&pdev->dev, "failed to allocate IB device\n"); dev_err(&pdev->dev, "failed to allocate IB device\n");
return -ENOMEM; return -ENOMEM;
......
...@@ -91,7 +91,7 @@ struct rvt_dev_info *rvt_alloc_device(size_t size, int nports) ...@@ -91,7 +91,7 @@ struct rvt_dev_info *rvt_alloc_device(size_t size, int nports)
{ {
struct rvt_dev_info *rdi; 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) if (!rdi)
return rdi; return rdi;
......
...@@ -555,7 +555,7 @@ struct rxe_dev *rxe_net_add(struct net_device *ndev) ...@@ -555,7 +555,7 @@ struct rxe_dev *rxe_net_add(struct net_device *ndev)
int err; int err;
struct rxe_dev *rxe = NULL; struct rxe_dev *rxe = NULL;
rxe = (struct rxe_dev *)ib_alloc_device(sizeof(*rxe)); rxe = ib_alloc_device(rxe_dev, ib_dev);
if (!rxe) if (!rxe)
return NULL; return NULL;
......
...@@ -2621,7 +2621,13 @@ struct ib_client { ...@@ -2621,7 +2621,13 @@ struct ib_client {
struct list_head list; 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_dealloc_device(struct ib_device *device);
void ib_get_device_fw_str(struct ib_device *device, char *str); void ib_get_device_fw_str(struct ib_device *device, char *str);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment