[PATCH 5/6] kvm tools: Protect MMIO tree by rwsem

Sasha Levin
2011-05-26T14:26:14Z

Make MMIO code thread-safe.

Signed-off-by: Sasha Levin <levinsasha928@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