From mboxrd@z Thu Jan 1 00:00:00 1970 From: Sasha Levin Subject: [PATCH 5/6] kvm tools: Protect MMIO tree by rwsem Date: Thu, 26 May 2011 17:25:49 +0300 Message-ID: <1306419950-19064-5-git-send-email-levinsasha928@gmail.com> References: <1306419950-19064-1-git-send-email-levinsasha928@gmail.com> Cc: john@jfloren.net, kvm@vger.kernel.org, mingo@elte.hu, asias.hejun@gmail.com, gorcunov@gmail.com, prasadjoshi124@gmail.com, Sasha Levin To: penberg@kernel.org Return-path: Received: from mail-ww0-f44.google.com ([74.125.82.44]:62634 "EHLO mail-ww0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932563Ab1EZO0O (ORCPT ); Thu, 26 May 2011 10:26:14 -0400 Received: by mail-ww0-f44.google.com with SMTP id 36so831594wwa.1 for ; Thu, 26 May 2011 07:26:14 -0700 (PDT) In-Reply-To: <1306419950-19064-1-git-send-email-levinsasha928@gmail.com> Sender: kvm-owner@vger.kernel.org List-ID: Make MMIO code thread-safe. Signed-off-by: Sasha Levin --- 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 #include @@ -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