util: vfio-helpers: Factor out and fix processing of existing ram blocks

Factor it out into common code when a new notifier is registered, just
as done with the memory region notifier. This keeps logic about how to
process existing ram blocks at a central place.

Just like when adding a new ram block, we have to register the max_length.
Ram blocks are only "fake resized". All memory (max_length) is mapped.

Print the warning from inside qemu_vfio_ram_block_added().

Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20210429112708.12291-2-david@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
This commit is contained in:
David Hildenbrand 2021-04-29 13:26:59 +02:00 committed by Dr. David Alan Gilbert
parent 372043f389
commit 082851a3af
4 changed files with 28 additions and 21 deletions

View File

@ -802,9 +802,23 @@ void query_numa_node_mem(NumaNodeMem node_mem[], MachineState *ms)
}
}
static int ram_block_notify_add_single(RAMBlock *rb, void *opaque)
{
const ram_addr_t max_size = qemu_ram_get_max_length(rb);
void *host = qemu_ram_get_host_addr(rb);
RAMBlockNotifier *notifier = opaque;
if (host) {
notifier->ram_block_added(notifier, host, max_size);
}
return 0;
}
void ram_block_notifier_add(RAMBlockNotifier *n)
{
QLIST_INSERT_HEAD(&ram_list.ramblock_notifiers, n, next);
/* Notify about all existing ram blocks. */
qemu_ram_foreach_block(ram_block_notify_add_single, n);
}
void ram_block_notifier_remove(RAMBlockNotifier *n)

View File

@ -57,6 +57,7 @@ const char *qemu_ram_get_idstr(RAMBlock *rb);
void *qemu_ram_get_host_addr(RAMBlock *rb);
ram_addr_t qemu_ram_get_offset(RAMBlock *rb);
ram_addr_t qemu_ram_get_used_length(RAMBlock *rb);
ram_addr_t qemu_ram_get_max_length(RAMBlock *rb);
bool qemu_ram_is_shared(RAMBlock *rb);
bool qemu_ram_is_uf_zeroable(RAMBlock *rb);
void qemu_ram_set_uf_zeroable(RAMBlock *rb);

View File

@ -1694,6 +1694,11 @@ ram_addr_t qemu_ram_get_used_length(RAMBlock *rb)
return rb->used_length;
}
ram_addr_t qemu_ram_get_max_length(RAMBlock *rb)
{
return rb->max_length;
}
bool qemu_ram_is_shared(RAMBlock *rb)
{
return rb->flags & RAM_SHARED;

View File

@ -463,8 +463,14 @@ static void qemu_vfio_ram_block_added(RAMBlockNotifier *n,
void *host, size_t size)
{
QEMUVFIOState *s = container_of(n, QEMUVFIOState, ram_notifier);
int ret;
trace_qemu_vfio_ram_block_added(s, host, size);
qemu_vfio_dma_map(s, host, size, false, NULL);
ret = qemu_vfio_dma_map(s, host, size, false, NULL);
if (ret) {
error_report("qemu_vfio_dma_map(%p, %zu) failed: %s", host, size,
strerror(-ret));
}
}
static void qemu_vfio_ram_block_removed(RAMBlockNotifier *n,
@ -477,33 +483,14 @@ static void qemu_vfio_ram_block_removed(RAMBlockNotifier *n,
}
}
static int qemu_vfio_init_ramblock(RAMBlock *rb, void *opaque)
{
void *host_addr = qemu_ram_get_host_addr(rb);
ram_addr_t length = qemu_ram_get_used_length(rb);
int ret;
QEMUVFIOState *s = opaque;
if (!host_addr) {
return 0;
}
ret = qemu_vfio_dma_map(s, host_addr, length, false, NULL);
if (ret) {
fprintf(stderr, "qemu_vfio_init_ramblock: failed %p %" PRId64 "\n",
host_addr, (uint64_t)length);
}
return 0;
}
static void qemu_vfio_open_common(QEMUVFIOState *s)
{
qemu_mutex_init(&s->lock);
s->ram_notifier.ram_block_added = qemu_vfio_ram_block_added;
s->ram_notifier.ram_block_removed = qemu_vfio_ram_block_removed;
ram_block_notifier_add(&s->ram_notifier);
s->low_water_mark = QEMU_VFIO_IOVA_MIN;
s->high_water_mark = QEMU_VFIO_IOVA_MAX;
qemu_ram_foreach_block(qemu_vfio_init_ramblock, s);
ram_block_notifier_add(&s->ram_notifier);
}
/**