Skip to content

Commit

Permalink
util: vfio-helpers: Factor out and fix processing of existing ram blocks
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
davidhildenbrand authored and dagrh committed May 13, 2021
1 parent 372043f commit 082851a
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 21 deletions.
14 changes: 14 additions & 0 deletions hw/core/numa.c
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions include/exec/cpu-common.h
Expand Up @@ -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);
Expand Down
5 changes: 5 additions & 0 deletions softmmu/physmem.c
Expand Up @@ -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;
Expand Down
29 changes: 8 additions & 21 deletions util/vfio-helpers.c
Expand Up @@ -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,
Expand All @@ -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);
}

/**
Expand Down

0 comments on commit 082851a

Please sign in to comment.