Make MMIO code thread-safe.

Signed-off-by: Sasha Levin <levinsasha...@gmail.com>
---
 tools/kvm/mmio.c |   24 +++++++++++++++++++++---
 1 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/tools/kvm/mmio.c b/tools/kvm/mmio.c
index ef986bf..59512c3 100644
--- a/tools/kvm/mmio.c
+++ b/tools/kvm/mmio.c
@@ -1,5 +1,6 @@
 #include "kvm/kvm.h"
 #include "kvm/rbtree-interval.h"
+#include "kvm/rwsem.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -15,6 +16,7 @@ struct mmio_mapping {
 };
 
 static struct rb_root mmio_tree = RB_ROOT;
+static DECLARE_RWSEM(mmio_tree_sem);
 
 static struct mmio_mapping *mmio_search(struct rb_root *root, u64 addr, u64 
len)
 {
@@ -55,35 +57,51 @@ static const char *to_direction(u8 is_write)
 bool kvm__register_mmio(u64 phys_addr, u64 phys_addr_len, void 
(*kvm_mmio_callback_fn)(u64 addr, u8 *data, u32 len, u8 is_write))
 {
        struct mmio_mapping *mmio;
+       int ret;
 
        mmio = malloc(sizeof(*mmio));
        if (mmio == NULL)
                return false;
 
+       down_write(&mmio_tree_sem);
+
        *mmio = (struct mmio_mapping) {
                .node = RB_INT_INIT(phys_addr, phys_addr + phys_addr_len),
                .kvm_mmio_callback_fn = kvm_mmio_callback_fn,
        };
 
-       return mmio_insert(&mmio_tree, mmio);
+       ret = mmio_insert(&mmio_tree, mmio);
+       
+       up_write(&mmio_tree_sem);
+
+       return ret;
 }
 
 bool kvm__deregister_mmio(u64 phys_addr)
 {
        struct mmio_mapping *mmio;
 
+       down_write(&mmio_tree_sem);
        mmio = mmio_search_single(&mmio_tree, phys_addr);
-       if (mmio == NULL)
+       if (mmio == NULL) {
+               up_write(&mmio_tree_sem);
                return false;
+       }
 
        rb_int_erase(&mmio_tree, &mmio->node);
        free(mmio);
+       up_write(&mmio_tree_sem);
+       
        return true;
 }
 
 bool kvm__emulate_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len, u8 
is_write)
 {
-       struct mmio_mapping *mmio = mmio_search(&mmio_tree, phys_addr, len);
+       struct mmio_mapping *mmio;
+
+       down_read(&mmio_tree_sem);
+       mmio = mmio_search(&mmio_tree, phys_addr, len);
+       up_read(&mmio_tree_sem);
 
        if (mmio)
                mmio->kvm_mmio_callback_fn(phys_addr, data, len, is_write);
-- 
1.7.5.rc3

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to