Skip to content

Commit

Permalink
RDMA/ocrdma: Dont use PD 0 for userpace CQ DB
Browse files Browse the repository at this point in the history
Create_CQ verb doesn't provide a PD pointer.  So, until now we are
creating all (both userspace and kernel) CQ DB regions from PD0.  This
will result in mmapping PD0 to applications.  A rogue userspace
application can mess things up.

Also more serious issues is even the be2net NIC uses PD0.

This patch addresses this problem by:

1) Create a PD page for every userspace application when the
   alloc_ucontext is called. This will be destroyed in
   dealloc_ucontext.
2) All CQs for that context will use the PD allocated in ucontext.
3) The first create_PD call from application will result in returning
   the PD address from its ucontext (no new PD will be created).
4) For subsecquent create_pd calls from application, we create new PDs for
   the application.

Signed-off-by: Naresh Gottumukkala <bgottumukkala@emulex.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
  • Loading branch information
Naresh Gottumukkala authored and Roland Dreier committed Sep 3, 2013
1 parent 2b51a9b commit cffce99
Showing 6 changed files with 339 additions and 40 deletions.
3 changes: 3 additions & 0 deletions drivers/infiniband/hw/ocrdma/ocrdma.h
Original file line number Diff line number Diff line change
@@ -324,6 +324,9 @@ struct ocrdma_ucontext {

struct list_head mm_head;
struct mutex mm_list_lock; /* protects list entries of mm type */
struct ocrdma_pd *cntxt_pd;
int pd_in_use;

struct {
u32 *va;
dma_addr_t pa;
5 changes: 3 additions & 2 deletions drivers/infiniband/hw/ocrdma/ocrdma_hw.c
Original file line number Diff line number Diff line change
@@ -1309,7 +1309,7 @@ static void ocrdma_unbind_eq(struct ocrdma_dev *dev, u16 eq_id)
}

int ocrdma_mbx_create_cq(struct ocrdma_dev *dev, struct ocrdma_cq *cq,
int entries, int dpp_cq)
int entries, int dpp_cq, u16 pd_id)
{
int status = -ENOMEM; int max_hw_cqe;
struct pci_dev *pdev = dev->nic_info.pdev;
@@ -1357,7 +1357,7 @@ int ocrdma_mbx_create_cq(struct ocrdma_dev *dev, struct ocrdma_cq *cq,
cmd->cmd.ev_cnt_flags = OCRDMA_CREATE_CQ_DEF_FLAGS;

cq->eqn = ocrdma_bind_eq(dev);
cmd->cmd.req.rsvd_version = OCRDMA_CREATE_CQ_VER2;
cmd->cmd.req.rsvd_version = OCRDMA_CREATE_CQ_VER3;
cqe_count = cq->len / cqe_size;
if (cqe_count > 1024) {
/* Set cnt to 3 to indicate more than 1024 cq entries */
@@ -1393,6 +1393,7 @@ int ocrdma_mbx_create_cq(struct ocrdma_dev *dev, struct ocrdma_cq *cq,
cq->phase_change = true;
}

cmd->cmd.pd_id = pd_id; /* valid only for v3 */
ocrdma_build_q_pages(&cmd->cmd.pa[0], hw_pages, cq->pa, page_size);
status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd);
if (status)
7 changes: 6 additions & 1 deletion drivers/infiniband/hw/ocrdma/ocrdma_hw.h
Original file line number Diff line number Diff line change
@@ -78,6 +78,11 @@ static inline void ocrdma_copy_le32_to_cpu(void *dst, void *src, u32 len)
#endif
}

static inline u64 ocrdma_get_db_addr(struct ocrdma_dev *dev, u32 pdid)
{
return dev->nic_info.unmapped_db + (pdid * dev->nic_info.db_page_size);
}

int ocrdma_init_hw(struct ocrdma_dev *);
void ocrdma_cleanup_hw(struct ocrdma_dev *);

@@ -100,7 +105,7 @@ int ocrdma_mbx_dealloc_lkey(struct ocrdma_dev *, int fmr, u32 lkey);
int ocrdma_reg_mr(struct ocrdma_dev *, struct ocrdma_hw_mr *hwmr,
u32 pd_id, int acc);
int ocrdma_mbx_create_cq(struct ocrdma_dev *, struct ocrdma_cq *,
int entries, int dpp_cq);
int entries, int dpp_cq, u16 pd_id);
int ocrdma_mbx_destroy_cq(struct ocrdma_dev *, struct ocrdma_cq *);

int ocrdma_mbx_create_qp(struct ocrdma_qp *, struct ib_qp_init_attr *attrs,
1 change: 1 addition & 0 deletions drivers/infiniband/hw/ocrdma/ocrdma_main.c
Original file line number Diff line number Diff line change
@@ -326,6 +326,7 @@ static int ocrdma_register_device(struct ocrdma_dev *dev)
dev->ibdev.req_notify_cq = ocrdma_arm_cq;

dev->ibdev.get_dma_mr = ocrdma_get_dma_mr;
dev->ibdev.reg_phys_mr = ocrdma_reg_kernel_mr;
dev->ibdev.dereg_mr = ocrdma_dereg_mr;
dev->ibdev.reg_user_mr = ocrdma_reg_user_mr;

4 changes: 3 additions & 1 deletion drivers/infiniband/hw/ocrdma/ocrdma_sli.h
Original file line number Diff line number Diff line change
@@ -547,6 +547,7 @@ enum {

enum {
OCRDMA_CREATE_CQ_VER2 = 2,
OCRDMA_CREATE_CQ_VER3 = 3,

OCRDMA_CREATE_CQ_PAGE_CNT_MASK = 0xFFFF,
OCRDMA_CREATE_CQ_PAGE_SIZE_SHIFT = 16,
@@ -580,7 +581,8 @@ struct ocrdma_create_cq_cmd {
u32 pgsz_pgcnt;
u32 ev_cnt_flags;
u32 eqn;
u32 cqe_count;
u16 cqe_count;
u16 pd_id;
u32 rsvd6;
struct ocrdma_pa pa[OCRDMA_CREATE_CQ_MAX_PAGES];
};
Loading

0 comments on commit cffce99

Please sign in to comment.