aboutsummaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2022-10-13 14:59:04 -0400
committerStefan Hajnoczi <stefanha@redhat.com>2022-10-26 14:56:42 -0400
commit7f9241d805b4711a4f7dc5489df0e7e30b8c1496 (patch)
treeb55d8bd8bcda24191e0119e5393b917445f59dfe /block
parent4fdd0a1a7ea174c5ee573e49c11f7d3bce00984d (diff)
downloadqemu-7f9241d805b4711a4f7dc5489df0e7e30b8c1496.zip
qemu-7f9241d805b4711a4f7dc5489df0e7e30b8c1496.tar.gz
qemu-7f9241d805b4711a4f7dc5489df0e7e30b8c1496.tar.bz2
block: add BlockRAMRegistrar
Emulated devices and other BlockBackend users wishing to take advantage of blk_register_buf() all have the same repetitive job: register RAMBlocks with the BlockBackend using RAMBlockNotifier. Add a BlockRAMRegistrar API to do this. A later commit will use this from hw/block/virtio-blk.c. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com> Message-id: 20221013185908.1297568-10-stefanha@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'block')
-rw-r--r--block/block-ram-registrar.c58
-rw-r--r--block/meson.build1
2 files changed, 59 insertions, 0 deletions
diff --git a/block/block-ram-registrar.c b/block/block-ram-registrar.c
new file mode 100644
index 0000000..25dbafa
--- /dev/null
+++ b/block/block-ram-registrar.c
@@ -0,0 +1,58 @@
+/*
+ * BlockBackend RAM Registrar
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "sysemu/block-backend.h"
+#include "sysemu/block-ram-registrar.h"
+#include "qapi/error.h"
+
+static void ram_block_added(RAMBlockNotifier *n, void *host, size_t size,
+ size_t max_size)
+{
+ BlockRAMRegistrar *r = container_of(n, BlockRAMRegistrar, notifier);
+ Error *err = NULL;
+
+ if (!r->ok) {
+ return; /* don't try again if we've already failed */
+ }
+
+ if (!blk_register_buf(r->blk, host, max_size, &err)) {
+ error_report_err(err);
+ ram_block_notifier_remove(&r->notifier);
+ r->ok = false;
+ }
+}
+
+static void ram_block_removed(RAMBlockNotifier *n, void *host, size_t size,
+ size_t max_size)
+{
+ BlockRAMRegistrar *r = container_of(n, BlockRAMRegistrar, notifier);
+ blk_unregister_buf(r->blk, host, max_size);
+}
+
+void blk_ram_registrar_init(BlockRAMRegistrar *r, BlockBackend *blk)
+{
+ r->blk = blk;
+ r->notifier = (RAMBlockNotifier){
+ .ram_block_added = ram_block_added,
+ .ram_block_removed = ram_block_removed,
+
+ /*
+ * .ram_block_resized() is not necessary because we use the max_size
+ * value that does not change across resize.
+ */
+ };
+ r->ok = true;
+
+ ram_block_notifier_add(&r->notifier);
+}
+
+void blk_ram_registrar_destroy(BlockRAMRegistrar *r)
+{
+ if (r->ok) {
+ ram_block_notifier_remove(&r->notifier);
+ }
+}
diff --git a/block/meson.build b/block/meson.build
index 500878f..b7c68b8 100644
--- a/block/meson.build
+++ b/block/meson.build
@@ -46,6 +46,7 @@ block_ss.add(files(
), zstd, zlib, gnutls)
softmmu_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c'))
+softmmu_ss.add(files('block-ram-registrar.c'))
if get_option('qcow1').allowed()
block_ss.add(files('qcow.c'))