Use brlock to protect mmio and ioport modules and make them update-safe. Signed-off-by: Sasha Levin <levinsasha928@xxxxxxxxx> --- tools/kvm/ioport.c | 10 +++++++++- tools/kvm/mmio.c | 17 +++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/tools/kvm/ioport.c b/tools/kvm/ioport.c index d0a1aa8..e00fb59 100644 --- a/tools/kvm/ioport.c +++ b/tools/kvm/ioport.c @@ -2,7 +2,7 @@ #include "kvm/kvm.h" #include "kvm/util.h" - +#include "kvm/brlock.h" #include "kvm/rbtree-interval.h" #include "kvm/mutex.h" @@ -84,6 +84,7 @@ u16 ioport__register(u16 port, struct ioport_operations *ops, int count, void *p { struct ioport *entry; + br_write_lock(); if (port == IOPORT_EMPTY) port = ioport__find_free_port(); @@ -105,6 +106,8 @@ u16 ioport__register(u16 port, struct ioport_operations *ops, int count, void *p ioport_insert(&ioport_tree, entry); + br_write_unlock(); + return port; } @@ -127,6 +130,7 @@ bool kvm__emulate_io(struct kvm *kvm, u16 port, void *data, int direction, int s bool ret = false; struct ioport *entry; + br_read_lock(); entry = ioport_search(&ioport_tree, port); if (!entry) goto error; @@ -141,11 +145,15 @@ bool kvm__emulate_io(struct kvm *kvm, u16 port, void *data, int direction, int s ret = ops->io_out(entry, kvm, port, data, size, count); } + br_read_unlock(); + if (!ret) goto error; return true; error: + br_read_unlock(); + if (ioport_debug) ioport_error(port, data, direction, size, count); diff --git a/tools/kvm/mmio.c b/tools/kvm/mmio.c index ef986bf..a57abeb 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/brlock.h" #include <stdio.h> #include <stdlib.h> @@ -55,41 +56,53 @@ 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; + br_write_lock(); *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); + br_write_unlock(); + + return ret; } bool kvm__deregister_mmio(u64 phys_addr) { struct mmio_mapping *mmio; + br_write_lock(); mmio = mmio_search_single(&mmio_tree, phys_addr); if (mmio == NULL) return false; rb_int_erase(&mmio_tree, &mmio->node); + br_write_unlock(); + free(mmio); 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; + + br_read_lock(); + mmio = mmio_search(&mmio_tree, phys_addr, len); if (mmio) mmio->kvm_mmio_callback_fn(phys_addr, data, len, is_write); else fprintf(stderr, "Warning: Ignoring MMIO %s at %016llx (length %u)\n", to_direction(is_write), phys_addr, len); + br_read_unlock(); return true; } -- 1.7.5.rc3 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html