On Wed, 01/10 16:52, Stefan Hajnoczi wrote: > On Wed, Jan 10, 2018 at 05:18:39PM +0800, Fam Zheng wrote: > > +/* Map [host, host + size) area into a contiguous IOVA address space, and > > store > > + * the result in @iova if not NULL. The caller need to make sure the area > > is > > + * aligned to page size, and mustn't overlap with existing mapping areas > > (split > > + * mapping status within this area is not allowed). > > + */ > > +int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size, > > + bool temporary, uint64_t *iova) > > +{ > > + int ret = 0; > > + int index; > > + IOVAMapping *mapping; > > + uint64_t iova0; > > + > > + assert(QEMU_PTR_IS_ALIGNED(host, getpagesize())); > > + assert(QEMU_IS_ALIGNED(size, getpagesize())); > > + trace_qemu_vfio_dma_map(s, host, size, temporary, iova); > > + qemu_mutex_lock(&s->lock); > > + mapping = qemu_vfio_find_mapping(s, host, &index); > > + if (mapping) { > > + iova0 = mapping->iova + ((uint8_t *)host - (uint8_t > > *)mapping->host); > > + } else { > > + if (s->high_water_mark - s->low_water_mark + 1 < size) { > > + ret = -ENOMEM; > > + goto out; > > + } > > + if (!temporary) { > > + iova0 = s->low_water_mark; > > + mapping = qemu_vfio_add_mapping(s, host, size, index + 1, > > iova0); > > + if (!mapping) { > > + ret = -ENOMEM; > > + goto out; > > + } > > + assert(qemu_vfio_verify_mappings(s)); > > + ret = qemu_vfio_do_mapping(s, host, size, iova0); > > + if (ret) { > > + qemu_vfio_undo_mapping(s, mapping, NULL); > > + goto out; > > + } > > + s->low_water_mark += size; > > + qemu_vfio_dump_mappings(s); > > + } else { > > + iova0 = s->high_water_mark - size; > > + ret = qemu_vfio_do_mapping(s, host, size, iova0); > > + if (ret) { > > + goto out; > > + } > > + s->high_water_mark -= size; > > + } > > + } > > + if (iova) { > > + *iova = iova0; > > + } > > + qemu_mutex_unlock(&s->lock); > > +out: > > Unlock needs to be here to avoid leaking the lock.
Yes, will fix. Fam