76daa3
From cecb1f8cba3d5e15f6f16e7156dfc4e5bbfd36c0 Mon Sep 17 00:00:00 2001
76daa3
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
76daa3
Date: Thu, 27 Jul 2017 12:06:58 +0200
76daa3
Subject: [PATCH 10/17] migration/rdma: Safely convert control types
76daa3
76daa3
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
76daa3
Message-id: <20170727120659.8640-5-dgilbert@redhat.com>
76daa3
Patchwork-id: 75860
76daa3
O-Subject: [Pegas-1.0 qemu-kvm PATCH 4/5] migration/rdma: Safely convert control types
76daa3
Bugzilla: 1475751
76daa3
RH-Acked-by: Peter Xu <peterx@redhat.com>
76daa3
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
76daa3
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
76daa3
76daa3
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
76daa3
76daa3
control_desc[] is an array of strings that correspond to a
76daa3
series of message types; they're used only for error messages, but if
76daa3
the message type is seriously broken then we could go off the end of
76daa3
the array.
76daa3
76daa3
Convert the array to a function control_desc() that bound checks.
76daa3
76daa3
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
76daa3
Reviewed-by: Peter Xu <peterx@redhat.com>
76daa3
Reviewed-by: Juan Quintela <quintela@redhat.com>
76daa3
Message-Id: <20170717110936.23314-6-dgilbert@redhat.com>
76daa3
Signed-off-by: Juan Quintela <quintela@redhat.com>
76daa3
(cherry picked from commit 482a33c53cbc9d2b0c47d4df03b659bf50258c21)
76daa3
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
76daa3
---
76daa3
 migration/rdma.c | 54 ++++++++++++++++++++++++++++++++----------------------
76daa3
 1 file changed, 32 insertions(+), 22 deletions(-)
76daa3
76daa3
diff --git a/migration/rdma.c b/migration/rdma.c
76daa3
index 666c84f..fa88ccf 100644
76daa3
--- a/migration/rdma.c
76daa3
+++ b/migration/rdma.c
76daa3
@@ -163,20 +163,6 @@ enum {
76daa3
     RDMA_CONTROL_UNREGISTER_FINISHED, /* unpinning finished */
76daa3
 };
76daa3
 
76daa3
-static const char *control_desc[] = {
76daa3
-    [RDMA_CONTROL_NONE] = "NONE",
76daa3
-    [RDMA_CONTROL_ERROR] = "ERROR",
76daa3
-    [RDMA_CONTROL_READY] = "READY",
76daa3
-    [RDMA_CONTROL_QEMU_FILE] = "QEMU FILE",
76daa3
-    [RDMA_CONTROL_RAM_BLOCKS_REQUEST] = "RAM BLOCKS REQUEST",
76daa3
-    [RDMA_CONTROL_RAM_BLOCKS_RESULT] = "RAM BLOCKS RESULT",
76daa3
-    [RDMA_CONTROL_COMPRESS] = "COMPRESS",
76daa3
-    [RDMA_CONTROL_REGISTER_REQUEST] = "REGISTER REQUEST",
76daa3
-    [RDMA_CONTROL_REGISTER_RESULT] = "REGISTER RESULT",
76daa3
-    [RDMA_CONTROL_REGISTER_FINISHED] = "REGISTER FINISHED",
76daa3
-    [RDMA_CONTROL_UNREGISTER_REQUEST] = "UNREGISTER REQUEST",
76daa3
-    [RDMA_CONTROL_UNREGISTER_FINISHED] = "UNREGISTER FINISHED",
76daa3
-};
76daa3
 
76daa3
 /*
76daa3
  * Memory and MR structures used to represent an IB Send/Recv work request.
76daa3
@@ -249,6 +235,30 @@ typedef struct QEMU_PACKED RDMADestBlock {
76daa3
     uint32_t padding;
76daa3
 } RDMADestBlock;
76daa3
 
76daa3
+static const char *control_desc(unsigned int rdma_control)
76daa3
+{
76daa3
+    static const char *strs[] = {
76daa3
+        [RDMA_CONTROL_NONE] = "NONE",
76daa3
+        [RDMA_CONTROL_ERROR] = "ERROR",
76daa3
+        [RDMA_CONTROL_READY] = "READY",
76daa3
+        [RDMA_CONTROL_QEMU_FILE] = "QEMU FILE",
76daa3
+        [RDMA_CONTROL_RAM_BLOCKS_REQUEST] = "RAM BLOCKS REQUEST",
76daa3
+        [RDMA_CONTROL_RAM_BLOCKS_RESULT] = "RAM BLOCKS RESULT",
76daa3
+        [RDMA_CONTROL_COMPRESS] = "COMPRESS",
76daa3
+        [RDMA_CONTROL_REGISTER_REQUEST] = "REGISTER REQUEST",
76daa3
+        [RDMA_CONTROL_REGISTER_RESULT] = "REGISTER RESULT",
76daa3
+        [RDMA_CONTROL_REGISTER_FINISHED] = "REGISTER FINISHED",
76daa3
+        [RDMA_CONTROL_UNREGISTER_REQUEST] = "UNREGISTER REQUEST",
76daa3
+        [RDMA_CONTROL_UNREGISTER_FINISHED] = "UNREGISTER FINISHED",
76daa3
+    };
76daa3
+
76daa3
+    if (rdma_control > RDMA_CONTROL_UNREGISTER_FINISHED) {
76daa3
+        return "??BAD CONTROL VALUE??";
76daa3
+    }
76daa3
+
76daa3
+    return strs[rdma_control];
76daa3
+}
76daa3
+
76daa3
 static uint64_t htonll(uint64_t v)
76daa3
 {
76daa3
     union { uint32_t lv[2]; uint64_t llv; } u;
76daa3
@@ -1639,7 +1649,7 @@ static int qemu_rdma_post_send_control(RDMAContext *rdma, uint8_t *buf,
76daa3
                                    .num_sge = 1,
76daa3
                                 };
76daa3
 
76daa3
-    trace_qemu_rdma_post_send_control(control_desc[head->type]);
76daa3
+    trace_qemu_rdma_post_send_control(control_desc(head->type));
76daa3
 
76daa3
     /*
76daa3
      * We don't actually need to do a memcpy() in here if we used
76daa3
@@ -1718,16 +1728,16 @@ static int qemu_rdma_exchange_get_response(RDMAContext *rdma,
76daa3
     network_to_control((void *) rdma->wr_data[idx].control);
76daa3
     memcpy(head, rdma->wr_data[idx].control, sizeof(RDMAControlHeader));
76daa3
 
76daa3
-    trace_qemu_rdma_exchange_get_response_start(control_desc[expecting]);
76daa3
+    trace_qemu_rdma_exchange_get_response_start(control_desc(expecting));
76daa3
 
76daa3
     if (expecting == RDMA_CONTROL_NONE) {
76daa3
-        trace_qemu_rdma_exchange_get_response_none(control_desc[head->type],
76daa3
+        trace_qemu_rdma_exchange_get_response_none(control_desc(head->type),
76daa3
                                              head->type);
76daa3
     } else if (head->type != expecting || head->type == RDMA_CONTROL_ERROR) {
76daa3
         error_report("Was expecting a %s (%d) control message"
76daa3
                 ", but got: %s (%d), length: %d",
76daa3
-                control_desc[expecting], expecting,
76daa3
-                control_desc[head->type], head->type, head->len);
76daa3
+                control_desc(expecting), expecting,
76daa3
+                control_desc(head->type), head->type, head->len);
76daa3
         if (head->type == RDMA_CONTROL_ERROR) {
76daa3
             rdma->received_error = true;
76daa3
         }
76daa3
@@ -1837,7 +1847,7 @@ static int qemu_rdma_exchange_send(RDMAContext *rdma, RDMAControlHeader *head,
76daa3
             }
76daa3
         }
76daa3
 
76daa3
-        trace_qemu_rdma_exchange_send_waiting(control_desc[resp->type]);
76daa3
+        trace_qemu_rdma_exchange_send_waiting(control_desc(resp->type));
76daa3
         ret = qemu_rdma_exchange_get_response(rdma, resp,
76daa3
                                               resp->type, RDMA_WRID_DATA);
76daa3
 
76daa3
@@ -1849,7 +1859,7 @@ static int qemu_rdma_exchange_send(RDMAContext *rdma, RDMAControlHeader *head,
76daa3
         if (resp_idx) {
76daa3
             *resp_idx = RDMA_WRID_DATA;
76daa3
         }
76daa3
-        trace_qemu_rdma_exchange_send_received(control_desc[resp->type]);
76daa3
+        trace_qemu_rdma_exchange_send_received(control_desc(resp->type));
76daa3
     }
76daa3
 
76daa3
     rdma->control_ready_expected = 1;
76daa3
@@ -3399,7 +3409,7 @@ static int qemu_rdma_registration_handle(QEMUFile *f, void *opaque)
76daa3
             ret = -EIO;
76daa3
             goto out;
76daa3
         default:
76daa3
-            error_report("Unknown control message %s", control_desc[head.type]);
76daa3
+            error_report("Unknown control message %s", control_desc(head.type));
76daa3
             ret = -EIO;
76daa3
             goto out;
76daa3
         }
76daa3
-- 
76daa3
1.8.3.1
76daa3