Make MMIO code thread-safe.
Signed-off-by: Sasha Levin <[email protected]>
---
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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html