smc: switch to usage of IB_PD_UNSAFE_GLOBAL_RKEY
authorUrsula Braun <ubraun@linux.vnet.ibm.com>
Mon, 15 May 2017 15:33:37 +0000 (17:33 +0200)
committerDavid S. Miller <davem@davemloft.net>
Tue, 16 May 2017 18:49:42 +0000 (14:49 -0400)
Currently, SMC enables remote access to physical memory when a user
has successfully configured and established an SMC-connection until ten
minutes after the last SMC connection is closed. Because this is considered
a security risk, drivers are supposed to use IB_PD_UNSAFE_GLOBAL_RKEY in
such a case.

This patch changes the current SMC code to use IB_PD_UNSAFE_GLOBAL_RKEY.
This improves user awareness, but does not remove the security risk itself.

Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/smc/smc_clc.c
net/smc/smc_core.c
net/smc/smc_core.h
net/smc/smc_ib.c
net/smc/smc_ib.h

index e41f594a1e1d0c3d47706e4c80f9de587f953c9b..03ec058d18df642ef7e219000a62e51bc6c0e6fe 100644 (file)
@@ -204,7 +204,7 @@ int smc_clc_send_confirm(struct smc_sock *smc)
        memcpy(&cclc.lcl.mac, &link->smcibdev->mac[link->ibport - 1], ETH_ALEN);
        hton24(cclc.qpn, link->roce_qp->qp_num);
        cclc.rmb_rkey =
-               htonl(conn->rmb_desc->mr_rx[SMC_SINGLE_LINK]->rkey);
+               htonl(conn->rmb_desc->rkey[SMC_SINGLE_LINK]);
        cclc.conn_idx = 1; /* for now: 1 RMB = 1 RMBE */
        cclc.rmbe_alert_token = htonl(conn->alert_token_local);
        cclc.qp_mtu = min(link->path_mtu, link->peer_mtu);
@@ -256,7 +256,7 @@ int smc_clc_send_accept(struct smc_sock *new_smc, int srv_first_contact)
        memcpy(&aclc.lcl.mac, link->smcibdev->mac[link->ibport - 1], ETH_ALEN);
        hton24(aclc.qpn, link->roce_qp->qp_num);
        aclc.rmb_rkey =
-               htonl(conn->rmb_desc->mr_rx[SMC_SINGLE_LINK]->rkey);
+               htonl(conn->rmb_desc->rkey[SMC_SINGLE_LINK]);
        aclc.conn_idx = 1;                      /* as long as 1 RMB = 1 RMBE */
        aclc.rmbe_alert_token = htonl(conn->alert_token_local);
        aclc.qp_mtu = link->path_mtu;
index 65020e93ff210bb7f5db079399984c55e54c80f1..3ac09a629ea1a4c38c6bc21d996a69611c1633b7 100644 (file)
@@ -613,19 +613,8 @@ int smc_rmb_create(struct smc_sock *smc)
                        rmb_desc = NULL;
                        continue; /* if mapping failed, try smaller one */
                }
-               rc = smc_ib_get_memory_region(lgr->lnk[SMC_SINGLE_LINK].roce_pd,
-                                             IB_ACCESS_REMOTE_WRITE |
-                                             IB_ACCESS_LOCAL_WRITE,
-                                            &rmb_desc->mr_rx[SMC_SINGLE_LINK]);
-               if (rc) {
-                       smc_ib_buf_unmap(lgr->lnk[SMC_SINGLE_LINK].smcibdev,
-                                        tmp_bufsize, rmb_desc,
-                                        DMA_FROM_DEVICE);
-                       kfree(rmb_desc->cpu_addr);
-                       kfree(rmb_desc);
-                       rmb_desc = NULL;
-                       continue;
-               }
+               rmb_desc->rkey[SMC_SINGLE_LINK] =
+                       lgr->lnk[SMC_SINGLE_LINK].roce_pd->unsafe_global_rkey;
                rmb_desc->used = 1;
                write_lock_bh(&lgr->rmbs_lock);
                list_add(&rmb_desc->list,
@@ -668,6 +657,7 @@ int smc_rmb_rtoken_handling(struct smc_connection *conn,
 
        for (i = 0; i < SMC_RMBS_PER_LGR_MAX; i++) {
                if ((lgr->rtokens[i][SMC_SINGLE_LINK].rkey == rkey) &&
+                   (lgr->rtokens[i][SMC_SINGLE_LINK].dma_addr == dma_addr) &&
                    test_bit(i, lgr->rtokens_used_mask)) {
                        conn->rtoken_idx = i;
                        return 0;
index 27eb38056a27fb07e3ce72afbacaffaf4ae55f73..b013cb43a327ea81cd8bc9e4a5ffff733f87f6a7 100644 (file)
@@ -93,7 +93,7 @@ struct smc_buf_desc {
        u64                     dma_addr[SMC_LINKS_PER_LGR_MAX];
                                                /* mapped address of buffer */
        void                    *cpu_addr;      /* virtual address of buffer */
-       struct ib_mr            *mr_rx[SMC_LINKS_PER_LGR_MAX];
+       u32                     rkey[SMC_LINKS_PER_LGR_MAX];
                                                /* for rmb only:
                                                 * rkey provided to peer
                                                 */
index cb69ab977cd73963fef1fe27b1407e58a6e7cadd..b31715505a358cd4e73d1af6c58a49ef7ef8ecbe 100644 (file)
@@ -37,24 +37,6 @@ u8 local_systemid[SMC_SYSTEMID_LEN] = SMC_LOCAL_SYSTEMID_RESET;      /* unique system
                                                                 * identifier
                                                                 */
 
-int smc_ib_get_memory_region(struct ib_pd *pd, int access_flags,
-                            struct ib_mr **mr)
-{
-       int rc;
-
-       if (*mr)
-               return 0; /* already done */
-
-       /* obtain unique key -
-        * next invocation of get_dma_mr returns a different key!
-        */
-       *mr = pd->device->get_dma_mr(pd, access_flags);
-       rc = PTR_ERR_OR_ZERO(*mr);
-       if (IS_ERR(*mr))
-               *mr = NULL;
-       return rc;
-}
-
 static int smc_ib_modify_qp_init(struct smc_link *lnk)
 {
        struct ib_qp_attr qp_attr;
@@ -210,7 +192,8 @@ int smc_ib_create_protection_domain(struct smc_link *lnk)
 {
        int rc;
 
-       lnk->roce_pd = ib_alloc_pd(lnk->smcibdev->ibdev, 0);
+       lnk->roce_pd = ib_alloc_pd(lnk->smcibdev->ibdev,
+                                  IB_PD_UNSAFE_GLOBAL_RKEY);
        rc = PTR_ERR_OR_ZERO(lnk->roce_pd);
        if (IS_ERR(lnk->roce_pd))
                lnk->roce_pd = NULL;
index 7e1f0e24d17790f526aa50d07ff5e5d6596b6f3c..b567152a526d48c86110a9574833e8610684af4b 100644 (file)
@@ -61,8 +61,6 @@ void smc_ib_dealloc_protection_domain(struct smc_link *lnk);
 int smc_ib_create_protection_domain(struct smc_link *lnk);
 void smc_ib_destroy_queue_pair(struct smc_link *lnk);
 int smc_ib_create_queue_pair(struct smc_link *lnk);
-int smc_ib_get_memory_region(struct ib_pd *pd, int access_flags,
-                            struct ib_mr **mr);
 int smc_ib_ready_link(struct smc_link *lnk);
 int smc_ib_modify_qp_rts(struct smc_link *lnk);
 int smc_ib_modify_qp_reset(struct smc_link *lnk);