* Sasha Levin <[email protected]> wrote:
> @@ -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,
> };
The initialization here does not use any global state AFAICS so it
does not need the write lock, right?
>
> - return mmio_insert(&mmio_tree, mmio);
> + ret = mmio_insert(&mmio_tree, mmio);
> + br_write_unlock();
Shouldnt mmio_insert() thus have the write_lock()/unlock() sequence?
> 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;
Here we leak the write lock!
> 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;
> }
Yummie, scalability here we come! :-)
Thanks,
Ingo
--
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