Re: [PATCH v3 00/14] macOS PV Graphics and new vmapple machine type

2024-10-03 Thread Alex Bennée
Phil Dennis-Jordan  writes:

> (Apologies to anyone who has received more than one version of this
> series of emails; my git-send-email was misconfigured and this is
> a new attempt.)
>
> This patch set introduces a new ARM and macOS HVF specific machine type
> called "vmapple", as well as a family of display devices based on the
> ParavirtualizedGraphics.framework in macOS. One of the display adapter
> variants, apple-gfx-vmapple, is required for the new machine type, while
> apple-gfx-pci can be used to enable 3D graphics acceleration with x86-64
> macOS guest OSes.
>

>
> There are currently a few limitations to this which aren't intrinsic,
> just imperfect emulation of the VZF, but it's good enough to be just
> about usable for some purposes:
>
>  * macOS 12 guests only. Versions 13+ currently fail during early boot.
>  * macOS 11+ arm64 hosts only, with hvf accel. (Perhaps some differences
>between Apple M series CPUs and TCG's aarch64 implementation? macOS
>hosts only because ParavirtualizedGraphics.framework is a black box
>implementing most of the logic behind the apple-gfx device.)

We don't currently have TCG CPU models for the Apple Silicon processors.
They are not too hard to add (basically setting the correct ID register
bits, c.f. aarch64_neoverse_n1_initfn for an example). However that
would only cover Aarch64 architectural features. We do no modelling of
the extra instructions that Apple added (although in theory that should
only be run in Apples own ML libraries).


-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH v3 10/22] hw/sdhci: fix -Werror=maybe-uninitialized false-positive

2024-09-30 Thread Alex Bennée
marcandre.lur...@redhat.com writes:

> From: Marc-André Lureau 
>
> ../hw/sd/sdhci.c:846:16: error: ‘res’ may be used uninitialized 
> [-Werror=maybe-uninitialized]
>
> False-positive, because "length" is non-null.

I certainly get that:

  length = dscr.length ? dscr.length : 64 * KiB;

means we always have something. Although get_adma_description() is
deserving of a g_assert_not_reached() lest we end up re-using a previous
descr.

I guess wider re-factoring is out of scope for this series though:

Reviewed-by: Alex Bennée 

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH v3] virtio: Implement Virtio Backend for SD/MMC in QEMU

2024-07-03 Thread Alex Bennée
Mikhail Krasheninnikov  writes:

> From: Mi 
>
> Add a Virtio backend for SD/MMC devices. Confirmed interoperability with
> Linux.
>
> Linux patch link:
> https://lore.kernel.org/linux-mmc/20240701120642.30001-1-krashmi...@gmail.com/

Is there a corresponding patch to the VirtIO specification?

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH 4/4] python: enable testing for 3.13

2024-07-03 Thread Alex Bennée
John Snow  writes:

> Python 3.13 is in beta and Fedora 41 is preparing to make it the default
> system interpreter; enable testing for it.
>
> (In the event problems develop prior to release, it should only impact
> the check-python-tox job, which is not run by default and is allowed to
> fail.)
>
> Signed-off-by: John Snow 

Reviewed-by: Alex Bennée 
Tested-by: Alex Bennée 

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH 2/4] python: Do not use pylint 3.2.4 with python 3.8

2024-07-03 Thread Alex Bennée
John Snow  writes:

> There is a bug in this version,
> see: https://github.com/pylint-dev/pylint/issues/9751
>
> Signed-off-by: John Snow 

Reviewed-by: Alex Bennée 

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH 1/4] python: linter changes for pylint 3.x

2024-07-03 Thread Alex Bennée
John Snow  writes:

> New bleeding edge versions, new nits to iron out. This addresses the
> 'check-python-tox' optional GitLab test, while 'check-python-minreqs'
> saw no regressions, since it's frozen on an older version of pylint.
>
> Fixes:
> qemu/machine/machine.py:345:52: E0606: Possibly using variable 'sock' before 
> assignment (possibly-used-before-assignment)
> qemu/utils/qemu_ga_client.py:168:4: R1711: Useless return at end of function 
> or method (useless-return)
>
> Signed-off-by: John Snow 

Reviewed-by: Alex Bennée 

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PULL 10/38] tests/qtest/migration: Add a test for the analyze-migration script

2024-05-22 Thread Alex Bennée
Fabiano Rosas  writes:

> Alex Bennée  writes:
>
>> Juan Quintela  writes:
>>
>>> From: Fabiano Rosas 
>>>
>>> Add a smoke test that migrates to a file and gives it to the
>>> script. It should catch the most annoying errors such as changes in
>>> the ram flags.
>>>
>>> After code has been merged it becomes way harder to figure out what is
>>> causing the script to fail, the person making the change is the most
>>> likely to know right away what the problem is.
>>>
>>> Signed-off-by: Fabiano Rosas 
>>> Acked-by: Thomas Huth 
>>> Reviewed-by: Juan Quintela 
>>> Signed-off-by: Juan Quintela 
>>> Message-ID: <20231009184326.15777-7-faro...@suse.de>
>>
>> I bisected the failures I'm seeing on s390x to the introduction of this
>> script. I don't know if its simply a timeout on a relatively slow VM:
>
> What's the range of your bisect? That test has been disabled and then
> reenabled on s390x. It could be tripping the bisect.
>
> 04131e0009 ("tests/qtest/migration-test: Disable the analyze-migration.py 
> test on s390x")
> 81c2c9dd5d ("tests/qtest/migration-test: Fix analyze-migration.py for
> s390x")

I ran between v8.1.0 and master.

But it is still failing @ HEAD 01782d6b294f95bcde334386f0aaac593cd28c0d
as you can see from the run I did at the end.

>
> I don't think that test itself could be timing out. It's a very simple
> test. It runs a migration and then uses the output to validate the
> script.
>
> I don't have a Z machine at hand and the migration tests only run with
> KVM for s390x, so it would be useful to take a look at meson's
> testlog.txt so we can see which test is failing and hopefully in what
> way it is failing.
>
> If you're up for it, running this in a loop is usually the best way to
> catch any intermittent issues:
>
> QTEST_QEMU_BINARY=./qemu-system-x86_64 ./tests/qtest/migration-test
>
> And once you figure out which test, there's this monstrosity:
>
> QTEST_QEMU_BINARY='gdb -q --ex "set pagination off"  \
>   --ex "set print thread-events off" \
>   --ex "handle SIGUSR1 noprint"  \
>   --ex "handle SIGPIPE noprint"  \
>   --ex "run" --ex "quit \$_exitcode" \
>   --args ./qemu-system-x86_64'   \
>   gdb -q --ex "set prompt (qtest) "  \
>   --ex "handle SIGPIPE noprint"  \
>   --args ./tests/qtest/migration-test -p 
> /x86_64/migration//
>
>> Summary of Failures:
>>
>>  36/546 qemu:qtest+qtest-s390x / qtest-s390x/migration-test  
>>  ERROR  93.51s   killed by signal 6 SIGABRT
>>
>> It seems to be unstable as we pass sometimes:
>>
>> 11:26:42 [ajb@qemu01:~/l/q/b/system] master|… + ./pyvenv/bin/meson test 
>> --repeat 100 qtest-s390x/migration-test
>> ninja: Entering directory `/home/ajb/lsrc/qemu.git/builds/system'
>> [1/9] Generating qemu-version.h with a custom command (wrapped by meson to 
>> capture output)
>>   1/100 qemu:qtest+qtest-s390x / qtest-s390x/migration-test  ERROR   
>>251.98s   killed by signal 6 SIGABRT
>>>>> MALLOC_PERTURB_=9
>>>>> PYTHON=/home/ajb/lsrc/qemu.git/builds/system/pyvenv/bin/python3
>>>>> G_TEST_DBUS_DAEMON=/home/ajb/lsrc/qemu.git/tests/dbus-vmstate-daemon.sh
>>>>> QTEST_QEMU_BINARY=./qemu-system-s390x QTEST_QEMU_IMG=./qemu-img
>>>>> QTEST_QEMU_STORAGE_DAEMON_BINARY=./storage-daemon/qemu-storage-daemon
>>>>> /home/ajb/lsrc/qemu.git/builds/system/tests/qtest/migration-test
>>>>> --tap -k
>>
>>   2/100 qemu:qtest+qtest-s390x / qtest-s390x/migration-test  ERROR   
>>258.71s   killed by signal 6 SIGABRT
>>>>> PYTHON=/home/ajb/lsrc/qemu.git/builds/system/pyvenv/bin/python3
>>>>> MALLOC_PERTURB_=205
>>>>> G_TEST_DBUS_DAEMON=/home/ajb/lsrc/qemu.git/tests/dbus-vmstate-daemon.sh
>>>>> QTEST_QEMU_BINARY=./qemu-system-s390x QTEST_QEMU_IMG=./qemu-img
>>>>> QTEST_QEMU_STORAGE_DAEMON_BINARY=./storage-daemon/qemu-storage-daemon
>>>>> /home/ajb/lsrc/qemu.git/builds/system/tests/qtest/migration-test
>>>>> --tap -k
>>
>>   3/100 qemu:qtest+qtest-s390x / qtest-s390x/migration-test  OK  
>>302.53s   46 subtests passed
>

Re: [PULL 10/38] tests/qtest/migration: Add a test for the analyze-migration script

2024-05-21 Thread Alex Bennée
> +
> +migrate_ensure_converge(from);
> +migrate_qmp(from, uri, "{}");
> +wait_for_migration_complete(from);
> +
> +pid = fork();
> +if (!pid) {
> +close(1);
> +open("/dev/null", O_WRONLY);
> +execl(python, python, ANALYZE_SCRIPT, "-f", file, NULL);
> +g_assert_not_reached();
> +}
> +
> +g_assert(waitpid(pid, &wstatus, 0) == pid);
> +if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) != 0) {
> +g_test_message("Failed to analyze the migration stream");
> +g_test_fail();
> +}
> +test_migrate_end(from, to, false);
> +cleanup("migfile");
> +}
> +#endif
> +
>  static void test_precopy_common(MigrateCommon *args)
>  {
>  QTestState *from, *to;
> @@ -2837,6 +2894,9 @@ int main(int argc, char **argv)
>  }
>  
>  qtest_add_func("/migration/bad_dest", test_baddest);
> +#ifndef _WIN32
> +qtest_add_func("/migration/analyze-script", test_analyze_script);
> +#endif
>  qtest_add_func("/migration/precopy/unix/plain", test_precopy_unix_plain);
>  qtest_add_func("/migration/precopy/unix/xbzrle", 
> test_precopy_unix_xbzrle);
>  /*
> diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
> index 66795cfcd2..d6022ebd64 100644
> --- a/tests/qtest/meson.build
> +++ b/tests/qtest/meson.build
> @@ -357,6 +357,8 @@ foreach dir : target_dirs
>  test_deps += [qsd]
>endif
>  
> +  qtest_env.set('PYTHON', python.full_path())
> +
>foreach test : target_qtests
>  # Executables are shared across targets, declare them only the first 
> time we
>  # encounter them

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH v3 6/6] hw/xen: convert stderr prints to error/warn reports

2024-01-30 Thread Alex Bennée
Manos Pitsidianakis  writes:

> According to the QEMU Coding Style document:
>
>> Do not use printf(), fprintf() or monitor_printf(). Instead, use
>> error_report() or error_vreport() from error-report.h. This ensures the
>> error is reported in the right place (current monitor or stderr), and in
>> a uniform format.
>> Use error_printf() & friends to print additional information.
>
> This commit changes fprintfs that report warnings and errors to the
> appropriate report functions.
>
> Reviewed-by: Philippe Mathieu-Daudé 
> Signed-off-by: Manos Pitsidianakis 

Reviewed-by: Alex Bennée 

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH v3 5/6] hw/xen/xen-hvm-common.c: convert DPRINTF to tracepoints

2024-01-30 Thread Alex Bennée
Manos Pitsidianakis  writes:

> Tracing DPRINTFs to stderr might not be desired. A developer that relies
> on tracepoints should be able to opt-in to each tracepoint and rely on
> QEMU's log redirection, instead of stderr by default.
>
> This commit converts DPRINTFs in this file that are used for tracing
> into tracepoints.
>
> Signed-off-by: Manos Pitsidianakis 

Reviewed-by: Alex Bennée 

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH v3 4/6] hw/xen/xen-mapcache.c: convert DPRINTF to tracepoints

2024-01-30 Thread Alex Bennée
Manos Pitsidianakis  writes:

> Tracing DPRINTFs to stderr might not be desired. A developer that relies
> on tracepoints should be able to opt-in to each tracepoint and rely on
> QEMU's log redirection, instead of stderr by default.
>
> This commit converts DPRINTFs in this file that are used for tracing
> into tracepoints.
>
> Signed-off-by: Manos Pitsidianakis 

Reviewed-by: Alex Bennée 

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH v3 3/6] hw/arm/xen_arm.c: convert DPRINTF to trace events and error/warn reports

2024-01-30 Thread Alex Bennée
Manos Pitsidianakis  writes:

> Tracing DPRINTFs to stderr might not be desired. A developer that relies
> on trace events should be able to opt-in to each trace event and rely on
> QEMU's log redirection, instead of stderr by default.
>
> This commit converts DPRINTFs in this file that are used for tracing
> into trace events. Errors or warnings are converted to error_report and
> warn_report calls.
>
> Signed-off-by: Manos Pitsidianakis 

Reviewed-by: Alex Bennée 

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH v3 2/6] hw/arm/z2: convert DPRINTF to trace events and guest errors

2024-01-30 Thread Alex Bennée
Manos Pitsidianakis  writes:

> Tracing DPRINTFs to stderr might not be desired. A developer that relies
> on trace events should be able to opt-in to each trace event and rely on
> QEMU's log redirection, instead of stderr by default.
>
> This commit converts DPRINTFs in this file that are used for tracing
> into trace events. DPRINTFs that report guest errors are logged with
> LOG_GUEST_ERROR.
>
> Signed-off-by: Manos Pitsidianakis 

Reviewed-by: Alex Bennée 

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH v3 1/6] hw/arm/strongarm.c: convert DPRINTF to trace events and guest errors

2024-01-29 Thread Alex Bennée
Manos Pitsidianakis  writes:

> Tracing DPRINTFs to stderr might not be desired. A developer that relies
> on trace events should be able to opt-in to each trace event and rely on
> QEMU's log redirection, instead of stderr by default.
>
> This commit converts DPRINTFs in this file that are used for tracing
> into trace events. DPRINTFs that report guest errors are logged with
> LOG_GUEST_ERROR.#
>
> Signed-off-by: Manos Pitsidianakis 

Reviewed-by: Alex Bennée 

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PULL 33/36] hw/elf_ops: Ignore loadable segments with zero size

2024-01-24 Thread Alex Bennée
t; -g_autofree char *label =
> -g_strdup_printf("%s ELF program header segment %d",
> -name, i);
> +if (load_rom) {
> +g_autofree char *label =
> +g_strdup_printf("%s ELF program header segment %d",
> +name, i);
>  
> -/*
> - * rom_add_elf_program() takes its own reference to
> - * 'mapped_file'.
> - */
> -rom_add_elf_program(label, mapped_file, data, file_size,
> -mem_size, addr, as);
> -} else {
> -MemTxResult res;
> +/*
> + * rom_add_elf_program() takes its own reference to
> + * 'mapped_file'.
> + */
> +rom_add_elf_program(label, mapped_file, data, file_size,
> +mem_size, addr, as);
> +} else {
> +MemTxResult res;
>  
> -res = address_space_write(as ? as : 
> &address_space_memory,
> -  addr, MEMTXATTRS_UNSPECIFIED,
> -  data, file_size);
> +res = address_space_write(as ? as : &address_space_memory,
> +  addr, MEMTXATTRS_UNSPECIFIED,
> +  data, file_size);
> +if (res != MEMTX_OK) {
> +goto fail;
> +}
> +/*
> + * We need to zero'ify the space that is not copied
> + * from file
> + */
> +if (file_size < mem_size) {
> +res = address_space_set(as ? as : &address_space_memory,
> +addr + file_size, 0,
> +mem_size - file_size,
> +MEMTXATTRS_UNSPECIFIED);
>  if (res != MEMTX_OK) {
>  goto fail;
>  }
> -/*
> - * We need to zero'ify the space that is not copied
> - * from file
> - */
> -if (file_size < mem_size) {
> -    res = address_space_set(as ? as : 
> &address_space_memory,
> -addr + file_size, 0,
> -mem_size - file_size,
> -MEMTXATTRS_UNSPECIFIED);
> -if (res != MEMTX_OK) {
> -goto fail;
> -}
> -}
>  }
>  }

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH v9 00/11] virtio: cleanup vhost-user-generic and reduce c&p + vhost-user-input

2024-01-10 Thread Alex Bennée
Alex Bennée  writes:

> A lot of our vhost-user stubs are large chunks of boilerplate that do
> (mostly) the same thing. This series continues the cleanups by
> splitting the vhost-user-base and vhost-user-generic implementations.
> After adding a new vq_size property the rng, gpio and i2c vhost-user
> devices become simple specialisations of the common base defining the
> ID, number of queues and potentially the config handling.
>
> I've also added Manos' vhost-user-sound and Leo's vhost-user-input
> stubs which are based on the same base.

Ping MST,

Are you waiting for anything else before pulling this into your queue?

>
> Changes
> ---
>
> v9
>   - re-base and fix conflicts
>   - add Leo's vhost-user-input series
>
> v8
>   - scrubbed errant Message-Id
>
> v7
>   - various review comments
>   - move to async teardown (fixes CI failure)
>
> v6
>   - re-base to current master
>   - make vhost-user-device abstract
>   - mention abstractness in docs
>
> v5
>   - addressing comments and tags
>   - improved the docs
>
> v4
>   - dropped the F_TRANSPORT work for another series
>   - added vhost-user-sound
>
> Alex Bennée (6):
>   virtio: split into vhost-user-base and vhost-user-device
>   hw/virtio: convert vhost-user-base to async shutdown
>   hw/virtio: derive vhost-user-rng from vhost-user-base
>   hw/virtio: derive vhost-user-gpio from vhost-user-base
>   hw/virtio: derive vhost-user-i2c from vhost-user-base
>   docs/system: add a basic enumeration of vhost-user devices
>
> Leo Yan (4):
>   hw/virtio: Support set_config() callback in vhost-user-base
>   docs/system: Add vhost-user-input documentation
>   hw/virtio: Move vhost-user-input into virtio folder
>   hw/virtio: derive vhost-user-input from vhost-user-base
>
> Manos Pitsidianakis (1):
>   hw/virtio: add vhost-user-snd and virtio-snd-pci devices
>
>  MAINTAINERS   |  16 +-
>  docs/system/device-emulation.rst  |   1 +
>  docs/system/devices/vhost-user-input.rst  |  45 ++
>  docs/system/devices/vhost-user-rng.rst|   2 +
>  docs/system/devices/vhost-user.rst|  72 +++-
>  ...{vhost-user-device.h => vhost-user-base.h} |  21 +-
>  include/hw/virtio/vhost-user-gpio.h   |  25 +-
>  include/hw/virtio/vhost-user-i2c.h|  14 +-
>  include/hw/virtio/vhost-user-rng.h|  13 +-
>  include/hw/virtio/vhost-user-snd.h|  24 ++
>  include/hw/virtio/virtio-input.h  |   6 +-
>  hw/input/vhost-user-input.c   | 136 --
>  hw/virtio/vhost-user-base.c   | 371 
>  hw/virtio/vhost-user-device-pci.c |  13 +-
>  hw/virtio/vhost-user-device.c | 338 +--
>  hw/virtio/vhost-user-gpio.c   | 407 +-
>  hw/virtio/vhost-user-i2c.c| 272 +---
>  hw/virtio/vhost-user-input-pci.c  |   3 -
>  hw/virtio/vhost-user-input.c  |  58 +++
>  hw/virtio/vhost-user-rng.c| 294 +
>  hw/virtio/vhost-user-snd-pci.c|  75 
>  hw/virtio/vhost-user-snd.c|  67 +++
>  hw/input/meson.build  |   1 -
>  hw/virtio/Kconfig |   5 +
>  hw/virtio/meson.build |  27 +-
>  25 files changed, 850 insertions(+), 1456 deletions(-)
>  create mode 100644 docs/system/devices/vhost-user-input.rst
>  rename include/hw/virtio/{vhost-user-device.h => vhost-user-base.h} (71%)
>  create mode 100644 include/hw/virtio/vhost-user-snd.h
>  delete mode 100644 hw/input/vhost-user-input.c
>  create mode 100644 hw/virtio/vhost-user-base.c
>  create mode 100644 hw/virtio/vhost-user-input.c
>  create mode 100644 hw/virtio/vhost-user-snd-pci.c
>  create mode 100644 hw/virtio/vhost-user-snd.c

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH v9 01/11] virtio: split into vhost-user-base and vhost-user-device

2024-01-05 Thread Alex Bennée
Philippe Mathieu-Daudé  writes:

> On 4/1/24 22:09, Alex Bennée wrote:
>> Lets keep a cleaner split between the base class and the derived
>> vhost-user-device which we can use for generic vhost-user stubs. This
>> includes an update to introduce the vq_size property so the number of
>> entries in a virtq can be defined.
>> Signed-off-by: Alex Bennée 
>> ---
>> v5
>>- s/parent/parent_obj/
>>- remove left over vhost-user-device.h
>>- use DEFINE_TYPES
>> v6
>>- rebase and set .abstract = true for vhost-user-device
>> v7
>>- checkpatch line length + MAINTAINERS
>>- s/abstract = true/dc->user_creatable = false/ for both mmio and pci
>> ---
>>   MAINTAINERS   |   6 +
>>   ...{vhost-user-device.h => vhost-user-base.h} |  21 +-
>>   hw/virtio/vhost-user-base.c   | 346 ++
>>   hw/virtio/vhost-user-device-pci.c |  13 +-
>>   hw/virtio/vhost-user-device.c | 338 +
>>   hw/virtio/meson.build |   1 +
>>   6 files changed, 383 insertions(+), 342 deletions(-)
>>   rename include/hw/virtio/{vhost-user-device.h => vhost-user-base.h} (71%)
>>   create mode 100644 hw/virtio/vhost-user-base.c
>
>
>> @@ -358,6 +42,9 @@ static void vud_class_init(ObjectClass *klass, void *data)
>>   {
>>   DeviceClass *dc = DEVICE_CLASS(klass);
>>   +/* Reason: stop inexperienced users confusing themselves */
>> +dc->user_creatable = false;
>
>
> What about making VHOST_USER_DEVICE_PCI and
> TYPE_VHOST_USER_DEVICE TypeInfos abstract instead?

I had in a previous iteration (v7) but AIUI abstract really means
something different - the device can be instantiated but we just want to
stop the user from creating it arbitrarily.

>
>> +
>>   device_class_set_props(dc, vud_properties);
>>   dc->vmsd = &vud_vmstate;
>>   set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
>> @@ -366,14 +53,11 @@ static void vud_class_init(ObjectClass *klass, void 
>> *data)
>>   static const TypeInfo vud_info = {
>>   .name = TYPE_VHOST_USER_DEVICE,
>>   .parent = TYPE_VHOST_USER_BASE,
>> -.instance_size = sizeof(VHostUserBase),
>>   .class_init = vud_class_init,
>> -.class_size = sizeof(VHostUserBaseClass),
>>   };

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



[PATCH v9 01/11] virtio: split into vhost-user-base and vhost-user-device

2024-01-04 Thread Alex Bennée
Lets keep a cleaner split between the base class and the derived
vhost-user-device which we can use for generic vhost-user stubs. This
includes an update to introduce the vq_size property so the number of
entries in a virtq can be defined.

Signed-off-by: Alex Bennée 

---
v5
  - s/parent/parent_obj/
  - remove left over vhost-user-device.h
  - use DEFINE_TYPES
v6
  - rebase and set .abstract = true for vhost-user-device
v7
  - checkpatch line length + MAINTAINERS
  - s/abstract = true/dc->user_creatable = false/ for both mmio and pci
---
 MAINTAINERS   |   6 +
 ...{vhost-user-device.h => vhost-user-base.h} |  21 +-
 hw/virtio/vhost-user-base.c   | 346 ++
 hw/virtio/vhost-user-device-pci.c |  13 +-
 hw/virtio/vhost-user-device.c | 338 +
 hw/virtio/meson.build |   1 +
 6 files changed, 383 insertions(+), 342 deletions(-)
 rename include/hw/virtio/{vhost-user-device.h => vhost-user-base.h} (71%)
 create mode 100644 hw/virtio/vhost-user-base.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 395f26ba861..0e832fd5d13 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2304,6 +2304,12 @@ F: include/sysemu/rng*.h
 F: backends/rng*.c
 F: tests/qtest/virtio-rng-test.c
 
+vhost-user-stubs
+M: Alex Bennée 
+S: Maintained
+F: hw/virtio/vhost-user-base.c
+F: hw/virtio/vhost-user-device*
+
 vhost-user-rng
 M: Mathieu Poirier 
 S: Supported
diff --git a/include/hw/virtio/vhost-user-device.h 
b/include/hw/virtio/vhost-user-base.h
similarity index 71%
rename from include/hw/virtio/vhost-user-device.h
rename to include/hw/virtio/vhost-user-base.h
index 3ddf88a146a..51d0968b893 100644
--- a/include/hw/virtio/vhost-user-device.h
+++ b/include/hw/virtio/vhost-user-base.h
@@ -6,8 +6,8 @@
  * SPDX-License-Identifier: GPL-2.0-or-later
  */
 
-#ifndef QEMU_VHOST_USER_DEVICE_H
-#define QEMU_VHOST_USER_DEVICE_H
+#ifndef QEMU_VHOST_USER_BASE_H
+#define QEMU_VHOST_USER_BASE_H
 
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
@@ -17,11 +17,13 @@
 OBJECT_DECLARE_TYPE(VHostUserBase, VHostUserBaseClass, VHOST_USER_BASE)
 
 struct VHostUserBase {
-VirtIODevice parent;
+VirtIODevice parent_obj;
+
 /* Properties */
 CharBackend chardev;
 uint16_t virtio_id;
 uint32_t num_vqs;
+uint32_t vq_size; /* can't exceed VIRTIO_QUEUE_MAX */
 uint32_t config_size;
 /* State tracking */
 VhostUserState vhost_user;
@@ -31,16 +33,17 @@ struct VHostUserBase {
 bool connected;
 };
 
-/* needed so we can use the base realize after specialisation
-   tweaks */
+/*
+ * Needed so we can use the base realize after specialisation
+ * tweaks
+ */
 struct VHostUserBaseClass {
-/*< private >*/
 VirtioDeviceClass parent_class;
-/*< public >*/
+
 DeviceRealize parent_realize;
 };
 
-/* shared for the benefit of the derived pci class */
+
 #define TYPE_VHOST_USER_DEVICE "vhost-user-device"
 
-#endif /* QEMU_VHOST_USER_DEVICE_H */
+#endif /* QEMU_VHOST_USER_BASE_H */
diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c
new file mode 100644
index 000..620fa5cb4a4
--- /dev/null
+++ b/hw/virtio/vhost-user-base.c
@@ -0,0 +1,346 @@
+/*
+ * Base vhost-user-base implementation. This can be used to derive a
+ * more fully specified vhost-user backend either generically (see
+ * vhost-user-device) or via a specific stub for a device which
+ * encapsulates some fixed parameters.
+ *
+ * Copyright (c) 2023 Linaro Ltd
+ * Author: Alex Bennée 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/qdev-properties.h"
+#include "hw/virtio/virtio-bus.h"
+#include "hw/virtio/vhost-user-base.h"
+#include "qemu/error-report.h"
+
+static void vub_start(VirtIODevice *vdev)
+{
+BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
+VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+VHostUserBase *vub = VHOST_USER_BASE(vdev);
+int ret, i;
+
+if (!k->set_guest_notifiers) {
+error_report("binding does not support guest notifiers");
+return;
+}
+
+ret = vhost_dev_enable_notifiers(&vub->vhost_dev, vdev);
+if (ret < 0) {
+error_report("Error enabling host notifiers: %d", -ret);
+return;
+}
+
+ret = k->set_guest_notifiers(qbus->parent, vub->vhost_dev.nvqs, true);
+if (ret < 0) {
+error_report("Error binding guest notifier: %d", -ret);
+goto err_host_notifiers;
+}
+
+vub->vhost_dev.acked_features = vdev->guest_features;
+
+ret = vhost_dev_start(&vub->vhost_dev, vdev, true);
+if (ret < 0) {
+error_report("Error starting vhost-user-base: %d", -ret);
+goto err_guest_notifiers;
+}
+

[PATCH v9 11/11] hw/virtio: derive vhost-user-input from vhost-user-base

2024-01-04 Thread Alex Bennée
From: Leo Yan 

This patch derives vhost-user-input from vhost-user-base class, so make
the input stub as a simpler boilerplate wrapper.

With the refactoring, vhost-user-input adds the property 'chardev', this
leads to conflict with the vhost-user-input-pci adds the same property.
To resolve the error, remove the duplicate property from
vhost-user-input-pci.

Signed-off-by: Leo Yan 
Reviewed-by: Manos Pitsidianakis 
Message-Id: <20231120043721.50555-5-leo@linaro.org>
Signed-off-by: Alex Bennée 
---
 include/hw/virtio/virtio-input.h |   6 +-
 hw/virtio/vhost-user-input-pci.c |   3 -
 hw/virtio/vhost-user-input.c | 114 +--
 3 files changed, 21 insertions(+), 102 deletions(-)

diff --git a/include/hw/virtio/virtio-input.h b/include/hw/virtio/virtio-input.h
index a6c97036440..e69c0aeca38 100644
--- a/include/hw/virtio/virtio-input.h
+++ b/include/hw/virtio/virtio-input.h
@@ -1,6 +1,8 @@
 #ifndef QEMU_VIRTIO_INPUT_H
 #define QEMU_VIRTIO_INPUT_H
 
+#include "hw/virtio/vhost-user.h"
+#include "hw/virtio/vhost-user-base.h"
 #include "ui/input.h"
 #include "sysemu/vhost-user-backend.h"
 
@@ -97,9 +99,7 @@ struct VirtIOInputHost {
 };
 
 struct VHostUserInput {
-VirtIOInput   parent_obj;
-
-VhostUserBackend  *vhost;
+VHostUserBase parent_obj;
 };
 
 void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event);
diff --git a/hw/virtio/vhost-user-input-pci.c b/hw/virtio/vhost-user-input-pci.c
index b858898a363..3f4761ce88a 100644
--- a/hw/virtio/vhost-user-input-pci.c
+++ b/hw/virtio/vhost-user-input-pci.c
@@ -30,9 +30,6 @@ static void vhost_user_input_pci_instance_init(Object *obj)
 
 virtio_instance_init_common(obj, &dev->vhi, sizeof(dev->vhi),
 TYPE_VHOST_USER_INPUT);
-
-object_property_add_alias(obj, "chardev",
-  OBJECT(&dev->vhi), "chardev");
 }
 
 static const VirtioPCIDeviceTypeInfo vhost_user_input_pci_info = {
diff --git a/hw/virtio/vhost-user-input.c b/hw/virtio/vhost-user-input.c
index 4ee3542106e..bedec0468c3 100644
--- a/hw/virtio/vhost-user-input.c
+++ b/hw/virtio/vhost-user-input.c
@@ -5,83 +5,25 @@
  */
 
 #include "qemu/osdep.h"
-#include "qemu/error-report.h"
-#include "qapi/error.h"
-
 #include "hw/virtio/virtio-input.h"
 
-static int vhost_input_config_change(struct vhost_dev *dev)
-{
-error_report("vhost-user-input: unhandled backend config change");
-return -1;
-}
-
-static const VhostDevConfigOps config_ops = {
-.vhost_dev_config_notifier = vhost_input_config_change,
+static Property vinput_properties[] = {
+DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
+DEFINE_PROP_END_OF_LIST(),
 };
 
-static void vhost_input_realize(DeviceState *dev, Error **errp)
-{
-VHostUserInput *vhi = VHOST_USER_INPUT(dev);
-VirtIOInput *vinput = VIRTIO_INPUT(dev);
-VirtIODevice *vdev = VIRTIO_DEVICE(dev);
-
-vhost_dev_set_config_notifier(&vhi->vhost->dev, &config_ops);
-vinput->cfg_size = sizeof_field(virtio_input_config, u);
-if (vhost_user_backend_dev_init(vhi->vhost, vdev, 2, errp) == -1) {
-return;
-}
-}
-
-static void vhost_input_change_active(VirtIOInput *vinput)
-{
-VHostUserInput *vhi = VHOST_USER_INPUT(vinput);
-
-if (vinput->active) {
-vhost_user_backend_start(vhi->vhost);
-} else {
-vhost_user_backend_stop(vhi->vhost);
-}
-}
-
-static void vhost_input_get_config(VirtIODevice *vdev, uint8_t *config_data)
-{
-VirtIOInput *vinput = VIRTIO_INPUT(vdev);
-VHostUserInput *vhi = VHOST_USER_INPUT(vdev);
-Error *local_err = NULL;
-int ret;
-
-memset(config_data, 0, vinput->cfg_size);
-
-ret = vhost_dev_get_config(&vhi->vhost->dev, config_data, vinput->cfg_size,
-   &local_err);
-if (ret) {
-error_report_err(local_err);
-return;
-}
-}
-
-static void vhost_input_set_config(VirtIODevice *vdev,
-   const uint8_t *config_data)
+static void vinput_realize(DeviceState *dev, Error **errp)
 {
-VHostUserInput *vhi = VHOST_USER_INPUT(vdev);
-int ret;
+VHostUserBase *vub = VHOST_USER_BASE(dev);
+VHostUserBaseClass *vubc = VHOST_USER_BASE_GET_CLASS(dev);
 
-ret = vhost_dev_set_config(&vhi->vhost->dev, config_data,
-   0, sizeof(virtio_input_config),
-   VHOST_SET_CONFIG_TYPE_FRONTEND);
-if (ret) {
-error_report("vhost-user-input: set device config space failed");
-return;
-}
+/* Fixed for input device */
+vub->virtio_id = VIRTIO_ID_INPUT;
+vub->num_vqs = 2;
+vub->vq_size = 4;
+vub->config_size = sizeof(virtio_input_co

[PATCH v9 08/11] hw/virtio: Support set_config() callback in vhost-user-base

2024-01-04 Thread Alex Bennée
From: Leo Yan 

The Virtio input device invokes set_config() callback for retrieving
the event configuration info, but the callback is not supported in
vhost-user-base.

This patch adds support set_config() callback in vhost-user-base.

Signed-off-by: Leo Yan 
Reviewed-by: Marc-André Lureau 
Message-Id: <20231120043721.50555-2-leo@linaro.org>
Signed-off-by: Alex Bennée 
---
 hw/virtio/vhost-user-base.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c
index 78cfa9a5bbc..a83167191ee 100644
--- a/hw/virtio/vhost-user-base.c
+++ b/hw/virtio/vhost-user-base.c
@@ -140,6 +140,22 @@ static void vub_get_config(VirtIODevice *vdev, uint8_t 
*config)
 }
 }
 
+static void vub_set_config(VirtIODevice *vdev, const uint8_t *config_data)
+{
+VHostUserBase *vub = VHOST_USER_BASE(vdev);
+int ret;
+
+g_assert(vub->config_size && vub->vhost_user.supports_config == true);
+
+ret = vhost_dev_set_config(&vub->vhost_dev, config_data,
+   0, vub->config_size,
+   VHOST_SET_CONFIG_TYPE_FRONTEND);
+if (ret) {
+error_report("vhost guest set device config space failed: %d", ret);
+return;
+}
+}
+
 /*
  * When the daemon signals an update to the config we just need to
  * signal the guest as we re-read the config on demand above.
@@ -337,6 +353,7 @@ static void vub_class_init(ObjectClass *klass, void *data)
 vdc->unrealize = vub_device_unrealize;
 vdc->get_features = vub_get_features;
 vdc->get_config = vub_get_config;
+vdc->set_config = vub_set_config;
 vdc->set_status = vub_set_status;
 }
 
-- 
2.39.2




[PATCH v9 03/11] hw/virtio: derive vhost-user-rng from vhost-user-base

2024-01-04 Thread Alex Bennée
Now we can take advantage of our new base class and make
vhost-user-rng a much simpler boilerplate wrapper. Also as this
doesn't require any target specific hacks we only need to build the
stubs once.

Acked-by: Mark Cave-Ayland 
Signed-off-by: Alex Bennée 

---
v5
  - don't remove the in-QEMU RNG emulation!
v7
  - s/parent/parent_obj/
v8
  - fix merge conflict (idx == VIRTIO_CONFIG_IRQ_IDX not needed as
base doesn't use notifiers)
---
 include/hw/virtio/vhost-user-rng.h |  13 +-
 hw/virtio/vhost-user-rng.c | 294 +++--
 hw/virtio/meson.build  |   9 +-
 3 files changed, 31 insertions(+), 285 deletions(-)

diff --git a/include/hw/virtio/vhost-user-rng.h 
b/include/hw/virtio/vhost-user-rng.h
index ddd9f01eea6..10868c7de4d 100644
--- a/include/hw/virtio/vhost-user-rng.h
+++ b/include/hw/virtio/vhost-user-rng.h
@@ -12,22 +12,13 @@
 #include "hw/virtio/virtio.h"
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
-#include "chardev/char-fe.h"
+#include "hw/virtio/vhost-user-base.h"
 
 #define TYPE_VHOST_USER_RNG "vhost-user-rng"
 OBJECT_DECLARE_SIMPLE_TYPE(VHostUserRNG, VHOST_USER_RNG)
 
 struct VHostUserRNG {
-/*< private >*/
-VirtIODevice parent;
-CharBackend chardev;
-struct vhost_virtqueue *vhost_vq;
-struct vhost_dev vhost_dev;
-VhostUserState vhost_user;
-VirtQueue *req_vq;
-bool connected;
-
-/*< public >*/
+VHostUserBase parent_obj;
 };
 
 #endif /* QEMU_VHOST_USER_RNG_H */
diff --git a/hw/virtio/vhost-user-rng.c b/hw/virtio/vhost-user-rng.c
index 24ac1a22c83..01879c863df 100644
--- a/hw/virtio/vhost-user-rng.c
+++ b/hw/virtio/vhost-user-rng.c
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2021 Mathieu Poirier 
  *
- * Implementation seriously tailored on vhost-user-i2c.c
+ * Simple wrapper of the generic vhost-user-device.
  *
  * SPDX-License-Identifier: GPL-2.0-or-later
  */
@@ -13,297 +13,47 @@
 #include "hw/qdev-properties.h"
 #include "hw/virtio/virtio-bus.h"
 #include "hw/virtio/vhost-user-rng.h"
-#include "qemu/error-report.h"
 #include "standard-headers/linux/virtio_ids.h"
 
-static const int feature_bits[] = {
-VIRTIO_F_RING_RESET,
-VHOST_INVALID_FEATURE_BIT
-};
-
-static void vu_rng_start(VirtIODevice *vdev)
-{
-VHostUserRNG *rng = VHOST_USER_RNG(vdev);
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-int ret;
-int i;
-
-if (!k->set_guest_notifiers) {
-error_report("binding does not support guest notifiers");
-return;
-}
-
-ret = vhost_dev_enable_notifiers(&rng->vhost_dev, vdev);
-if (ret < 0) {
-error_report("Error enabling host notifiers: %d", -ret);
-return;
-}
-
-ret = k->set_guest_notifiers(qbus->parent, rng->vhost_dev.nvqs, true);
-if (ret < 0) {
-error_report("Error binding guest notifier: %d", -ret);
-goto err_host_notifiers;
-}
-
-rng->vhost_dev.acked_features = vdev->guest_features;
-ret = vhost_dev_start(&rng->vhost_dev, vdev, true);
-if (ret < 0) {
-error_report("Error starting vhost-user-rng: %d", -ret);
-goto err_guest_notifiers;
-}
-
-/*
- * guest_notifier_mask/pending not used yet, so just unmask
- * everything here. virtio-pci will do the right thing by
- * enabling/disabling irqfd.
- */
-for (i = 0; i < rng->vhost_dev.nvqs; i++) {
-vhost_virtqueue_mask(&rng->vhost_dev, vdev, i, false);
-}
-
-return;
-
-err_guest_notifiers:
-k->set_guest_notifiers(qbus->parent, rng->vhost_dev.nvqs, false);
-err_host_notifiers:
-vhost_dev_disable_notifiers(&rng->vhost_dev, vdev);
-}
-
-static void vu_rng_stop(VirtIODevice *vdev)
-{
-VHostUserRNG *rng = VHOST_USER_RNG(vdev);
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-int ret;
-
-if (!k->set_guest_notifiers) {
-return;
-}
-
-vhost_dev_stop(&rng->vhost_dev, vdev, true);
-
-ret = k->set_guest_notifiers(qbus->parent, rng->vhost_dev.nvqs, false);
-if (ret < 0) {
-error_report("vhost guest notifier cleanup failed: %d", ret);
-return;
-}
-
-vhost_dev_disable_notifiers(&rng->vhost_dev, vdev);
-}
-
-static void vu_rng_set_status(VirtIODevice *vdev, uint8_t status)
-{
-VHostUserRNG *rng = VHOST_USER_RNG(vdev);
-bool should_start = virtio_device_should_start(vdev, status);
-
-if (vhost_dev_is_started(&rng->vhost_dev) == should_start) {
-return;
-}
-
-if (should_start) {
-vu_rng_start(vdev);
-} else {
-vu_rng_stop(vdev);
-}
-}
-
-static uint64_t vu_rn

[PATCH v9 04/11] hw/virtio: derive vhost-user-gpio from vhost-user-base

2024-01-04 Thread Alex Bennée
Now the new base class supports config handling we can take advantage
and make vhost-user-gpio a much simpler boilerplate wrapper. Also as
this doesn't require any target specific hacks we only need to build
the stubs once.

Acked-by: Mark Cave-Ayland 
Acked-by: Viresh Kumar 
Signed-off-by: Alex Bennée 

---
v7
  - s/parent/parent_obj/
v8
  - fix merge conflicts
---
 include/hw/virtio/vhost-user-gpio.h |  25 +-
 hw/virtio/vhost-user-gpio.c | 407 ++--
 hw/virtio/meson.build   |   5 +-
 3 files changed, 22 insertions(+), 415 deletions(-)

diff --git a/include/hw/virtio/vhost-user-gpio.h 
b/include/hw/virtio/vhost-user-gpio.h
index a9d3f9b049f..5814a8400a0 100644
--- a/include/hw/virtio/vhost-user-gpio.h
+++ b/include/hw/virtio/vhost-user-gpio.h
@@ -12,34 +12,13 @@
 #include "hw/virtio/virtio.h"
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
-#include "standard-headers/linux/virtio_gpio.h"
-#include "chardev/char-fe.h"
+#include "hw/virtio/vhost-user-base.h"
 
 #define TYPE_VHOST_USER_GPIO "vhost-user-gpio-device"
 OBJECT_DECLARE_SIMPLE_TYPE(VHostUserGPIO, VHOST_USER_GPIO);
 
 struct VHostUserGPIO {
-/*< private >*/
-VirtIODevice parent_obj;
-CharBackend chardev;
-struct virtio_gpio_config config;
-struct vhost_virtqueue *vhost_vqs;
-struct vhost_dev vhost_dev;
-VhostUserState vhost_user;
-VirtQueue *command_vq;
-VirtQueue *interrupt_vq;
-/**
- * There are at least two steps of initialization of the
- * vhost-user device. The first is a "connect" step and
- * second is a "start" step. Make a separation between
- * those initialization phases by using two fields.
- *
- * @connected: see vu_gpio_connect()/vu_gpio_disconnect()
- * @started_vu: see vu_gpio_start()/vu_gpio_stop()
- */
-bool connected;
-bool started_vu;
-/*< public >*/
+VHostUserBase parent_obj;
 };
 
 #endif /* _QEMU_VHOST_USER_GPIO_H */
diff --git a/hw/virtio/vhost-user-gpio.c b/hw/virtio/vhost-user-gpio.c
index a83437a5da3..9f37c254159 100644
--- a/hw/virtio/vhost-user-gpio.c
+++ b/hw/virtio/vhost-user-gpio.c
@@ -11,388 +11,25 @@
 #include "hw/qdev-properties.h"
 #include "hw/virtio/virtio-bus.h"
 #include "hw/virtio/vhost-user-gpio.h"
-#include "qemu/error-report.h"
 #include "standard-headers/linux/virtio_ids.h"
-#include "trace.h"
+#include "standard-headers/linux/virtio_gpio.h"
 
-#define VHOST_NVQS 2
-
-/* Features required from VirtIO */
-static const int feature_bits[] = {
-VIRTIO_F_VERSION_1,
-VIRTIO_F_NOTIFY_ON_EMPTY,
-VIRTIO_RING_F_INDIRECT_DESC,
-VIRTIO_RING_F_EVENT_IDX,
-VIRTIO_GPIO_F_IRQ,
-VIRTIO_F_RING_RESET,
-VHOST_INVALID_FEATURE_BIT
+static Property vgpio_properties[] = {
+DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
+DEFINE_PROP_END_OF_LIST(),
 };
 
-static void vu_gpio_get_config(VirtIODevice *vdev, uint8_t *config)
+static void vgpio_realize(DeviceState *dev, Error **errp)
 {
-VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev);
+VHostUserBase *vub = VHOST_USER_BASE(dev);
+VHostUserBaseClass *vubc = VHOST_USER_BASE_GET_CLASS(dev);
 
-memcpy(config, &gpio->config, sizeof(gpio->config));
-}
+/* Fixed for GPIO */
+vub->virtio_id = VIRTIO_ID_GPIO;
+vub->num_vqs = 2;
+vub->config_size = sizeof(struct virtio_gpio_config);
 
-static int vu_gpio_config_notifier(struct vhost_dev *dev)
-{
-VHostUserGPIO *gpio = VHOST_USER_GPIO(dev->vdev);
-
-memcpy(dev->vdev->config, &gpio->config, sizeof(gpio->config));
-virtio_notify_config(dev->vdev);
-
-return 0;
-}
-
-const VhostDevConfigOps gpio_ops = {
-.vhost_dev_config_notifier = vu_gpio_config_notifier,
-};
-
-static int vu_gpio_start(VirtIODevice *vdev)
-{
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev);
-struct vhost_dev *vhost_dev = &gpio->vhost_dev;
-int ret, i;
-
-if (!k->set_guest_notifiers) {
-error_report("binding does not support guest notifiers");
-return -ENOSYS;
-}
-
-ret = vhost_dev_enable_notifiers(vhost_dev, vdev);
-if (ret < 0) {
-error_report("Error enabling host notifiers: %d", ret);
-return ret;
-}
-
-ret = k->set_guest_notifiers(qbus->parent, vhost_dev->nvqs, true);
-if (ret < 0) {
-error_report("Error binding guest notifier: %d", ret);
-goto err_host_notifiers;
-}
-
-/*
- * Before we start up we need to ensure we have the final feature
- * set needed for the vhost configuration. The backend may also
- * apply backend_features when the featur

[PATCH v9 00/11] virtio: cleanup vhost-user-generic and reduce c&p + vhost-user-input

2024-01-04 Thread Alex Bennée
A lot of our vhost-user stubs are large chunks of boilerplate that do
(mostly) the same thing. This series continues the cleanups by
splitting the vhost-user-base and vhost-user-generic implementations.
After adding a new vq_size property the rng, gpio and i2c vhost-user
devices become simple specialisations of the common base defining the
ID, number of queues and potentially the config handling.

I've also added Manos' vhost-user-sound and Leo's vhost-user-input
stubs which are based on the same base.

Changes
---

v9
  - re-base and fix conflicts
  - add Leo's vhost-user-input series

v8
  - scrubbed errant Message-Id

v7
  - various review comments
  - move to async teardown (fixes CI failure)

v6
  - re-base to current master
  - make vhost-user-device abstract
  - mention abstractness in docs

v5
  - addressing comments and tags
  - improved the docs

v4
  - dropped the F_TRANSPORT work for another series
  - added vhost-user-sound

Alex Bennée (6):
  virtio: split into vhost-user-base and vhost-user-device
  hw/virtio: convert vhost-user-base to async shutdown
  hw/virtio: derive vhost-user-rng from vhost-user-base
  hw/virtio: derive vhost-user-gpio from vhost-user-base
  hw/virtio: derive vhost-user-i2c from vhost-user-base
  docs/system: add a basic enumeration of vhost-user devices

Leo Yan (4):
  hw/virtio: Support set_config() callback in vhost-user-base
  docs/system: Add vhost-user-input documentation
  hw/virtio: Move vhost-user-input into virtio folder
  hw/virtio: derive vhost-user-input from vhost-user-base

Manos Pitsidianakis (1):
  hw/virtio: add vhost-user-snd and virtio-snd-pci devices

 MAINTAINERS   |  16 +-
 docs/system/device-emulation.rst  |   1 +
 docs/system/devices/vhost-user-input.rst  |  45 ++
 docs/system/devices/vhost-user-rng.rst|   2 +
 docs/system/devices/vhost-user.rst|  72 +++-
 ...{vhost-user-device.h => vhost-user-base.h} |  21 +-
 include/hw/virtio/vhost-user-gpio.h   |  25 +-
 include/hw/virtio/vhost-user-i2c.h|  14 +-
 include/hw/virtio/vhost-user-rng.h|  13 +-
 include/hw/virtio/vhost-user-snd.h|  24 ++
 include/hw/virtio/virtio-input.h  |   6 +-
 hw/input/vhost-user-input.c   | 136 --
 hw/virtio/vhost-user-base.c   | 371 
 hw/virtio/vhost-user-device-pci.c |  13 +-
 hw/virtio/vhost-user-device.c | 338 +--
 hw/virtio/vhost-user-gpio.c   | 407 +-
 hw/virtio/vhost-user-i2c.c| 272 +---
 hw/virtio/vhost-user-input-pci.c  |   3 -
 hw/virtio/vhost-user-input.c  |  58 +++
 hw/virtio/vhost-user-rng.c| 294 +
 hw/virtio/vhost-user-snd-pci.c|  75 
 hw/virtio/vhost-user-snd.c|  67 +++
 hw/input/meson.build  |   1 -
 hw/virtio/Kconfig |   5 +
 hw/virtio/meson.build |  27 +-
 25 files changed, 850 insertions(+), 1456 deletions(-)
 create mode 100644 docs/system/devices/vhost-user-input.rst
 rename include/hw/virtio/{vhost-user-device.h => vhost-user-base.h} (71%)
 create mode 100644 include/hw/virtio/vhost-user-snd.h
 delete mode 100644 hw/input/vhost-user-input.c
 create mode 100644 hw/virtio/vhost-user-base.c
 create mode 100644 hw/virtio/vhost-user-input.c
 create mode 100644 hw/virtio/vhost-user-snd-pci.c
 create mode 100644 hw/virtio/vhost-user-snd.c

-- 
2.39.2




[PATCH v9 05/11] hw/virtio: derive vhost-user-i2c from vhost-user-base

2024-01-04 Thread Alex Bennée
Now we can take advantage of the new base class and make
vhost-user-i2c a much simpler boilerplate wrapper. Also as this
doesn't require any target specific hacks we only need to build the
stubs once.

Acked-by: Mark Cave-Ayland 
Acked-by: Viresh Kumar 
Signed-off-by: Alex Bennée 

---
v7
  - s/parent/parent_obj/
---
 include/hw/virtio/vhost-user-i2c.h |  14 +-
 hw/virtio/vhost-user-i2c.c | 272 ++---
 hw/virtio/meson.build  |   5 +-
 3 files changed, 23 insertions(+), 268 deletions(-)

diff --git a/include/hw/virtio/vhost-user-i2c.h 
b/include/hw/virtio/vhost-user-i2c.h
index 0f7acd40e3a..a9b5612ad01 100644
--- a/include/hw/virtio/vhost-user-i2c.h
+++ b/include/hw/virtio/vhost-user-i2c.h
@@ -9,23 +9,17 @@
 #ifndef QEMU_VHOST_USER_I2C_H
 #define QEMU_VHOST_USER_I2C_H
 
+#include "hw/virtio/virtio.h"
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
+#include "hw/virtio/vhost-user-base.h"
 
 #define TYPE_VHOST_USER_I2C "vhost-user-i2c-device"
+
 OBJECT_DECLARE_SIMPLE_TYPE(VHostUserI2C, VHOST_USER_I2C)
 
 struct VHostUserI2C {
-VirtIODevice parent;
-CharBackend chardev;
-struct vhost_virtqueue *vhost_vq;
-struct vhost_dev vhost_dev;
-VhostUserState vhost_user;
-VirtQueue *vq;
-bool connected;
+VHostUserBase parent_obj;
 };
 
-/* Virtio Feature bits */
-#define VIRTIO_I2C_F_ZERO_LENGTH_REQUEST   0
-
 #endif /* QEMU_VHOST_USER_I2C_H */
diff --git a/hw/virtio/vhost-user-i2c.c b/hw/virtio/vhost-user-i2c.c
index 4eef3f06337..a464f5e0399 100644
--- a/hw/virtio/vhost-user-i2c.c
+++ b/hw/virtio/vhost-user-i2c.c
@@ -14,253 +14,22 @@
 #include "qemu/error-report.h"
 #include "standard-headers/linux/virtio_ids.h"
 
-static const int feature_bits[] = {
-VIRTIO_I2C_F_ZERO_LENGTH_REQUEST,
-VIRTIO_F_RING_RESET,
-VHOST_INVALID_FEATURE_BIT
+static Property vi2c_properties[] = {
+DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
+DEFINE_PROP_END_OF_LIST(),
 };
 
-static void vu_i2c_start(VirtIODevice *vdev)
-{
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-int ret, i;
-
-if (!k->set_guest_notifiers) {
-error_report("binding does not support guest notifiers");
-return;
-}
-
-ret = vhost_dev_enable_notifiers(&i2c->vhost_dev, vdev);
-if (ret < 0) {
-error_report("Error enabling host notifiers: %d", -ret);
-return;
-}
-
-ret = k->set_guest_notifiers(qbus->parent, i2c->vhost_dev.nvqs, true);
-if (ret < 0) {
-error_report("Error binding guest notifier: %d", -ret);
-goto err_host_notifiers;
-}
-
-i2c->vhost_dev.acked_features = vdev->guest_features;
-
-ret = vhost_dev_start(&i2c->vhost_dev, vdev, true);
-if (ret < 0) {
-error_report("Error starting vhost-user-i2c: %d", -ret);
-goto err_guest_notifiers;
-}
-
-/*
- * guest_notifier_mask/pending not used yet, so just unmask
- * everything here. virtio-pci will do the right thing by
- * enabling/disabling irqfd.
- */
-for (i = 0; i < i2c->vhost_dev.nvqs; i++) {
-vhost_virtqueue_mask(&i2c->vhost_dev, vdev, i, false);
-}
-
-return;
-
-err_guest_notifiers:
-k->set_guest_notifiers(qbus->parent, i2c->vhost_dev.nvqs, false);
-err_host_notifiers:
-vhost_dev_disable_notifiers(&i2c->vhost_dev, vdev);
-}
-
-static void vu_i2c_stop(VirtIODevice *vdev)
-{
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-int ret;
-
-if (!k->set_guest_notifiers) {
-return;
-}
-
-vhost_dev_stop(&i2c->vhost_dev, vdev, true);
-
-ret = k->set_guest_notifiers(qbus->parent, i2c->vhost_dev.nvqs, false);
-if (ret < 0) {
-error_report("vhost guest notifier cleanup failed: %d", ret);
-return;
-}
-
-vhost_dev_disable_notifiers(&i2c->vhost_dev, vdev);
-}
-
-static void vu_i2c_set_status(VirtIODevice *vdev, uint8_t status)
-{
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-bool should_start = virtio_device_should_start(vdev, status);
-
-if (vhost_dev_is_started(&i2c->vhost_dev) == should_start) {
-return;
-}
-
-if (should_start) {
-vu_i2c_start(vdev);
-} else {
-vu_i2c_stop(vdev);
-}
-}
-
-static uint64_t vu_i2c_get_features(VirtIODevice *vdev,
-uint64_t requested_features, Error **errp)
-{
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-
-virtio_add_feature(&requested_features, VIRTIO_I2C_F_ZERO_LENGTH_REQUEST);
-return vhost_get_fea

[PATCH v9 07/11] docs/system: add a basic enumeration of vhost-user devices

2024-01-04 Thread Alex Bennée
Make it clear the vhost-user-device is intended for expert use only.

Signed-off-by: Alex Bennée 

---
v5
  - split vhost-user-device out of the table
  - sort the table alphabetically
  - add sound and scmi devices
v6
  - add note re vhost-user-device
v7
  - fix patching description
---
 docs/system/devices/vhost-user-rng.rst |  2 +
 docs/system/devices/vhost-user.rst | 70 +-
 2 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/docs/system/devices/vhost-user-rng.rst 
b/docs/system/devices/vhost-user-rng.rst
index a145d4105c1..ead14053264 100644
--- a/docs/system/devices/vhost-user-rng.rst
+++ b/docs/system/devices/vhost-user-rng.rst
@@ -1,3 +1,5 @@
+.. _vhost_user_rng:
+
 QEMU vhost-user-rng - RNG emulation
 ===
 
diff --git a/docs/system/devices/vhost-user.rst 
b/docs/system/devices/vhost-user.rst
index a80e95a48ae..c6afc4836f9 100644
--- a/docs/system/devices/vhost-user.rst
+++ b/docs/system/devices/vhost-user.rst
@@ -8,13 +8,81 @@ outside of QEMU itself. To do this there are a number of 
things
 required.
 
 vhost-user device
-===
+=
 
 These are simple stub devices that ensure the VirtIO device is visible
 to the guest. The code is mostly boilerplate although each device has
 a ``chardev`` option which specifies the ID of the ``--chardev``
 device that connects via a socket to the vhost-user *daemon*.
 
+Each device will have an virtio-mmio and virtio-pci variant. See your
+platform details for what sort of virtio bus to use.
+
+.. list-table:: vhost-user devices
+  :widths: 20 20 60
+  :header-rows: 1
+
+  * - Device
+- Type
+- Notes
+  * - vhost-user-blk
+- Block storage
+- See contrib/vhost-user-blk
+  * - vhost-user-fs
+- File based storage driver
+- See https://gitlab.com/virtio-fs/virtiofsd
+  * - vhost-user-gpio
+- Proxy gpio pins to host
+- See https://github.com/rust-vmm/vhost-device
+  * - vhost-user-gpu
+- GPU driver
+- See contrib/vhost-user-gpu
+  * - vhost-user-i2c
+- Proxy i2c devices to host
+- See https://github.com/rust-vmm/vhost-device
+  * - vhost-user-input
+- Generic input driver
+- See contrib/vhost-user-input
+  * - vhost-user-rng
+- Entropy driver
+- :ref:`vhost_user_rng`
+  * - vhost-user-scmi
+- System Control and Management Interface
+- See https://github.com/rust-vmm/vhost-device
+  * - vhost-user-snd
+- Audio device
+- See https://github.com/rust-vmm/vhost-device/staging
+  * - vhost-user-scsi
+- SCSI based storage
+- See contrib/vhost-user-scsi
+  * - vhost-user-vsock
+- Socket based communication
+- See https://github.com/rust-vmm/vhost-device
+
+The referenced *daemons* are not exhaustive, any conforming backend
+implementing the device and using the vhost-user protocol should work.
+
+vhost-user-device
+^
+
+The vhost-user-device is a generic development device intended for
+expert use while developing new backends. The user needs to specify
+all the required parameters including:
+
+  - Device ``virtio-id``
+  - The ``num_vqs`` it needs and their ``vq_size``
+  - The ``config_size`` if needed
+
+.. note::
+  To prevent user confusion you cannot currently instantiate
+  vhost-user-device without first patching out::
+
+/* Reason: stop inexperienced users confusing themselves */
+dc->user_creatable = false;
+
+  in ``vhost-user-device.c`` and ``vhost-user-device-pci.c`` file and
+  rebuilding.
+
 vhost-user daemon
 =
 
-- 
2.39.2




[PATCH v9 09/11] docs/system: Add vhost-user-input documentation

2024-01-04 Thread Alex Bennée
From: Leo Yan 

This adds basic documentation for vhost-user-input.

Signed-off-by: Leo Yan 
Message-Id: <20231120043721.50555-3-leo@linaro.org>
Signed-off-by: Alex Bennée 
---
 MAINTAINERS  |  1 +
 docs/system/device-emulation.rst |  1 +
 docs/system/devices/vhost-user-input.rst | 45 
 docs/system/devices/vhost-user.rst   |  4 ++-
 4 files changed, 50 insertions(+), 1 deletion(-)
 create mode 100644 docs/system/devices/vhost-user-input.rst

diff --git a/MAINTAINERS b/MAINTAINERS
index 607f71817f8..ff70987aeb3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2274,6 +2274,7 @@ L: virtio...@lists.linux.dev
 virtio-input
 M: Gerd Hoffmann 
 S: Odd Fixes
+F: docs/system/devices/vhost-user-input.rst
 F: hw/input/vhost-user-input.c
 F: hw/input/virtio-input*.c
 F: include/hw/virtio/virtio-input.h
diff --git a/docs/system/device-emulation.rst b/docs/system/device-emulation.rst
index d1f3277cb02..f19777411cd 100644
--- a/docs/system/device-emulation.rst
+++ b/docs/system/device-emulation.rst
@@ -94,6 +94,7 @@ Emulated Devices
devices/virtio-gpu.rst
devices/virtio-pmem.rst
devices/virtio-snd.rst
+   devices/vhost-user-input.rst
devices/vhost-user-rng.rst
devices/canokey.rst
devices/usb-u2f.rst
diff --git a/docs/system/devices/vhost-user-input.rst 
b/docs/system/devices/vhost-user-input.rst
new file mode 100644
index 000..118eb78101c
--- /dev/null
+++ b/docs/system/devices/vhost-user-input.rst
@@ -0,0 +1,45 @@
+.. _vhost_user_input:
+
+QEMU vhost-user-input - Input emulation
+===
+
+This document describes the setup and usage of the Virtio input device.
+The Virtio input device is a paravirtualized device for input events.
+
+Description
+---
+
+The vhost-user-input device implementation was designed to work with a daemon
+polling on input devices and passes input events to the guest.
+
+QEMU provides a backend implementation in contrib/vhost-user-input.
+
+Linux kernel support
+
+
+Virtio input requires a guest Linux kernel built with the
+``CONFIG_VIRTIO_INPUT`` option.
+
+Examples
+
+
+The backend daemon should be started first:
+
+::
+
+  host# vhost-user-input --socket-path=input.sock  \
+  --evdev-path=/dev/input/event17
+
+The QEMU invocation needs to create a chardev socket to communicate with the
+backend daemon and access the VirtIO queues with the guest over the
+:ref:`shared memory `.
+
+::
+
+  host# qemu-system
\
+  -chardev socket,path=/tmp/input.sock,id=mouse0   
\
+  -device vhost-user-input-pci,chardev=mouse0  
\
+  -m 4096  
\
+  -object memory-backend-file,id=mem,size=4G,mem-path=/dev/shm,share=on
\
+  -numa node,memdev=mem
\
+  ...
diff --git a/docs/system/devices/vhost-user.rst 
b/docs/system/devices/vhost-user.rst
index c6afc4836f9..9b2da106cec 100644
--- a/docs/system/devices/vhost-user.rst
+++ b/docs/system/devices/vhost-user.rst
@@ -42,7 +42,7 @@ platform details for what sort of virtio bus to use.
 - See https://github.com/rust-vmm/vhost-device
   * - vhost-user-input
 - Generic input driver
-- See contrib/vhost-user-input
+- :ref:`vhost_user_input`
   * - vhost-user-rng
 - Entropy driver
 - :ref:`vhost_user_rng`
@@ -91,6 +91,8 @@ following the :ref:`vhost_user_proto`. There are a number of 
daemons
 that can be built when enabled by the project although any daemon that
 meets the specification for a given device can be used.
 
+.. _shared_memory_object:
+
 Shared memory object
 
 
-- 
2.39.2




[PATCH v9 06/11] hw/virtio: add vhost-user-snd and virtio-snd-pci devices

2024-01-04 Thread Alex Bennée
From: Manos Pitsidianakis 

Tested with rust-vmm vhost-user-sound daemon:

RUST_LOG=trace cargo run --bin vhost-user-sound -- --socket /tmp/snd.sock 
--backend null

Invocation:

qemu-system-x86_64  \
-qmp unix:./qmp-sock,server,wait=off  \
-m 4096 \
-numa node,memdev=mem \
-object 
memory-backend-file,id=mem,size=4G,mem-path=/dev/shm,share=on \
-D qemu.log \
-d guest_errors,trace:\*snd\*,trace:\*sound\*,trace:\*vhost\* \
-chardev socket,id=vsnd,path=/tmp/snd.sock \
-device vhost-user-snd-pci,chardev=vsnd,id=snd \
/path/to/disk

[AJB: imported from 
https://github.com/epilys/qemu-virtio-snd/commit/54ae1cdd15fef2d88e9e387a175f099a38c636f4.patch]

Signed-off-by: Alex Bennée 
Signed-off-by: Manos Pitsidianakis 

---
v7
  - s/parent/parent_obj/
  - add MAINTAINERS
  - add missing s-o-b
---
 MAINTAINERS|  7 +++
 include/hw/virtio/vhost-user-snd.h | 24 ++
 hw/virtio/vhost-user-snd-pci.c | 75 ++
 hw/virtio/vhost-user-snd.c | 67 ++
 hw/virtio/Kconfig  |  5 ++
 hw/virtio/meson.build  |  3 ++
 6 files changed, 181 insertions(+)
 create mode 100644 include/hw/virtio/vhost-user-snd.h
 create mode 100644 hw/virtio/vhost-user-snd-pci.c
 create mode 100644 hw/virtio/vhost-user-snd.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 0e832fd5d13..607f71817f8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2327,6 +2327,13 @@ F: hw/virtio/vhost-user-gpio*
 F: include/hw/virtio/vhost-user-gpio.h
 F: tests/qtest/libqos/virtio-gpio.*
 
+vhost-user-snd
+M: Alex Bennée 
+R: Manos Pitsidianakis 
+S: Maintained
+F: hw/virtio/vhost-user-snd*
+F: include/hw/virtio/vhost-user-snd.h
+
 vhost-user-scmi
 R: mzama...@redhat.com
 S: Supported
diff --git a/include/hw/virtio/vhost-user-snd.h 
b/include/hw/virtio/vhost-user-snd.h
new file mode 100644
index 000..f9260116a73
--- /dev/null
+++ b/include/hw/virtio/vhost-user-snd.h
@@ -0,0 +1,24 @@
+/*
+ * Vhost-user Sound virtio device
+ *
+ * Copyright (c) 2021 Mathieu Poirier 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef QEMU_VHOST_USER_SND_H
+#define QEMU_VHOST_USER_SND_H
+
+#include "hw/virtio/virtio.h"
+#include "hw/virtio/vhost.h"
+#include "hw/virtio/vhost-user.h"
+#include "hw/virtio/vhost-user-base.h"
+
+#define TYPE_VHOST_USER_SND "vhost-user-snd"
+OBJECT_DECLARE_SIMPLE_TYPE(VHostUserSound, VHOST_USER_SND)
+
+struct VHostUserSound {
+VHostUserBase parent_obj;
+};
+
+#endif /* QEMU_VHOST_USER_SND_H */
diff --git a/hw/virtio/vhost-user-snd-pci.c b/hw/virtio/vhost-user-snd-pci.c
new file mode 100644
index 000..d61cfdae631
--- /dev/null
+++ b/hw/virtio/vhost-user-snd-pci.c
@@ -0,0 +1,75 @@
+/*
+ * Vhost-user Sound virtio device PCI glue
+ *
+ * Copyright (c) 2023 Manos Pitsidianakis 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/qdev-properties.h"
+#include "hw/virtio/vhost-user-snd.h"
+#include "hw/virtio/virtio-pci.h"
+
+struct VHostUserSoundPCI {
+VirtIOPCIProxy parent_obj;
+VHostUserSound vdev;
+};
+
+typedef struct VHostUserSoundPCI VHostUserSoundPCI;
+
+#define TYPE_VHOST_USER_SND_PCI "vhost-user-snd-pci-base"
+
+DECLARE_INSTANCE_CHECKER(VHostUserSoundPCI, VHOST_USER_SND_PCI,
+ TYPE_VHOST_USER_SND_PCI)
+
+static Property vhost_user_snd_pci_properties[] = {
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void vhost_user_snd_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
+{
+VHostUserSoundPCI *dev = VHOST_USER_SND_PCI(vpci_dev);
+DeviceState *vdev = DEVICE(&dev->vdev);
+
+vpci_dev->nvectors = 1;
+
+qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
+}
+
+static void vhost_user_snd_pci_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+k->realize = vhost_user_snd_pci_realize;
+set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
+device_class_set_props(dc, vhost_user_snd_pci_properties);
+pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+pcidev_k->device_id = 0; /* Set by virtio-pci based on virtio id */
+pcidev_k->revision = 0x00;
+pcidev_k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
+}
+
+static void vhost_user_snd_pci_instance_init(Object *obj)
+{
+VHostUserSoundPCI *dev = VHOST_USER_SND_PCI(obj);
+
+virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
+TYPE_VHOST_USER_SND);
+}
+
+static const VirtioPCIDeviceTypeInfo vhost_user_snd_pci_info = {
+.base_name = TYPE_VHOST_USER_SND_PCI,
+.non_transitional_name = "vhost-user-snd-pci"

[PATCH v9 10/11] hw/virtio: Move vhost-user-input into virtio folder

2024-01-04 Thread Alex Bennée
From: Leo Yan 

vhost-user-input is in the input folder.  On the other hand, the folder
'hw/virtio' maintains other virtio stubs (e.g. I2C, RNG, GPIO, etc).

This patch moves vhost-user-input into the virtio folder for better code
organization.  No functionality change.

Signed-off-by: Leo Yan 
Reviewed-by: Manos Pitsidianakis 
Message-Id: <20231120043721.50555-4-leo@linaro.org>
Signed-off-by: Alex Bennée 
---
 MAINTAINERS | 2 +-
 hw/{input => virtio}/vhost-user-input.c | 0
 hw/input/meson.build| 1 -
 hw/virtio/meson.build   | 4 +++-
 4 files changed, 4 insertions(+), 3 deletions(-)
 rename hw/{input => virtio}/vhost-user-input.c (100%)

diff --git a/MAINTAINERS b/MAINTAINERS
index ff70987aeb3..66bd1eadc78 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2275,8 +2275,8 @@ virtio-input
 M: Gerd Hoffmann 
 S: Odd Fixes
 F: docs/system/devices/vhost-user-input.rst
-F: hw/input/vhost-user-input.c
 F: hw/input/virtio-input*.c
+F: hw/virtio/vhost-user-input.c
 F: include/hw/virtio/virtio-input.h
 F: contrib/vhost-user-input/*
 
diff --git a/hw/input/vhost-user-input.c b/hw/virtio/vhost-user-input.c
similarity index 100%
rename from hw/input/vhost-user-input.c
rename to hw/virtio/vhost-user-input.c
diff --git a/hw/input/meson.build b/hw/input/meson.build
index 640556bbbcc..3cc8ab85f0c 100644
--- a/hw/input/meson.build
+++ b/hw/input/meson.build
@@ -11,7 +11,6 @@ system_ss.add(when: 'CONFIG_TSC2005', if_true: 
files('tsc2005.c'))
 system_ss.add(when: 'CONFIG_VIRTIO_INPUT', if_true: files('virtio-input.c'))
 system_ss.add(when: 'CONFIG_VIRTIO_INPUT', if_true: 
files('virtio-input-hid.c'))
 system_ss.add(when: 'CONFIG_VIRTIO_INPUT_HOST', if_true: 
files('virtio-input-host.c'))
-system_ss.add(when: 'CONFIG_VHOST_USER_INPUT', if_true: 
files('vhost-user-input.c'))
 
 system_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_keypad.c'))
 system_ss.add(when: 'CONFIG_TSC210X', if_true: files('tsc210x.c'))
diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
index 118d4d4da7c..c924afcafc0 100644
--- a/hw/virtio/meson.build
+++ b/hw/virtio/meson.build
@@ -25,6 +25,7 @@ if have_vhost
 system_virtio_ss.add(when: 'CONFIG_VHOST_USER_I2C', if_true: 
files('vhost-user-i2c.c'))
 system_virtio_ss.add(when: 'CONFIG_VHOST_USER_RNG', if_true: 
files('vhost-user-rng.c'))
 system_virtio_ss.add(when: 'CONFIG_VHOST_USER_SND', if_true: 
files('vhost-user-snd.c'))
+system_virtio_ss.add(when: 'CONFIG_VHOST_USER_INPUT', if_true: 
files('vhost-user-input.c'))
 
 # PCI Stubs
 system_virtio_ss.add(when: 'CONFIG_VIRTIO_PCI', if_true: 
files('vhost-user-device-pci.c'))
@@ -36,6 +37,8 @@ if have_vhost
  if_true: files('vhost-user-rng-pci.c'))
 system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_SND'],
  if_true: files('vhost-user-snd-pci.c'))
+system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 
'CONFIG_VHOST_USER_INPUT'],
+ if_true: files('vhost-user-input-pci.c'))
   endif
   if have_vhost_vdpa
 system_virtio_ss.add(files('vhost-vdpa.c'))
@@ -59,7 +62,6 @@ virtio_pci_ss = ss.source_set()
 virtio_pci_ss.add(when: 'CONFIG_VHOST_VSOCK', if_true: 
files('vhost-vsock-pci.c'))
 virtio_pci_ss.add(when: 'CONFIG_VHOST_USER_VSOCK', if_true: 
files('vhost-user-vsock-pci.c'))
 virtio_pci_ss.add(when: 'CONFIG_VHOST_USER_BLK', if_true: 
files('vhost-user-blk-pci.c'))
-virtio_pci_ss.add(when: 'CONFIG_VHOST_USER_INPUT', if_true: 
files('vhost-user-input-pci.c'))
 virtio_pci_ss.add(when: 'CONFIG_VHOST_USER_SCSI', if_true: 
files('vhost-user-scsi-pci.c'))
 virtio_pci_ss.add(when: 'CONFIG_VHOST_SCSI', if_true: 
files('vhost-scsi-pci.c'))
 virtio_pci_ss.add(when: 'CONFIG_VHOST_USER_FS', if_true: 
files('vhost-user-fs-pci.c'))
-- 
2.39.2




[PATCH v9 02/11] hw/virtio: convert vhost-user-base to async shutdown

2024-01-04 Thread Alex Bennée
We are about to convert at least one stubs which was using the async
teardown so lets use it for all the cases.

Signed-off-by: Alex Bennée 
---
 hw/virtio/vhost-user-base.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c
index 620fa5cb4a4..78cfa9a5bbc 100644
--- a/hw/virtio/vhost-user-base.c
+++ b/hw/virtio/vhost-user-base.c
@@ -201,6 +201,8 @@ static int vub_connect(DeviceState *dev)
 return 0;
 }
 
+static void vub_event(void *opaque, QEMUChrEvent event);
+
 static void vub_disconnect(DeviceState *dev)
 {
 VirtIODevice *vdev = VIRTIO_DEVICE(dev);
@@ -211,9 +213,13 @@ static void vub_disconnect(DeviceState *dev)
 }
 vub->connected = false;
 
-if (vhost_dev_is_started(&vub->vhost_dev)) {
-vub_stop(vdev);
-}
+vub_stop(vdev);
+vhost_dev_cleanup(&vub->vhost_dev);
+
+/* Re-instate the event handler for new connections */
+qemu_chr_fe_set_handlers(&vub->chardev,
+ NULL, NULL, vub_event,
+ NULL, dev, NULL, true);
 }
 
 static void vub_event(void *opaque, QEMUChrEvent event)
@@ -230,7 +236,9 @@ static void vub_event(void *opaque, QEMUChrEvent event)
 }
 break;
 case CHR_EVENT_CLOSED:
-vub_disconnect(dev);
+/* defer close until later to avoid circular close */
+vhost_user_async_close(dev, &vub->chardev, &vub->vhost_dev,
+   vub_disconnect, vub_event);
 break;
 case CHR_EVENT_BREAK:
 case CHR_EVENT_MUX_IN:
-- 
2.39.2




qemu-block@nongnu.org

2023-11-07 Thread Alex Bennée
"Michael S. Tsirkin"  writes:

> On Tue, Nov 07, 2023 at 06:07:45PM +, Alex Bennée wrote:
>> A lot of our vhost-user stubs are large chunks of boilerplate that do
>> (mostly) the same thing. This series continues the cleanups by
>> splitting the vhost-user-base and vhost-user-generic implementations.
>> After adding a new vq_size property the rng, gpio and i2c vhost-user
>> devices become simple specialisations of the common base defining the
>> ID, number of queues and potentially the config handling.
>> 
>> I've also added Manos' vhost-user-sound while I was at it.
>> 
>> Changes
>> ---
>> 
>> v8
>>   - scrubbed errant Message-Id
>
> did you pass this by checkpatch btw? there were some warnings on v6.

yes - its checkpatch clean:

  https://gitlab.com/stsquad/qemu/-/jobs/5480800819

>
>> v7
>>   - various review comments
>>   - move to async teardown (fixes CI failure)
>> 
>> v6
>>   - re-base to current master
>>   - make vhost-user-device abstract
>>   - mention abstractness in docs
>> 
>> v5
>>   - addressing comments and tags
>>   - improved the docs
>> 
>> v4
>>   - dropped the F_TRANSPORT work for another series
>>   - added vhost-user-sound
>> 
>> Alex Bennée (6):
>>   virtio: split into vhost-user-base and vhost-user-device
>>   hw/virtio: convert vhost-user-base to async shutdown
>>   hw/virtio: derive vhost-user-rng from vhost-user-base
>>   hw/virtio: derive vhost-user-gpio from vhost-user-base
>>   hw/virtio: derive vhost-user-i2c from vhost-user-base
>>   docs/system: add a basic enumeration of vhost-user devices
>> 
>> Manos Pitsidianakis (1):
>>   hw/virtio: add vhost-user-snd and virtio-snd-pci devices
>> 
>>  MAINTAINERS   |  13 +
>>  docs/system/devices/vhost-user-rng.rst|   2 +
>>  docs/system/devices/vhost-user.rst|  70 ++-
>>  ...{vhost-user-device.h => vhost-user-base.h} |  21 +-
>>  include/hw/virtio/vhost-user-gpio.h   |  25 +-
>>  include/hw/virtio/vhost-user-i2c.h|  14 +-
>>  include/hw/virtio/vhost-user-rng.h|  13 +-
>>  include/hw/virtio/vhost-user-snd.h|  24 ++
>>  hw/virtio/vhost-user-base.c   | 354 +++
>>  hw/virtio/vhost-user-device-pci.c |  13 +-
>>  hw/virtio/vhost-user-device.c | 338 +--
>>  hw/virtio/vhost-user-gpio.c   | 406 +-
>>  hw/virtio/vhost-user-i2c.c| 272 +---
>>  hw/virtio/vhost-user-rng.c| 278 +---
>>  hw/virtio/vhost-user-snd-pci.c|  75 
>>  hw/virtio/vhost-user-snd.c|  67 +++
>>  hw/virtio/Kconfig |   5 +
>>  hw/virtio/meson.build     |  23 +-
>>  18 files changed, 719 insertions(+), 1294 deletions(-)
>>  rename include/hw/virtio/{vhost-user-device.h => vhost-user-base.h} (71%)
>>  create mode 100644 include/hw/virtio/vhost-user-snd.h
>>  create mode 100644 hw/virtio/vhost-user-base.c
>>  create mode 100644 hw/virtio/vhost-user-snd-pci.c
>>  create mode 100644 hw/virtio/vhost-user-snd.c
>> 
>> -- 
>> 2.39.2

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



qemu-block@nongnu.org

2023-11-07 Thread Alex Bennée
"Michael S. Tsirkin"  writes:

> On Mon, Nov 06, 2023 at 07:15:09PM +, Alex Bennée wrote:
>> A lot of our vhost-user stubs are large chunks of boilerplate that do
>> (mostly) the same thing. This series continues the cleanups by
>> splitting the vhost-user-base and vhost-user-generic implementations.
>> After adding a new vq_size property the rng, gpio and i2c vhost-user
>> devices become simple specialisations of the common base defining the
>> ID, number of queues and potentially the config handling.
>> 
>> I've also added Manos' vhost-user-sound while I was at it.
>
> Dropped due to CI failures. Pls make sure this passes gitlab CI.
> Also pls ping me after release to help make sure it does not get lost.
> Thanks!

Your intuition about the async tear down was right (or at least avoids
the racey qos-test failure). I've added a final patch and sent :

  https://patchew.org/QEMU/20231107180752.3458672-1-alex.ben...@linaro.org/

It's running the CI as we speak:

  https://gitlab.com/stsquad/qemu/-/pipelines/1064197949

>
>> Changes
>> ---
>> 
>> v6
>>   - re-base to current master
>>   - make vhost-user-device abstract
>>   - mention abstractness in docs
>> 
>> v5
>>   - addressing comments and tags
>>   - improved the docs
>> 
>> v4
>>   - dropped the F_TRANSPORT work for another series
>>   - added vhost-user-sound
>> 
>> Alex Bennée (5):
>>   virtio: split into vhost-user-base and vhost-user-device
>>   hw/virtio: derive vhost-user-rng from vhost-user-base
>>   hw/virtio: derive vhost-user-gpio from vhost-user-base
>>   hw/virtio: derive vhost-user-i2c from vhost-user-base
>>   docs/system: add a basic enumeration of vhost-user devices
>> 
>> Manos Pitsidianakis (1):
>>   hw/virtio: add vhost-user-snd and virtio-snd-pci devices
>> 
>>  docs/system/devices/vhost-user-rng.rst|   2 +
>>  docs/system/devices/vhost-user.rst|  65 ++-
>>  ...{vhost-user-device.h => vhost-user-base.h} |  21 +-
>>  include/hw/virtio/vhost-user-gpio.h   |  23 +-
>>  include/hw/virtio/vhost-user-i2c.h|  14 +-
>>  include/hw/virtio/vhost-user-rng.h|  11 +-
>>  include/hw/virtio/vhost-user-snd.h|  26 ++
>>  hw/virtio/vhost-user-base.c   | 345 +++
>>  hw/virtio/vhost-user-device-pci.c |  10 +-
>>  hw/virtio/vhost-user-device.c | 337 +--
>>  hw/virtio/vhost-user-gpio.c   | 406 +-
>>  hw/virtio/vhost-user-i2c.c| 272 +---
>>  hw/virtio/vhost-user-rng.c| 278 +---
>>  hw/virtio/vhost-user-snd-pci.c|  75 
>>  hw/virtio/vhost-user-snd.c|  67 +++
>>  hw/virtio/Kconfig |   5 +
>>  hw/virtio/meson.build |  23 +-
>>  17 files changed, 690 insertions(+), 1290 deletions(-)
>>  rename include/hw/virtio/{vhost-user-device.h => vhost-user-base.h} (71%)
>>  create mode 100644 include/hw/virtio/vhost-user-snd.h
>>  create mode 100644 hw/virtio/vhost-user-base.c
>>  create mode 100644 hw/virtio/vhost-user-snd-pci.c
>>  create mode 100644 hw/virtio/vhost-user-snd.c
>> 
>> -- 
>> 2.39.2

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



[PATCH v8 7/7] docs/system: add a basic enumeration of vhost-user devices

2023-11-07 Thread Alex Bennée
Make it clear the vhost-user-device is intended for expert use only.

Signed-off-by: Alex Bennée 

---
v5
  - split vhost-user-device out of the table
  - sort the table alphabetically
  - add sound and scmi devices
v6
  - add note re vhost-user-device
v7
  - fix patching description
---
 docs/system/devices/vhost-user-rng.rst |  2 +
 docs/system/devices/vhost-user.rst | 70 +-
 2 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/docs/system/devices/vhost-user-rng.rst 
b/docs/system/devices/vhost-user-rng.rst
index a145d4105c..ead1405326 100644
--- a/docs/system/devices/vhost-user-rng.rst
+++ b/docs/system/devices/vhost-user-rng.rst
@@ -1,3 +1,5 @@
+.. _vhost_user_rng:
+
 QEMU vhost-user-rng - RNG emulation
 ===
 
diff --git a/docs/system/devices/vhost-user.rst 
b/docs/system/devices/vhost-user.rst
index a80e95a48a..c6afc4836f 100644
--- a/docs/system/devices/vhost-user.rst
+++ b/docs/system/devices/vhost-user.rst
@@ -8,13 +8,81 @@ outside of QEMU itself. To do this there are a number of 
things
 required.
 
 vhost-user device
-===
+=
 
 These are simple stub devices that ensure the VirtIO device is visible
 to the guest. The code is mostly boilerplate although each device has
 a ``chardev`` option which specifies the ID of the ``--chardev``
 device that connects via a socket to the vhost-user *daemon*.
 
+Each device will have an virtio-mmio and virtio-pci variant. See your
+platform details for what sort of virtio bus to use.
+
+.. list-table:: vhost-user devices
+  :widths: 20 20 60
+  :header-rows: 1
+
+  * - Device
+- Type
+- Notes
+  * - vhost-user-blk
+- Block storage
+- See contrib/vhost-user-blk
+  * - vhost-user-fs
+- File based storage driver
+- See https://gitlab.com/virtio-fs/virtiofsd
+  * - vhost-user-gpio
+- Proxy gpio pins to host
+- See https://github.com/rust-vmm/vhost-device
+  * - vhost-user-gpu
+- GPU driver
+- See contrib/vhost-user-gpu
+  * - vhost-user-i2c
+- Proxy i2c devices to host
+- See https://github.com/rust-vmm/vhost-device
+  * - vhost-user-input
+- Generic input driver
+- See contrib/vhost-user-input
+  * - vhost-user-rng
+- Entropy driver
+- :ref:`vhost_user_rng`
+  * - vhost-user-scmi
+- System Control and Management Interface
+- See https://github.com/rust-vmm/vhost-device
+  * - vhost-user-snd
+- Audio device
+- See https://github.com/rust-vmm/vhost-device/staging
+  * - vhost-user-scsi
+- SCSI based storage
+- See contrib/vhost-user-scsi
+  * - vhost-user-vsock
+- Socket based communication
+- See https://github.com/rust-vmm/vhost-device
+
+The referenced *daemons* are not exhaustive, any conforming backend
+implementing the device and using the vhost-user protocol should work.
+
+vhost-user-device
+^
+
+The vhost-user-device is a generic development device intended for
+expert use while developing new backends. The user needs to specify
+all the required parameters including:
+
+  - Device ``virtio-id``
+  - The ``num_vqs`` it needs and their ``vq_size``
+  - The ``config_size`` if needed
+
+.. note::
+  To prevent user confusion you cannot currently instantiate
+  vhost-user-device without first patching out::
+
+/* Reason: stop inexperienced users confusing themselves */
+dc->user_creatable = false;
+
+  in ``vhost-user-device.c`` and ``vhost-user-device-pci.c`` file and
+  rebuilding.
+
 vhost-user daemon
 =
 
-- 
2.39.2




[PATCH v8 1/7] virtio: split into vhost-user-base and vhost-user-device

2023-11-07 Thread Alex Bennée
Lets keep a cleaner split between the base class and the derived
vhost-user-device which we can use for generic vhost-user stubs. This
includes an update to introduce the vq_size property so the number of
entries in a virtq can be defined.

Signed-off-by: Alex Bennée 

---
v5
  - s/parent/parent_obj/
  - remove left over vhost-user-device.h
  - use DEFINE_TYPES
v6
  - rebase and set .abstract = true for vhost-user-device
v7
  - checkpatch line length + MAINTAINERS
  - s/abstract = true/dc->user_creatable = false/ for both mmio and pci
---
 MAINTAINERS   |   6 +
 ...{vhost-user-device.h => vhost-user-base.h} |  21 +-
 hw/virtio/vhost-user-base.c   | 346 ++
 hw/virtio/vhost-user-device-pci.c |  13 +-
 hw/virtio/vhost-user-device.c | 338 +
 hw/virtio/meson.build |   1 +
 6 files changed, 383 insertions(+), 342 deletions(-)
 rename include/hw/virtio/{vhost-user-device.h => vhost-user-base.h} (71%)
 create mode 100644 hw/virtio/vhost-user-base.c

diff --git a/MAINTAINERS b/MAINTAINERS
index b86ea7f75a..2ff908d039 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2263,6 +2263,12 @@ F: include/sysemu/rng*.h
 F: backends/rng*.c
 F: tests/qtest/virtio-rng-test.c
 
+vhost-user-stubs
+M: Alex Bennée 
+S: Maintained
+F: hw/virtio/vhost-user-base.c
+F: hw/virtio/vhost-user-device*
+
 vhost-user-rng
 M: Mathieu Poirier 
 S: Supported
diff --git a/include/hw/virtio/vhost-user-device.h 
b/include/hw/virtio/vhost-user-base.h
similarity index 71%
rename from include/hw/virtio/vhost-user-device.h
rename to include/hw/virtio/vhost-user-base.h
index 3ddf88a146..51d0968b89 100644
--- a/include/hw/virtio/vhost-user-device.h
+++ b/include/hw/virtio/vhost-user-base.h
@@ -6,8 +6,8 @@
  * SPDX-License-Identifier: GPL-2.0-or-later
  */
 
-#ifndef QEMU_VHOST_USER_DEVICE_H
-#define QEMU_VHOST_USER_DEVICE_H
+#ifndef QEMU_VHOST_USER_BASE_H
+#define QEMU_VHOST_USER_BASE_H
 
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
@@ -17,11 +17,13 @@
 OBJECT_DECLARE_TYPE(VHostUserBase, VHostUserBaseClass, VHOST_USER_BASE)
 
 struct VHostUserBase {
-VirtIODevice parent;
+VirtIODevice parent_obj;
+
 /* Properties */
 CharBackend chardev;
 uint16_t virtio_id;
 uint32_t num_vqs;
+uint32_t vq_size; /* can't exceed VIRTIO_QUEUE_MAX */
 uint32_t config_size;
 /* State tracking */
 VhostUserState vhost_user;
@@ -31,16 +33,17 @@ struct VHostUserBase {
 bool connected;
 };
 
-/* needed so we can use the base realize after specialisation
-   tweaks */
+/*
+ * Needed so we can use the base realize after specialisation
+ * tweaks
+ */
 struct VHostUserBaseClass {
-/*< private >*/
 VirtioDeviceClass parent_class;
-/*< public >*/
+
 DeviceRealize parent_realize;
 };
 
-/* shared for the benefit of the derived pci class */
+
 #define TYPE_VHOST_USER_DEVICE "vhost-user-device"
 
-#endif /* QEMU_VHOST_USER_DEVICE_H */
+#endif /* QEMU_VHOST_USER_BASE_H */
diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c
new file mode 100644
index 00..620fa5cb4a
--- /dev/null
+++ b/hw/virtio/vhost-user-base.c
@@ -0,0 +1,346 @@
+/*
+ * Base vhost-user-base implementation. This can be used to derive a
+ * more fully specified vhost-user backend either generically (see
+ * vhost-user-device) or via a specific stub for a device which
+ * encapsulates some fixed parameters.
+ *
+ * Copyright (c) 2023 Linaro Ltd
+ * Author: Alex Bennée 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/qdev-properties.h"
+#include "hw/virtio/virtio-bus.h"
+#include "hw/virtio/vhost-user-base.h"
+#include "qemu/error-report.h"
+
+static void vub_start(VirtIODevice *vdev)
+{
+BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
+VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+VHostUserBase *vub = VHOST_USER_BASE(vdev);
+int ret, i;
+
+if (!k->set_guest_notifiers) {
+error_report("binding does not support guest notifiers");
+return;
+}
+
+ret = vhost_dev_enable_notifiers(&vub->vhost_dev, vdev);
+if (ret < 0) {
+error_report("Error enabling host notifiers: %d", -ret);
+return;
+}
+
+ret = k->set_guest_notifiers(qbus->parent, vub->vhost_dev.nvqs, true);
+if (ret < 0) {
+error_report("Error binding guest notifier: %d", -ret);
+goto err_host_notifiers;
+}
+
+vub->vhost_dev.acked_features = vdev->guest_features;
+
+ret = vhost_dev_start(&vub->vhost_dev, vdev, true);
+if (ret < 0) {
+error_report("Error starting vhost-user-base: %d", -ret);
+goto err_guest_notifiers;
+}
+
+/

[PATCH v8 5/7] hw/virtio: derive vhost-user-i2c from vhost-user-base

2023-11-07 Thread Alex Bennée
Now we can take advantage of the new base class and make
vhost-user-i2c a much simpler boilerplate wrapper. Also as this
doesn't require any target specific hacks we only need to build the
stubs once.

Acked-by: Mark Cave-Ayland 
Acked-by: Viresh Kumar 
Signed-off-by: Alex Bennée 

---
v7
  - s/parent/parent_obj/
---
 include/hw/virtio/vhost-user-i2c.h |  14 +-
 hw/virtio/vhost-user-i2c.c | 272 ++---
 hw/virtio/meson.build  |   5 +-
 3 files changed, 23 insertions(+), 268 deletions(-)

diff --git a/include/hw/virtio/vhost-user-i2c.h 
b/include/hw/virtio/vhost-user-i2c.h
index 0f7acd40e3..a9b5612ad0 100644
--- a/include/hw/virtio/vhost-user-i2c.h
+++ b/include/hw/virtio/vhost-user-i2c.h
@@ -9,23 +9,17 @@
 #ifndef QEMU_VHOST_USER_I2C_H
 #define QEMU_VHOST_USER_I2C_H
 
+#include "hw/virtio/virtio.h"
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
+#include "hw/virtio/vhost-user-base.h"
 
 #define TYPE_VHOST_USER_I2C "vhost-user-i2c-device"
+
 OBJECT_DECLARE_SIMPLE_TYPE(VHostUserI2C, VHOST_USER_I2C)
 
 struct VHostUserI2C {
-VirtIODevice parent;
-CharBackend chardev;
-struct vhost_virtqueue *vhost_vq;
-struct vhost_dev vhost_dev;
-VhostUserState vhost_user;
-VirtQueue *vq;
-bool connected;
+VHostUserBase parent_obj;
 };
 
-/* Virtio Feature bits */
-#define VIRTIO_I2C_F_ZERO_LENGTH_REQUEST   0
-
 #endif /* QEMU_VHOST_USER_I2C_H */
diff --git a/hw/virtio/vhost-user-i2c.c b/hw/virtio/vhost-user-i2c.c
index 4eef3f0633..a464f5e039 100644
--- a/hw/virtio/vhost-user-i2c.c
+++ b/hw/virtio/vhost-user-i2c.c
@@ -14,253 +14,22 @@
 #include "qemu/error-report.h"
 #include "standard-headers/linux/virtio_ids.h"
 
-static const int feature_bits[] = {
-VIRTIO_I2C_F_ZERO_LENGTH_REQUEST,
-VIRTIO_F_RING_RESET,
-VHOST_INVALID_FEATURE_BIT
+static Property vi2c_properties[] = {
+DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
+DEFINE_PROP_END_OF_LIST(),
 };
 
-static void vu_i2c_start(VirtIODevice *vdev)
-{
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-int ret, i;
-
-if (!k->set_guest_notifiers) {
-error_report("binding does not support guest notifiers");
-return;
-}
-
-ret = vhost_dev_enable_notifiers(&i2c->vhost_dev, vdev);
-if (ret < 0) {
-error_report("Error enabling host notifiers: %d", -ret);
-return;
-}
-
-ret = k->set_guest_notifiers(qbus->parent, i2c->vhost_dev.nvqs, true);
-if (ret < 0) {
-error_report("Error binding guest notifier: %d", -ret);
-goto err_host_notifiers;
-}
-
-i2c->vhost_dev.acked_features = vdev->guest_features;
-
-ret = vhost_dev_start(&i2c->vhost_dev, vdev, true);
-if (ret < 0) {
-error_report("Error starting vhost-user-i2c: %d", -ret);
-goto err_guest_notifiers;
-}
-
-/*
- * guest_notifier_mask/pending not used yet, so just unmask
- * everything here. virtio-pci will do the right thing by
- * enabling/disabling irqfd.
- */
-for (i = 0; i < i2c->vhost_dev.nvqs; i++) {
-vhost_virtqueue_mask(&i2c->vhost_dev, vdev, i, false);
-}
-
-return;
-
-err_guest_notifiers:
-k->set_guest_notifiers(qbus->parent, i2c->vhost_dev.nvqs, false);
-err_host_notifiers:
-vhost_dev_disable_notifiers(&i2c->vhost_dev, vdev);
-}
-
-static void vu_i2c_stop(VirtIODevice *vdev)
-{
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-int ret;
-
-if (!k->set_guest_notifiers) {
-return;
-}
-
-vhost_dev_stop(&i2c->vhost_dev, vdev, true);
-
-ret = k->set_guest_notifiers(qbus->parent, i2c->vhost_dev.nvqs, false);
-if (ret < 0) {
-error_report("vhost guest notifier cleanup failed: %d", ret);
-return;
-}
-
-vhost_dev_disable_notifiers(&i2c->vhost_dev, vdev);
-}
-
-static void vu_i2c_set_status(VirtIODevice *vdev, uint8_t status)
-{
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-bool should_start = virtio_device_should_start(vdev, status);
-
-if (vhost_dev_is_started(&i2c->vhost_dev) == should_start) {
-return;
-}
-
-if (should_start) {
-vu_i2c_start(vdev);
-} else {
-vu_i2c_stop(vdev);
-}
-}
-
-static uint64_t vu_i2c_get_features(VirtIODevice *vdev,
-uint64_t requested_features, Error **errp)
-{
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-
-virtio_add_feature(&requested_features, VIRTIO_I2C_F_ZERO_LENGTH_REQUEST);
-return vhost_get_features

[PATCH v8 4/7] hw/virtio: derive vhost-user-gpio from vhost-user-base

2023-11-07 Thread Alex Bennée
Now the new base class supports config handling we can take advantage
and make vhost-user-gpio a much simpler boilerplate wrapper. Also as
this doesn't require any target specific hacks we only need to build
the stubs once.

Acked-by: Mark Cave-Ayland 
Acked-by: Viresh Kumar 
Signed-off-by: Alex Bennée 

---
v7
  - s/parent/parent_obj/
---
 include/hw/virtio/vhost-user-gpio.h |  25 +-
 hw/virtio/vhost-user-gpio.c | 406 ++--
 hw/virtio/meson.build   |   5 +-
 3 files changed, 22 insertions(+), 414 deletions(-)

diff --git a/include/hw/virtio/vhost-user-gpio.h 
b/include/hw/virtio/vhost-user-gpio.h
index a9d3f9b049..5814a8400a 100644
--- a/include/hw/virtio/vhost-user-gpio.h
+++ b/include/hw/virtio/vhost-user-gpio.h
@@ -12,34 +12,13 @@
 #include "hw/virtio/virtio.h"
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
-#include "standard-headers/linux/virtio_gpio.h"
-#include "chardev/char-fe.h"
+#include "hw/virtio/vhost-user-base.h"
 
 #define TYPE_VHOST_USER_GPIO "vhost-user-gpio-device"
 OBJECT_DECLARE_SIMPLE_TYPE(VHostUserGPIO, VHOST_USER_GPIO);
 
 struct VHostUserGPIO {
-/*< private >*/
-VirtIODevice parent_obj;
-CharBackend chardev;
-struct virtio_gpio_config config;
-struct vhost_virtqueue *vhost_vqs;
-struct vhost_dev vhost_dev;
-VhostUserState vhost_user;
-VirtQueue *command_vq;
-VirtQueue *interrupt_vq;
-/**
- * There are at least two steps of initialization of the
- * vhost-user device. The first is a "connect" step and
- * second is a "start" step. Make a separation between
- * those initialization phases by using two fields.
- *
- * @connected: see vu_gpio_connect()/vu_gpio_disconnect()
- * @started_vu: see vu_gpio_start()/vu_gpio_stop()
- */
-bool connected;
-bool started_vu;
-/*< public >*/
+VHostUserBase parent_obj;
 };
 
 #endif /* _QEMU_VHOST_USER_GPIO_H */
diff --git a/hw/virtio/vhost-user-gpio.c b/hw/virtio/vhost-user-gpio.c
index aff2d7eff6..9f37c25415 100644
--- a/hw/virtio/vhost-user-gpio.c
+++ b/hw/virtio/vhost-user-gpio.c
@@ -11,387 +11,25 @@
 #include "hw/qdev-properties.h"
 #include "hw/virtio/virtio-bus.h"
 #include "hw/virtio/vhost-user-gpio.h"
-#include "qemu/error-report.h"
 #include "standard-headers/linux/virtio_ids.h"
-#include "trace.h"
+#include "standard-headers/linux/virtio_gpio.h"
 
-#define VHOST_NVQS 2
-
-/* Features required from VirtIO */
-static const int feature_bits[] = {
-VIRTIO_F_VERSION_1,
-VIRTIO_F_NOTIFY_ON_EMPTY,
-VIRTIO_RING_F_INDIRECT_DESC,
-VIRTIO_RING_F_EVENT_IDX,
-VIRTIO_GPIO_F_IRQ,
-VIRTIO_F_RING_RESET,
-VHOST_INVALID_FEATURE_BIT
-};
-
-static void vu_gpio_get_config(VirtIODevice *vdev, uint8_t *config)
-{
-VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev);
-
-memcpy(config, &gpio->config, sizeof(gpio->config));
-}
-
-static int vu_gpio_config_notifier(struct vhost_dev *dev)
-{
-VHostUserGPIO *gpio = VHOST_USER_GPIO(dev->vdev);
-
-memcpy(dev->vdev->config, &gpio->config, sizeof(gpio->config));
-virtio_notify_config(dev->vdev);
-
-return 0;
-}
-
-const VhostDevConfigOps gpio_ops = {
-.vhost_dev_config_notifier = vu_gpio_config_notifier,
+static Property vgpio_properties[] = {
+DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
+DEFINE_PROP_END_OF_LIST(),
 };
 
-static int vu_gpio_start(VirtIODevice *vdev)
-{
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev);
-struct vhost_dev *vhost_dev = &gpio->vhost_dev;
-int ret, i;
-
-if (!k->set_guest_notifiers) {
-error_report("binding does not support guest notifiers");
-return -ENOSYS;
-}
-
-ret = vhost_dev_enable_notifiers(vhost_dev, vdev);
-if (ret < 0) {
-error_report("Error enabling host notifiers: %d", ret);
-return ret;
-}
-
-ret = k->set_guest_notifiers(qbus->parent, vhost_dev->nvqs, true);
-if (ret < 0) {
-error_report("Error binding guest notifier: %d", ret);
-goto err_host_notifiers;
-}
-
-/*
- * Before we start up we need to ensure we have the final feature
- * set needed for the vhost configuration. The backend may also
- * apply backend_features when the feature set is sent.
- */
-vhost_ack_features(&gpio->vhost_dev, feature_bits, vdev->guest_features);
-
-ret = vhost_dev_start(&gpio->vhost_dev, vdev, false);
-if (ret < 0) {
-error_report("Error starting vhost-user-gpio: %d", ret);
-goto err_guest_notifiers;
-}
-gpio->start

[PATCH v8 3/7] hw/virtio: derive vhost-user-rng from vhost-user-base

2023-11-07 Thread Alex Bennée
Now we can take advantage of our new base class and make
vhost-user-rng a much simpler boilerplate wrapper. Also as this
doesn't require any target specific hacks we only need to build the
stubs once.

Acked-by: Mark Cave-Ayland 
Signed-off-by: Alex Bennée 

---
v5
  - don't remove the in-QEMU RNG emulation!
v7
  - s/parent/parent_obj/
---
 include/hw/virtio/vhost-user-rng.h |  13 +-
 hw/virtio/vhost-user-rng.c | 278 +++--
 hw/virtio/meson.build  |   9 +-
 3 files changed, 31 insertions(+), 269 deletions(-)

diff --git a/include/hw/virtio/vhost-user-rng.h 
b/include/hw/virtio/vhost-user-rng.h
index ddd9f01eea..10868c7de4 100644
--- a/include/hw/virtio/vhost-user-rng.h
+++ b/include/hw/virtio/vhost-user-rng.h
@@ -12,22 +12,13 @@
 #include "hw/virtio/virtio.h"
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
-#include "chardev/char-fe.h"
+#include "hw/virtio/vhost-user-base.h"
 
 #define TYPE_VHOST_USER_RNG "vhost-user-rng"
 OBJECT_DECLARE_SIMPLE_TYPE(VHostUserRNG, VHOST_USER_RNG)
 
 struct VHostUserRNG {
-/*< private >*/
-VirtIODevice parent;
-CharBackend chardev;
-struct vhost_virtqueue *vhost_vq;
-struct vhost_dev vhost_dev;
-VhostUserState vhost_user;
-VirtQueue *req_vq;
-bool connected;
-
-/*< public >*/
+VHostUserBase parent_obj;
 };
 
 #endif /* QEMU_VHOST_USER_RNG_H */
diff --git a/hw/virtio/vhost-user-rng.c b/hw/virtio/vhost-user-rng.c
index efc54cd3fb..01879c863d 100644
--- a/hw/virtio/vhost-user-rng.c
+++ b/hw/virtio/vhost-user-rng.c
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2021 Mathieu Poirier 
  *
- * Implementation seriously tailored on vhost-user-i2c.c
+ * Simple wrapper of the generic vhost-user-device.
  *
  * SPDX-License-Identifier: GPL-2.0-or-later
  */
@@ -13,281 +13,47 @@
 #include "hw/qdev-properties.h"
 #include "hw/virtio/virtio-bus.h"
 #include "hw/virtio/vhost-user-rng.h"
-#include "qemu/error-report.h"
 #include "standard-headers/linux/virtio_ids.h"
 
-static const int feature_bits[] = {
-VIRTIO_F_RING_RESET,
-VHOST_INVALID_FEATURE_BIT
-};
-
-static void vu_rng_start(VirtIODevice *vdev)
-{
-VHostUserRNG *rng = VHOST_USER_RNG(vdev);
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-int ret;
-int i;
-
-if (!k->set_guest_notifiers) {
-error_report("binding does not support guest notifiers");
-return;
-}
-
-ret = vhost_dev_enable_notifiers(&rng->vhost_dev, vdev);
-if (ret < 0) {
-error_report("Error enabling host notifiers: %d", -ret);
-return;
-}
-
-ret = k->set_guest_notifiers(qbus->parent, rng->vhost_dev.nvqs, true);
-if (ret < 0) {
-error_report("Error binding guest notifier: %d", -ret);
-goto err_host_notifiers;
-}
-
-rng->vhost_dev.acked_features = vdev->guest_features;
-ret = vhost_dev_start(&rng->vhost_dev, vdev, true);
-if (ret < 0) {
-error_report("Error starting vhost-user-rng: %d", -ret);
-goto err_guest_notifiers;
-}
-
-/*
- * guest_notifier_mask/pending not used yet, so just unmask
- * everything here. virtio-pci will do the right thing by
- * enabling/disabling irqfd.
- */
-for (i = 0; i < rng->vhost_dev.nvqs; i++) {
-vhost_virtqueue_mask(&rng->vhost_dev, vdev, i, false);
-}
-
-return;
-
-err_guest_notifiers:
-k->set_guest_notifiers(qbus->parent, rng->vhost_dev.nvqs, false);
-err_host_notifiers:
-vhost_dev_disable_notifiers(&rng->vhost_dev, vdev);
-}
-
-static void vu_rng_stop(VirtIODevice *vdev)
-{
-VHostUserRNG *rng = VHOST_USER_RNG(vdev);
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-int ret;
-
-if (!k->set_guest_notifiers) {
-return;
-}
-
-vhost_dev_stop(&rng->vhost_dev, vdev, true);
-
-ret = k->set_guest_notifiers(qbus->parent, rng->vhost_dev.nvqs, false);
-if (ret < 0) {
-error_report("vhost guest notifier cleanup failed: %d", ret);
-return;
-}
-
-vhost_dev_disable_notifiers(&rng->vhost_dev, vdev);
-}
-
-static void vu_rng_set_status(VirtIODevice *vdev, uint8_t status)
-{
-VHostUserRNG *rng = VHOST_USER_RNG(vdev);
-bool should_start = virtio_device_should_start(vdev, status);
-
-if (vhost_dev_is_started(&rng->vhost_dev) == should_start) {
-return;
-}
-
-if (should_start) {
-vu_rng_start(vdev);
-} else {
-vu_rng_stop(vdev);
-}
-}
-
-static uint64_t vu_rng_get_features(VirtIODevice *vdev,
-uint64_t requested_features, Error **errp)

[PATCH v8 6/7] hw/virtio: add vhost-user-snd and virtio-snd-pci devices

2023-11-07 Thread Alex Bennée
From: Manos Pitsidianakis 

Tested with rust-vmm vhost-user-sound daemon:

RUST_LOG=trace cargo run --bin vhost-user-sound -- --socket /tmp/snd.sock 
--backend null

Invocation:

qemu-system-x86_64  \
-qmp unix:./qmp-sock,server,wait=off  \
-m 4096 \
-numa node,memdev=mem \
-object 
memory-backend-file,id=mem,size=4G,mem-path=/dev/shm,share=on \
-D qemu.log \
-d guest_errors,trace:\*snd\*,trace:\*sound\*,trace:\*vhost\* \
-chardev socket,id=vsnd,path=/tmp/snd.sock \
-device vhost-user-snd-pci,chardev=vsnd,id=snd \
/path/to/disk

[AJB: imported from 
https://github.com/epilys/qemu-virtio-snd/commit/54ae1cdd15fef2d88e9e387a175f099a38c636f4.patch]

Signed-off-by: Alex Bennée 
Signed-off-by: Manos Pitsidianakis 

---
v7
  - s/parent/parent_obj/
  - add MAINTAINERS
  - add missing s-o-b
---
 MAINTAINERS|  7 +++
 include/hw/virtio/vhost-user-snd.h | 24 ++
 hw/virtio/vhost-user-snd-pci.c | 75 ++
 hw/virtio/vhost-user-snd.c | 67 ++
 hw/virtio/Kconfig  |  5 ++
 hw/virtio/meson.build  |  3 ++
 6 files changed, 181 insertions(+)
 create mode 100644 include/hw/virtio/vhost-user-snd.h
 create mode 100644 hw/virtio/vhost-user-snd-pci.c
 create mode 100644 hw/virtio/vhost-user-snd.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 2ff908d039..86c649784e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2286,6 +2286,13 @@ F: hw/virtio/vhost-user-gpio*
 F: include/hw/virtio/vhost-user-gpio.h
 F: tests/qtest/libqos/virtio-gpio.*
 
+vhost-user-snd
+M: Alex Bennée 
+R: Manos Pitsidianakis 
+S: Maintained
+F: hw/virtio/vhost-user-snd*
+F: include/hw/virtio/vhost-user-snd.h
+
 vhost-user-scmi
 R: mzama...@redhat.com
 S: Supported
diff --git a/include/hw/virtio/vhost-user-snd.h 
b/include/hw/virtio/vhost-user-snd.h
new file mode 100644
index 00..f9260116a7
--- /dev/null
+++ b/include/hw/virtio/vhost-user-snd.h
@@ -0,0 +1,24 @@
+/*
+ * Vhost-user Sound virtio device
+ *
+ * Copyright (c) 2021 Mathieu Poirier 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef QEMU_VHOST_USER_SND_H
+#define QEMU_VHOST_USER_SND_H
+
+#include "hw/virtio/virtio.h"
+#include "hw/virtio/vhost.h"
+#include "hw/virtio/vhost-user.h"
+#include "hw/virtio/vhost-user-base.h"
+
+#define TYPE_VHOST_USER_SND "vhost-user-snd"
+OBJECT_DECLARE_SIMPLE_TYPE(VHostUserSound, VHOST_USER_SND)
+
+struct VHostUserSound {
+VHostUserBase parent_obj;
+};
+
+#endif /* QEMU_VHOST_USER_SND_H */
diff --git a/hw/virtio/vhost-user-snd-pci.c b/hw/virtio/vhost-user-snd-pci.c
new file mode 100644
index 00..d61cfdae63
--- /dev/null
+++ b/hw/virtio/vhost-user-snd-pci.c
@@ -0,0 +1,75 @@
+/*
+ * Vhost-user Sound virtio device PCI glue
+ *
+ * Copyright (c) 2023 Manos Pitsidianakis 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/qdev-properties.h"
+#include "hw/virtio/vhost-user-snd.h"
+#include "hw/virtio/virtio-pci.h"
+
+struct VHostUserSoundPCI {
+VirtIOPCIProxy parent_obj;
+VHostUserSound vdev;
+};
+
+typedef struct VHostUserSoundPCI VHostUserSoundPCI;
+
+#define TYPE_VHOST_USER_SND_PCI "vhost-user-snd-pci-base"
+
+DECLARE_INSTANCE_CHECKER(VHostUserSoundPCI, VHOST_USER_SND_PCI,
+ TYPE_VHOST_USER_SND_PCI)
+
+static Property vhost_user_snd_pci_properties[] = {
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void vhost_user_snd_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
+{
+VHostUserSoundPCI *dev = VHOST_USER_SND_PCI(vpci_dev);
+DeviceState *vdev = DEVICE(&dev->vdev);
+
+vpci_dev->nvectors = 1;
+
+qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
+}
+
+static void vhost_user_snd_pci_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+k->realize = vhost_user_snd_pci_realize;
+set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
+device_class_set_props(dc, vhost_user_snd_pci_properties);
+pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+pcidev_k->device_id = 0; /* Set by virtio-pci based on virtio id */
+pcidev_k->revision = 0x00;
+pcidev_k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
+}
+
+static void vhost_user_snd_pci_instance_init(Object *obj)
+{
+VHostUserSoundPCI *dev = VHOST_USER_SND_PCI(obj);
+
+virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
+TYPE_VHOST_USER_SND);
+}
+
+static const VirtioPCIDeviceTypeInfo vhost_user_snd_pci_info = {
+.base_name = TYPE_VHOST_USER_SND_PCI,
+.non_transitional_name = "vhost-user-snd-pci",
+.instanc

[PATCH v8 2/7] hw/virtio: convert vhost-user-base to async shutdown

2023-11-07 Thread Alex Bennée
We are about to convert at least one stubs which was using the async
teardown so lets use it for all the cases.

Signed-off-by: Alex Bennée 
---
 hw/virtio/vhost-user-base.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c
index 620fa5cb4a..78cfa9a5bb 100644
--- a/hw/virtio/vhost-user-base.c
+++ b/hw/virtio/vhost-user-base.c
@@ -201,6 +201,8 @@ static int vub_connect(DeviceState *dev)
 return 0;
 }
 
+static void vub_event(void *opaque, QEMUChrEvent event);
+
 static void vub_disconnect(DeviceState *dev)
 {
 VirtIODevice *vdev = VIRTIO_DEVICE(dev);
@@ -211,9 +213,13 @@ static void vub_disconnect(DeviceState *dev)
 }
 vub->connected = false;
 
-if (vhost_dev_is_started(&vub->vhost_dev)) {
-vub_stop(vdev);
-}
+vub_stop(vdev);
+vhost_dev_cleanup(&vub->vhost_dev);
+
+/* Re-instate the event handler for new connections */
+qemu_chr_fe_set_handlers(&vub->chardev,
+ NULL, NULL, vub_event,
+ NULL, dev, NULL, true);
 }
 
 static void vub_event(void *opaque, QEMUChrEvent event)
@@ -230,7 +236,9 @@ static void vub_event(void *opaque, QEMUChrEvent event)
 }
 break;
 case CHR_EVENT_CLOSED:
-vub_disconnect(dev);
+/* defer close until later to avoid circular close */
+vhost_user_async_close(dev, &vub->chardev, &vub->vhost_dev,
+   vub_disconnect, vub_event);
 break;
 case CHR_EVENT_BREAK:
 case CHR_EVENT_MUX_IN:
-- 
2.39.2




qemu-block@nongnu.org

2023-11-07 Thread Alex Bennée
A lot of our vhost-user stubs are large chunks of boilerplate that do
(mostly) the same thing. This series continues the cleanups by
splitting the vhost-user-base and vhost-user-generic implementations.
After adding a new vq_size property the rng, gpio and i2c vhost-user
devices become simple specialisations of the common base defining the
ID, number of queues and potentially the config handling.

I've also added Manos' vhost-user-sound while I was at it.

Changes
---

v8
  - scrubbed errant Message-Id

v7
  - various review comments
  - move to async teardown (fixes CI failure)

v6
  - re-base to current master
  - make vhost-user-device abstract
  - mention abstractness in docs

v5
  - addressing comments and tags
  - improved the docs

v4
  - dropped the F_TRANSPORT work for another series
  - added vhost-user-sound

Alex Bennée (6):
  virtio: split into vhost-user-base and vhost-user-device
  hw/virtio: convert vhost-user-base to async shutdown
  hw/virtio: derive vhost-user-rng from vhost-user-base
  hw/virtio: derive vhost-user-gpio from vhost-user-base
  hw/virtio: derive vhost-user-i2c from vhost-user-base
  docs/system: add a basic enumeration of vhost-user devices

Manos Pitsidianakis (1):
  hw/virtio: add vhost-user-snd and virtio-snd-pci devices

 MAINTAINERS   |  13 +
 docs/system/devices/vhost-user-rng.rst|   2 +
 docs/system/devices/vhost-user.rst|  70 ++-
 ...{vhost-user-device.h => vhost-user-base.h} |  21 +-
 include/hw/virtio/vhost-user-gpio.h   |  25 +-
 include/hw/virtio/vhost-user-i2c.h|  14 +-
 include/hw/virtio/vhost-user-rng.h|  13 +-
 include/hw/virtio/vhost-user-snd.h|  24 ++
 hw/virtio/vhost-user-base.c   | 354 +++
 hw/virtio/vhost-user-device-pci.c |  13 +-
 hw/virtio/vhost-user-device.c | 338 +--
 hw/virtio/vhost-user-gpio.c   | 406 +-
 hw/virtio/vhost-user-i2c.c| 272 +---
 hw/virtio/vhost-user-rng.c| 278 +---
 hw/virtio/vhost-user-snd-pci.c|  75 
 hw/virtio/vhost-user-snd.c|  67 +++
 hw/virtio/Kconfig |   5 +
 hw/virtio/meson.build |  23 +-
 18 files changed, 719 insertions(+), 1294 deletions(-)
 rename include/hw/virtio/{vhost-user-device.h => vhost-user-base.h} (71%)
 create mode 100644 include/hw/virtio/vhost-user-snd.h
 create mode 100644 hw/virtio/vhost-user-base.c
 create mode 100644 hw/virtio/vhost-user-snd-pci.c
 create mode 100644 hw/virtio/vhost-user-snd.c

-- 
2.39.2




qemu-block@nongnu.org

2023-11-07 Thread Alex Bennée
A lot of our vhost-user stubs are large chunks of boilerplate that do
(mostly) the same thing. This series continues the cleanups by
splitting the vhost-user-base and vhost-user-generic implementations.
After adding a new vq_size property the rng, gpio and i2c vhost-user
devices become simple specialisations of the common base defining the
ID, number of queues and potentially the config handling.

I've also added Manos' vhost-user-sound while I was at it.

Changes
---

v7
  - various review comments
  - move to async teardown (fixes CI failure)

v6
  - re-base to current master
  - make vhost-user-device abstract
  - mention abstractness in docs

v5
  - addressing comments and tags
  - improved the docs

v4
  - dropped the F_TRANSPORT work for another series
  - added vhost-user-sound

Alex Bennée (6):
  virtio: split into vhost-user-base and vhost-user-device
  hw/virtio: convert vhost-user-base to async shutdown
  hw/virtio: derive vhost-user-rng from vhost-user-base
  hw/virtio: derive vhost-user-gpio from vhost-user-base
  hw/virtio: derive vhost-user-i2c from vhost-user-base
  docs/system: add a basic enumeration of vhost-user devices

Manos Pitsidianakis (1):
  hw/virtio: add vhost-user-snd and virtio-snd-pci devices

 MAINTAINERS   |  13 +
 docs/system/devices/vhost-user-rng.rst|   2 +
 docs/system/devices/vhost-user.rst|  70 ++-
 ...{vhost-user-device.h => vhost-user-base.h} |  21 +-
 include/hw/virtio/vhost-user-gpio.h   |  25 +-
 include/hw/virtio/vhost-user-i2c.h|  14 +-
 include/hw/virtio/vhost-user-rng.h|  13 +-
 include/hw/virtio/vhost-user-snd.h|  24 ++
 hw/virtio/vhost-user-base.c   | 354 +++
 hw/virtio/vhost-user-device-pci.c |  13 +-
 hw/virtio/vhost-user-device.c | 338 +--
 hw/virtio/vhost-user-gpio.c   | 406 +-
 hw/virtio/vhost-user-i2c.c| 272 +---
 hw/virtio/vhost-user-rng.c| 278 +---
 hw/virtio/vhost-user-snd-pci.c|  75 
 hw/virtio/vhost-user-snd.c|  67 +++
 hw/virtio/Kconfig |   5 +
 hw/virtio/meson.build |  23 +-
 18 files changed, 719 insertions(+), 1294 deletions(-)
 rename include/hw/virtio/{vhost-user-device.h => vhost-user-base.h} (71%)
 create mode 100644 include/hw/virtio/vhost-user-snd.h
 create mode 100644 hw/virtio/vhost-user-base.c
 create mode 100644 hw/virtio/vhost-user-snd-pci.c
 create mode 100644 hw/virtio/vhost-user-snd.c

-- 
2.39.2




[PATCH v7 6/7] hw/virtio: add vhost-user-snd and virtio-snd-pci devices

2023-11-07 Thread Alex Bennée
From: Manos Pitsidianakis 

Tested with rust-vmm vhost-user-sound daemon:

RUST_LOG=trace cargo run --bin vhost-user-sound -- --socket /tmp/snd.sock 
--backend null

Invocation:

qemu-system-x86_64  \
-qmp unix:./qmp-sock,server,wait=off  \
-m 4096 \
-numa node,memdev=mem \
-object 
memory-backend-file,id=mem,size=4G,mem-path=/dev/shm,share=on \
-D qemu.log \
-d guest_errors,trace:\*snd\*,trace:\*sound\*,trace:\*vhost\* \
-chardev socket,id=vsnd,path=/tmp/snd.sock \
-device vhost-user-snd-pci,chardev=vsnd,id=snd \
/path/to/disk

[AJB: imported from 
https://github.com/epilys/qemu-virtio-snd/commit/54ae1cdd15fef2d88e9e387a175f099a38c636f4.patch]

Signed-off-by: Alex Bennée 
Signed-off-by: Manos Pitsidianakis 

---
v7
  - s/parent/parent_obj/
  - add MAINTAINERS
  - add missing s-o-b
---
 MAINTAINERS|  7 +++
 include/hw/virtio/vhost-user-snd.h | 24 ++
 hw/virtio/vhost-user-snd-pci.c | 75 ++
 hw/virtio/vhost-user-snd.c | 67 ++
 hw/virtio/Kconfig  |  5 ++
 hw/virtio/meson.build  |  3 ++
 6 files changed, 181 insertions(+)
 create mode 100644 include/hw/virtio/vhost-user-snd.h
 create mode 100644 hw/virtio/vhost-user-snd-pci.c
 create mode 100644 hw/virtio/vhost-user-snd.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 2ff908d039..86c649784e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2286,6 +2286,13 @@ F: hw/virtio/vhost-user-gpio*
 F: include/hw/virtio/vhost-user-gpio.h
 F: tests/qtest/libqos/virtio-gpio.*
 
+vhost-user-snd
+M: Alex Bennée 
+R: Manos Pitsidianakis 
+S: Maintained
+F: hw/virtio/vhost-user-snd*
+F: include/hw/virtio/vhost-user-snd.h
+
 vhost-user-scmi
 R: mzama...@redhat.com
 S: Supported
diff --git a/include/hw/virtio/vhost-user-snd.h 
b/include/hw/virtio/vhost-user-snd.h
new file mode 100644
index 00..f9260116a7
--- /dev/null
+++ b/include/hw/virtio/vhost-user-snd.h
@@ -0,0 +1,24 @@
+/*
+ * Vhost-user Sound virtio device
+ *
+ * Copyright (c) 2021 Mathieu Poirier 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef QEMU_VHOST_USER_SND_H
+#define QEMU_VHOST_USER_SND_H
+
+#include "hw/virtio/virtio.h"
+#include "hw/virtio/vhost.h"
+#include "hw/virtio/vhost-user.h"
+#include "hw/virtio/vhost-user-base.h"
+
+#define TYPE_VHOST_USER_SND "vhost-user-snd"
+OBJECT_DECLARE_SIMPLE_TYPE(VHostUserSound, VHOST_USER_SND)
+
+struct VHostUserSound {
+VHostUserBase parent_obj;
+};
+
+#endif /* QEMU_VHOST_USER_SND_H */
diff --git a/hw/virtio/vhost-user-snd-pci.c b/hw/virtio/vhost-user-snd-pci.c
new file mode 100644
index 00..d61cfdae63
--- /dev/null
+++ b/hw/virtio/vhost-user-snd-pci.c
@@ -0,0 +1,75 @@
+/*
+ * Vhost-user Sound virtio device PCI glue
+ *
+ * Copyright (c) 2023 Manos Pitsidianakis 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/qdev-properties.h"
+#include "hw/virtio/vhost-user-snd.h"
+#include "hw/virtio/virtio-pci.h"
+
+struct VHostUserSoundPCI {
+VirtIOPCIProxy parent_obj;
+VHostUserSound vdev;
+};
+
+typedef struct VHostUserSoundPCI VHostUserSoundPCI;
+
+#define TYPE_VHOST_USER_SND_PCI "vhost-user-snd-pci-base"
+
+DECLARE_INSTANCE_CHECKER(VHostUserSoundPCI, VHOST_USER_SND_PCI,
+ TYPE_VHOST_USER_SND_PCI)
+
+static Property vhost_user_snd_pci_properties[] = {
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void vhost_user_snd_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
+{
+VHostUserSoundPCI *dev = VHOST_USER_SND_PCI(vpci_dev);
+DeviceState *vdev = DEVICE(&dev->vdev);
+
+vpci_dev->nvectors = 1;
+
+qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
+}
+
+static void vhost_user_snd_pci_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+k->realize = vhost_user_snd_pci_realize;
+set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
+device_class_set_props(dc, vhost_user_snd_pci_properties);
+pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+pcidev_k->device_id = 0; /* Set by virtio-pci based on virtio id */
+pcidev_k->revision = 0x00;
+pcidev_k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
+}
+
+static void vhost_user_snd_pci_instance_init(Object *obj)
+{
+VHostUserSoundPCI *dev = VHOST_USER_SND_PCI(obj);
+
+virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
+TYPE_VHOST_USER_SND);
+}
+
+static const VirtioPCIDeviceTypeInfo vhost_user_snd_pci_info = {
+.base_name = TYPE_VHOST_USER_SND_PCI,
+.non_transitional_name = "vhost-user-snd-pci",
+.instanc

[PATCH v7 5/7] hw/virtio: derive vhost-user-i2c from vhost-user-base

2023-11-07 Thread Alex Bennée
Now we can take advantage of the new base class and make
vhost-user-i2c a much simpler boilerplate wrapper. Also as this
doesn't require any target specific hacks we only need to build the
stubs once.

Acked-by: Mark Cave-Ayland 
Acked-by: Viresh Kumar 
Signed-off-by: Alex Bennée 

---
v7
  - s/parent/parent_obj/
---
 include/hw/virtio/vhost-user-i2c.h |  14 +-
 hw/virtio/vhost-user-i2c.c | 272 ++---
 hw/virtio/meson.build  |   5 +-
 3 files changed, 23 insertions(+), 268 deletions(-)

diff --git a/include/hw/virtio/vhost-user-i2c.h 
b/include/hw/virtio/vhost-user-i2c.h
index 0f7acd40e3..a9b5612ad0 100644
--- a/include/hw/virtio/vhost-user-i2c.h
+++ b/include/hw/virtio/vhost-user-i2c.h
@@ -9,23 +9,17 @@
 #ifndef QEMU_VHOST_USER_I2C_H
 #define QEMU_VHOST_USER_I2C_H
 
+#include "hw/virtio/virtio.h"
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
+#include "hw/virtio/vhost-user-base.h"
 
 #define TYPE_VHOST_USER_I2C "vhost-user-i2c-device"
+
 OBJECT_DECLARE_SIMPLE_TYPE(VHostUserI2C, VHOST_USER_I2C)
 
 struct VHostUserI2C {
-VirtIODevice parent;
-CharBackend chardev;
-struct vhost_virtqueue *vhost_vq;
-struct vhost_dev vhost_dev;
-VhostUserState vhost_user;
-VirtQueue *vq;
-bool connected;
+VHostUserBase parent_obj;
 };
 
-/* Virtio Feature bits */
-#define VIRTIO_I2C_F_ZERO_LENGTH_REQUEST   0
-
 #endif /* QEMU_VHOST_USER_I2C_H */
diff --git a/hw/virtio/vhost-user-i2c.c b/hw/virtio/vhost-user-i2c.c
index 4eef3f0633..a464f5e039 100644
--- a/hw/virtio/vhost-user-i2c.c
+++ b/hw/virtio/vhost-user-i2c.c
@@ -14,253 +14,22 @@
 #include "qemu/error-report.h"
 #include "standard-headers/linux/virtio_ids.h"
 
-static const int feature_bits[] = {
-VIRTIO_I2C_F_ZERO_LENGTH_REQUEST,
-VIRTIO_F_RING_RESET,
-VHOST_INVALID_FEATURE_BIT
+static Property vi2c_properties[] = {
+DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
+DEFINE_PROP_END_OF_LIST(),
 };
 
-static void vu_i2c_start(VirtIODevice *vdev)
-{
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-int ret, i;
-
-if (!k->set_guest_notifiers) {
-error_report("binding does not support guest notifiers");
-return;
-}
-
-ret = vhost_dev_enable_notifiers(&i2c->vhost_dev, vdev);
-if (ret < 0) {
-error_report("Error enabling host notifiers: %d", -ret);
-return;
-}
-
-ret = k->set_guest_notifiers(qbus->parent, i2c->vhost_dev.nvqs, true);
-if (ret < 0) {
-error_report("Error binding guest notifier: %d", -ret);
-goto err_host_notifiers;
-}
-
-i2c->vhost_dev.acked_features = vdev->guest_features;
-
-ret = vhost_dev_start(&i2c->vhost_dev, vdev, true);
-if (ret < 0) {
-error_report("Error starting vhost-user-i2c: %d", -ret);
-goto err_guest_notifiers;
-}
-
-/*
- * guest_notifier_mask/pending not used yet, so just unmask
- * everything here. virtio-pci will do the right thing by
- * enabling/disabling irqfd.
- */
-for (i = 0; i < i2c->vhost_dev.nvqs; i++) {
-vhost_virtqueue_mask(&i2c->vhost_dev, vdev, i, false);
-}
-
-return;
-
-err_guest_notifiers:
-k->set_guest_notifiers(qbus->parent, i2c->vhost_dev.nvqs, false);
-err_host_notifiers:
-vhost_dev_disable_notifiers(&i2c->vhost_dev, vdev);
-}
-
-static void vu_i2c_stop(VirtIODevice *vdev)
-{
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-int ret;
-
-if (!k->set_guest_notifiers) {
-return;
-}
-
-vhost_dev_stop(&i2c->vhost_dev, vdev, true);
-
-ret = k->set_guest_notifiers(qbus->parent, i2c->vhost_dev.nvqs, false);
-if (ret < 0) {
-error_report("vhost guest notifier cleanup failed: %d", ret);
-return;
-}
-
-vhost_dev_disable_notifiers(&i2c->vhost_dev, vdev);
-}
-
-static void vu_i2c_set_status(VirtIODevice *vdev, uint8_t status)
-{
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-bool should_start = virtio_device_should_start(vdev, status);
-
-if (vhost_dev_is_started(&i2c->vhost_dev) == should_start) {
-return;
-}
-
-if (should_start) {
-vu_i2c_start(vdev);
-} else {
-vu_i2c_stop(vdev);
-}
-}
-
-static uint64_t vu_i2c_get_features(VirtIODevice *vdev,
-uint64_t requested_features, Error **errp)
-{
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-
-virtio_add_feature(&requested_features, VIRTIO_I2C_F_ZERO_LENGTH_REQUEST);
-return vhost_get_features

[PATCH v7 2/7] hw/virtio: convert vhost-user-base to async shutdown

2023-11-07 Thread Alex Bennée
We are about to convert at least one stubs which was using the async
teardown so lets use it for all the cases.

Signed-off-by: Alex Bennée 
---
 hw/virtio/vhost-user-base.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c
index 620fa5cb4a..78cfa9a5bb 100644
--- a/hw/virtio/vhost-user-base.c
+++ b/hw/virtio/vhost-user-base.c
@@ -201,6 +201,8 @@ static int vub_connect(DeviceState *dev)
 return 0;
 }
 
+static void vub_event(void *opaque, QEMUChrEvent event);
+
 static void vub_disconnect(DeviceState *dev)
 {
 VirtIODevice *vdev = VIRTIO_DEVICE(dev);
@@ -211,9 +213,13 @@ static void vub_disconnect(DeviceState *dev)
 }
 vub->connected = false;
 
-if (vhost_dev_is_started(&vub->vhost_dev)) {
-vub_stop(vdev);
-}
+vub_stop(vdev);
+vhost_dev_cleanup(&vub->vhost_dev);
+
+/* Re-instate the event handler for new connections */
+qemu_chr_fe_set_handlers(&vub->chardev,
+ NULL, NULL, vub_event,
+ NULL, dev, NULL, true);
 }
 
 static void vub_event(void *opaque, QEMUChrEvent event)
@@ -230,7 +236,9 @@ static void vub_event(void *opaque, QEMUChrEvent event)
 }
 break;
 case CHR_EVENT_CLOSED:
-vub_disconnect(dev);
+/* defer close until later to avoid circular close */
+vhost_user_async_close(dev, &vub->chardev, &vub->vhost_dev,
+   vub_disconnect, vub_event);
 break;
 case CHR_EVENT_BREAK:
 case CHR_EVENT_MUX_IN:
-- 
2.39.2




[PATCH v7 4/7] hw/virtio: derive vhost-user-gpio from vhost-user-base

2023-11-07 Thread Alex Bennée
Now the new base class supports config handling we can take advantage
and make vhost-user-gpio a much simpler boilerplate wrapper. Also as
this doesn't require any target specific hacks we only need to build
the stubs once.

Acked-by: Mark Cave-Ayland 
Acked-by: Viresh Kumar 
Signed-off-by: Alex Bennée 

---
v7
  - s/parent/parent_obj/
---
 include/hw/virtio/vhost-user-gpio.h |  25 +-
 hw/virtio/vhost-user-gpio.c | 406 ++--
 hw/virtio/meson.build   |   5 +-
 3 files changed, 22 insertions(+), 414 deletions(-)

diff --git a/include/hw/virtio/vhost-user-gpio.h 
b/include/hw/virtio/vhost-user-gpio.h
index a9d3f9b049..5814a8400a 100644
--- a/include/hw/virtio/vhost-user-gpio.h
+++ b/include/hw/virtio/vhost-user-gpio.h
@@ -12,34 +12,13 @@
 #include "hw/virtio/virtio.h"
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
-#include "standard-headers/linux/virtio_gpio.h"
-#include "chardev/char-fe.h"
+#include "hw/virtio/vhost-user-base.h"
 
 #define TYPE_VHOST_USER_GPIO "vhost-user-gpio-device"
 OBJECT_DECLARE_SIMPLE_TYPE(VHostUserGPIO, VHOST_USER_GPIO);
 
 struct VHostUserGPIO {
-/*< private >*/
-VirtIODevice parent_obj;
-CharBackend chardev;
-struct virtio_gpio_config config;
-struct vhost_virtqueue *vhost_vqs;
-struct vhost_dev vhost_dev;
-VhostUserState vhost_user;
-VirtQueue *command_vq;
-VirtQueue *interrupt_vq;
-/**
- * There are at least two steps of initialization of the
- * vhost-user device. The first is a "connect" step and
- * second is a "start" step. Make a separation between
- * those initialization phases by using two fields.
- *
- * @connected: see vu_gpio_connect()/vu_gpio_disconnect()
- * @started_vu: see vu_gpio_start()/vu_gpio_stop()
- */
-bool connected;
-bool started_vu;
-/*< public >*/
+VHostUserBase parent_obj;
 };
 
 #endif /* _QEMU_VHOST_USER_GPIO_H */
diff --git a/hw/virtio/vhost-user-gpio.c b/hw/virtio/vhost-user-gpio.c
index aff2d7eff6..9f37c25415 100644
--- a/hw/virtio/vhost-user-gpio.c
+++ b/hw/virtio/vhost-user-gpio.c
@@ -11,387 +11,25 @@
 #include "hw/qdev-properties.h"
 #include "hw/virtio/virtio-bus.h"
 #include "hw/virtio/vhost-user-gpio.h"
-#include "qemu/error-report.h"
 #include "standard-headers/linux/virtio_ids.h"
-#include "trace.h"
+#include "standard-headers/linux/virtio_gpio.h"
 
-#define VHOST_NVQS 2
-
-/* Features required from VirtIO */
-static const int feature_bits[] = {
-VIRTIO_F_VERSION_1,
-VIRTIO_F_NOTIFY_ON_EMPTY,
-VIRTIO_RING_F_INDIRECT_DESC,
-VIRTIO_RING_F_EVENT_IDX,
-VIRTIO_GPIO_F_IRQ,
-VIRTIO_F_RING_RESET,
-VHOST_INVALID_FEATURE_BIT
-};
-
-static void vu_gpio_get_config(VirtIODevice *vdev, uint8_t *config)
-{
-VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev);
-
-memcpy(config, &gpio->config, sizeof(gpio->config));
-}
-
-static int vu_gpio_config_notifier(struct vhost_dev *dev)
-{
-VHostUserGPIO *gpio = VHOST_USER_GPIO(dev->vdev);
-
-memcpy(dev->vdev->config, &gpio->config, sizeof(gpio->config));
-virtio_notify_config(dev->vdev);
-
-return 0;
-}
-
-const VhostDevConfigOps gpio_ops = {
-.vhost_dev_config_notifier = vu_gpio_config_notifier,
+static Property vgpio_properties[] = {
+DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
+DEFINE_PROP_END_OF_LIST(),
 };
 
-static int vu_gpio_start(VirtIODevice *vdev)
-{
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev);
-struct vhost_dev *vhost_dev = &gpio->vhost_dev;
-int ret, i;
-
-if (!k->set_guest_notifiers) {
-error_report("binding does not support guest notifiers");
-return -ENOSYS;
-}
-
-ret = vhost_dev_enable_notifiers(vhost_dev, vdev);
-if (ret < 0) {
-error_report("Error enabling host notifiers: %d", ret);
-return ret;
-}
-
-ret = k->set_guest_notifiers(qbus->parent, vhost_dev->nvqs, true);
-if (ret < 0) {
-error_report("Error binding guest notifier: %d", ret);
-goto err_host_notifiers;
-}
-
-/*
- * Before we start up we need to ensure we have the final feature
- * set needed for the vhost configuration. The backend may also
- * apply backend_features when the feature set is sent.
- */
-vhost_ack_features(&gpio->vhost_dev, feature_bits, vdev->guest_features);
-
-ret = vhost_dev_start(&gpio->vhost_dev, vdev, false);
-if (ret < 0) {
-error_report("Error starting vhost-user-gpio: %d", ret);
-goto err_guest_notifiers;
-}
-gpio->start

[PATCH v7 7/7] docs/system: add a basic enumeration of vhost-user devices

2023-11-07 Thread Alex Bennée
Make it clear the vhost-user-device is intended for expert use only.

Signed-off-by: Alex Bennée 
Message-Id: <20231009095937.195728-7-alex.ben...@linaro.org>

---
v5
  - split vhost-user-device out of the table
  - sort the table alphabetically
  - add sound and scmi devices
v6
  - add note re vhost-user-device
v7
  - fix patching description
---
 docs/system/devices/vhost-user-rng.rst |  2 +
 docs/system/devices/vhost-user.rst | 70 +-
 2 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/docs/system/devices/vhost-user-rng.rst 
b/docs/system/devices/vhost-user-rng.rst
index a145d4105c..ead1405326 100644
--- a/docs/system/devices/vhost-user-rng.rst
+++ b/docs/system/devices/vhost-user-rng.rst
@@ -1,3 +1,5 @@
+.. _vhost_user_rng:
+
 QEMU vhost-user-rng - RNG emulation
 ===
 
diff --git a/docs/system/devices/vhost-user.rst 
b/docs/system/devices/vhost-user.rst
index a80e95a48a..c6afc4836f 100644
--- a/docs/system/devices/vhost-user.rst
+++ b/docs/system/devices/vhost-user.rst
@@ -8,13 +8,81 @@ outside of QEMU itself. To do this there are a number of 
things
 required.
 
 vhost-user device
-===
+=
 
 These are simple stub devices that ensure the VirtIO device is visible
 to the guest. The code is mostly boilerplate although each device has
 a ``chardev`` option which specifies the ID of the ``--chardev``
 device that connects via a socket to the vhost-user *daemon*.
 
+Each device will have an virtio-mmio and virtio-pci variant. See your
+platform details for what sort of virtio bus to use.
+
+.. list-table:: vhost-user devices
+  :widths: 20 20 60
+  :header-rows: 1
+
+  * - Device
+- Type
+- Notes
+  * - vhost-user-blk
+- Block storage
+- See contrib/vhost-user-blk
+  * - vhost-user-fs
+- File based storage driver
+- See https://gitlab.com/virtio-fs/virtiofsd
+  * - vhost-user-gpio
+- Proxy gpio pins to host
+- See https://github.com/rust-vmm/vhost-device
+  * - vhost-user-gpu
+- GPU driver
+- See contrib/vhost-user-gpu
+  * - vhost-user-i2c
+- Proxy i2c devices to host
+- See https://github.com/rust-vmm/vhost-device
+  * - vhost-user-input
+- Generic input driver
+- See contrib/vhost-user-input
+  * - vhost-user-rng
+- Entropy driver
+- :ref:`vhost_user_rng`
+  * - vhost-user-scmi
+- System Control and Management Interface
+- See https://github.com/rust-vmm/vhost-device
+  * - vhost-user-snd
+- Audio device
+- See https://github.com/rust-vmm/vhost-device/staging
+  * - vhost-user-scsi
+- SCSI based storage
+- See contrib/vhost-user-scsi
+  * - vhost-user-vsock
+- Socket based communication
+- See https://github.com/rust-vmm/vhost-device
+
+The referenced *daemons* are not exhaustive, any conforming backend
+implementing the device and using the vhost-user protocol should work.
+
+vhost-user-device
+^
+
+The vhost-user-device is a generic development device intended for
+expert use while developing new backends. The user needs to specify
+all the required parameters including:
+
+  - Device ``virtio-id``
+  - The ``num_vqs`` it needs and their ``vq_size``
+  - The ``config_size`` if needed
+
+.. note::
+  To prevent user confusion you cannot currently instantiate
+  vhost-user-device without first patching out::
+
+/* Reason: stop inexperienced users confusing themselves */
+dc->user_creatable = false;
+
+  in ``vhost-user-device.c`` and ``vhost-user-device-pci.c`` file and
+  rebuilding.
+
 vhost-user daemon
 =
 
-- 
2.39.2




[PATCH v7 3/7] hw/virtio: derive vhost-user-rng from vhost-user-base

2023-11-07 Thread Alex Bennée
Now we can take advantage of our new base class and make
vhost-user-rng a much simpler boilerplate wrapper. Also as this
doesn't require any target specific hacks we only need to build the
stubs once.

Acked-by: Mark Cave-Ayland 
Signed-off-by: Alex Bennée 

---
v5
  - don't remove the in-QEMU RNG emulation!
v7
  - s/parent/parent_obj/
---
 include/hw/virtio/vhost-user-rng.h |  13 +-
 hw/virtio/vhost-user-rng.c | 278 +++--
 hw/virtio/meson.build  |   9 +-
 3 files changed, 31 insertions(+), 269 deletions(-)

diff --git a/include/hw/virtio/vhost-user-rng.h 
b/include/hw/virtio/vhost-user-rng.h
index ddd9f01eea..10868c7de4 100644
--- a/include/hw/virtio/vhost-user-rng.h
+++ b/include/hw/virtio/vhost-user-rng.h
@@ -12,22 +12,13 @@
 #include "hw/virtio/virtio.h"
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
-#include "chardev/char-fe.h"
+#include "hw/virtio/vhost-user-base.h"
 
 #define TYPE_VHOST_USER_RNG "vhost-user-rng"
 OBJECT_DECLARE_SIMPLE_TYPE(VHostUserRNG, VHOST_USER_RNG)
 
 struct VHostUserRNG {
-/*< private >*/
-VirtIODevice parent;
-CharBackend chardev;
-struct vhost_virtqueue *vhost_vq;
-struct vhost_dev vhost_dev;
-VhostUserState vhost_user;
-VirtQueue *req_vq;
-bool connected;
-
-/*< public >*/
+VHostUserBase parent_obj;
 };
 
 #endif /* QEMU_VHOST_USER_RNG_H */
diff --git a/hw/virtio/vhost-user-rng.c b/hw/virtio/vhost-user-rng.c
index efc54cd3fb..01879c863d 100644
--- a/hw/virtio/vhost-user-rng.c
+++ b/hw/virtio/vhost-user-rng.c
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2021 Mathieu Poirier 
  *
- * Implementation seriously tailored on vhost-user-i2c.c
+ * Simple wrapper of the generic vhost-user-device.
  *
  * SPDX-License-Identifier: GPL-2.0-or-later
  */
@@ -13,281 +13,47 @@
 #include "hw/qdev-properties.h"
 #include "hw/virtio/virtio-bus.h"
 #include "hw/virtio/vhost-user-rng.h"
-#include "qemu/error-report.h"
 #include "standard-headers/linux/virtio_ids.h"
 
-static const int feature_bits[] = {
-VIRTIO_F_RING_RESET,
-VHOST_INVALID_FEATURE_BIT
-};
-
-static void vu_rng_start(VirtIODevice *vdev)
-{
-VHostUserRNG *rng = VHOST_USER_RNG(vdev);
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-int ret;
-int i;
-
-if (!k->set_guest_notifiers) {
-error_report("binding does not support guest notifiers");
-return;
-}
-
-ret = vhost_dev_enable_notifiers(&rng->vhost_dev, vdev);
-if (ret < 0) {
-error_report("Error enabling host notifiers: %d", -ret);
-return;
-}
-
-ret = k->set_guest_notifiers(qbus->parent, rng->vhost_dev.nvqs, true);
-if (ret < 0) {
-error_report("Error binding guest notifier: %d", -ret);
-goto err_host_notifiers;
-}
-
-rng->vhost_dev.acked_features = vdev->guest_features;
-ret = vhost_dev_start(&rng->vhost_dev, vdev, true);
-if (ret < 0) {
-error_report("Error starting vhost-user-rng: %d", -ret);
-goto err_guest_notifiers;
-}
-
-/*
- * guest_notifier_mask/pending not used yet, so just unmask
- * everything here. virtio-pci will do the right thing by
- * enabling/disabling irqfd.
- */
-for (i = 0; i < rng->vhost_dev.nvqs; i++) {
-vhost_virtqueue_mask(&rng->vhost_dev, vdev, i, false);
-}
-
-return;
-
-err_guest_notifiers:
-k->set_guest_notifiers(qbus->parent, rng->vhost_dev.nvqs, false);
-err_host_notifiers:
-vhost_dev_disable_notifiers(&rng->vhost_dev, vdev);
-}
-
-static void vu_rng_stop(VirtIODevice *vdev)
-{
-VHostUserRNG *rng = VHOST_USER_RNG(vdev);
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-int ret;
-
-if (!k->set_guest_notifiers) {
-return;
-}
-
-vhost_dev_stop(&rng->vhost_dev, vdev, true);
-
-ret = k->set_guest_notifiers(qbus->parent, rng->vhost_dev.nvqs, false);
-if (ret < 0) {
-error_report("vhost guest notifier cleanup failed: %d", ret);
-return;
-}
-
-vhost_dev_disable_notifiers(&rng->vhost_dev, vdev);
-}
-
-static void vu_rng_set_status(VirtIODevice *vdev, uint8_t status)
-{
-VHostUserRNG *rng = VHOST_USER_RNG(vdev);
-bool should_start = virtio_device_should_start(vdev, status);
-
-if (vhost_dev_is_started(&rng->vhost_dev) == should_start) {
-return;
-}
-
-if (should_start) {
-vu_rng_start(vdev);
-} else {
-vu_rng_stop(vdev);
-}
-}
-
-static uint64_t vu_rng_get_features(VirtIODevice *vdev,
-uint64_t requested_features, Error **errp)

[PATCH v7 1/7] virtio: split into vhost-user-base and vhost-user-device

2023-11-07 Thread Alex Bennée
Lets keep a cleaner split between the base class and the derived
vhost-user-device which we can use for generic vhost-user stubs. This
includes an update to introduce the vq_size property so the number of
entries in a virtq can be defined.

Signed-off-by: Alex Bennée 

---
v5
  - s/parent/parent_obj/
  - remove left over vhost-user-device.h
  - use DEFINE_TYPES
v6
  - rebase and set .abstract = true for vhost-user-device
v7
  - checkpatch line length + MAINTAINERS
  - s/abstract = true/dc->user_creatable = false/ for both mmio and pci
---
 MAINTAINERS   |   6 +
 ...{vhost-user-device.h => vhost-user-base.h} |  21 +-
 hw/virtio/vhost-user-base.c   | 346 ++
 hw/virtio/vhost-user-device-pci.c |  13 +-
 hw/virtio/vhost-user-device.c | 338 +
 hw/virtio/meson.build |   1 +
 6 files changed, 383 insertions(+), 342 deletions(-)
 rename include/hw/virtio/{vhost-user-device.h => vhost-user-base.h} (71%)
 create mode 100644 hw/virtio/vhost-user-base.c

diff --git a/MAINTAINERS b/MAINTAINERS
index b86ea7f75a..2ff908d039 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2263,6 +2263,12 @@ F: include/sysemu/rng*.h
 F: backends/rng*.c
 F: tests/qtest/virtio-rng-test.c
 
+vhost-user-stubs
+M: Alex Bennée 
+S: Maintained
+F: hw/virtio/vhost-user-base.c
+F: hw/virtio/vhost-user-device*
+
 vhost-user-rng
 M: Mathieu Poirier 
 S: Supported
diff --git a/include/hw/virtio/vhost-user-device.h 
b/include/hw/virtio/vhost-user-base.h
similarity index 71%
rename from include/hw/virtio/vhost-user-device.h
rename to include/hw/virtio/vhost-user-base.h
index 3ddf88a146..51d0968b89 100644
--- a/include/hw/virtio/vhost-user-device.h
+++ b/include/hw/virtio/vhost-user-base.h
@@ -6,8 +6,8 @@
  * SPDX-License-Identifier: GPL-2.0-or-later
  */
 
-#ifndef QEMU_VHOST_USER_DEVICE_H
-#define QEMU_VHOST_USER_DEVICE_H
+#ifndef QEMU_VHOST_USER_BASE_H
+#define QEMU_VHOST_USER_BASE_H
 
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
@@ -17,11 +17,13 @@
 OBJECT_DECLARE_TYPE(VHostUserBase, VHostUserBaseClass, VHOST_USER_BASE)
 
 struct VHostUserBase {
-VirtIODevice parent;
+VirtIODevice parent_obj;
+
 /* Properties */
 CharBackend chardev;
 uint16_t virtio_id;
 uint32_t num_vqs;
+uint32_t vq_size; /* can't exceed VIRTIO_QUEUE_MAX */
 uint32_t config_size;
 /* State tracking */
 VhostUserState vhost_user;
@@ -31,16 +33,17 @@ struct VHostUserBase {
 bool connected;
 };
 
-/* needed so we can use the base realize after specialisation
-   tweaks */
+/*
+ * Needed so we can use the base realize after specialisation
+ * tweaks
+ */
 struct VHostUserBaseClass {
-/*< private >*/
 VirtioDeviceClass parent_class;
-/*< public >*/
+
 DeviceRealize parent_realize;
 };
 
-/* shared for the benefit of the derived pci class */
+
 #define TYPE_VHOST_USER_DEVICE "vhost-user-device"
 
-#endif /* QEMU_VHOST_USER_DEVICE_H */
+#endif /* QEMU_VHOST_USER_BASE_H */
diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c
new file mode 100644
index 00..620fa5cb4a
--- /dev/null
+++ b/hw/virtio/vhost-user-base.c
@@ -0,0 +1,346 @@
+/*
+ * Base vhost-user-base implementation. This can be used to derive a
+ * more fully specified vhost-user backend either generically (see
+ * vhost-user-device) or via a specific stub for a device which
+ * encapsulates some fixed parameters.
+ *
+ * Copyright (c) 2023 Linaro Ltd
+ * Author: Alex Bennée 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/qdev-properties.h"
+#include "hw/virtio/virtio-bus.h"
+#include "hw/virtio/vhost-user-base.h"
+#include "qemu/error-report.h"
+
+static void vub_start(VirtIODevice *vdev)
+{
+BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
+VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+VHostUserBase *vub = VHOST_USER_BASE(vdev);
+int ret, i;
+
+if (!k->set_guest_notifiers) {
+error_report("binding does not support guest notifiers");
+return;
+}
+
+ret = vhost_dev_enable_notifiers(&vub->vhost_dev, vdev);
+if (ret < 0) {
+error_report("Error enabling host notifiers: %d", -ret);
+return;
+}
+
+ret = k->set_guest_notifiers(qbus->parent, vub->vhost_dev.nvqs, true);
+if (ret < 0) {
+error_report("Error binding guest notifier: %d", -ret);
+goto err_host_notifiers;
+}
+
+vub->vhost_dev.acked_features = vdev->guest_features;
+
+ret = vhost_dev_start(&vub->vhost_dev, vdev, true);
+if (ret < 0) {
+error_report("Error starting vhost-user-base: %d", -ret);
+goto err_guest_notifiers;
+}
+
+/

Re: [PATCH v6 1/6] virtio: split into vhost-user-base and vhost-user-device

2023-11-07 Thread Alex Bennée
"Michael S. Tsirkin"  writes:

> On Mon, Nov 06, 2023 at 07:15:10PM +, Alex Bennée wrote:
>> Lets keep a cleaner split between the base class and the derived
>> vhost-user-device which we can use for generic vhost-user stubs. This
>> includes an update to introduce the vq_size property so the number of
>> entries in a virtq can be defined.
>> 
>> Signed-off-by: Alex Bennée 
>> Message-Id: <20231009095937.195728-2-alex.ben...@linaro.org>
>> 
>> ---
>> v5
>>   - s/parent/parent_obj/
>>   - remove left over vhost-user-device.h
>>   - use DEFINE_TYPES
>> v6
>>   - rebase and set .abstrace = true for vhost-user-device
>
> abstract :)

How do I stop the PCI device being instantiated by qtest?

# Testing device 'vhost-user-device-pci'
Bail out! ERROR:../../qom/object.c:524:object_initialize_with_type: assertion 
failed: (type->abstract == false)
--- stderr ---
**
ERROR:../../qom/object.c:524:object_initialize_with_type: assertion failed: 
(type->abstract == false)
Broken pipe
../../tests/qtest/libqtest.c:204: kill_qemu() detected QEMU death from signal 6 
(Aborted)

(test program exited with status code -6)

>
>
> ...
>
>
>> +static const TypeInfo vub_types[] = {
>> +{
>> +.name = TYPE_VHOST_USER_BASE,
>> +.parent = TYPE_VIRTIO_DEVICE,
>> +.instance_size = sizeof(VHostUserBase),
>> +.class_init = vub_class_init,
>> +.class_size = sizeof(VHostUserBaseClass),
>> +.abstract = true
>
> I suspect it's this change that breaks CI: 
>
> https://gitlab.com/mstredhat/qemu/-/jobs/5472898562
>
> WARNING: qemu received signal 6; command: "./qemu-system-ppc -display none 
> -vga none -chardev socket,id=mon,fd=3 -mon chardev=mon,mode=control -S 
> -machine g3beige,accel=tcg -device vhost-user-device-pci"
> CRITICAL: failed: binary=./qemu-system-ppc accel=tcg machine=g3beige 
> device=vhost-user-device-pci
> CRITICAL: cmdline: ./qemu-system-ppc -S -machine g3beige,accel=tcg -device 
> vhost-user-device-pci
> CRITICAL: log: **
> CRITICAL: log: ERROR:../qom/object.c:524:object_initialize_with_type: 
> assertion failed: (type->abstract == false)
> CRITICAL: log: Bail out! 
> ERROR:../qom/object.c:524:object_initialize_with_type: assertion failed: 
> (type->abstract == false)
> CRITICAL: exit code: -6
>
> 146/395 qemu:qtest+qtest-mips / qtest-mips/device-introspect-test 
> ERROR   1.27s   killed by signal 6 SIGABRT
> 153/395 qemu:qtest+qtest-xtensa / qtest-xtensa/device-introspect-test 
> ERROR   1.56s   killed by signal 6 SIGABRT
> 171/395 qemu:qtest+qtest-riscv32 / qtest-riscv32/device-introspect-test   
> ERROR   1.40s   killed by signal 6 SIGABRT
> 184/395 qemu:qtest+qtest-ppc / qtest-ppc/device-introspect-test   
> ERROR   1.51s   killed by signal 6 SIGABRT
> 195/395 qemu:qtest+qtest-sparc64 / qtest-sparc64/device-introspect-test   
> ERROR   1.35s   killed by signal 6 SIGABRT
>
> I dropped this .abstract = true line for now and the part about it in
> docs.  Pls send patch on top once pull is merged.

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH v6 1/6] virtio: split into vhost-user-base and vhost-user-device

2023-11-07 Thread Alex Bennée
"Michael S. Tsirkin"  writes:

> On Mon, Nov 06, 2023 at 07:15:10PM +, Alex Bennée wrote:
>> Lets keep a cleaner split between the base class and the derived
>> vhost-user-device which we can use for generic vhost-user stubs. This
>> includes an update to introduce the vq_size property so the number of
>> entries in a virtq can be defined.
>> 
>> Signed-off-by: Alex Bennée 
>> Message-Id: <20231009095937.195728-2-alex.ben...@linaro.org>
>
> Please do not put Message-Id tags in patches you post.
> These are used to map patches to email - this patch was
> In-Reply-To: <20231106191515.2801863-2-alex.ben...@linaro.org>

It was the last time it was posted. I just strip off the old ones when I
apply to my tree before preparing a pull request.

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH v5 3/6] hw/virtio: derive vhost-user-gpio from vhost-user-base

2023-11-06 Thread Alex Bennée
"Michael S. Tsirkin"  writes:

> On Mon, Nov 06, 2023 at 05:30:39PM +, Alex Bennée wrote:
>> "Michael S. Tsirkin"  writes:
>> 
>> > On Thu, Oct 19, 2023 at 10:56:07AM +0100, Alex Bennée wrote:
>> >> Now the new base class supports config handling we can take advantage
>> >> and make vhost-user-gpio a much simpler boilerplate wrapper. Also as
>> >> this doesn't require any target specific hacks we only need to build
>> >> the stubs once.
>> >> 
>> >> Message-Id: <20230418162140.373219-12-alex.ben...@linaro.org>
>> >> Acked-by: Mark Cave-Ayland 
>> >> Acked-by: Viresh Kumar 
>> >> Signed-off-by: Alex Bennée 
>> >> Message-Id: <20231009095937.195728-4-alex.ben...@linaro.org>
>> >> ---
>> >> -case CHR_EVENT_OPENED:
>> >> -if (vu_gpio_connect(dev, &local_err) < 0) {
>> >> -qemu_chr_fe_disconnect(&gpio->chardev);
>> >> -return;
>> >> -}
>> >> -break;
>> >> -case CHR_EVENT_CLOSED:
>> >> -/* defer close until later to avoid circular close */
>> >> -vhost_user_async_close(dev, &gpio->chardev, &gpio->vhost_dev,
>> >> -   vu_gpio_disconnect);
>> >
>> > Hmm. Looking at this, it seems that the base device will handle close
>> > synchronously. No? Why isn't this a problem?
>> 
>> I suspect it was a copy and paste from another vhost-user impl. But
>> testing has shown it works ok.
>
> Can you rebase on latest master then please? There have been
> changes exactly in this area.

Sent v6 to the list:

  https://patchew.org/QEMU/20231106191515.2801863-1-alex.ben...@linaro.org/

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



[PATCH v6 1/6] virtio: split into vhost-user-base and vhost-user-device

2023-11-06 Thread Alex Bennée
Lets keep a cleaner split between the base class and the derived
vhost-user-device which we can use for generic vhost-user stubs. This
includes an update to introduce the vq_size property so the number of
entries in a virtq can be defined.

Signed-off-by: Alex Bennée 
Message-Id: <20231009095937.195728-2-alex.ben...@linaro.org>

---
v5
  - s/parent/parent_obj/
  - remove left over vhost-user-device.h
  - use DEFINE_TYPES
v6
  - rebase and set .abstrace = true for vhost-user-device
---
 ...{vhost-user-device.h => vhost-user-base.h} |  21 +-
 hw/virtio/vhost-user-base.c   | 345 ++
 hw/virtio/vhost-user-device-pci.c |  10 +-
 hw/virtio/vhost-user-device.c | 337 +
 hw/virtio/meson.build |   1 +
 5 files changed, 372 insertions(+), 342 deletions(-)
 rename include/hw/virtio/{vhost-user-device.h => vhost-user-base.h} (71%)
 create mode 100644 hw/virtio/vhost-user-base.c

diff --git a/include/hw/virtio/vhost-user-device.h 
b/include/hw/virtio/vhost-user-base.h
similarity index 71%
rename from include/hw/virtio/vhost-user-device.h
rename to include/hw/virtio/vhost-user-base.h
index 3ddf88a146..51d0968b89 100644
--- a/include/hw/virtio/vhost-user-device.h
+++ b/include/hw/virtio/vhost-user-base.h
@@ -6,8 +6,8 @@
  * SPDX-License-Identifier: GPL-2.0-or-later
  */
 
-#ifndef QEMU_VHOST_USER_DEVICE_H
-#define QEMU_VHOST_USER_DEVICE_H
+#ifndef QEMU_VHOST_USER_BASE_H
+#define QEMU_VHOST_USER_BASE_H
 
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
@@ -17,11 +17,13 @@
 OBJECT_DECLARE_TYPE(VHostUserBase, VHostUserBaseClass, VHOST_USER_BASE)
 
 struct VHostUserBase {
-VirtIODevice parent;
+VirtIODevice parent_obj;
+
 /* Properties */
 CharBackend chardev;
 uint16_t virtio_id;
 uint32_t num_vqs;
+uint32_t vq_size; /* can't exceed VIRTIO_QUEUE_MAX */
 uint32_t config_size;
 /* State tracking */
 VhostUserState vhost_user;
@@ -31,16 +33,17 @@ struct VHostUserBase {
 bool connected;
 };
 
-/* needed so we can use the base realize after specialisation
-   tweaks */
+/*
+ * Needed so we can use the base realize after specialisation
+ * tweaks
+ */
 struct VHostUserBaseClass {
-/*< private >*/
 VirtioDeviceClass parent_class;
-/*< public >*/
+
 DeviceRealize parent_realize;
 };
 
-/* shared for the benefit of the derived pci class */
+
 #define TYPE_VHOST_USER_DEVICE "vhost-user-device"
 
-#endif /* QEMU_VHOST_USER_DEVICE_H */
+#endif /* QEMU_VHOST_USER_BASE_H */
diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c
new file mode 100644
index 00..ebb4795ebf
--- /dev/null
+++ b/hw/virtio/vhost-user-base.c
@@ -0,0 +1,345 @@
+/*
+ * Base vhost-user-base implementation. This can be used to derive a
+ * more fully specified vhost-user backend either generically (see
+ * vhost-user-device) or via a specific stub for a device which
+ * encapsulates some fixed parameters.
+ *
+ * Copyright (c) 2023 Linaro Ltd
+ * Author: Alex Bennée 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/qdev-properties.h"
+#include "hw/virtio/virtio-bus.h"
+#include "hw/virtio/vhost-user-base.h"
+#include "qemu/error-report.h"
+
+static void vub_start(VirtIODevice *vdev)
+{
+BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
+VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+VHostUserBase *vub = VHOST_USER_BASE(vdev);
+int ret, i;
+
+if (!k->set_guest_notifiers) {
+error_report("binding does not support guest notifiers");
+return;
+}
+
+ret = vhost_dev_enable_notifiers(&vub->vhost_dev, vdev);
+if (ret < 0) {
+error_report("Error enabling host notifiers: %d", -ret);
+return;
+}
+
+ret = k->set_guest_notifiers(qbus->parent, vub->vhost_dev.nvqs, true);
+if (ret < 0) {
+error_report("Error binding guest notifier: %d", -ret);
+goto err_host_notifiers;
+}
+
+vub->vhost_dev.acked_features = vdev->guest_features;
+
+ret = vhost_dev_start(&vub->vhost_dev, vdev, true);
+if (ret < 0) {
+error_report("Error starting vhost-user-base: %d", -ret);
+goto err_guest_notifiers;
+}
+
+/*
+ * guest_notifier_mask/pending not used yet, so just unmask
+ * everything here. virtio-pci will do the right thing by
+ * enabling/disabling irqfd.
+ */
+for (i = 0; i < vub->vhost_dev.nvqs; i++) {
+vhost_virtqueue_mask(&vub->vhost_dev, vdev, i, false);
+}
+
+return;
+
+err_guest_notifiers:
+k->set_guest_notifiers(qbus->parent, vub->vhost_dev.nvqs, false);
+err_host_notifiers:
+vhost_dev_disable_notifiers(&vub->

qemu-block@nongnu.org

2023-11-06 Thread Alex Bennée
A lot of our vhost-user stubs are large chunks of boilerplate that do
(mostly) the same thing. This series continues the cleanups by
splitting the vhost-user-base and vhost-user-generic implementations.
After adding a new vq_size property the rng, gpio and i2c vhost-user
devices become simple specialisations of the common base defining the
ID, number of queues and potentially the config handling.

I've also added Manos' vhost-user-sound while I was at it.

Changes
---

v6
  - re-base to current master
  - make vhost-user-device abstract
  - mention abstractness in docs

v5
  - addressing comments and tags
  - improved the docs

v4
  - dropped the F_TRANSPORT work for another series
  - added vhost-user-sound

Alex Bennée (5):
  virtio: split into vhost-user-base and vhost-user-device
  hw/virtio: derive vhost-user-rng from vhost-user-base
  hw/virtio: derive vhost-user-gpio from vhost-user-base
  hw/virtio: derive vhost-user-i2c from vhost-user-base
  docs/system: add a basic enumeration of vhost-user devices

Manos Pitsidianakis (1):
  hw/virtio: add vhost-user-snd and virtio-snd-pci devices

 docs/system/devices/vhost-user-rng.rst|   2 +
 docs/system/devices/vhost-user.rst|  65 ++-
 ...{vhost-user-device.h => vhost-user-base.h} |  21 +-
 include/hw/virtio/vhost-user-gpio.h   |  23 +-
 include/hw/virtio/vhost-user-i2c.h|  14 +-
 include/hw/virtio/vhost-user-rng.h|  11 +-
 include/hw/virtio/vhost-user-snd.h|  26 ++
 hw/virtio/vhost-user-base.c   | 345 +++
 hw/virtio/vhost-user-device-pci.c |  10 +-
 hw/virtio/vhost-user-device.c | 337 +--
 hw/virtio/vhost-user-gpio.c   | 406 +-
 hw/virtio/vhost-user-i2c.c| 272 +---
 hw/virtio/vhost-user-rng.c| 278 +---
 hw/virtio/vhost-user-snd-pci.c|  75 
 hw/virtio/vhost-user-snd.c|  67 +++
 hw/virtio/Kconfig |   5 +
 hw/virtio/meson.build |  23 +-
 17 files changed, 690 insertions(+), 1290 deletions(-)
 rename include/hw/virtio/{vhost-user-device.h => vhost-user-base.h} (71%)
 create mode 100644 include/hw/virtio/vhost-user-snd.h
 create mode 100644 hw/virtio/vhost-user-base.c
 create mode 100644 hw/virtio/vhost-user-snd-pci.c
 create mode 100644 hw/virtio/vhost-user-snd.c

-- 
2.39.2




[PATCH v6 4/6] hw/virtio: derive vhost-user-i2c from vhost-user-base

2023-11-06 Thread Alex Bennée
Now we can take advantage of the new base class and make
vhost-user-i2c a much simpler boilerplate wrapper. Also as this
doesn't require any target specific hacks we only need to build the
stubs once.

Message-Id: <20230418162140.373219-13-alex.ben...@linaro.org>
Acked-by: Mark Cave-Ayland 
Acked-by: Viresh Kumar 
Signed-off-by: Alex Bennée 
Message-Id: <20231009095937.195728-5-alex.ben...@linaro.org>
---
 include/hw/virtio/vhost-user-i2c.h |  14 +-
 hw/virtio/vhost-user-i2c.c | 272 ++---
 hw/virtio/meson.build  |   5 +-
 3 files changed, 23 insertions(+), 268 deletions(-)

diff --git a/include/hw/virtio/vhost-user-i2c.h 
b/include/hw/virtio/vhost-user-i2c.h
index 0f7acd40e3..a8fcb108db 100644
--- a/include/hw/virtio/vhost-user-i2c.h
+++ b/include/hw/virtio/vhost-user-i2c.h
@@ -9,23 +9,17 @@
 #ifndef QEMU_VHOST_USER_I2C_H
 #define QEMU_VHOST_USER_I2C_H
 
+#include "hw/virtio/virtio.h"
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
+#include "hw/virtio/vhost-user-base.h"
 
 #define TYPE_VHOST_USER_I2C "vhost-user-i2c-device"
+
 OBJECT_DECLARE_SIMPLE_TYPE(VHostUserI2C, VHOST_USER_I2C)
 
 struct VHostUserI2C {
-VirtIODevice parent;
-CharBackend chardev;
-struct vhost_virtqueue *vhost_vq;
-struct vhost_dev vhost_dev;
-VhostUserState vhost_user;
-VirtQueue *vq;
-bool connected;
+VHostUserBase parent;
 };
 
-/* Virtio Feature bits */
-#define VIRTIO_I2C_F_ZERO_LENGTH_REQUEST   0
-
 #endif /* QEMU_VHOST_USER_I2C_H */
diff --git a/hw/virtio/vhost-user-i2c.c b/hw/virtio/vhost-user-i2c.c
index 4eef3f0633..a464f5e039 100644
--- a/hw/virtio/vhost-user-i2c.c
+++ b/hw/virtio/vhost-user-i2c.c
@@ -14,253 +14,22 @@
 #include "qemu/error-report.h"
 #include "standard-headers/linux/virtio_ids.h"
 
-static const int feature_bits[] = {
-VIRTIO_I2C_F_ZERO_LENGTH_REQUEST,
-VIRTIO_F_RING_RESET,
-VHOST_INVALID_FEATURE_BIT
+static Property vi2c_properties[] = {
+DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
+DEFINE_PROP_END_OF_LIST(),
 };
 
-static void vu_i2c_start(VirtIODevice *vdev)
-{
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-int ret, i;
-
-if (!k->set_guest_notifiers) {
-error_report("binding does not support guest notifiers");
-return;
-}
-
-ret = vhost_dev_enable_notifiers(&i2c->vhost_dev, vdev);
-if (ret < 0) {
-error_report("Error enabling host notifiers: %d", -ret);
-return;
-}
-
-ret = k->set_guest_notifiers(qbus->parent, i2c->vhost_dev.nvqs, true);
-if (ret < 0) {
-error_report("Error binding guest notifier: %d", -ret);
-goto err_host_notifiers;
-}
-
-i2c->vhost_dev.acked_features = vdev->guest_features;
-
-ret = vhost_dev_start(&i2c->vhost_dev, vdev, true);
-if (ret < 0) {
-error_report("Error starting vhost-user-i2c: %d", -ret);
-goto err_guest_notifiers;
-}
-
-/*
- * guest_notifier_mask/pending not used yet, so just unmask
- * everything here. virtio-pci will do the right thing by
- * enabling/disabling irqfd.
- */
-for (i = 0; i < i2c->vhost_dev.nvqs; i++) {
-vhost_virtqueue_mask(&i2c->vhost_dev, vdev, i, false);
-}
-
-return;
-
-err_guest_notifiers:
-k->set_guest_notifiers(qbus->parent, i2c->vhost_dev.nvqs, false);
-err_host_notifiers:
-vhost_dev_disable_notifiers(&i2c->vhost_dev, vdev);
-}
-
-static void vu_i2c_stop(VirtIODevice *vdev)
-{
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-int ret;
-
-if (!k->set_guest_notifiers) {
-return;
-}
-
-vhost_dev_stop(&i2c->vhost_dev, vdev, true);
-
-ret = k->set_guest_notifiers(qbus->parent, i2c->vhost_dev.nvqs, false);
-if (ret < 0) {
-error_report("vhost guest notifier cleanup failed: %d", ret);
-return;
-}
-
-vhost_dev_disable_notifiers(&i2c->vhost_dev, vdev);
-}
-
-static void vu_i2c_set_status(VirtIODevice *vdev, uint8_t status)
-{
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-bool should_start = virtio_device_should_start(vdev, status);
-
-if (vhost_dev_is_started(&i2c->vhost_dev) == should_start) {
-return;
-}
-
-if (should_start) {
-vu_i2c_start(vdev);
-} else {
-vu_i2c_stop(vdev);
-}
-}
-
-static uint64_t vu_i2c_get_features(VirtIODevice *vdev,
-uint64_t requested_features, Error **errp)
-{
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-
-virtio_add_

[PATCH v6 2/6] hw/virtio: derive vhost-user-rng from vhost-user-base

2023-11-06 Thread Alex Bennée
Now we can take advantage of our new base class and make
vhost-user-rng a much simpler boilerplate wrapper. Also as this
doesn't require any target specific hacks we only need to build the
stubs once.

Acked-by: Mark Cave-Ayland 
Signed-off-by: Alex Bennée 
Message-Id: <20231009095937.195728-3-alex.ben...@linaro.org>

---
v5
  - don't remove the in-QEMU RNG emulation!
---
 include/hw/virtio/vhost-user-rng.h |  11 +-
 hw/virtio/vhost-user-rng.c | 278 +++--
 hw/virtio/meson.build  |   9 +-
 3 files changed, 31 insertions(+), 267 deletions(-)

diff --git a/include/hw/virtio/vhost-user-rng.h 
b/include/hw/virtio/vhost-user-rng.h
index ddd9f01eea..6cffe28807 100644
--- a/include/hw/virtio/vhost-user-rng.h
+++ b/include/hw/virtio/vhost-user-rng.h
@@ -12,21 +12,14 @@
 #include "hw/virtio/virtio.h"
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
-#include "chardev/char-fe.h"
+#include "hw/virtio/vhost-user-base.h"
 
 #define TYPE_VHOST_USER_RNG "vhost-user-rng"
 OBJECT_DECLARE_SIMPLE_TYPE(VHostUserRNG, VHOST_USER_RNG)
 
 struct VHostUserRNG {
 /*< private >*/
-VirtIODevice parent;
-CharBackend chardev;
-struct vhost_virtqueue *vhost_vq;
-struct vhost_dev vhost_dev;
-VhostUserState vhost_user;
-VirtQueue *req_vq;
-bool connected;
-
+VHostUserBase parent;
 /*< public >*/
 };
 
diff --git a/hw/virtio/vhost-user-rng.c b/hw/virtio/vhost-user-rng.c
index efc54cd3fb..01879c863d 100644
--- a/hw/virtio/vhost-user-rng.c
+++ b/hw/virtio/vhost-user-rng.c
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2021 Mathieu Poirier 
  *
- * Implementation seriously tailored on vhost-user-i2c.c
+ * Simple wrapper of the generic vhost-user-device.
  *
  * SPDX-License-Identifier: GPL-2.0-or-later
  */
@@ -13,281 +13,47 @@
 #include "hw/qdev-properties.h"
 #include "hw/virtio/virtio-bus.h"
 #include "hw/virtio/vhost-user-rng.h"
-#include "qemu/error-report.h"
 #include "standard-headers/linux/virtio_ids.h"
 
-static const int feature_bits[] = {
-VIRTIO_F_RING_RESET,
-VHOST_INVALID_FEATURE_BIT
-};
-
-static void vu_rng_start(VirtIODevice *vdev)
-{
-VHostUserRNG *rng = VHOST_USER_RNG(vdev);
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-int ret;
-int i;
-
-if (!k->set_guest_notifiers) {
-error_report("binding does not support guest notifiers");
-return;
-}
-
-ret = vhost_dev_enable_notifiers(&rng->vhost_dev, vdev);
-if (ret < 0) {
-error_report("Error enabling host notifiers: %d", -ret);
-return;
-}
-
-ret = k->set_guest_notifiers(qbus->parent, rng->vhost_dev.nvqs, true);
-if (ret < 0) {
-error_report("Error binding guest notifier: %d", -ret);
-goto err_host_notifiers;
-}
-
-rng->vhost_dev.acked_features = vdev->guest_features;
-ret = vhost_dev_start(&rng->vhost_dev, vdev, true);
-if (ret < 0) {
-error_report("Error starting vhost-user-rng: %d", -ret);
-goto err_guest_notifiers;
-}
-
-/*
- * guest_notifier_mask/pending not used yet, so just unmask
- * everything here. virtio-pci will do the right thing by
- * enabling/disabling irqfd.
- */
-for (i = 0; i < rng->vhost_dev.nvqs; i++) {
-vhost_virtqueue_mask(&rng->vhost_dev, vdev, i, false);
-}
-
-return;
-
-err_guest_notifiers:
-k->set_guest_notifiers(qbus->parent, rng->vhost_dev.nvqs, false);
-err_host_notifiers:
-vhost_dev_disable_notifiers(&rng->vhost_dev, vdev);
-}
-
-static void vu_rng_stop(VirtIODevice *vdev)
-{
-VHostUserRNG *rng = VHOST_USER_RNG(vdev);
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-int ret;
-
-if (!k->set_guest_notifiers) {
-return;
-}
-
-vhost_dev_stop(&rng->vhost_dev, vdev, true);
-
-ret = k->set_guest_notifiers(qbus->parent, rng->vhost_dev.nvqs, false);
-if (ret < 0) {
-error_report("vhost guest notifier cleanup failed: %d", ret);
-return;
-}
-
-vhost_dev_disable_notifiers(&rng->vhost_dev, vdev);
-}
-
-static void vu_rng_set_status(VirtIODevice *vdev, uint8_t status)
-{
-VHostUserRNG *rng = VHOST_USER_RNG(vdev);
-bool should_start = virtio_device_should_start(vdev, status);
-
-if (vhost_dev_is_started(&rng->vhost_dev) == should_start) {
-return;
-}
-
-if (should_start) {
-vu_rng_start(vdev);
-} else {
-vu_rng_stop(vdev);
-}
-}
-
-static uint64_t vu_rng_get_features(VirtIODevice *vdev,
-uint64_t requested_features, Error **errp)
-

[PATCH v6 3/6] hw/virtio: derive vhost-user-gpio from vhost-user-base

2023-11-06 Thread Alex Bennée
Now the new base class supports config handling we can take advantage
and make vhost-user-gpio a much simpler boilerplate wrapper. Also as
this doesn't require any target specific hacks we only need to build
the stubs once.

Message-Id: <20230418162140.373219-12-alex.ben...@linaro.org>
Acked-by: Mark Cave-Ayland 
Acked-by: Viresh Kumar 
Signed-off-by: Alex Bennée 
Message-Id: <20231009095937.195728-4-alex.ben...@linaro.org>
---
 include/hw/virtio/vhost-user-gpio.h |  23 +-
 hw/virtio/vhost-user-gpio.c | 406 ++--
 hw/virtio/meson.build   |   5 +-
 3 files changed, 22 insertions(+), 412 deletions(-)

diff --git a/include/hw/virtio/vhost-user-gpio.h 
b/include/hw/virtio/vhost-user-gpio.h
index a9d3f9b049..5201d5f072 100644
--- a/include/hw/virtio/vhost-user-gpio.h
+++ b/include/hw/virtio/vhost-user-gpio.h
@@ -12,33 +12,14 @@
 #include "hw/virtio/virtio.h"
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
-#include "standard-headers/linux/virtio_gpio.h"
-#include "chardev/char-fe.h"
+#include "hw/virtio/vhost-user-base.h"
 
 #define TYPE_VHOST_USER_GPIO "vhost-user-gpio-device"
 OBJECT_DECLARE_SIMPLE_TYPE(VHostUserGPIO, VHOST_USER_GPIO);
 
 struct VHostUserGPIO {
 /*< private >*/
-VirtIODevice parent_obj;
-CharBackend chardev;
-struct virtio_gpio_config config;
-struct vhost_virtqueue *vhost_vqs;
-struct vhost_dev vhost_dev;
-VhostUserState vhost_user;
-VirtQueue *command_vq;
-VirtQueue *interrupt_vq;
-/**
- * There are at least two steps of initialization of the
- * vhost-user device. The first is a "connect" step and
- * second is a "start" step. Make a separation between
- * those initialization phases by using two fields.
- *
- * @connected: see vu_gpio_connect()/vu_gpio_disconnect()
- * @started_vu: see vu_gpio_start()/vu_gpio_stop()
- */
-bool connected;
-bool started_vu;
+VHostUserBase parent;
 /*< public >*/
 };
 
diff --git a/hw/virtio/vhost-user-gpio.c b/hw/virtio/vhost-user-gpio.c
index aff2d7eff6..9f37c25415 100644
--- a/hw/virtio/vhost-user-gpio.c
+++ b/hw/virtio/vhost-user-gpio.c
@@ -11,387 +11,25 @@
 #include "hw/qdev-properties.h"
 #include "hw/virtio/virtio-bus.h"
 #include "hw/virtio/vhost-user-gpio.h"
-#include "qemu/error-report.h"
 #include "standard-headers/linux/virtio_ids.h"
-#include "trace.h"
+#include "standard-headers/linux/virtio_gpio.h"
 
-#define VHOST_NVQS 2
-
-/* Features required from VirtIO */
-static const int feature_bits[] = {
-VIRTIO_F_VERSION_1,
-VIRTIO_F_NOTIFY_ON_EMPTY,
-VIRTIO_RING_F_INDIRECT_DESC,
-VIRTIO_RING_F_EVENT_IDX,
-VIRTIO_GPIO_F_IRQ,
-VIRTIO_F_RING_RESET,
-VHOST_INVALID_FEATURE_BIT
-};
-
-static void vu_gpio_get_config(VirtIODevice *vdev, uint8_t *config)
-{
-VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev);
-
-memcpy(config, &gpio->config, sizeof(gpio->config));
-}
-
-static int vu_gpio_config_notifier(struct vhost_dev *dev)
-{
-VHostUserGPIO *gpio = VHOST_USER_GPIO(dev->vdev);
-
-memcpy(dev->vdev->config, &gpio->config, sizeof(gpio->config));
-virtio_notify_config(dev->vdev);
-
-return 0;
-}
-
-const VhostDevConfigOps gpio_ops = {
-.vhost_dev_config_notifier = vu_gpio_config_notifier,
+static Property vgpio_properties[] = {
+DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
+DEFINE_PROP_END_OF_LIST(),
 };
 
-static int vu_gpio_start(VirtIODevice *vdev)
-{
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev);
-struct vhost_dev *vhost_dev = &gpio->vhost_dev;
-int ret, i;
-
-if (!k->set_guest_notifiers) {
-error_report("binding does not support guest notifiers");
-return -ENOSYS;
-}
-
-ret = vhost_dev_enable_notifiers(vhost_dev, vdev);
-if (ret < 0) {
-error_report("Error enabling host notifiers: %d", ret);
-return ret;
-}
-
-ret = k->set_guest_notifiers(qbus->parent, vhost_dev->nvqs, true);
-if (ret < 0) {
-error_report("Error binding guest notifier: %d", ret);
-goto err_host_notifiers;
-}
-
-/*
- * Before we start up we need to ensure we have the final feature
- * set needed for the vhost configuration. The backend may also
- * apply backend_features when the feature set is sent.
- */
-vhost_ack_features(&gpio->vhost_dev, feature_bits, vdev->guest_features);
-
-ret = vhost_dev_start(&gpio->vhost_dev, vdev, false);
-if (ret < 0) {
-error_report("Error starting vhost-user-gpio: %d", ret);
-goto er

[PATCH v6 6/6] docs/system: add a basic enumeration of vhost-user devices

2023-11-06 Thread Alex Bennée
Make it clear the vhost-user-device is intended for expert use only.

Signed-off-by: Alex Bennée 
Message-Id: <20231009095937.195728-7-alex.ben...@linaro.org>

---
v5
  - split vhost-user-device out of the table
  - sort the table alphabetically
  - add sound and scmi devices
v6
  - add note re vhost-user-device
---
 docs/system/devices/vhost-user-rng.rst |  2 +
 docs/system/devices/vhost-user.rst | 65 +-
 2 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/docs/system/devices/vhost-user-rng.rst 
b/docs/system/devices/vhost-user-rng.rst
index a145d4105c..ead1405326 100644
--- a/docs/system/devices/vhost-user-rng.rst
+++ b/docs/system/devices/vhost-user-rng.rst
@@ -1,3 +1,5 @@
+.. _vhost_user_rng:
+
 QEMU vhost-user-rng - RNG emulation
 ===
 
diff --git a/docs/system/devices/vhost-user.rst 
b/docs/system/devices/vhost-user.rst
index a80e95a48a..74c8b2f8be 100644
--- a/docs/system/devices/vhost-user.rst
+++ b/docs/system/devices/vhost-user.rst
@@ -8,13 +8,76 @@ outside of QEMU itself. To do this there are a number of 
things
 required.
 
 vhost-user device
-===
+=
 
 These are simple stub devices that ensure the VirtIO device is visible
 to the guest. The code is mostly boilerplate although each device has
 a ``chardev`` option which specifies the ID of the ``--chardev``
 device that connects via a socket to the vhost-user *daemon*.
 
+Each device will have an virtio-mmio and virtio-pci variant. See your
+platform details for what sort of virtio bus to use.
+
+.. list-table:: vhost-user devices
+  :widths: 20 20 60
+  :header-rows: 1
+
+  * - Device
+- Type
+- Notes
+  * - vhost-user-blk
+- Block storage
+- See contrib/vhost-user-blk
+  * - vhost-user-fs
+- File based storage driver
+- See https://gitlab.com/virtio-fs/virtiofsd
+  * - vhost-user-gpio
+- Proxy gpio pins to host
+- See https://github.com/rust-vmm/vhost-device
+  * - vhost-user-gpu
+- GPU driver
+- See contrib/vhost-user-gpu
+  * - vhost-user-i2c
+- Proxy i2c devices to host
+- See https://github.com/rust-vmm/vhost-device
+  * - vhost-user-input
+- Generic input driver
+- See contrib/vhost-user-input
+  * - vhost-user-rng
+- Entropy driver
+- :ref:`vhost_user_rng`
+  * - vhost-user-scmi
+- System Control and Management Interface
+- See https://github.com/rust-vmm/vhost-device
+  * - vhost-user-snd
+- Audio device
+- See https://github.com/rust-vmm/vhost-device/staging
+  * - vhost-user-scsi
+- SCSI based storage
+- See contrib/vhost-user-scsi
+  * - vhost-user-vsock
+- Socket based communication
+- See https://github.com/rust-vmm/vhost-device
+
+The referenced *daemons* are not exhaustive, any conforming backend
+implementing the device and using the vhost-user protocol should work.
+
+vhost-user-device
+^
+
+The vhost-user-device is a generic development device intended for
+expert use while developing new backends. The user needs to specify
+all the required parameters including:
+
+  - Device ``virtio-id``
+  - The ``num_vqs`` it needs and their ``vq_size``
+  - The ``config_size`` if needed
+
+.. note::
+  To prevent user confusion you cannot currently instantiate
+  vhost-user-device without first patching out ``.abstract = true`` in
+  the ``vhost-user-device.c`` file and rebuilding.
+
 vhost-user daemon
 =
 
-- 
2.39.2




[PATCH v6 5/6] hw/virtio: add vhost-user-snd and virtio-snd-pci devices

2023-11-06 Thread Alex Bennée
From: Manos Pitsidianakis 

Tested with rust-vmm vhost-user-sound daemon:

RUST_LOG=trace cargo run --bin vhost-user-sound -- --socket /tmp/snd.sock 
--backend null

Invocation:

qemu-system-x86_64  \
-qmp unix:./qmp-sock,server,wait=off  \
-m 4096 \
-numa node,memdev=mem \
-object 
memory-backend-file,id=mem,size=4G,mem-path=/dev/shm,share=on \
-D qemu.log \
-d guest_errors,trace:\*snd\*,trace:\*sound\*,trace:\*vhost\* \
-chardev socket,id=vsnd,path=/tmp/snd.sock \
-device vhost-user-snd-pci,chardev=vsnd,id=snd \
/path/to/disk

[AJB: imported from 
https://github.com/epilys/qemu-virtio-snd/commit/54ae1cdd15fef2d88e9e387a175f099a38c636f4.patch]

Signed-off-by: Alex Bennée 
Message-Id: <20231009095937.195728-6-alex.ben...@linaro.org>
---
 include/hw/virtio/vhost-user-snd.h | 26 +++
 hw/virtio/vhost-user-snd-pci.c | 75 ++
 hw/virtio/vhost-user-snd.c | 67 ++
 hw/virtio/Kconfig  |  5 ++
 hw/virtio/meson.build  |  3 ++
 5 files changed, 176 insertions(+)
 create mode 100644 include/hw/virtio/vhost-user-snd.h
 create mode 100644 hw/virtio/vhost-user-snd-pci.c
 create mode 100644 hw/virtio/vhost-user-snd.c

diff --git a/include/hw/virtio/vhost-user-snd.h 
b/include/hw/virtio/vhost-user-snd.h
new file mode 100644
index 00..a1627003a0
--- /dev/null
+++ b/include/hw/virtio/vhost-user-snd.h
@@ -0,0 +1,26 @@
+/*
+ * Vhost-user Sound virtio device
+ *
+ * Copyright (c) 2021 Mathieu Poirier 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef QEMU_VHOST_USER_SND_H
+#define QEMU_VHOST_USER_SND_H
+
+#include "hw/virtio/virtio.h"
+#include "hw/virtio/vhost.h"
+#include "hw/virtio/vhost-user.h"
+#include "hw/virtio/vhost-user-base.h"
+
+#define TYPE_VHOST_USER_SND "vhost-user-snd"
+OBJECT_DECLARE_SIMPLE_TYPE(VHostUserSound, VHOST_USER_SND)
+
+struct VHostUserSound {
+/*< private >*/
+VHostUserBase parent;
+/*< public >*/
+};
+
+#endif /* QEMU_VHOST_USER_SND_H */
diff --git a/hw/virtio/vhost-user-snd-pci.c b/hw/virtio/vhost-user-snd-pci.c
new file mode 100644
index 00..d61cfdae63
--- /dev/null
+++ b/hw/virtio/vhost-user-snd-pci.c
@@ -0,0 +1,75 @@
+/*
+ * Vhost-user Sound virtio device PCI glue
+ *
+ * Copyright (c) 2023 Manos Pitsidianakis 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/qdev-properties.h"
+#include "hw/virtio/vhost-user-snd.h"
+#include "hw/virtio/virtio-pci.h"
+
+struct VHostUserSoundPCI {
+VirtIOPCIProxy parent_obj;
+VHostUserSound vdev;
+};
+
+typedef struct VHostUserSoundPCI VHostUserSoundPCI;
+
+#define TYPE_VHOST_USER_SND_PCI "vhost-user-snd-pci-base"
+
+DECLARE_INSTANCE_CHECKER(VHostUserSoundPCI, VHOST_USER_SND_PCI,
+ TYPE_VHOST_USER_SND_PCI)
+
+static Property vhost_user_snd_pci_properties[] = {
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void vhost_user_snd_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
+{
+VHostUserSoundPCI *dev = VHOST_USER_SND_PCI(vpci_dev);
+DeviceState *vdev = DEVICE(&dev->vdev);
+
+vpci_dev->nvectors = 1;
+
+qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
+}
+
+static void vhost_user_snd_pci_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+k->realize = vhost_user_snd_pci_realize;
+set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
+device_class_set_props(dc, vhost_user_snd_pci_properties);
+pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+pcidev_k->device_id = 0; /* Set by virtio-pci based on virtio id */
+pcidev_k->revision = 0x00;
+pcidev_k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
+}
+
+static void vhost_user_snd_pci_instance_init(Object *obj)
+{
+VHostUserSoundPCI *dev = VHOST_USER_SND_PCI(obj);
+
+virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
+TYPE_VHOST_USER_SND);
+}
+
+static const VirtioPCIDeviceTypeInfo vhost_user_snd_pci_info = {
+.base_name = TYPE_VHOST_USER_SND_PCI,
+.non_transitional_name = "vhost-user-snd-pci",
+.instance_size = sizeof(VHostUserSoundPCI),
+.instance_init = vhost_user_snd_pci_instance_init,
+.class_init = vhost_user_snd_pci_class_init,
+};
+
+static void vhost_user_snd_pci_register(void)
+{
+virtio_pci_types_register(&vhost_user_snd_pci_info);
+}
+
+type_init(vhost_user_snd_pci_register);
diff --git a/hw/virtio/vhost-user-snd.c b/hw/virtio/vhost-user-snd.c
new file mode 100644
index 00..9a217543f8
--- /dev/null
+++ b/hw/virtio/vhost-user-snd.c
@@ -0,0 +1,67

Re: [PATCH v5 1/6] virtio: split into vhost-user-base and vhost-user-device

2023-11-06 Thread Alex Bennée
"Michael S. Tsirkin"  writes:

> On Thu, Oct 19, 2023 at 10:56:05AM +0100, Alex Bennée wrote:
>> Lets keep a cleaner split between the base class and the derived
>> vhost-user-device which we can use for generic vhost-user stubs. This
>> includes an update to introduce the vq_size property so the number of
>> entries in a virtq can be defined.
>> 
>> Signed-off-by: Alex Bennée 
>> Message-Id: <20231009095937.195728-2-alex.ben...@linaro.org>
>
> I applied but I think for this release we are better off just
> preventing users from instanciating these on command line -
> developers can always hack code to drop this.

I guess if a user doesn't read the documentation and makes up some
random numbers for the properties they deserve what they get?

> Can you post a patch please?

Is:

/* comment out if you want to use backends qemu doesn't know about */
.abstract = true,

really worth it?


-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH v5 3/6] hw/virtio: derive vhost-user-gpio from vhost-user-base

2023-11-06 Thread Alex Bennée
"Michael S. Tsirkin"  writes:

> On Thu, Oct 19, 2023 at 10:56:07AM +0100, Alex Bennée wrote:
>> Now the new base class supports config handling we can take advantage
>> and make vhost-user-gpio a much simpler boilerplate wrapper. Also as
>> this doesn't require any target specific hacks we only need to build
>> the stubs once.
>> 
>> Message-Id: <20230418162140.373219-12-alex.ben...@linaro.org>
>> Acked-by: Mark Cave-Ayland 
>> Acked-by: Viresh Kumar 
>> Signed-off-by: Alex Bennée 
>> Message-Id: <20231009095937.195728-4-alex.ben...@linaro.org>
>> ---
>> -case CHR_EVENT_OPENED:
>> -if (vu_gpio_connect(dev, &local_err) < 0) {
>> -qemu_chr_fe_disconnect(&gpio->chardev);
>> -return;
>> -}
>> -break;
>> -case CHR_EVENT_CLOSED:
>> -/* defer close until later to avoid circular close */
>> -vhost_user_async_close(dev, &gpio->chardev, &gpio->vhost_dev,
>> -   vu_gpio_disconnect);
>
> Hmm. Looking at this, it seems that the base device will handle close
> synchronously. No? Why isn't this a problem?

I suspect it was a copy and paste from another vhost-user impl. But
testing has shown it works ok.


-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



qemu-block@nongnu.org

2023-10-24 Thread Alex Bennée


Alex Bennée  writes:

> A lot of our vhost-user stubs are large chunks of boilerplate that do
> (mostly) the same thing. This series continues the cleanups by
> splitting the vhost-user-base and vhost-user-generic implementations.
> After adding a new vq_size property the rng, gpio and i2c vhost-user
> devices become simple specialisations of the common base defining the
> ID, number of queues and potentially the config handling.
>
> I've also added Manos' vhost-user-sound while I was at it.

Ping MST. Any more comments or happy to take as is?

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH 0/12] Get Xen PV shim running in qemu

2023-10-24 Thread Alex Bennée


David Woodhouse  writes:

> I hadn't got round to getting the PV shim running yet; I thought it would
> need work on the multiboot loader. Turns out it doesn't. I *did* need to
> fix a couple of brown-paper-bag bugs in the per-vCPU upcall vector support,
> and implement Xen console support though. Now I can test PV guests:
>
>  $ qemu-system-x86_64 --accel kvm,xen-version=0x40011,kernel-irqchip=split \
>-chardev stdio,mux=on,id=char0 -device xen-console,chardev=char0 \
>-drive file=${GUEST_IMAGE},if=xen -display none -m 1G \
>-kernel ~/git/xen/xen/xen -initrd ~/git/linux/arch/x86/boot/bzImage
>  \

So this is a KVM guest running the Xen hypervisor (via -kernel) and a
Dom0 Linux guest (via -initrd)?

Should this work for any Xen architecture or is this x86 specific? Does
the -M machine model matter?

Would it be possible to have some sort of overview document in our
manual for how Xen guests are supported under KVM?

>-append "loglvl=all -- console=hvc0 root=/dev/xvda1"
>


-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH v5 5/6] hw/virtio: add vhost-user-snd and virtio-snd-pci devices

2023-10-20 Thread Alex Bennée


Viresh Kumar  writes:

> On 19-10-23, 10:56, Alex Bennée wrote:
>> From: Manos Pitsidianakis 
>> 
>> Tested with rust-vmm vhost-user-sound daemon:
>> 
>> RUST_LOG=trace cargo run --bin vhost-user-sound -- --socket 
>> /tmp/snd.sock --backend null
>> 
>> Invocation:
>> 
>> qemu-system-x86_64  \
>> -qmp unix:./qmp-sock,server,wait=off  \
>> -m 4096 \
>> -numa node,memdev=mem \
>> -object 
>> memory-backend-file,id=mem,size=4G,mem-path=/dev/shm,share=on \
>> -D qemu.log \
>> -d guest_errors,trace:\*snd\*,trace:\*sound\*,trace:\*vhost\* \
>> -chardev socket,id=vsnd,path=/tmp/snd.sock \
>> -device vhost-user-snd-pci,chardev=vsnd,id=snd \
>> /path/to/disk
>> 
>> [AJB: imported from 
>> https://github.com/epilys/qemu-virtio-snd/commit/54ae1cdd15fef2d88e9e387a175f099a38c636f4.patch]
>> 
>> Signed-off-by: Alex Bennée 
>
> Missing SOB from Manos ?

oops, guess I need a respin then ;-)

>
>> Message-Id: <20231009095937.195728-6-alex.ben...@linaro.org>


-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



[PATCH v5 3/6] hw/virtio: derive vhost-user-gpio from vhost-user-base

2023-10-19 Thread Alex Bennée
Now the new base class supports config handling we can take advantage
and make vhost-user-gpio a much simpler boilerplate wrapper. Also as
this doesn't require any target specific hacks we only need to build
the stubs once.

Message-Id: <20230418162140.373219-12-alex.ben...@linaro.org>
Acked-by: Mark Cave-Ayland 
Acked-by: Viresh Kumar 
Signed-off-by: Alex Bennée 
Message-Id: <20231009095937.195728-4-alex.ben...@linaro.org>
---
 include/hw/virtio/vhost-user-gpio.h |  23 +-
 hw/virtio/vhost-user-gpio.c | 407 ++--
 hw/virtio/meson.build   |   5 +-
 3 files changed, 22 insertions(+), 413 deletions(-)

diff --git a/include/hw/virtio/vhost-user-gpio.h 
b/include/hw/virtio/vhost-user-gpio.h
index a9d3f9b049..5201d5f072 100644
--- a/include/hw/virtio/vhost-user-gpio.h
+++ b/include/hw/virtio/vhost-user-gpio.h
@@ -12,33 +12,14 @@
 #include "hw/virtio/virtio.h"
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
-#include "standard-headers/linux/virtio_gpio.h"
-#include "chardev/char-fe.h"
+#include "hw/virtio/vhost-user-base.h"
 
 #define TYPE_VHOST_USER_GPIO "vhost-user-gpio-device"
 OBJECT_DECLARE_SIMPLE_TYPE(VHostUserGPIO, VHOST_USER_GPIO);
 
 struct VHostUserGPIO {
 /*< private >*/
-VirtIODevice parent_obj;
-CharBackend chardev;
-struct virtio_gpio_config config;
-struct vhost_virtqueue *vhost_vqs;
-struct vhost_dev vhost_dev;
-VhostUserState vhost_user;
-VirtQueue *command_vq;
-VirtQueue *interrupt_vq;
-/**
- * There are at least two steps of initialization of the
- * vhost-user device. The first is a "connect" step and
- * second is a "start" step. Make a separation between
- * those initialization phases by using two fields.
- *
- * @connected: see vu_gpio_connect()/vu_gpio_disconnect()
- * @started_vu: see vu_gpio_start()/vu_gpio_stop()
- */
-bool connected;
-bool started_vu;
+VHostUserBase parent;
 /*< public >*/
 };
 
diff --git a/hw/virtio/vhost-user-gpio.c b/hw/virtio/vhost-user-gpio.c
index 3d7fae3984..9f37c25415 100644
--- a/hw/virtio/vhost-user-gpio.c
+++ b/hw/virtio/vhost-user-gpio.c
@@ -11,388 +11,25 @@
 #include "hw/qdev-properties.h"
 #include "hw/virtio/virtio-bus.h"
 #include "hw/virtio/vhost-user-gpio.h"
-#include "qemu/error-report.h"
 #include "standard-headers/linux/virtio_ids.h"
-#include "trace.h"
+#include "standard-headers/linux/virtio_gpio.h"
 
-#define REALIZE_CONNECTION_RETRIES 3
-#define VHOST_NVQS 2
-
-/* Features required from VirtIO */
-static const int feature_bits[] = {
-VIRTIO_F_VERSION_1,
-VIRTIO_F_NOTIFY_ON_EMPTY,
-VIRTIO_RING_F_INDIRECT_DESC,
-VIRTIO_RING_F_EVENT_IDX,
-VIRTIO_GPIO_F_IRQ,
-VIRTIO_F_RING_RESET,
-VHOST_INVALID_FEATURE_BIT
-};
-
-static void vu_gpio_get_config(VirtIODevice *vdev, uint8_t *config)
-{
-VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev);
-
-memcpy(config, &gpio->config, sizeof(gpio->config));
-}
-
-static int vu_gpio_config_notifier(struct vhost_dev *dev)
-{
-VHostUserGPIO *gpio = VHOST_USER_GPIO(dev->vdev);
-
-memcpy(dev->vdev->config, &gpio->config, sizeof(gpio->config));
-virtio_notify_config(dev->vdev);
-
-return 0;
-}
-
-const VhostDevConfigOps gpio_ops = {
-.vhost_dev_config_notifier = vu_gpio_config_notifier,
+static Property vgpio_properties[] = {
+DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
+DEFINE_PROP_END_OF_LIST(),
 };
 
-static int vu_gpio_start(VirtIODevice *vdev)
-{
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev);
-struct vhost_dev *vhost_dev = &gpio->vhost_dev;
-int ret, i;
-
-if (!k->set_guest_notifiers) {
-error_report("binding does not support guest notifiers");
-return -ENOSYS;
-}
-
-ret = vhost_dev_enable_notifiers(vhost_dev, vdev);
-if (ret < 0) {
-error_report("Error enabling host notifiers: %d", ret);
-return ret;
-}
-
-ret = k->set_guest_notifiers(qbus->parent, vhost_dev->nvqs, true);
-if (ret < 0) {
-error_report("Error binding guest notifier: %d", ret);
-goto err_host_notifiers;
-}
-
-/*
- * Before we start up we need to ensure we have the final feature
- * set needed for the vhost configuration. The backend may also
- * apply backend_features when the feature set is sent.
- */
-vhost_ack_features(&gpio->vhost_dev, feature_bits, vdev->guest_features);
-
-ret = vhost_dev_start(&gpio->vhost_dev, vdev, false);
-if (ret < 0) {
-error_report("Error starting vhost-user-gpi

[PATCH v5 4/6] hw/virtio: derive vhost-user-i2c from vhost-user-base

2023-10-19 Thread Alex Bennée
Now we can take advantage of the new base class and make
vhost-user-i2c a much simpler boilerplate wrapper. Also as this
doesn't require any target specific hacks we only need to build the
stubs once.

Message-Id: <20230418162140.373219-13-alex.ben...@linaro.org>
Acked-by: Mark Cave-Ayland 
Acked-by: Viresh Kumar 
Signed-off-by: Alex Bennée 
Message-Id: <20231009095937.195728-5-alex.ben...@linaro.org>
---
 include/hw/virtio/vhost-user-i2c.h |  14 +-
 hw/virtio/vhost-user-i2c.c | 272 ++---
 hw/virtio/meson.build  |   5 +-
 3 files changed, 23 insertions(+), 268 deletions(-)

diff --git a/include/hw/virtio/vhost-user-i2c.h 
b/include/hw/virtio/vhost-user-i2c.h
index 0f7acd40e3..a8fcb108db 100644
--- a/include/hw/virtio/vhost-user-i2c.h
+++ b/include/hw/virtio/vhost-user-i2c.h
@@ -9,23 +9,17 @@
 #ifndef QEMU_VHOST_USER_I2C_H
 #define QEMU_VHOST_USER_I2C_H
 
+#include "hw/virtio/virtio.h"
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
+#include "hw/virtio/vhost-user-base.h"
 
 #define TYPE_VHOST_USER_I2C "vhost-user-i2c-device"
+
 OBJECT_DECLARE_SIMPLE_TYPE(VHostUserI2C, VHOST_USER_I2C)
 
 struct VHostUserI2C {
-VirtIODevice parent;
-CharBackend chardev;
-struct vhost_virtqueue *vhost_vq;
-struct vhost_dev vhost_dev;
-VhostUserState vhost_user;
-VirtQueue *vq;
-bool connected;
+VHostUserBase parent;
 };
 
-/* Virtio Feature bits */
-#define VIRTIO_I2C_F_ZERO_LENGTH_REQUEST   0
-
 #endif /* QEMU_VHOST_USER_I2C_H */
diff --git a/hw/virtio/vhost-user-i2c.c b/hw/virtio/vhost-user-i2c.c
index 4eef3f0633..a464f5e039 100644
--- a/hw/virtio/vhost-user-i2c.c
+++ b/hw/virtio/vhost-user-i2c.c
@@ -14,253 +14,22 @@
 #include "qemu/error-report.h"
 #include "standard-headers/linux/virtio_ids.h"
 
-static const int feature_bits[] = {
-VIRTIO_I2C_F_ZERO_LENGTH_REQUEST,
-VIRTIO_F_RING_RESET,
-VHOST_INVALID_FEATURE_BIT
+static Property vi2c_properties[] = {
+DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
+DEFINE_PROP_END_OF_LIST(),
 };
 
-static void vu_i2c_start(VirtIODevice *vdev)
-{
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-int ret, i;
-
-if (!k->set_guest_notifiers) {
-error_report("binding does not support guest notifiers");
-return;
-}
-
-ret = vhost_dev_enable_notifiers(&i2c->vhost_dev, vdev);
-if (ret < 0) {
-error_report("Error enabling host notifiers: %d", -ret);
-return;
-}
-
-ret = k->set_guest_notifiers(qbus->parent, i2c->vhost_dev.nvqs, true);
-if (ret < 0) {
-error_report("Error binding guest notifier: %d", -ret);
-goto err_host_notifiers;
-}
-
-i2c->vhost_dev.acked_features = vdev->guest_features;
-
-ret = vhost_dev_start(&i2c->vhost_dev, vdev, true);
-if (ret < 0) {
-error_report("Error starting vhost-user-i2c: %d", -ret);
-goto err_guest_notifiers;
-}
-
-/*
- * guest_notifier_mask/pending not used yet, so just unmask
- * everything here. virtio-pci will do the right thing by
- * enabling/disabling irqfd.
- */
-for (i = 0; i < i2c->vhost_dev.nvqs; i++) {
-vhost_virtqueue_mask(&i2c->vhost_dev, vdev, i, false);
-}
-
-return;
-
-err_guest_notifiers:
-k->set_guest_notifiers(qbus->parent, i2c->vhost_dev.nvqs, false);
-err_host_notifiers:
-vhost_dev_disable_notifiers(&i2c->vhost_dev, vdev);
-}
-
-static void vu_i2c_stop(VirtIODevice *vdev)
-{
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-int ret;
-
-if (!k->set_guest_notifiers) {
-return;
-}
-
-vhost_dev_stop(&i2c->vhost_dev, vdev, true);
-
-ret = k->set_guest_notifiers(qbus->parent, i2c->vhost_dev.nvqs, false);
-if (ret < 0) {
-error_report("vhost guest notifier cleanup failed: %d", ret);
-return;
-}
-
-vhost_dev_disable_notifiers(&i2c->vhost_dev, vdev);
-}
-
-static void vu_i2c_set_status(VirtIODevice *vdev, uint8_t status)
-{
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-bool should_start = virtio_device_should_start(vdev, status);
-
-if (vhost_dev_is_started(&i2c->vhost_dev) == should_start) {
-return;
-}
-
-if (should_start) {
-vu_i2c_start(vdev);
-} else {
-vu_i2c_stop(vdev);
-}
-}
-
-static uint64_t vu_i2c_get_features(VirtIODevice *vdev,
-uint64_t requested_features, Error **errp)
-{
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-
-virtio_add_

[PATCH v5 1/6] virtio: split into vhost-user-base and vhost-user-device

2023-10-19 Thread Alex Bennée
Lets keep a cleaner split between the base class and the derived
vhost-user-device which we can use for generic vhost-user stubs. This
includes an update to introduce the vq_size property so the number of
entries in a virtq can be defined.

Signed-off-by: Alex Bennée 
Message-Id: <20231009095937.195728-2-alex.ben...@linaro.org>

---
v5
  - s/parent/parent_obj/
  - remove left over vhost-user-device.h
  - use DEFINE_TYPES
---
 ...{vhost-user-device.h => vhost-user-base.h} |  21 +-
 hw/virtio/vhost-user-base.c   | 345 ++
 hw/virtio/vhost-user-device-pci.c |  10 +-
 hw/virtio/vhost-user-device.c | 335 +
 hw/virtio/meson.build |   1 +
 5 files changed, 370 insertions(+), 342 deletions(-)
 rename include/hw/virtio/{vhost-user-device.h => vhost-user-base.h} (71%)
 create mode 100644 hw/virtio/vhost-user-base.c

diff --git a/include/hw/virtio/vhost-user-device.h 
b/include/hw/virtio/vhost-user-base.h
similarity index 71%
rename from include/hw/virtio/vhost-user-device.h
rename to include/hw/virtio/vhost-user-base.h
index 3ddf88a146..51d0968b89 100644
--- a/include/hw/virtio/vhost-user-device.h
+++ b/include/hw/virtio/vhost-user-base.h
@@ -6,8 +6,8 @@
  * SPDX-License-Identifier: GPL-2.0-or-later
  */
 
-#ifndef QEMU_VHOST_USER_DEVICE_H
-#define QEMU_VHOST_USER_DEVICE_H
+#ifndef QEMU_VHOST_USER_BASE_H
+#define QEMU_VHOST_USER_BASE_H
 
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
@@ -17,11 +17,13 @@
 OBJECT_DECLARE_TYPE(VHostUserBase, VHostUserBaseClass, VHOST_USER_BASE)
 
 struct VHostUserBase {
-VirtIODevice parent;
+VirtIODevice parent_obj;
+
 /* Properties */
 CharBackend chardev;
 uint16_t virtio_id;
 uint32_t num_vqs;
+uint32_t vq_size; /* can't exceed VIRTIO_QUEUE_MAX */
 uint32_t config_size;
 /* State tracking */
 VhostUserState vhost_user;
@@ -31,16 +33,17 @@ struct VHostUserBase {
 bool connected;
 };
 
-/* needed so we can use the base realize after specialisation
-   tweaks */
+/*
+ * Needed so we can use the base realize after specialisation
+ * tweaks
+ */
 struct VHostUserBaseClass {
-/*< private >*/
 VirtioDeviceClass parent_class;
-/*< public >*/
+
 DeviceRealize parent_realize;
 };
 
-/* shared for the benefit of the derived pci class */
+
 #define TYPE_VHOST_USER_DEVICE "vhost-user-device"
 
-#endif /* QEMU_VHOST_USER_DEVICE_H */
+#endif /* QEMU_VHOST_USER_BASE_H */
diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c
new file mode 100644
index 00..ebb4795ebf
--- /dev/null
+++ b/hw/virtio/vhost-user-base.c
@@ -0,0 +1,345 @@
+/*
+ * Base vhost-user-base implementation. This can be used to derive a
+ * more fully specified vhost-user backend either generically (see
+ * vhost-user-device) or via a specific stub for a device which
+ * encapsulates some fixed parameters.
+ *
+ * Copyright (c) 2023 Linaro Ltd
+ * Author: Alex Bennée 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/qdev-properties.h"
+#include "hw/virtio/virtio-bus.h"
+#include "hw/virtio/vhost-user-base.h"
+#include "qemu/error-report.h"
+
+static void vub_start(VirtIODevice *vdev)
+{
+BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
+VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+VHostUserBase *vub = VHOST_USER_BASE(vdev);
+int ret, i;
+
+if (!k->set_guest_notifiers) {
+error_report("binding does not support guest notifiers");
+return;
+}
+
+ret = vhost_dev_enable_notifiers(&vub->vhost_dev, vdev);
+if (ret < 0) {
+error_report("Error enabling host notifiers: %d", -ret);
+return;
+}
+
+ret = k->set_guest_notifiers(qbus->parent, vub->vhost_dev.nvqs, true);
+if (ret < 0) {
+error_report("Error binding guest notifier: %d", -ret);
+goto err_host_notifiers;
+}
+
+vub->vhost_dev.acked_features = vdev->guest_features;
+
+ret = vhost_dev_start(&vub->vhost_dev, vdev, true);
+if (ret < 0) {
+error_report("Error starting vhost-user-base: %d", -ret);
+goto err_guest_notifiers;
+}
+
+/*
+ * guest_notifier_mask/pending not used yet, so just unmask
+ * everything here. virtio-pci will do the right thing by
+ * enabling/disabling irqfd.
+ */
+for (i = 0; i < vub->vhost_dev.nvqs; i++) {
+vhost_virtqueue_mask(&vub->vhost_dev, vdev, i, false);
+}
+
+return;
+
+err_guest_notifiers:
+k->set_guest_notifiers(qbus->parent, vub->vhost_dev.nvqs, false);
+err_host_notifiers:
+vhost_dev_disable_notifiers(&vub->vhost_dev, vdev);
+}
+
+static void vub_stop(VirtIO

[PATCH v5 5/6] hw/virtio: add vhost-user-snd and virtio-snd-pci devices

2023-10-19 Thread Alex Bennée
From: Manos Pitsidianakis 

Tested with rust-vmm vhost-user-sound daemon:

RUST_LOG=trace cargo run --bin vhost-user-sound -- --socket /tmp/snd.sock 
--backend null

Invocation:

qemu-system-x86_64  \
-qmp unix:./qmp-sock,server,wait=off  \
-m 4096 \
-numa node,memdev=mem \
-object 
memory-backend-file,id=mem,size=4G,mem-path=/dev/shm,share=on \
-D qemu.log \
-d guest_errors,trace:\*snd\*,trace:\*sound\*,trace:\*vhost\* \
-chardev socket,id=vsnd,path=/tmp/snd.sock \
-device vhost-user-snd-pci,chardev=vsnd,id=snd \
/path/to/disk

[AJB: imported from 
https://github.com/epilys/qemu-virtio-snd/commit/54ae1cdd15fef2d88e9e387a175f099a38c636f4.patch]

Signed-off-by: Alex Bennée 
Message-Id: <20231009095937.195728-6-alex.ben...@linaro.org>
---
 include/hw/virtio/vhost-user-snd.h | 26 +++
 hw/virtio/vhost-user-snd-pci.c | 75 ++
 hw/virtio/vhost-user-snd.c | 67 ++
 hw/virtio/Kconfig  |  5 ++
 hw/virtio/meson.build  |  3 ++
 5 files changed, 176 insertions(+)
 create mode 100644 include/hw/virtio/vhost-user-snd.h
 create mode 100644 hw/virtio/vhost-user-snd-pci.c
 create mode 100644 hw/virtio/vhost-user-snd.c

diff --git a/include/hw/virtio/vhost-user-snd.h 
b/include/hw/virtio/vhost-user-snd.h
new file mode 100644
index 00..a1627003a0
--- /dev/null
+++ b/include/hw/virtio/vhost-user-snd.h
@@ -0,0 +1,26 @@
+/*
+ * Vhost-user Sound virtio device
+ *
+ * Copyright (c) 2021 Mathieu Poirier 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef QEMU_VHOST_USER_SND_H
+#define QEMU_VHOST_USER_SND_H
+
+#include "hw/virtio/virtio.h"
+#include "hw/virtio/vhost.h"
+#include "hw/virtio/vhost-user.h"
+#include "hw/virtio/vhost-user-base.h"
+
+#define TYPE_VHOST_USER_SND "vhost-user-snd"
+OBJECT_DECLARE_SIMPLE_TYPE(VHostUserSound, VHOST_USER_SND)
+
+struct VHostUserSound {
+/*< private >*/
+VHostUserBase parent;
+/*< public >*/
+};
+
+#endif /* QEMU_VHOST_USER_SND_H */
diff --git a/hw/virtio/vhost-user-snd-pci.c b/hw/virtio/vhost-user-snd-pci.c
new file mode 100644
index 00..d61cfdae63
--- /dev/null
+++ b/hw/virtio/vhost-user-snd-pci.c
@@ -0,0 +1,75 @@
+/*
+ * Vhost-user Sound virtio device PCI glue
+ *
+ * Copyright (c) 2023 Manos Pitsidianakis 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/qdev-properties.h"
+#include "hw/virtio/vhost-user-snd.h"
+#include "hw/virtio/virtio-pci.h"
+
+struct VHostUserSoundPCI {
+VirtIOPCIProxy parent_obj;
+VHostUserSound vdev;
+};
+
+typedef struct VHostUserSoundPCI VHostUserSoundPCI;
+
+#define TYPE_VHOST_USER_SND_PCI "vhost-user-snd-pci-base"
+
+DECLARE_INSTANCE_CHECKER(VHostUserSoundPCI, VHOST_USER_SND_PCI,
+ TYPE_VHOST_USER_SND_PCI)
+
+static Property vhost_user_snd_pci_properties[] = {
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void vhost_user_snd_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
+{
+VHostUserSoundPCI *dev = VHOST_USER_SND_PCI(vpci_dev);
+DeviceState *vdev = DEVICE(&dev->vdev);
+
+vpci_dev->nvectors = 1;
+
+qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
+}
+
+static void vhost_user_snd_pci_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+k->realize = vhost_user_snd_pci_realize;
+set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
+device_class_set_props(dc, vhost_user_snd_pci_properties);
+pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+pcidev_k->device_id = 0; /* Set by virtio-pci based on virtio id */
+pcidev_k->revision = 0x00;
+pcidev_k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
+}
+
+static void vhost_user_snd_pci_instance_init(Object *obj)
+{
+VHostUserSoundPCI *dev = VHOST_USER_SND_PCI(obj);
+
+virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
+TYPE_VHOST_USER_SND);
+}
+
+static const VirtioPCIDeviceTypeInfo vhost_user_snd_pci_info = {
+.base_name = TYPE_VHOST_USER_SND_PCI,
+.non_transitional_name = "vhost-user-snd-pci",
+.instance_size = sizeof(VHostUserSoundPCI),
+.instance_init = vhost_user_snd_pci_instance_init,
+.class_init = vhost_user_snd_pci_class_init,
+};
+
+static void vhost_user_snd_pci_register(void)
+{
+virtio_pci_types_register(&vhost_user_snd_pci_info);
+}
+
+type_init(vhost_user_snd_pci_register);
diff --git a/hw/virtio/vhost-user-snd.c b/hw/virtio/vhost-user-snd.c
new file mode 100644
index 00..9a217543f8
--- /dev/null
+++ b/hw/virtio/vhost-user-snd.c
@@ -0,0 +1,67

[PATCH v5 2/6] hw/virtio: derive vhost-user-rng from vhost-user-base

2023-10-19 Thread Alex Bennée
Now we can take advantage of our new base class and make
vhost-user-rng a much simpler boilerplate wrapper. Also as this
doesn't require any target specific hacks we only need to build the
stubs once.

Acked-by: Mark Cave-Ayland 
Signed-off-by: Alex Bennée 
Message-Id: <20231009095937.195728-3-alex.ben...@linaro.org>

---
v5
  - don't remove the in-QEMU RNG emulation!
---
 include/hw/virtio/vhost-user-rng.h |  11 +-
 hw/virtio/vhost-user-rng.c | 278 +++--
 hw/virtio/meson.build  |   9 +-
 3 files changed, 31 insertions(+), 267 deletions(-)

diff --git a/include/hw/virtio/vhost-user-rng.h 
b/include/hw/virtio/vhost-user-rng.h
index ddd9f01eea..6cffe28807 100644
--- a/include/hw/virtio/vhost-user-rng.h
+++ b/include/hw/virtio/vhost-user-rng.h
@@ -12,21 +12,14 @@
 #include "hw/virtio/virtio.h"
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
-#include "chardev/char-fe.h"
+#include "hw/virtio/vhost-user-base.h"
 
 #define TYPE_VHOST_USER_RNG "vhost-user-rng"
 OBJECT_DECLARE_SIMPLE_TYPE(VHostUserRNG, VHOST_USER_RNG)
 
 struct VHostUserRNG {
 /*< private >*/
-VirtIODevice parent;
-CharBackend chardev;
-struct vhost_virtqueue *vhost_vq;
-struct vhost_dev vhost_dev;
-VhostUserState vhost_user;
-VirtQueue *req_vq;
-bool connected;
-
+VHostUserBase parent;
 /*< public >*/
 };
 
diff --git a/hw/virtio/vhost-user-rng.c b/hw/virtio/vhost-user-rng.c
index efc54cd3fb..01879c863d 100644
--- a/hw/virtio/vhost-user-rng.c
+++ b/hw/virtio/vhost-user-rng.c
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2021 Mathieu Poirier 
  *
- * Implementation seriously tailored on vhost-user-i2c.c
+ * Simple wrapper of the generic vhost-user-device.
  *
  * SPDX-License-Identifier: GPL-2.0-or-later
  */
@@ -13,281 +13,47 @@
 #include "hw/qdev-properties.h"
 #include "hw/virtio/virtio-bus.h"
 #include "hw/virtio/vhost-user-rng.h"
-#include "qemu/error-report.h"
 #include "standard-headers/linux/virtio_ids.h"
 
-static const int feature_bits[] = {
-VIRTIO_F_RING_RESET,
-VHOST_INVALID_FEATURE_BIT
-};
-
-static void vu_rng_start(VirtIODevice *vdev)
-{
-VHostUserRNG *rng = VHOST_USER_RNG(vdev);
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-int ret;
-int i;
-
-if (!k->set_guest_notifiers) {
-error_report("binding does not support guest notifiers");
-return;
-}
-
-ret = vhost_dev_enable_notifiers(&rng->vhost_dev, vdev);
-if (ret < 0) {
-error_report("Error enabling host notifiers: %d", -ret);
-return;
-}
-
-ret = k->set_guest_notifiers(qbus->parent, rng->vhost_dev.nvqs, true);
-if (ret < 0) {
-error_report("Error binding guest notifier: %d", -ret);
-goto err_host_notifiers;
-}
-
-rng->vhost_dev.acked_features = vdev->guest_features;
-ret = vhost_dev_start(&rng->vhost_dev, vdev, true);
-if (ret < 0) {
-error_report("Error starting vhost-user-rng: %d", -ret);
-goto err_guest_notifiers;
-}
-
-/*
- * guest_notifier_mask/pending not used yet, so just unmask
- * everything here. virtio-pci will do the right thing by
- * enabling/disabling irqfd.
- */
-for (i = 0; i < rng->vhost_dev.nvqs; i++) {
-vhost_virtqueue_mask(&rng->vhost_dev, vdev, i, false);
-}
-
-return;
-
-err_guest_notifiers:
-k->set_guest_notifiers(qbus->parent, rng->vhost_dev.nvqs, false);
-err_host_notifiers:
-vhost_dev_disable_notifiers(&rng->vhost_dev, vdev);
-}
-
-static void vu_rng_stop(VirtIODevice *vdev)
-{
-VHostUserRNG *rng = VHOST_USER_RNG(vdev);
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-int ret;
-
-if (!k->set_guest_notifiers) {
-return;
-}
-
-vhost_dev_stop(&rng->vhost_dev, vdev, true);
-
-ret = k->set_guest_notifiers(qbus->parent, rng->vhost_dev.nvqs, false);
-if (ret < 0) {
-error_report("vhost guest notifier cleanup failed: %d", ret);
-return;
-}
-
-vhost_dev_disable_notifiers(&rng->vhost_dev, vdev);
-}
-
-static void vu_rng_set_status(VirtIODevice *vdev, uint8_t status)
-{
-VHostUserRNG *rng = VHOST_USER_RNG(vdev);
-bool should_start = virtio_device_should_start(vdev, status);
-
-if (vhost_dev_is_started(&rng->vhost_dev) == should_start) {
-return;
-}
-
-if (should_start) {
-vu_rng_start(vdev);
-} else {
-vu_rng_stop(vdev);
-}
-}
-
-static uint64_t vu_rng_get_features(VirtIODevice *vdev,
-uint64_t requested_features, Error **errp)
-

qemu-block@nongnu.org

2023-10-19 Thread Alex Bennée
A lot of our vhost-user stubs are large chunks of boilerplate that do
(mostly) the same thing. This series continues the cleanups by
splitting the vhost-user-base and vhost-user-generic implementations.
After adding a new vq_size property the rng, gpio and i2c vhost-user
devices become simple specialisations of the common base defining the
ID, number of queues and potentially the config handling.

I've also added Manos' vhost-user-sound while I was at it.

Changes
---

v5
  - addressing comments and tags
  - improved the docs

v4
  - dropped the F_TRANSPORT work for another series
  - added vhost-user-sound

Alex Bennée (5):
  virtio: split into vhost-user-base and vhost-user-device
  hw/virtio: derive vhost-user-rng from vhost-user-base
  hw/virtio: derive vhost-user-gpio from vhost-user-base
  hw/virtio: derive vhost-user-i2c from vhost-user-base
  docs/system: add a basic enumeration of vhost-user devices

Manos Pitsidianakis (1):
  hw/virtio: add vhost-user-snd and virtio-snd-pci devices

 docs/system/devices/vhost-user-rng.rst|   2 +
 docs/system/devices/vhost-user.rst|  60 ++-
 ...{vhost-user-device.h => vhost-user-base.h} |  21 +-
 include/hw/virtio/vhost-user-gpio.h   |  23 +-
 include/hw/virtio/vhost-user-i2c.h|  14 +-
 include/hw/virtio/vhost-user-rng.h|  11 +-
 include/hw/virtio/vhost-user-snd.h|  26 ++
 hw/virtio/vhost-user-base.c   | 345 +++
 hw/virtio/vhost-user-device-pci.c |  10 +-
 hw/virtio/vhost-user-device.c | 335 +-
 hw/virtio/vhost-user-gpio.c   | 407 +-
 hw/virtio/vhost-user-i2c.c| 272 +---
 hw/virtio/vhost-user-rng.c| 278 +---
 hw/virtio/vhost-user-snd-pci.c|  75 
 hw/virtio/vhost-user-snd.c|  67 +++
 hw/virtio/Kconfig |   5 +
 hw/virtio/meson.build |  23 +-
 17 files changed, 683 insertions(+), 1291 deletions(-)
 rename include/hw/virtio/{vhost-user-device.h => vhost-user-base.h} (71%)
 create mode 100644 include/hw/virtio/vhost-user-snd.h
 create mode 100644 hw/virtio/vhost-user-base.c
 create mode 100644 hw/virtio/vhost-user-snd-pci.c
 create mode 100644 hw/virtio/vhost-user-snd.c

-- 
2.39.2




[PATCH v5 6/6] docs/system: add a basic enumeration of vhost-user devices

2023-10-19 Thread Alex Bennée
Make it clear the vhost-user-device is intended for expert use only.

Signed-off-by: Alex Bennée 
Message-Id: <20231009095937.195728-7-alex.ben...@linaro.org>

---
v5
  - split vhost-user-device out of the table
  - sort the table alphabetically
  - add sound and scmi devices
---
 docs/system/devices/vhost-user-rng.rst |  2 +
 docs/system/devices/vhost-user.rst | 60 +-
 2 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/docs/system/devices/vhost-user-rng.rst 
b/docs/system/devices/vhost-user-rng.rst
index a145d4105c..ead1405326 100644
--- a/docs/system/devices/vhost-user-rng.rst
+++ b/docs/system/devices/vhost-user-rng.rst
@@ -1,3 +1,5 @@
+.. _vhost_user_rng:
+
 QEMU vhost-user-rng - RNG emulation
 ===
 
diff --git a/docs/system/devices/vhost-user.rst 
b/docs/system/devices/vhost-user.rst
index a80e95a48a..3e9fd2eba5 100644
--- a/docs/system/devices/vhost-user.rst
+++ b/docs/system/devices/vhost-user.rst
@@ -8,13 +8,71 @@ outside of QEMU itself. To do this there are a number of 
things
 required.
 
 vhost-user device
-===
+=
 
 These are simple stub devices that ensure the VirtIO device is visible
 to the guest. The code is mostly boilerplate although each device has
 a ``chardev`` option which specifies the ID of the ``--chardev``
 device that connects via a socket to the vhost-user *daemon*.
 
+Each device will have an virtio-mmio and virtio-pci variant. See your
+platform details for what sort of virtio bus to use.
+
+.. list-table:: vhost-user devices
+  :widths: 20 20 60
+  :header-rows: 1
+
+  * - Device
+- Type
+- Notes
+  * - vhost-user-blk
+- Block storage
+- See contrib/vhost-user-blk
+  * - vhost-user-fs
+- File based storage driver
+- See https://gitlab.com/virtio-fs/virtiofsd
+  * - vhost-user-gpio
+- Proxy gpio pins to host
+- See https://github.com/rust-vmm/vhost-device
+  * - vhost-user-gpu
+- GPU driver
+- See contrib/vhost-user-gpu
+  * - vhost-user-i2c
+- Proxy i2c devices to host
+- See https://github.com/rust-vmm/vhost-device
+  * - vhost-user-input
+- Generic input driver
+- See contrib/vhost-user-input
+  * - vhost-user-rng
+- Entropy driver
+- :ref:`vhost_user_rng`
+  * - vhost-user-scmi
+- System Control and Management Interface
+- See https://github.com/rust-vmm/vhost-device
+  * - vhost-user-snd
+- Audio device
+- See https://github.com/rust-vmm/vhost-device/staging
+  * - vhost-user-scsi
+- SCSI based storage
+- See contrib/vhost-user-scsi
+  * - vhost-user-vsock
+- Socket based communication
+- See https://github.com/rust-vmm/vhost-device
+
+The referenced *daemons* are not exhaustive, any conforming backend
+implementing the device and using the vhost-user protocol should work.
+
+vhost-user-device
+^
+
+The vhost-user-device is a generic development device intended for
+expert use while developing new backends. The user needs to specify
+all the required parameters including:
+
+  - Device ``virtio-id``
+  - The ``num_vqs`` it needs and their ``vq_size``
+  - The ``config_size`` if needed
+
 vhost-user daemon
 =
 
-- 
2.39.2




Re: [PATCH v4 2/6] hw/virtio: derive vhost-user-rng from vhost-user-base

2023-10-09 Thread Alex Bennée


Manos Pitsidianakis  writes:

> On Mon, 09 Oct 2023 12:59, Alex Bennée  wrote:
>>diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
>>index 51c3f97c2d..d0b963199c 100644
>>--- a/hw/virtio/meson.build
>>+++ b/hw/virtio/meson.build
>>@@ -18,8 +18,15 @@ if have_vhost
>> # fixme - this really should be generic
>> specific_virtio_ss.add(files('vhost-user.c'))
>> system_virtio_ss.add(files('vhost-user-base.c'))
>>+
>>+# MMIO Stubs
>> system_virtio_ss.add(files('vhost-user-device.c'))
>>+system_virtio_ss.add(when: 'CONFIG_VHOST_USER_RNG', if_true: 
>>files('vhost-user-rng.c'))
>>+
>>+# PCI Stubs
>> system_virtio_ss.add(when: 'CONFIG_VIRTIO_PCI', if_true: 
>> files('vhost-user-device-pci.c'))
>>+system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 
>>'CONFIG_VHOST_USER_RNG'],
>>+ if_true: files('vhost-user-rng-pci.c'))
>
> Is there a reason why the target was moved to system_virtio_ss from
> virtio_pci_ss?

So we build it once, virtio_pci_ss is still:

  specific_virtio_ss.add_all(when: 'CONFIG_VIRTIO_PCI', if_true: virtio_pci_ss)

which means we build it once for every target which is overkill.

>
>>   endif
>>   if have_vhost_vdpa
>> system_virtio_ss.add(files('vhost-vdpa.c'))
>>@@ -34,10 +41,8 @@ specific_virtio_ss.add(when: 'CONFIG_VHOST_USER_FS', 
>>if_true: files('vhost-user-
>> specific_virtio_ss.add(when: 'CONFIG_VIRTIO_PMEM', if_true: 
>> files('virtio-pmem.c'))
>> specific_virtio_ss.add(when: 'CONFIG_VHOST_VSOCK', if_true: 
>> files('vhost-vsock.c'))
>> specific_virtio_ss.add(when: 'CONFIG_VHOST_USER_VSOCK', if_true: 
>> files('vhost-user-vsock.c'))
>>-specific_virtio_ss.add(when: 'CONFIG_VIRTIO_RNG', if_true: 
>>files('virtio-rng.c'))
>
> Was this accidental? It's not added anywhere else, only deleted.

Oops yes. Didn't mean to delete the in-tree emulation. Will fix.

>
>> @@ -57,7 +61,6 @@ virtio_pci_ss.add(when: 'CONFIG_VHOST_USER_FS',
>> if_true: files('vhost-user-fs-pc
>> virtio_pci_ss.add(when: 'CONFIG_VIRTIO_CRYPTO', if_true: 
>> files('virtio-crypto-pci.c'))
>> virtio_pci_ss.add(when: 'CONFIG_VIRTIO_INPUT_HOST', if_true: 
>> files('virtio-input-host-pci.c'))
>> virtio_pci_ss.add(when: 'CONFIG_VIRTIO_INPUT', if_true: 
>> files('virtio-input-pci.c'))
>>-virtio_pci_ss.add(when: 'CONFIG_VIRTIO_RNG', if_true: 
>>files('virtio-rng-pci.c'))
>> virtio_pci_ss.add(when: 'CONFIG_VIRTIO_BALLOON', if_true: 
>> files('virtio-balloon-pci.c'))
>> virtio_pci_ss.add(when: 'CONFIG_VIRTIO_9P', if_true: 
>> files('virtio-9p-pci.c'))
>> virtio_pci_ss.add(when: 'CONFIG_VIRTIO_SCSI', if_true: 
>> files('virtio-scsi-pci.c'))
>
> Same here
>
> Manos


-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



[PATCH v4 3/6] hw/virtio: derive vhost-user-gpio from vhost-user-base

2023-10-09 Thread Alex Bennée
Now the new base class supports config handling we can take advantage
and make vhost-user-gpio a much simpler boilerplate wrapper. Also as
this doesn't require any target specific hacks we only need to build
the stubs once.

Message-Id: <20230418162140.373219-12-alex.ben...@linaro.org>
Signed-off-by: Alex Bennée 
Acked-by: Mark Cave-Ayland 

---
v2
  - use new vhost-user-base
  - move build to common code
v3
  - fix inadvertent double link
v4
  - merge conflict
  - update includes
---
 include/hw/virtio/vhost-user-gpio.h |  23 +-
 hw/virtio/vhost-user-gpio.c | 407 ++--
 hw/virtio/meson.build   |   5 +-
 3 files changed, 22 insertions(+), 413 deletions(-)

diff --git a/include/hw/virtio/vhost-user-gpio.h 
b/include/hw/virtio/vhost-user-gpio.h
index a9d3f9b049..5201d5f072 100644
--- a/include/hw/virtio/vhost-user-gpio.h
+++ b/include/hw/virtio/vhost-user-gpio.h
@@ -12,33 +12,14 @@
 #include "hw/virtio/virtio.h"
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
-#include "standard-headers/linux/virtio_gpio.h"
-#include "chardev/char-fe.h"
+#include "hw/virtio/vhost-user-base.h"
 
 #define TYPE_VHOST_USER_GPIO "vhost-user-gpio-device"
 OBJECT_DECLARE_SIMPLE_TYPE(VHostUserGPIO, VHOST_USER_GPIO);
 
 struct VHostUserGPIO {
 /*< private >*/
-VirtIODevice parent_obj;
-CharBackend chardev;
-struct virtio_gpio_config config;
-struct vhost_virtqueue *vhost_vqs;
-struct vhost_dev vhost_dev;
-VhostUserState vhost_user;
-VirtQueue *command_vq;
-VirtQueue *interrupt_vq;
-/**
- * There are at least two steps of initialization of the
- * vhost-user device. The first is a "connect" step and
- * second is a "start" step. Make a separation between
- * those initialization phases by using two fields.
- *
- * @connected: see vu_gpio_connect()/vu_gpio_disconnect()
- * @started_vu: see vu_gpio_start()/vu_gpio_stop()
- */
-bool connected;
-bool started_vu;
+VHostUserBase parent;
 /*< public >*/
 };
 
diff --git a/hw/virtio/vhost-user-gpio.c b/hw/virtio/vhost-user-gpio.c
index 3d7fae3984..9f37c25415 100644
--- a/hw/virtio/vhost-user-gpio.c
+++ b/hw/virtio/vhost-user-gpio.c
@@ -11,388 +11,25 @@
 #include "hw/qdev-properties.h"
 #include "hw/virtio/virtio-bus.h"
 #include "hw/virtio/vhost-user-gpio.h"
-#include "qemu/error-report.h"
 #include "standard-headers/linux/virtio_ids.h"
-#include "trace.h"
+#include "standard-headers/linux/virtio_gpio.h"
 
-#define REALIZE_CONNECTION_RETRIES 3
-#define VHOST_NVQS 2
-
-/* Features required from VirtIO */
-static const int feature_bits[] = {
-VIRTIO_F_VERSION_1,
-VIRTIO_F_NOTIFY_ON_EMPTY,
-VIRTIO_RING_F_INDIRECT_DESC,
-VIRTIO_RING_F_EVENT_IDX,
-VIRTIO_GPIO_F_IRQ,
-VIRTIO_F_RING_RESET,
-VHOST_INVALID_FEATURE_BIT
-};
-
-static void vu_gpio_get_config(VirtIODevice *vdev, uint8_t *config)
-{
-VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev);
-
-memcpy(config, &gpio->config, sizeof(gpio->config));
-}
-
-static int vu_gpio_config_notifier(struct vhost_dev *dev)
-{
-VHostUserGPIO *gpio = VHOST_USER_GPIO(dev->vdev);
-
-memcpy(dev->vdev->config, &gpio->config, sizeof(gpio->config));
-virtio_notify_config(dev->vdev);
-
-return 0;
-}
-
-const VhostDevConfigOps gpio_ops = {
-.vhost_dev_config_notifier = vu_gpio_config_notifier,
+static Property vgpio_properties[] = {
+DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
+DEFINE_PROP_END_OF_LIST(),
 };
 
-static int vu_gpio_start(VirtIODevice *vdev)
-{
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev);
-struct vhost_dev *vhost_dev = &gpio->vhost_dev;
-int ret, i;
-
-if (!k->set_guest_notifiers) {
-error_report("binding does not support guest notifiers");
-return -ENOSYS;
-}
-
-ret = vhost_dev_enable_notifiers(vhost_dev, vdev);
-if (ret < 0) {
-error_report("Error enabling host notifiers: %d", ret);
-return ret;
-}
-
-ret = k->set_guest_notifiers(qbus->parent, vhost_dev->nvqs, true);
-if (ret < 0) {
-error_report("Error binding guest notifier: %d", ret);
-goto err_host_notifiers;
-}
-
-/*
- * Before we start up we need to ensure we have the final feature
- * set needed for the vhost configuration. The backend may also
- * apply backend_features when the feature set is sent.
- */
-vhost_ack_features(&gpio->vhost_dev, feature_bits, vdev->guest_features);
-
-ret = vhost_dev_start(&gpio->vhost_dev, vdev, false);
-if (ret < 0) {
- 

[PATCH v4 2/6] hw/virtio: derive vhost-user-rng from vhost-user-base

2023-10-09 Thread Alex Bennée
Now we can take advantage of our new base class and make
vhost-user-rng a much simpler boilerplate wrapper. Also as this
doesn't require any target specific hacks we only need to build the
stubs once.

Message-Id: <20230418162140.373219-10-alex.ben...@linaro.org>
Acked-by: Mark Cave-Ayland 
Signed-off-by: Alex Bennée 

---
v2
  - new derivation layout
  - move directly to softmmu_virtio_ss
v3
  - use vqsize
---
 include/hw/virtio/vhost-user-rng.h |  11 +-
 hw/virtio/vhost-user-rng.c | 278 +++--
 hw/virtio/meson.build  |  11 +-
 3 files changed, 31 insertions(+), 269 deletions(-)

diff --git a/include/hw/virtio/vhost-user-rng.h 
b/include/hw/virtio/vhost-user-rng.h
index ddd9f01eea..6cffe28807 100644
--- a/include/hw/virtio/vhost-user-rng.h
+++ b/include/hw/virtio/vhost-user-rng.h
@@ -12,21 +12,14 @@
 #include "hw/virtio/virtio.h"
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
-#include "chardev/char-fe.h"
+#include "hw/virtio/vhost-user-base.h"
 
 #define TYPE_VHOST_USER_RNG "vhost-user-rng"
 OBJECT_DECLARE_SIMPLE_TYPE(VHostUserRNG, VHOST_USER_RNG)
 
 struct VHostUserRNG {
 /*< private >*/
-VirtIODevice parent;
-CharBackend chardev;
-struct vhost_virtqueue *vhost_vq;
-struct vhost_dev vhost_dev;
-VhostUserState vhost_user;
-VirtQueue *req_vq;
-bool connected;
-
+VHostUserBase parent;
 /*< public >*/
 };
 
diff --git a/hw/virtio/vhost-user-rng.c b/hw/virtio/vhost-user-rng.c
index efc54cd3fb..01879c863d 100644
--- a/hw/virtio/vhost-user-rng.c
+++ b/hw/virtio/vhost-user-rng.c
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2021 Mathieu Poirier 
  *
- * Implementation seriously tailored on vhost-user-i2c.c
+ * Simple wrapper of the generic vhost-user-device.
  *
  * SPDX-License-Identifier: GPL-2.0-or-later
  */
@@ -13,281 +13,47 @@
 #include "hw/qdev-properties.h"
 #include "hw/virtio/virtio-bus.h"
 #include "hw/virtio/vhost-user-rng.h"
-#include "qemu/error-report.h"
 #include "standard-headers/linux/virtio_ids.h"
 
-static const int feature_bits[] = {
-VIRTIO_F_RING_RESET,
-VHOST_INVALID_FEATURE_BIT
-};
-
-static void vu_rng_start(VirtIODevice *vdev)
-{
-VHostUserRNG *rng = VHOST_USER_RNG(vdev);
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-int ret;
-int i;
-
-if (!k->set_guest_notifiers) {
-error_report("binding does not support guest notifiers");
-return;
-}
-
-ret = vhost_dev_enable_notifiers(&rng->vhost_dev, vdev);
-if (ret < 0) {
-error_report("Error enabling host notifiers: %d", -ret);
-return;
-}
-
-ret = k->set_guest_notifiers(qbus->parent, rng->vhost_dev.nvqs, true);
-if (ret < 0) {
-error_report("Error binding guest notifier: %d", -ret);
-goto err_host_notifiers;
-}
-
-rng->vhost_dev.acked_features = vdev->guest_features;
-ret = vhost_dev_start(&rng->vhost_dev, vdev, true);
-if (ret < 0) {
-error_report("Error starting vhost-user-rng: %d", -ret);
-goto err_guest_notifiers;
-}
-
-/*
- * guest_notifier_mask/pending not used yet, so just unmask
- * everything here. virtio-pci will do the right thing by
- * enabling/disabling irqfd.
- */
-for (i = 0; i < rng->vhost_dev.nvqs; i++) {
-vhost_virtqueue_mask(&rng->vhost_dev, vdev, i, false);
-}
-
-return;
-
-err_guest_notifiers:
-k->set_guest_notifiers(qbus->parent, rng->vhost_dev.nvqs, false);
-err_host_notifiers:
-vhost_dev_disable_notifiers(&rng->vhost_dev, vdev);
-}
-
-static void vu_rng_stop(VirtIODevice *vdev)
-{
-VHostUserRNG *rng = VHOST_USER_RNG(vdev);
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-int ret;
-
-if (!k->set_guest_notifiers) {
-return;
-}
-
-vhost_dev_stop(&rng->vhost_dev, vdev, true);
-
-ret = k->set_guest_notifiers(qbus->parent, rng->vhost_dev.nvqs, false);
-if (ret < 0) {
-error_report("vhost guest notifier cleanup failed: %d", ret);
-return;
-}
-
-vhost_dev_disable_notifiers(&rng->vhost_dev, vdev);
-}
-
-static void vu_rng_set_status(VirtIODevice *vdev, uint8_t status)
-{
-VHostUserRNG *rng = VHOST_USER_RNG(vdev);
-bool should_start = virtio_device_should_start(vdev, status);
-
-if (vhost_dev_is_started(&rng->vhost_dev) == should_start) {
-return;
-}
-
-if (should_start) {
-vu_rng_start(vdev);
-} else {
-vu_rng_stop(vdev);
-}
-}
-
-static uint64_t vu_rng_get_features(VirtIODevice *vdev,
-

[PATCH v4 5/6] hw/virtio: add vhost-user-snd and virtio-snd-pci devices

2023-10-09 Thread Alex Bennée
From: Manos Pitsidianakis 

Tested with rust-vmm vhost-user-sound daemon:

RUST_LOG=trace cargo run --bin vhost-user-sound -- --socket /tmp/snd.sock 
--backend null

Invocation:

qemu-system-x86_64  \
-qmp unix:./qmp-sock,server,wait=off  \
-m 4096 \
-numa node,memdev=mem \
-object 
memory-backend-file,id=mem,size=4G,mem-path=/dev/shm,share=on \
-D qemu.log \
-d guest_errors,trace:\*snd\*,trace:\*sound\*,trace:\*vhost\* \
-chardev socket,id=vsnd,path=/tmp/snd.sock \
-device vhost-user-snd-pci,chardev=vsnd,id=snd \
/path/to/disk

[AJB: imported from 
https://github.com/epilys/qemu-virtio-snd/commit/54ae1cdd15fef2d88e9e387a175f099a38c636f4.patch]
Signed-off-by: Alex Bennée 

---
v1
  - import and test
---
 include/hw/virtio/vhost-user-snd.h | 26 +++
 hw/virtio/vhost-user-snd-pci.c | 75 ++
 hw/virtio/vhost-user-snd.c | 67 ++
 hw/virtio/Kconfig  |  5 ++
 hw/virtio/meson.build  |  3 ++
 5 files changed, 176 insertions(+)
 create mode 100644 include/hw/virtio/vhost-user-snd.h
 create mode 100644 hw/virtio/vhost-user-snd-pci.c
 create mode 100644 hw/virtio/vhost-user-snd.c

diff --git a/include/hw/virtio/vhost-user-snd.h 
b/include/hw/virtio/vhost-user-snd.h
new file mode 100644
index 00..a1627003a0
--- /dev/null
+++ b/include/hw/virtio/vhost-user-snd.h
@@ -0,0 +1,26 @@
+/*
+ * Vhost-user Sound virtio device
+ *
+ * Copyright (c) 2021 Mathieu Poirier 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef QEMU_VHOST_USER_SND_H
+#define QEMU_VHOST_USER_SND_H
+
+#include "hw/virtio/virtio.h"
+#include "hw/virtio/vhost.h"
+#include "hw/virtio/vhost-user.h"
+#include "hw/virtio/vhost-user-base.h"
+
+#define TYPE_VHOST_USER_SND "vhost-user-snd"
+OBJECT_DECLARE_SIMPLE_TYPE(VHostUserSound, VHOST_USER_SND)
+
+struct VHostUserSound {
+/*< private >*/
+VHostUserBase parent;
+/*< public >*/
+};
+
+#endif /* QEMU_VHOST_USER_SND_H */
diff --git a/hw/virtio/vhost-user-snd-pci.c b/hw/virtio/vhost-user-snd-pci.c
new file mode 100644
index 00..d61cfdae63
--- /dev/null
+++ b/hw/virtio/vhost-user-snd-pci.c
@@ -0,0 +1,75 @@
+/*
+ * Vhost-user Sound virtio device PCI glue
+ *
+ * Copyright (c) 2023 Manos Pitsidianakis 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/qdev-properties.h"
+#include "hw/virtio/vhost-user-snd.h"
+#include "hw/virtio/virtio-pci.h"
+
+struct VHostUserSoundPCI {
+VirtIOPCIProxy parent_obj;
+VHostUserSound vdev;
+};
+
+typedef struct VHostUserSoundPCI VHostUserSoundPCI;
+
+#define TYPE_VHOST_USER_SND_PCI "vhost-user-snd-pci-base"
+
+DECLARE_INSTANCE_CHECKER(VHostUserSoundPCI, VHOST_USER_SND_PCI,
+ TYPE_VHOST_USER_SND_PCI)
+
+static Property vhost_user_snd_pci_properties[] = {
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void vhost_user_snd_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
+{
+VHostUserSoundPCI *dev = VHOST_USER_SND_PCI(vpci_dev);
+DeviceState *vdev = DEVICE(&dev->vdev);
+
+vpci_dev->nvectors = 1;
+
+qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
+}
+
+static void vhost_user_snd_pci_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+k->realize = vhost_user_snd_pci_realize;
+set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
+device_class_set_props(dc, vhost_user_snd_pci_properties);
+pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+pcidev_k->device_id = 0; /* Set by virtio-pci based on virtio id */
+pcidev_k->revision = 0x00;
+pcidev_k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
+}
+
+static void vhost_user_snd_pci_instance_init(Object *obj)
+{
+VHostUserSoundPCI *dev = VHOST_USER_SND_PCI(obj);
+
+virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
+TYPE_VHOST_USER_SND);
+}
+
+static const VirtioPCIDeviceTypeInfo vhost_user_snd_pci_info = {
+.base_name = TYPE_VHOST_USER_SND_PCI,
+.non_transitional_name = "vhost-user-snd-pci",
+.instance_size = sizeof(VHostUserSoundPCI),
+.instance_init = vhost_user_snd_pci_instance_init,
+.class_init = vhost_user_snd_pci_class_init,
+};
+
+static void vhost_user_snd_pci_register(void)
+{
+virtio_pci_types_register(&vhost_user_snd_pci_info);
+}
+
+type_init(vhost_user_snd_pci_register);
diff --git a/hw/virtio/vhost-user-snd.c b/hw/virtio/vhost-user-snd.c
new file mode 100644
index 00..9a217543f8
--- /dev/null
+++ b/hw/virtio/vhost-user-snd.c
@@ -0,0 +1,67 @@
+/*
+ * Vhost-user s

[PATCH v4 4/6] hw/virtio: derive vhost-user-i2c from vhost-user-base

2023-10-09 Thread Alex Bennée
Now we can take advantage of the new base class and make
vhost-user-i2c a much simpler boilerplate wrapper. Also as this
doesn't require any target specific hacks we only need to build the
stubs once.

Message-Id: <20230418162140.373219-13-alex.ben...@linaro.org>
Acked-by: Mark Cave-Ayland 
Signed-off-by: Alex Bennée 

---
v2
  - update to new inheritance scheme
  - move build to common code
v3
  - fix merge conflict in meson
  - style updates, remove duplicate includes
v4
  - use vqsize
---
 include/hw/virtio/vhost-user-i2c.h |  14 +-
 hw/virtio/vhost-user-i2c.c | 272 ++---
 hw/virtio/meson.build  |   5 +-
 3 files changed, 23 insertions(+), 268 deletions(-)

diff --git a/include/hw/virtio/vhost-user-i2c.h 
b/include/hw/virtio/vhost-user-i2c.h
index 0f7acd40e3..a8fcb108db 100644
--- a/include/hw/virtio/vhost-user-i2c.h
+++ b/include/hw/virtio/vhost-user-i2c.h
@@ -9,23 +9,17 @@
 #ifndef QEMU_VHOST_USER_I2C_H
 #define QEMU_VHOST_USER_I2C_H
 
+#include "hw/virtio/virtio.h"
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
+#include "hw/virtio/vhost-user-base.h"
 
 #define TYPE_VHOST_USER_I2C "vhost-user-i2c-device"
+
 OBJECT_DECLARE_SIMPLE_TYPE(VHostUserI2C, VHOST_USER_I2C)
 
 struct VHostUserI2C {
-VirtIODevice parent;
-CharBackend chardev;
-struct vhost_virtqueue *vhost_vq;
-struct vhost_dev vhost_dev;
-VhostUserState vhost_user;
-VirtQueue *vq;
-bool connected;
+VHostUserBase parent;
 };
 
-/* Virtio Feature bits */
-#define VIRTIO_I2C_F_ZERO_LENGTH_REQUEST   0
-
 #endif /* QEMU_VHOST_USER_I2C_H */
diff --git a/hw/virtio/vhost-user-i2c.c b/hw/virtio/vhost-user-i2c.c
index 4eef3f0633..a464f5e039 100644
--- a/hw/virtio/vhost-user-i2c.c
+++ b/hw/virtio/vhost-user-i2c.c
@@ -14,253 +14,22 @@
 #include "qemu/error-report.h"
 #include "standard-headers/linux/virtio_ids.h"
 
-static const int feature_bits[] = {
-VIRTIO_I2C_F_ZERO_LENGTH_REQUEST,
-VIRTIO_F_RING_RESET,
-VHOST_INVALID_FEATURE_BIT
+static Property vi2c_properties[] = {
+DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
+DEFINE_PROP_END_OF_LIST(),
 };
 
-static void vu_i2c_start(VirtIODevice *vdev)
-{
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-int ret, i;
-
-if (!k->set_guest_notifiers) {
-error_report("binding does not support guest notifiers");
-return;
-}
-
-ret = vhost_dev_enable_notifiers(&i2c->vhost_dev, vdev);
-if (ret < 0) {
-error_report("Error enabling host notifiers: %d", -ret);
-return;
-}
-
-ret = k->set_guest_notifiers(qbus->parent, i2c->vhost_dev.nvqs, true);
-if (ret < 0) {
-error_report("Error binding guest notifier: %d", -ret);
-goto err_host_notifiers;
-}
-
-i2c->vhost_dev.acked_features = vdev->guest_features;
-
-ret = vhost_dev_start(&i2c->vhost_dev, vdev, true);
-if (ret < 0) {
-error_report("Error starting vhost-user-i2c: %d", -ret);
-goto err_guest_notifiers;
-}
-
-/*
- * guest_notifier_mask/pending not used yet, so just unmask
- * everything here. virtio-pci will do the right thing by
- * enabling/disabling irqfd.
- */
-for (i = 0; i < i2c->vhost_dev.nvqs; i++) {
-vhost_virtqueue_mask(&i2c->vhost_dev, vdev, i, false);
-}
-
-return;
-
-err_guest_notifiers:
-k->set_guest_notifiers(qbus->parent, i2c->vhost_dev.nvqs, false);
-err_host_notifiers:
-vhost_dev_disable_notifiers(&i2c->vhost_dev, vdev);
-}
-
-static void vu_i2c_stop(VirtIODevice *vdev)
-{
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-int ret;
-
-if (!k->set_guest_notifiers) {
-return;
-}
-
-vhost_dev_stop(&i2c->vhost_dev, vdev, true);
-
-ret = k->set_guest_notifiers(qbus->parent, i2c->vhost_dev.nvqs, false);
-if (ret < 0) {
-error_report("vhost guest notifier cleanup failed: %d", ret);
-return;
-}
-
-vhost_dev_disable_notifiers(&i2c->vhost_dev, vdev);
-}
-
-static void vu_i2c_set_status(VirtIODevice *vdev, uint8_t status)
-{
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-bool should_start = virtio_device_should_start(vdev, status);
-
-if (vhost_dev_is_started(&i2c->vhost_dev) == should_start) {
-return;
-}
-
-if (should_start) {
-vu_i2c_start(vdev);
-} else {
-vu_i2c_stop(vdev);
-}
-}
-
-static uint64_t vu_i2c_get_features(VirtIODevice *vdev,
-uint64_t requested_features, 

[PATCH v4 1/6] virtio: split into vhost-user-base and vhost-user-device

2023-10-09 Thread Alex Bennée
Lets keep a cleaner split between the base class and the derived
vhost-user-device which we can use for generic vhost-user stubs. This
includes an update to introduce the vq_size property so the number of
entries in a virtq can be defined.

Signed-off-by: Alex Bennée 

---
v1
  - merge and re-base, reset testing/review tags
---
 include/hw/virtio/vhost-user-base.h |  49 
 hw/virtio/vhost-user-base.c | 348 
 hw/virtio/vhost-user-device-pci.c   |  10 +-
 hw/virtio/vhost-user-device.c   | 335 +-
 hw/virtio/meson.build   |   1 +
 5 files changed, 410 insertions(+), 333 deletions(-)
 create mode 100644 include/hw/virtio/vhost-user-base.h
 create mode 100644 hw/virtio/vhost-user-base.c

diff --git a/include/hw/virtio/vhost-user-base.h 
b/include/hw/virtio/vhost-user-base.h
new file mode 100644
index 00..cad377468b
--- /dev/null
+++ b/include/hw/virtio/vhost-user-base.h
@@ -0,0 +1,49 @@
+/*
+ * Vhost-user generic virtio device
+ *
+ * Copyright (c) 2023 Linaro Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef QEMU_VHOST_USER_BASE_H
+#define QEMU_VHOST_USER_BASE_H
+
+#include "hw/virtio/vhost.h"
+#include "hw/virtio/vhost-user.h"
+
+#define TYPE_VHOST_USER_BASE "vhost-user-base"
+
+OBJECT_DECLARE_TYPE(VHostUserBase, VHostUserBaseClass, VHOST_USER_BASE)
+
+struct VHostUserBase {
+VirtIODevice parent;
+
+/* Properties */
+CharBackend chardev;
+uint16_t virtio_id;
+uint32_t num_vqs;
+uint32_t vq_size; /* can't exceed VIRTIO_QUEUE_MAX */
+uint32_t config_size;
+/* State tracking */
+VhostUserState vhost_user;
+struct vhost_virtqueue *vhost_vq;
+struct vhost_dev vhost_dev;
+GPtrArray *vqs;
+bool connected;
+};
+
+/*
+ * Needed so we can use the base realize after specialisation
+ * tweaks
+ */
+struct VHostUserBaseClass {
+VirtioDeviceClass parent_class;
+
+DeviceRealize parent_realize;
+};
+
+
+#define TYPE_VHOST_USER_DEVICE "vhost-user-device"
+
+#endif /* QEMU_VHOST_USER_BASE_H */
diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c
new file mode 100644
index 00..a8b811c394
--- /dev/null
+++ b/hw/virtio/vhost-user-base.c
@@ -0,0 +1,348 @@
+/*
+ * Base vhost-user-base implementation. This can be used to derive a
+ * more fully specified vhost-user backend either generically (see
+ * vhost-user-device) or via a specific stub for a device which
+ * encapsulates some fixed parameters.
+ *
+ * Copyright (c) 2023 Linaro Ltd
+ * Author: Alex Bennée 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/qdev-properties.h"
+#include "hw/virtio/virtio-bus.h"
+#include "hw/virtio/vhost-user-base.h"
+#include "qemu/error-report.h"
+
+static void vub_start(VirtIODevice *vdev)
+{
+BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
+VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+VHostUserBase *vub = VHOST_USER_BASE(vdev);
+int ret, i;
+
+if (!k->set_guest_notifiers) {
+error_report("binding does not support guest notifiers");
+return;
+}
+
+ret = vhost_dev_enable_notifiers(&vub->vhost_dev, vdev);
+if (ret < 0) {
+error_report("Error enabling host notifiers: %d", -ret);
+return;
+}
+
+ret = k->set_guest_notifiers(qbus->parent, vub->vhost_dev.nvqs, true);
+if (ret < 0) {
+error_report("Error binding guest notifier: %d", -ret);
+goto err_host_notifiers;
+}
+
+vub->vhost_dev.acked_features = vdev->guest_features;
+
+ret = vhost_dev_start(&vub->vhost_dev, vdev, true);
+if (ret < 0) {
+error_report("Error starting vhost-user-base: %d", -ret);
+goto err_guest_notifiers;
+}
+
+/*
+ * guest_notifier_mask/pending not used yet, so just unmask
+ * everything here. virtio-pci will do the right thing by
+ * enabling/disabling irqfd.
+ */
+for (i = 0; i < vub->vhost_dev.nvqs; i++) {
+vhost_virtqueue_mask(&vub->vhost_dev, vdev, i, false);
+}
+
+return;
+
+err_guest_notifiers:
+k->set_guest_notifiers(qbus->parent, vub->vhost_dev.nvqs, false);
+err_host_notifiers:
+vhost_dev_disable_notifiers(&vub->vhost_dev, vdev);
+}
+
+static void vub_stop(VirtIODevice *vdev)
+{
+VHostUserBase *vub = VHOST_USER_BASE(vdev);
+BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
+VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+int ret;
+
+if (!k->set_guest_notifiers) {
+return;
+}
+
+vhost_dev_stop(&vub->vhost_dev, vdev, true);
+
+ret = k->set_guest_notifiers(qbus->parent, vub->vhost_dev.nvqs, false);
+if (ret < 0) {
+error_report("vh

[PATCH v4 6/6] docs/system: add a basic enumeration of vhost-user devices

2023-10-09 Thread Alex Bennée
Make it clear the vhost-user-device is intended for expert use only.

Signed-off-by: Alex Bennée 

---
v2
  - make clear vhost-user-device for expert use
---
 docs/system/devices/vhost-user-rng.rst |  2 ++
 docs/system/devices/vhost-user.rst | 41 ++
 2 files changed, 43 insertions(+)

diff --git a/docs/system/devices/vhost-user-rng.rst 
b/docs/system/devices/vhost-user-rng.rst
index a145d4105c..ead1405326 100644
--- a/docs/system/devices/vhost-user-rng.rst
+++ b/docs/system/devices/vhost-user-rng.rst
@@ -1,3 +1,5 @@
+.. _vhost_user_rng:
+
 QEMU vhost-user-rng - RNG emulation
 ===
 
diff --git a/docs/system/devices/vhost-user.rst 
b/docs/system/devices/vhost-user.rst
index a80e95a48a..0f9eec3f00 100644
--- a/docs/system/devices/vhost-user.rst
+++ b/docs/system/devices/vhost-user.rst
@@ -15,6 +15,47 @@ to the guest. The code is mostly boilerplate although each 
device has
 a ``chardev`` option which specifies the ID of the ``--chardev``
 device that connects via a socket to the vhost-user *daemon*.
 
+Each device will have an virtio-mmio and virtio-pci variant. See your
+platform details for what sort of virtio bus to use.
+
+.. list-table:: vhost-user devices
+  :widths: 20 20 60
+  :header-rows: 1
+
+  * - Device
+- Type
+- Notes
+  * - vhost-user-device
+- Generic Development Device
+- You must manually specify ``virtio-id`` and the correct ``num_vqs``. 
Intended for expert use.
+  * - vhost-user-blk
+- Block storage
+-
+  * - vhost-user-fs
+- File based storage driver
+- See https://gitlab.com/virtio-fs/virtiofsd
+  * - vhost-user-scsi
+- SCSI based storage
+- See contrib/vhost-user/scsi
+  * - vhost-user-gpio
+- Proxy gpio pins to host
+- See https://github.com/rust-vmm/vhost-device
+  * - vhost-user-i2c
+- Proxy i2c devices to host
+- See https://github.com/rust-vmm/vhost-device
+  * - vhost-user-input
+- Generic input driver
+- See contrib/vhost-user-input
+  * - vhost-user-rng
+- Entropy driver
+- :ref:`vhost_user_rng`
+  * - vhost-user-gpu
+- GPU driver
+-
+  * - vhost-user-vsock
+- Socket based communication
+- See https://github.com/rust-vmm/vhost-device
+
 vhost-user daemon
 =
 
-- 
2.39.2




qemu-block@nongnu.org

2023-10-09 Thread Alex Bennée
A lot of our vhost-user stubs are large chunks of boilerplate that do
(mostly) the same thing. This series continues the cleanups by
splitting the vhost-user-base and vhost-user-generic implementations.
After adding a new vq_size property the rng, gpio and i2c vhost-user
devices become simple specialisations of the common base defining the
ID, number of queues and potentially the config handling.

I've also added Manos' vhost-user-sound while I was at it.

Changes
---

I've dropped the F_TRANSPORT work from this series to keep this small
and ready to merge. The changes for F_TRANSPORT are a bit more
invasive and still need a bit of debugging but I wanted to get this
stuff merged now.

Alex Bennée (5):
  virtio: split into vhost-user-base and vhost-user-device
  hw/virtio: derive vhost-user-rng from vhost-user-base
  hw/virtio: derive vhost-user-gpio from vhost-user-base
  hw/virtio: derive vhost-user-i2c from vhost-user-base
  docs/system: add a basic enumeration of vhost-user devices

Manos Pitsidianakis (1):
  hw/virtio: add vhost-user-snd and virtio-snd-pci devices

 docs/system/devices/vhost-user-rng.rst |   2 +
 docs/system/devices/vhost-user.rst |  41 +++
 include/hw/virtio/vhost-user-base.h|  49 +++
 include/hw/virtio/vhost-user-gpio.h|  23 +-
 include/hw/virtio/vhost-user-i2c.h |  14 +-
 include/hw/virtio/vhost-user-rng.h |  11 +-
 include/hw/virtio/vhost-user-snd.h |  26 ++
 hw/virtio/vhost-user-base.c| 348 +
 hw/virtio/vhost-user-device-pci.c  |  10 +-
 hw/virtio/vhost-user-device.c  | 335 +---
 hw/virtio/vhost-user-gpio.c| 407 ++---
 hw/virtio/vhost-user-i2c.c | 272 +
 hw/virtio/vhost-user-rng.c | 278 ++---
 hw/virtio/vhost-user-snd-pci.c |  75 +
 hw/virtio/vhost-user-snd.c |  67 
 hw/virtio/Kconfig  |   5 +
 hw/virtio/meson.build  |  25 +-
 17 files changed, 705 insertions(+), 1283 deletions(-)
 create mode 100644 include/hw/virtio/vhost-user-base.h
 create mode 100644 include/hw/virtio/vhost-user-snd.h
 create mode 100644 hw/virtio/vhost-user-base.c
 create mode 100644 hw/virtio/vhost-user-snd-pci.c
 create mode 100644 hw/virtio/vhost-user-snd.c

-- 
2.39.2




Re: [PATCH v3 05/16] plugins/loader: Clean up global variable shadowing

2023-10-04 Thread Alex Bennée


Philippe Mathieu-Daudé  writes:

> Fix:
>
>   include/qemu/plugin.h:245:54: error: declaration shadows a variable in the 
> global scope [-Werror,-Wshadow]
>   static inline void qemu_plugin_opt_parse(const char *optarg,
>^
>   
> /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/getopt.h:77:14:
>  note: previous declaration is here
>   extern char *optarg;/* getopt(3) external
>   variables */

My same raised eyebrows are how exactly getopt.h is getting included but
anyway:

Acked-by: Alex Bennée 

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH v3 13/16] semihosting/arm-compat: Clean up local variable shadowing

2023-10-04 Thread Alex Bennée


Philippe Mathieu-Daudé  writes:

> Fix:
>
>   semihosting/arm-compat-semi.c: In function ‘do_common_semihosting’:
>   semihosting/arm-compat-semi.c:379:13: warning: declaration of ‘ret’ shadows 
> a previous local [-Wshadow=local]
> 379 | int ret, err = 0;
> | ^~~
>   semihosting/arm-compat-semi.c:370:14: note: shadowed declaration is here
> 370 | uint32_t ret;
> |  ^~~
>   semihosting/arm-compat-semi.c:682:27: warning: declaration of ‘ret’
> shadows a previous local [-Wshadow=local]
> 682 | abi_ulong ret;
> |   ^~~
>   semihosting/arm-compat-semi.c:370:9: note: shadowed declaration is here
> 370 | int ret;
> | ^~~
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  semihosting/arm-compat-semi.c | 5 -
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
> index 564fe17f75..0033a1e018 100644
> --- a/semihosting/arm-compat-semi.c
> +++ b/semihosting/arm-compat-semi.c
> @@ -367,7 +367,6 @@ void do_common_semihosting(CPUState *cs)
>  target_ulong ul_ret;
>  char * s;
>  int nr;
> -uint32_t ret;
>  int64_t elapsed;
>  
>  nr = common_semi_arg(cs, 0) & 0xU;
> @@ -725,6 +724,9 @@ void do_common_semihosting(CPUState *cs)
>  
>  case TARGET_SYS_EXIT:
>  case TARGET_SYS_EXIT_EXTENDED:
> +{
> +uint32_t ret;
> +

I suspect this could just as well be an int with an explicit cast for ret = arg1
because the consumers are all expecting int anyway.

Otherwise:

Reviewed-by: Alex Bennée 

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH v3 09/16] semihosting: Clean up global variable shadowing

2023-10-04 Thread Alex Bennée


Philippe Mathieu-Daudé  writes:

> Fix:
>
>   semihosting/config.c:134:49: error: declaration shadows a variable in the 
> global scope [-Werror,-Wshadow]
>   int qemu_semihosting_config_options(const char *optarg)
>   ^
>   
> /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/getopt.h:77:14:
>  note: previous declaration is here
>   extern char *optarg;/* getopt(3) external
>   variables */

I'm going to assume the getopt.h is somehow swept up by osdep.h?

Anyway:

Acked-by: Alex Bennée 

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH v3 07/20] virtio: add vhost-user-base and a generic vhost-user-device

2023-09-05 Thread Alex Bennée


Matias Ezequiel Vara Larsen  writes:

> On Mon, Jul 10, 2023 at 04:35:09PM +0100, Alex Bennée wrote:
>> In theory we shouldn't need to repeat so much boilerplate to support
>> vhost-user backends. This provides a generic vhost-user-base QOM
>> object and a derived vhost-user-device for which the user needs to
>> provide the few bits of information that aren't currently provided by
>> the vhost-user protocol. This should provide a baseline implementation
>> from which the other vhost-user stub can specialise.
>> 
>> Signed-off-by: Alex Bennée 
>> 
>> ---
>> v2
>>   - split into vub and vud

>> +
>> +/*
>> + * Disable guest notifiers, by default all notifications will be via the
>> + * asynchronous vhost-user socket.
>> + */
>> +vdev->use_guest_notifier_mask = false;
>> +
>> +/* Allocate queues */
>> +vub->vqs = g_ptr_array_sized_new(vub->num_vqs);
>> +for (int i = 0; i < vub->num_vqs; i++) {
>> +g_ptr_array_add(vub->vqs,
>> +virtio_add_queue(vdev, 4, vub_handle_output));
>> +}
>> +
>
> Hello Alex, apologies if someone already asked this. If I understand
> correctly, the second parameter of virtio_add_queue() is the len of the
> queue. Why have you chosen "4" as its value? Shall qemu query the len of
> the queue from the vhost-user device instead?

Hmm yeah that is inherited from the virtio-rng backend which has a
pretty short queue. I don't think it is intrinsic to the device
implementation (although I guess that depends if a device will have
multiple requests in flight).

I propose making is some useful ^2 (like 64) and adding a config knob to
increase it if needed.

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH v3 10/20] hw/virtio: add config support to vhost-user-device

2023-08-31 Thread Alex Bennée


Albert Esteve  writes:

> Sorry to bring up this post, it's been a while since you posted.
> But I have been testing the patch the last couple of days.
>
> On Mon, Jul 10, 2023 at 9:58 PM Michael S. Tsirkin  wrote:
>
>  On Mon, Jul 10, 2023 at 04:35:12PM +0100, Alex Bennée wrote:
>  > To use the generic device the user will need to provide the config
>  > region size via the command line. We also add a notifier so the guest
>  > can be pinged if the remote daemon updates the config.
>  > 
>  > With these changes:
>  > 
>  >   -device vhost-user-device-pci,virtio-id=41,num_vqs=2,config_size=8
>  > 
>  > is equivalent to:
>  > 
>  >   -device vhost-user-gpio-pci
>  > 
>  > Signed-off-by: Alex Bennée 
>
>  This one I think it's best to defer until we get a better
>  handle on how we want the configuration to look.
>
>  > ---
>  >  include/hw/virtio/vhost-user-device.h |  1 +
>  >  hw/virtio/vhost-user-device.c | 58 ++-
>  >  2 files changed, 58 insertions(+), 1 deletion(-)
>  > 
>  > diff --git a/include/hw/virtio/vhost-user-device.h 
> b/include/hw/virtio/vhost-user-device.h
>  > index 9105011e25..3ddf88a146 100644
>  > --- a/include/hw/virtio/vhost-user-device.h
>  > +++ b/include/hw/virtio/vhost-user-device.h
>  > @@ -22,6 +22,7 @@ struct VHostUserBase {
>  >  CharBackend chardev;
>  >  uint16_t virtio_id;
>  >  uint32_t num_vqs;
>  > +uint32_t config_size;
>  >  /* State tracking */
>  >  VhostUserState vhost_user;
>  >  struct vhost_virtqueue *vhost_vq;
>  > diff --git a/hw/virtio/vhost-user-device.c b/hw/virtio/vhost-user-device.c
>  > index b0239fa033..2b028cae08 100644
>  > --- a/hw/virtio/vhost-user-device.c
>  > +++ b/hw/virtio/vhost-user-device.c
>  > @@ -117,6 +117,42 @@ static uint64_t vub_get_features(VirtIODevice *vdev,
>  >  return vub->vhost_dev.features & ~(1ULL << 
> VHOST_USER_F_PROTOCOL_FEATURES);
>  >  }
>  >  
>  > +/*
>  > + * To handle VirtIO config we need to know the size of the config
>  > + * space. We don't cache the config but re-fetch it from the guest
>  > + * every time in case something has changed.
>  > + */
>  > +static void vub_get_config(VirtIODevice *vdev, uint8_t *config)
>  > +{
>  > +VHostUserBase *vub = VHOST_USER_BASE(vdev);
>  > +Error *local_err = NULL;
>  > +
>  > +/*
>  > + * There will have been a warning during vhost_dev_init, but lets
>  > + * assert here as nothing will go right now.
>  > + */
>  > +g_assert(vub->config_size && vub->vhost_user.supports_config == true);
>  > +
>  > +if (vhost_dev_get_config(&vub->vhost_dev, config,
>  > + vub->config_size, &local_err)) {
>  > +error_report_err(local_err);
>  > +}
>  > +}
>  > +
>  > +/*
>  > + * When the daemon signals an update to the config we just need to
>  > + * signal the guest as we re-read the config on demand above.
>  > + */
>  > +static int vub_config_notifier(struct vhost_dev *dev)
>  > +{
>  > +virtio_notify_config(dev->vdev);
>  > +return 0;
>  > +}
>  > +
>  > +const VhostDevConfigOps vub_config_ops = {
>  > +.vhost_dev_config_notifier = vub_config_notifier,
>  > +};
>  > +
>  >  static void vub_handle_output(VirtIODevice *vdev, VirtQueue *vq)
>  >  {
>  >  /*
>  > @@ -141,12 +177,21 @@ static int vub_connect(DeviceState *dev)
>  >  {
>  >  VirtIODevice *vdev = VIRTIO_DEVICE(dev);
>  >  VHostUserBase *vub = VHOST_USER_BASE(vdev);
>  > +struct vhost_dev *vhost_dev = &vub->vhost_dev;
>  >  
>  >  if (vub->connected) {
>  >  return 0;
>  >  }
>  >  vub->connected = true;
>  >  
>  > +/*
>  > + * If we support VHOST_USER_GET_CONFIG we must enable the notifier
>  > + * so we can ping the guest when it updates.
>  > + */
>  > +if (vub->vhost_user.supports_config) {
>  > +vhost_dev_set_config_notifier(vhost_dev, &vub_config_ops);
>  > +}
>  > +
>  >  /* restore vhost state */
>  >  if (virtio_device_started(vdev, vdev->status)) {
>  >  vub_start(vdev);
>  > @@ -214,11 +259,20 @@ static void vub_device_realize(DeviceState *dev, 
> Error **errp)
>  >  vub->num_vqs = 1; /* reasonable default? */
>  >  }
>  >  
>  > +/*
&g

Re: [PATCH] qemu-options.hx: Rephrase the descriptions of the -hd* and -cdrom options

2023-08-29 Thread Alex Bennée


Thomas Huth  writes:

> The current description says that these options will create a device
> on the IDE bus, which is only true on x86. So rephrase these sentences
> a little bit to speak of "default bus" instead.
>
> Signed-off-by: Thomas Huth 
> ---
>  qemu-options.hx | 20 
>  1 file changed, 12 insertions(+), 8 deletions(-)
>
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 29b98c3d4c..a7ce5f0f7a 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -1209,10 +1209,10 @@ SRST
>  ERST
>  
>  DEF("hda", HAS_ARG, QEMU_OPTION_hda,
> -"-hda/-hdb file  use 'file' as IDE hard disk 0/1 image\n", QEMU_ARCH_ALL)
> +"-hda/-hdb file  use 'file' as hard disk 0/1 image\n", QEMU_ARCH_ALL)
>  DEF("hdb", HAS_ARG, QEMU_OPTION_hdb, "", QEMU_ARCH_ALL)
>  DEF("hdc", HAS_ARG, QEMU_OPTION_hdc,
> -"-hdc/-hdd file  use 'file' as IDE hard disk 2/3 image\n", QEMU_ARCH_ALL)
> +"-hdc/-hdd file  use 'file' as hard disk 2/3 image\n", QEMU_ARCH_ALL)
>  DEF("hdd", HAS_ARG, QEMU_OPTION_hdd, "", QEMU_ARCH_ALL)
>  SRST
>  ``-hda file``
> @@ -1222,18 +1222,22 @@ SRST
>  ``-hdc file``
>\ 
>  ``-hdd file``
> -Use file as hard disk 0, 1, 2 or 3 image (see the :ref:`disk images`
> -chapter in the System Emulation Users Guide).
> +Use file as hard disk 0, 1, 2 or 3 image on the default bus of the
> +emulated machine (this is for example the IDE bus on most x86 machines,
> +but it can also be SCSI, virtio or something else on other target
> +architectures). See al the :ref:`disk images` chapter in the
>  System

See also?

> +Emulation Users Guide.
>  ERST
>  
>  DEF("cdrom", HAS_ARG, QEMU_OPTION_cdrom,
> -"-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)\n",
> +"-cdrom file use 'file' as CD-ROM image\n",
>  QEMU_ARCH_ALL)
>  SRST
>  ``-cdrom file``
> -Use file as CD-ROM image (you cannot use ``-hdc`` and ``-cdrom`` at
> -the same time). You can use the host CD-ROM by using ``/dev/cdrom``
> -as filename.
> +Use file as CD-ROM image on the default bus of the emulated machine
> +(which is IDE1 master on x86, so you cannot use ``-hdc`` and ``-cdrom``
> +at the same time there). On systems that support it, you can use the
> +host CD-ROM by using ``/dev/cdrom`` as filename.
>  ERST
>  
>  DEF("blockdev", HAS_ARG, QEMU_OPTION_blockdev,

Otherwise:

Reviewed-by: Alex Bennée 

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



[RFC PATCH v3 13/20] docs/system: add a basic enumeration of vhost-user devices

2023-07-10 Thread Alex Bennée
Make it clear the vhost-user-device is intended for expert use only.

Signed-off-by: Alex Bennée 

---
v2
  - make clear vhost-user-device for expert use
---
 docs/system/devices/vhost-user-rng.rst |  2 ++
 docs/system/devices/vhost-user.rst | 41 ++
 2 files changed, 43 insertions(+)

diff --git a/docs/system/devices/vhost-user-rng.rst 
b/docs/system/devices/vhost-user-rng.rst
index a145d4105c..ead1405326 100644
--- a/docs/system/devices/vhost-user-rng.rst
+++ b/docs/system/devices/vhost-user-rng.rst
@@ -1,3 +1,5 @@
+.. _vhost_user_rng:
+
 QEMU vhost-user-rng - RNG emulation
 ===
 
diff --git a/docs/system/devices/vhost-user.rst 
b/docs/system/devices/vhost-user.rst
index a80e95a48a..0f9eec3f00 100644
--- a/docs/system/devices/vhost-user.rst
+++ b/docs/system/devices/vhost-user.rst
@@ -15,6 +15,47 @@ to the guest. The code is mostly boilerplate although each 
device has
 a ``chardev`` option which specifies the ID of the ``--chardev``
 device that connects via a socket to the vhost-user *daemon*.
 
+Each device will have an virtio-mmio and virtio-pci variant. See your
+platform details for what sort of virtio bus to use.
+
+.. list-table:: vhost-user devices
+  :widths: 20 20 60
+  :header-rows: 1
+
+  * - Device
+- Type
+- Notes
+  * - vhost-user-device
+- Generic Development Device
+- You must manually specify ``virtio-id`` and the correct ``num_vqs``. 
Intended for expert use.
+  * - vhost-user-blk
+- Block storage
+-
+  * - vhost-user-fs
+- File based storage driver
+- See https://gitlab.com/virtio-fs/virtiofsd
+  * - vhost-user-scsi
+- SCSI based storage
+- See contrib/vhost-user/scsi
+  * - vhost-user-gpio
+- Proxy gpio pins to host
+- See https://github.com/rust-vmm/vhost-device
+  * - vhost-user-i2c
+- Proxy i2c devices to host
+- See https://github.com/rust-vmm/vhost-device
+  * - vhost-user-input
+- Generic input driver
+- See contrib/vhost-user-input
+  * - vhost-user-rng
+- Entropy driver
+- :ref:`vhost_user_rng`
+  * - vhost-user-gpu
+- GPU driver
+-
+  * - vhost-user-vsock
+- Socket based communication
+- See https://github.com/rust-vmm/vhost-device
+
 vhost-user daemon
 =
 
-- 
2.39.2




[PATCH v3 12/20] hw/virtio: derive vhost-user-i2c from vhost-user-base

2023-07-10 Thread Alex Bennée
Now we can take advantage of the new base class and make
vhost-user-i2c a much simpler boilerplate wrapper. Also as this
doesn't require any target specific hacks we only need to build the
stubs once.

Signed-off-by: Alex Bennée 

---
v2
  - update to new inheritance scheme
  - move build to common code
v3
  - fix merge conflict in meson
---
 include/hw/virtio/vhost-user-i2c.h |  18 +-
 hw/virtio/vhost-user-i2c.c | 271 ++---
 hw/virtio/meson.build  |   5 +-
 3 files changed, 26 insertions(+), 268 deletions(-)

diff --git a/include/hw/virtio/vhost-user-i2c.h 
b/include/hw/virtio/vhost-user-i2c.h
index 0f7acd40e3..47153782d1 100644
--- a/include/hw/virtio/vhost-user-i2c.h
+++ b/include/hw/virtio/vhost-user-i2c.h
@@ -12,20 +12,18 @@
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
 
+#include "hw/virtio/virtio.h"
+#include "hw/virtio/vhost.h"
+#include "hw/virtio/vhost-user.h"
+#include "hw/virtio/vhost-user-device.h"
+
 #define TYPE_VHOST_USER_I2C "vhost-user-i2c-device"
 OBJECT_DECLARE_SIMPLE_TYPE(VHostUserI2C, VHOST_USER_I2C)
 
 struct VHostUserI2C {
-VirtIODevice parent;
-CharBackend chardev;
-struct vhost_virtqueue *vhost_vq;
-struct vhost_dev vhost_dev;
-VhostUserState vhost_user;
-VirtQueue *vq;
-bool connected;
+/*< private >*/
+VHostUserBase parent;
+/*< public >*/
 };
 
-/* Virtio Feature bits */
-#define VIRTIO_I2C_F_ZERO_LENGTH_REQUEST   0
-
 #endif /* QEMU_VHOST_USER_I2C_H */
diff --git a/hw/virtio/vhost-user-i2c.c b/hw/virtio/vhost-user-i2c.c
index 4eef3f0633..4a1f644a87 100644
--- a/hw/virtio/vhost-user-i2c.c
+++ b/hw/virtio/vhost-user-i2c.c
@@ -14,253 +14,21 @@
 #include "qemu/error-report.h"
 #include "standard-headers/linux/virtio_ids.h"
 
-static const int feature_bits[] = {
-VIRTIO_I2C_F_ZERO_LENGTH_REQUEST,
-VIRTIO_F_RING_RESET,
-VHOST_INVALID_FEATURE_BIT
+static Property vi2c_properties[] = {
+DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
+DEFINE_PROP_END_OF_LIST(),
 };
 
-static void vu_i2c_start(VirtIODevice *vdev)
-{
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-int ret, i;
-
-if (!k->set_guest_notifiers) {
-error_report("binding does not support guest notifiers");
-return;
-}
-
-ret = vhost_dev_enable_notifiers(&i2c->vhost_dev, vdev);
-if (ret < 0) {
-error_report("Error enabling host notifiers: %d", -ret);
-return;
-}
-
-ret = k->set_guest_notifiers(qbus->parent, i2c->vhost_dev.nvqs, true);
-if (ret < 0) {
-error_report("Error binding guest notifier: %d", -ret);
-goto err_host_notifiers;
-}
-
-i2c->vhost_dev.acked_features = vdev->guest_features;
-
-ret = vhost_dev_start(&i2c->vhost_dev, vdev, true);
-if (ret < 0) {
-error_report("Error starting vhost-user-i2c: %d", -ret);
-goto err_guest_notifiers;
-}
-
-/*
- * guest_notifier_mask/pending not used yet, so just unmask
- * everything here. virtio-pci will do the right thing by
- * enabling/disabling irqfd.
- */
-for (i = 0; i < i2c->vhost_dev.nvqs; i++) {
-vhost_virtqueue_mask(&i2c->vhost_dev, vdev, i, false);
-}
-
-return;
-
-err_guest_notifiers:
-k->set_guest_notifiers(qbus->parent, i2c->vhost_dev.nvqs, false);
-err_host_notifiers:
-vhost_dev_disable_notifiers(&i2c->vhost_dev, vdev);
-}
-
-static void vu_i2c_stop(VirtIODevice *vdev)
-{
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-int ret;
-
-if (!k->set_guest_notifiers) {
-return;
-}
-
-vhost_dev_stop(&i2c->vhost_dev, vdev, true);
-
-ret = k->set_guest_notifiers(qbus->parent, i2c->vhost_dev.nvqs, false);
-if (ret < 0) {
-error_report("vhost guest notifier cleanup failed: %d", ret);
-return;
-}
-
-vhost_dev_disable_notifiers(&i2c->vhost_dev, vdev);
-}
-
-static void vu_i2c_set_status(VirtIODevice *vdev, uint8_t status)
-{
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-bool should_start = virtio_device_should_start(vdev, status);
-
-if (vhost_dev_is_started(&i2c->vhost_dev) == should_start) {
-return;
-}
-
-if (should_start) {
-vu_i2c_start(vdev);
-} else {
-vu_i2c_stop(vdev);
-}
-}
-
-static uint64_t vu_i2c_get_features(VirtIODevice *vdev,
-uint64_t requested_features, Error **errp)
-{
-VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
-
-virtio_a

[RFC PATCH v3 16/20] hw/virtio: move virtq initialisation into internal helper

2023-07-10 Thread Alex Bennée
This will be useful if we end up having to consider initialising the
virtqs at a seperate time.

Signed-off-by: Alex Bennée 
---
 hw/virtio/vhost.c | 60 ---
 1 file changed, 41 insertions(+), 19 deletions(-)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 82394331bf..971df8ccc5 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -1382,12 +1382,47 @@ static void vhost_virtqueue_cleanup(struct 
vhost_virtqueue *vq)
 }
 }
 
+/*
+ * Initialise the virtqs. This can happen soon after the initial
+ * connection if we have all the details we need or be deferred until
+ * later.
+ */
+static bool vhost_init_virtqs(struct vhost_dev *hdev, uint32_t 
busyloop_timeout,
+  Error **errp)
+{
+int i, r, n_initialized_vqs = 0;
+
+for (i = 0; i < hdev->nvqs; ++i, ++n_initialized_vqs) {
+r = vhost_virtqueue_init(hdev, hdev->vqs + i, hdev->vq_index + i);
+if (r < 0) {
+error_setg_errno(errp, -r, "Failed to initialize virtqueue %d", i);
+/* not sure what the point of this is if we have failed... */
+hdev->nvqs = n_initialized_vqs;
+return false;
+}
+}
+
+if (busyloop_timeout) {
+for (i = 0; i < hdev->nvqs; ++i) {
+r = vhost_virtqueue_set_busyloop_timeout(hdev, hdev->vq_index + i,
+ busyloop_timeout);
+if (r < 0) {
+error_setg_errno(errp, -r, "Failed to set busyloop timeout");
+return false;
+}
+}
+}
+
+g_assert(hdev->nvqs == n_initialized_vqs);
+return true;
+}
+
 int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
VhostBackendType backend_type, uint32_t busyloop_timeout,
Error **errp)
 {
 uint64_t features;
-int i, r, n_initialized_vqs = 0;
+int i, r;
 
 hdev->vdev = NULL;
 hdev->migration_blocker = NULL;
@@ -1412,22 +1447,10 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
 goto fail;
 }
 
-for (i = 0; i < hdev->nvqs; ++i, ++n_initialized_vqs) {
-r = vhost_virtqueue_init(hdev, hdev->vqs + i, hdev->vq_index + i);
-if (r < 0) {
-error_setg_errno(errp, -r, "Failed to initialize virtqueue %d", i);
-goto fail;
-}
-}
-
-if (busyloop_timeout) {
-for (i = 0; i < hdev->nvqs; ++i) {
-r = vhost_virtqueue_set_busyloop_timeout(hdev, hdev->vq_index + i,
- busyloop_timeout);
-if (r < 0) {
-error_setg_errno(errp, -r, "Failed to set busyloop timeout");
-goto fail_busyloop;
-}
+/* Skip if we don't yet have number of vqs */
+if (hdev->vqs && hdev->nvqs) {
+if (!vhost_init_virtqs(hdev, busyloop_timeout, errp)) {
+goto fail_busyloop;
 }
 }
 
@@ -1492,12 +1515,11 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
 
 fail_busyloop:
 if (busyloop_timeout) {
-while (--i >= 0) {
+for (i = 0; i < hdev->nvqs; ++i) {
 vhost_virtqueue_set_busyloop_timeout(hdev, hdev->vq_index + i, 0);
 }
 }
 fail:
-hdev->nvqs = n_initialized_vqs;
 vhost_dev_cleanup(hdev);
 return r;
 }
-- 
2.39.2




[RFC PATCH v3 20/20] hw/virtio: allow vhost-user-device to be driven by backend

2023-07-10 Thread Alex Bennée
Instead of requiring all the information up front allow the
vhost_dev_init to complete and then see what information we have from
the backend.

This does change the order around somewhat.

Signed-off-by: Alex Bennée 
---
 hw/virtio/vhost-user-device.c | 45 +--
 1 file changed, 32 insertions(+), 13 deletions(-)

diff --git a/hw/virtio/vhost-user-device.c b/hw/virtio/vhost-user-device.c
index 0109d4829d..b30b6265fb 100644
--- a/hw/virtio/vhost-user-device.c
+++ b/hw/virtio/vhost-user-device.c
@@ -243,7 +243,6 @@ static void vub_device_realize(DeviceState *dev, Error 
**errp)
 {
 VirtIODevice *vdev = VIRTIO_DEVICE(dev);
 VHostUserBase *vub = VHOST_USER_BASE(dev);
-int ret;
 
 if (!vub->chardev.chr) {
 error_setg(errp, "vhost-user-device: missing chardev");
@@ -254,13 +253,43 @@ static void vub_device_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
+if (vhost_dev_init(&vub->vhost_dev, &vub->vhost_user,
+   VHOST_BACKEND_TYPE_USER, 0, errp)!=0) {
+error_setg(errp, "vhost-user-device: unable to start connection");
+return;
+}
+
+if (vub->vhost_dev.specs.device_id) {
+if (vub->virtio_id && vub->virtio_id != 
vub->vhost_dev.specs.device_id) {
+error_setg(errp, "vhost-user-device: backend id %d doesn't match 
cli %d",
+   vub->vhost_dev.specs.device_id, vub->virtio_id);
+return;
+}
+vub->virtio_id = vub->vhost_dev.specs.device_id;
+}
+
 if (!vub->virtio_id) {
-error_setg(errp, "vhost-user-device: need to define device id");
+error_setg(errp, "vhost-user-device: need to define or be told device 
id");
 return;
 }
 
+if (vub->vhost_dev.specs.min_vqs) {
+if (vub->num_vqs) {
+if (vub->num_vqs < vub->vhost_dev.specs.min_vqs ||
+vub->num_vqs > vub->vhost_dev.specs.max_vqs) {
+error_setg(errp,
+   "vhost-user-device: selected nvqs (%d) out of 
bounds (%d->%d)",
+   vub->num_vqs,
+   vub->vhost_dev.specs.min_vqs, 
vub->vhost_dev.specs.max_vqs);
+return;
+}
+} else {
+vub->num_vqs = vub->vhost_dev.specs.min_vqs;
+}
+}
+
 if (!vub->num_vqs) {
-vub->num_vqs = 1; /* reasonable default? */
+error_setg(errp, "vhost-user-device: need to define number of vqs");
 }
 
 /*
@@ -287,16 +316,6 @@ static void vub_device_realize(DeviceState *dev, Error 
**errp)
 virtio_add_queue(vdev, 4, vub_handle_output));
 }
 
-vub->vhost_dev.nvqs = vub->num_vqs;
-
-/* connect to backend */
-ret = vhost_dev_init(&vub->vhost_dev, &vub->vhost_user,
- VHOST_BACKEND_TYPE_USER, 0, errp);
-
-if (ret < 0) {
-do_vhost_user_cleanup(vdev, vub);
-}
-
 qemu_chr_fe_set_handlers(&vub->chardev, NULL, NULL, vub_event, NULL,
  dev, NULL, true);
 }
-- 
2.39.2




[RFC PATCH v3 14/20] docs/interop: define STANDALONE protocol feature for vhost-user

2023-07-10 Thread Alex Bennée
Currently QEMU has to know some details about the back-end to be able
to setup the guest. While various parts of the setup can be delegated
to the backend (for example config handling) this is a very piecemeal
approach.

This patch suggests a new feature flag (VHOST_USER_PROTOCOL_F_STANDALONE)
which the back-end can advertise which allows a probe message to be
sent to get all the details QEMU needs to know in one message.

Signed-off-by: Alex Bennée 

---
Initial RFC for discussion. I intend to prototype this work with QEMU
and one of the rust-vmm vhost-user daemons.
---
 docs/interop/vhost-user.rst | 39 +
 hw/virtio/vhost-user.c  |  8 
 2 files changed, 47 insertions(+)

diff --git a/docs/interop/vhost-user.rst b/docs/interop/vhost-user.rst
index 5a070adbc1..a2080f56f3 100644
--- a/docs/interop/vhost-user.rst
+++ b/docs/interop/vhost-user.rst
@@ -275,6 +275,21 @@ Inflight description
 
 :queue size: a 16-bit size of virtqueues
 
+Backend specifications
+^^
+
++---+-+++
+| device id | config size |   min_vqs  |   max_vqs  |
++---+-+++
+
+:device id: a 32-bit value holding the VirtIO device ID
+
+:config size: a 32-bit value holding the config size (see 
``VHOST_USER_GET_CONFIG``)
+
+:min_vqs: a 32-bit value holding the minimum number of vqs supported
+
+:max_vqs: a 32-bit value holding the maximum number of vqs supported, must be 
>= min_vqs
+
 C structure
 ---
 
@@ -296,6 +311,7 @@ In QEMU the vhost-user message is implemented with the 
following struct:
   VhostUserConfig config;
   VhostUserVringArea area;
   VhostUserInflight inflight;
+  VhostUserBackendSpecs specs;
   };
   } QEMU_PACKED VhostUserMsg;
 
@@ -316,6 +332,7 @@ replies. Here is a list of the ones that do:
 * ``VHOST_USER_GET_VRING_BASE``
 * ``VHOST_USER_SET_LOG_BASE`` (if ``VHOST_USER_PROTOCOL_F_LOG_SHMFD``)
 * ``VHOST_USER_GET_INFLIGHT_FD`` (if ``VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD``)
+* ``VHOST_USER_GET_BACKEND_SPECS`` (if ``VHOST_USER_PROTOCOL_F_STANDALONE``)
 
 .. seealso::
 
@@ -885,6 +902,15 @@ Protocol features
   #define VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS  15
   #define VHOST_USER_PROTOCOL_F_STATUS   16
   #define VHOST_USER_PROTOCOL_F_XEN_MMAP 17
+  #define VHOST_USER_PROTOCOL_F_STANDALONE   18
+
+Some features depend on others to be supported:
+
+* ``VHOST_USER_PROTOCOL_F_STANDALONE`` depends on:
+
+  * ``VHOST_USER_PROTOCOL_F_STATUS``
+  * ``VHOST_USER_PROTOCOL_F_CONFIG`` (if there is a config space)
+
 
 Front-end message types
 ---
@@ -1440,6 +1466,19 @@ Front-end message types
   query the back-end for its device status as defined in the Virtio
   specification.
 
+``VHOST_USER_GET_BACKEND_SPECS``
+  :id: 41
+  :request payload: N/A
+  :reply payload: ``Backend specifications``
+
+  When the ``VHOST_USER_PROTOCOL_F_STANDALONE`` protocol feature has been
+  successfully negotiated, this message is submitted by the front-end to
+  query the back-end for its capabilities. This is intended to remove
+  the need for the front-end to know ahead of time what the VirtIO
+  device the backend emulates is.
+
+  The reply contains the device id, size of the config space and the
+  range of VirtQueues the backend supports.
 
 Back-end message types
 --
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index c4e0cbd702..28b021d5d3 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -202,6 +202,13 @@ typedef struct VhostUserInflight {
 uint16_t queue_size;
 } VhostUserInflight;
 
+typedef struct VhostUserBackendSpecs {
+uint32_t device_id;
+uint32_t config_size;
+uint32_t min_vqs;
+uint32_t max_vqs;
+} VhostUserBackendSpecs;
+
 typedef struct {
 VhostUserRequest request;
 
@@ -226,6 +233,7 @@ typedef union {
 VhostUserCryptoSession session;
 VhostUserVringArea area;
 VhostUserInflight inflight;
+VhostUserBackendSpecs specs;
 } VhostUserPayload;
 
 typedef struct VhostUserMsg {
-- 
2.39.2




[PATCH v3 01/20] include: attempt to document device_class_set_props

2023-07-10 Thread Alex Bennée
I'm still not sure how I achieve by use case of the parent class
defining the following properties:

  static Property vud_properties[] = {
  DEFINE_PROP_CHR("chardev", VHostUserDevice, chardev),
  DEFINE_PROP_UINT16("id", VHostUserDevice, id, 0),
  DEFINE_PROP_UINT32("num_vqs", VHostUserDevice, num_vqs, 1),
  DEFINE_PROP_END_OF_LIST(),
  };

But for the specialisation of the class I want the id to default to
the actual device id, e.g.:

  static Property vu_rng_properties[] = {
  DEFINE_PROP_UINT16("id", VHostUserDevice, id, VIRTIO_ID_RNG),
  DEFINE_PROP_UINT32("num_vqs", VHostUserDevice, num_vqs, 1),
  DEFINE_PROP_END_OF_LIST(),
  };

And so far the API for doing that isn't super clear.

Signed-off-by: Alex Bennée 
---
 include/hw/qdev-core.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 06cadfc492..196ebf6d91 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -926,6 +926,15 @@ BusState *sysbus_get_default(void);
 char *qdev_get_fw_dev_path(DeviceState *dev);
 char *qdev_get_own_fw_dev_path_from_handler(BusState *bus, DeviceState *dev);
 
+/**
+ * device_class_set_props(): add a set of properties to an device
+ * @dc: the parent DeviceClass all devices inherit
+ * @props: an array of properties, terminate by DEFINE_PROP_END_OF_LIST()
+ *
+ * This will add a set of properties to the object. It will fault if
+ * you attempt to add an existing property defined by a parent class.
+ * To modify an inherited property you need to use
+ */
 void device_class_set_props(DeviceClass *dc, Property *props);
 
 /**
-- 
2.39.2




[PATCH v3 09/20] hw/virtio: derive vhost-user-rng from vhost-user-device

2023-07-10 Thread Alex Bennée
Now we can take advantage of our new base class and make
vhost-user-rng a much simpler boilerplate wrapper. Also as this
doesn't require any target specific hacks we only need to build the
stubs once.

Signed-off-by: Alex Bennée 

---
v2
  - new derivation layout
  - move directly to softmmu_virtio_ss
---
 include/hw/virtio/vhost-user-rng.h |  11 +-
 hw/virtio/vhost-user-rng.c | 277 +++--
 hw/virtio/meson.build  |   7 +-
 3 files changed, 28 insertions(+), 267 deletions(-)

diff --git a/include/hw/virtio/vhost-user-rng.h 
b/include/hw/virtio/vhost-user-rng.h
index ddd9f01eea..13139c0d9d 100644
--- a/include/hw/virtio/vhost-user-rng.h
+++ b/include/hw/virtio/vhost-user-rng.h
@@ -12,21 +12,14 @@
 #include "hw/virtio/virtio.h"
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
-#include "chardev/char-fe.h"
+#include "hw/virtio/vhost-user-device.h"
 
 #define TYPE_VHOST_USER_RNG "vhost-user-rng"
 OBJECT_DECLARE_SIMPLE_TYPE(VHostUserRNG, VHOST_USER_RNG)
 
 struct VHostUserRNG {
 /*< private >*/
-VirtIODevice parent;
-CharBackend chardev;
-struct vhost_virtqueue *vhost_vq;
-struct vhost_dev vhost_dev;
-VhostUserState vhost_user;
-VirtQueue *req_vq;
-bool connected;
-
+VHostUserBase parent;
 /*< public >*/
 };
 
diff --git a/hw/virtio/vhost-user-rng.c b/hw/virtio/vhost-user-rng.c
index efc54cd3fb..71d3991f93 100644
--- a/hw/virtio/vhost-user-rng.c
+++ b/hw/virtio/vhost-user-rng.c
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2021 Mathieu Poirier 
  *
- * Implementation seriously tailored on vhost-user-i2c.c
+ * Simple wrapper of the generic vhost-user-device.
  *
  * SPDX-License-Identifier: GPL-2.0-or-later
  */
@@ -13,281 +13,46 @@
 #include "hw/qdev-properties.h"
 #include "hw/virtio/virtio-bus.h"
 #include "hw/virtio/vhost-user-rng.h"
-#include "qemu/error-report.h"
 #include "standard-headers/linux/virtio_ids.h"
 
-static const int feature_bits[] = {
-VIRTIO_F_RING_RESET,
-VHOST_INVALID_FEATURE_BIT
-};
-
-static void vu_rng_start(VirtIODevice *vdev)
-{
-VHostUserRNG *rng = VHOST_USER_RNG(vdev);
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-int ret;
-int i;
-
-if (!k->set_guest_notifiers) {
-error_report("binding does not support guest notifiers");
-return;
-}
-
-ret = vhost_dev_enable_notifiers(&rng->vhost_dev, vdev);
-if (ret < 0) {
-error_report("Error enabling host notifiers: %d", -ret);
-return;
-}
-
-ret = k->set_guest_notifiers(qbus->parent, rng->vhost_dev.nvqs, true);
-if (ret < 0) {
-error_report("Error binding guest notifier: %d", -ret);
-goto err_host_notifiers;
-}
-
-rng->vhost_dev.acked_features = vdev->guest_features;
-ret = vhost_dev_start(&rng->vhost_dev, vdev, true);
-if (ret < 0) {
-error_report("Error starting vhost-user-rng: %d", -ret);
-goto err_guest_notifiers;
-}
-
-/*
- * guest_notifier_mask/pending not used yet, so just unmask
- * everything here. virtio-pci will do the right thing by
- * enabling/disabling irqfd.
- */
-for (i = 0; i < rng->vhost_dev.nvqs; i++) {
-vhost_virtqueue_mask(&rng->vhost_dev, vdev, i, false);
-}
-
-return;
-
-err_guest_notifiers:
-k->set_guest_notifiers(qbus->parent, rng->vhost_dev.nvqs, false);
-err_host_notifiers:
-vhost_dev_disable_notifiers(&rng->vhost_dev, vdev);
-}
-
-static void vu_rng_stop(VirtIODevice *vdev)
-{
-VHostUserRNG *rng = VHOST_USER_RNG(vdev);
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-int ret;
-
-if (!k->set_guest_notifiers) {
-return;
-}
-
-vhost_dev_stop(&rng->vhost_dev, vdev, true);
-
-ret = k->set_guest_notifiers(qbus->parent, rng->vhost_dev.nvqs, false);
-if (ret < 0) {
-error_report("vhost guest notifier cleanup failed: %d", ret);
-return;
-}
-
-vhost_dev_disable_notifiers(&rng->vhost_dev, vdev);
-}
-
-static void vu_rng_set_status(VirtIODevice *vdev, uint8_t status)
-{
-VHostUserRNG *rng = VHOST_USER_RNG(vdev);
-bool should_start = virtio_device_should_start(vdev, status);
-
-if (vhost_dev_is_started(&rng->vhost_dev) == should_start) {
-return;
-}
-
-if (should_start) {
-vu_rng_start(vdev);
-} else {
-vu_rng_stop(vdev);
-}
-}
-
-static uint64_t vu_rng_get_features(VirtIODevice *vdev,
-uint64_t requested_features, Error **errp)
-{
-VHostUserRNG *rng = VHOST_USER_RNG(vdev);
-
-return vhost_get_feat

[RFC PATCH v3 15/20] hw/virtio: move vhost_user_init earlier

2023-07-10 Thread Alex Bennée
In preparation for getting the details of the VirtIO device directly
from the vhost-user daemon we should connect once we have validated
the chardev. We will actually move the connection in the next patch to
keep the changes small and bisectable.

Signed-off-by: Alex Bennée 
---
 hw/virtio/vhost-user-device.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/virtio/vhost-user-device.c b/hw/virtio/vhost-user-device.c
index 2b028cae08..d787f52364 100644
--- a/hw/virtio/vhost-user-device.c
+++ b/hw/virtio/vhost-user-device.c
@@ -250,6 +250,10 @@ static void vub_device_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
+if (!vhost_user_init(&vub->vhost_user, &vub->chardev, errp)) {
+return;
+}
+
 if (!vub->virtio_id) {
 error_setg(errp, "vhost-user-device: need to define device id");
 return;
@@ -268,10 +272,6 @@ static void vub_device_realize(DeviceState *dev, Error 
**errp)
 vub->vhost_user.supports_config = true;
 }
 
-if (!vhost_user_init(&vub->vhost_user, &vub->chardev, errp)) {
-return;
-}
-
 virtio_init(vdev, vub->virtio_id, vub->config_size);
 
 /*
-- 
2.39.2




[PATCH v3 10/20] hw/virtio: add config support to vhost-user-device

2023-07-10 Thread Alex Bennée
To use the generic device the user will need to provide the config
region size via the command line. We also add a notifier so the guest
can be pinged if the remote daemon updates the config.

With these changes:

  -device vhost-user-device-pci,virtio-id=41,num_vqs=2,config_size=8

is equivalent to:

  -device vhost-user-gpio-pci

Signed-off-by: Alex Bennée 
---
 include/hw/virtio/vhost-user-device.h |  1 +
 hw/virtio/vhost-user-device.c | 58 ++-
 2 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/include/hw/virtio/vhost-user-device.h 
b/include/hw/virtio/vhost-user-device.h
index 9105011e25..3ddf88a146 100644
--- a/include/hw/virtio/vhost-user-device.h
+++ b/include/hw/virtio/vhost-user-device.h
@@ -22,6 +22,7 @@ struct VHostUserBase {
 CharBackend chardev;
 uint16_t virtio_id;
 uint32_t num_vqs;
+uint32_t config_size;
 /* State tracking */
 VhostUserState vhost_user;
 struct vhost_virtqueue *vhost_vq;
diff --git a/hw/virtio/vhost-user-device.c b/hw/virtio/vhost-user-device.c
index b0239fa033..2b028cae08 100644
--- a/hw/virtio/vhost-user-device.c
+++ b/hw/virtio/vhost-user-device.c
@@ -117,6 +117,42 @@ static uint64_t vub_get_features(VirtIODevice *vdev,
 return vub->vhost_dev.features & ~(1ULL << VHOST_USER_F_PROTOCOL_FEATURES);
 }
 
+/*
+ * To handle VirtIO config we need to know the size of the config
+ * space. We don't cache the config but re-fetch it from the guest
+ * every time in case something has changed.
+ */
+static void vub_get_config(VirtIODevice *vdev, uint8_t *config)
+{
+VHostUserBase *vub = VHOST_USER_BASE(vdev);
+Error *local_err = NULL;
+
+/*
+ * There will have been a warning during vhost_dev_init, but lets
+ * assert here as nothing will go right now.
+ */
+g_assert(vub->config_size && vub->vhost_user.supports_config == true);
+
+if (vhost_dev_get_config(&vub->vhost_dev, config,
+ vub->config_size, &local_err)) {
+error_report_err(local_err);
+}
+}
+
+/*
+ * When the daemon signals an update to the config we just need to
+ * signal the guest as we re-read the config on demand above.
+ */
+static int vub_config_notifier(struct vhost_dev *dev)
+{
+virtio_notify_config(dev->vdev);
+return 0;
+}
+
+const VhostDevConfigOps vub_config_ops = {
+.vhost_dev_config_notifier = vub_config_notifier,
+};
+
 static void vub_handle_output(VirtIODevice *vdev, VirtQueue *vq)
 {
 /*
@@ -141,12 +177,21 @@ static int vub_connect(DeviceState *dev)
 {
 VirtIODevice *vdev = VIRTIO_DEVICE(dev);
 VHostUserBase *vub = VHOST_USER_BASE(vdev);
+struct vhost_dev *vhost_dev = &vub->vhost_dev;
 
 if (vub->connected) {
 return 0;
 }
 vub->connected = true;
 
+/*
+ * If we support VHOST_USER_GET_CONFIG we must enable the notifier
+ * so we can ping the guest when it updates.
+ */
+if (vub->vhost_user.supports_config) {
+vhost_dev_set_config_notifier(vhost_dev, &vub_config_ops);
+}
+
 /* restore vhost state */
 if (virtio_device_started(vdev, vdev->status)) {
 vub_start(vdev);
@@ -214,11 +259,20 @@ static void vub_device_realize(DeviceState *dev, Error 
**errp)
 vub->num_vqs = 1; /* reasonable default? */
 }
 
+/*
+ * We can't handle config requests unless we know the size of the
+ * config region, specialisations of the vhost-user-device will be
+ * able to set this.
+ */
+if (vub->config_size) {
+vub->vhost_user.supports_config = true;
+}
+
 if (!vhost_user_init(&vub->vhost_user, &vub->chardev, errp)) {
 return;
 }
 
-virtio_init(vdev, vub->virtio_id, 0);
+virtio_init(vdev, vub->virtio_id, vub->config_size);
 
 /*
  * Disable guest notifiers, by default all notifications will be via the
@@ -268,6 +322,7 @@ static void vub_class_init(ObjectClass *klass, void *data)
 vdc->realize = vub_device_realize;
 vdc->unrealize = vub_device_unrealize;
 vdc->get_features = vub_get_features;
+vdc->get_config = vub_get_config;
 vdc->set_status = vub_set_status;
 }
 
@@ -295,6 +350,7 @@ static Property vud_properties[] = {
 DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
 DEFINE_PROP_UINT16("virtio-id", VHostUserBase, virtio_id, 0),
 DEFINE_PROP_UINT32("num_vqs", VHostUserBase, num_vqs, 1),
+DEFINE_PROP_UINT32("config_size", VHostUserBase, config_size, 0),
 DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.39.2




[RFC PATCH v3 17/20] hw/virtio: push down allocation responsibility for vhost_dev->vqs

2023-07-10 Thread Alex Bennée
All the allocations are a function the number of vqs we are allocating
so let the vhost code deal with it directly. This allows to eliminate
some complexity of the clean-up code (because vhost_dev_init cleanups
after itself if it fails). We can also places where we store copies of
@vqs in child objects.

Signed-off-by: Alex Bennée 
---
 include/hw/virtio/vhost-user-blk.h |  1 -
 include/hw/virtio/vhost.h  |  9 +
 backends/vhost-user.c  |  1 -
 hw/block/vhost-user-blk.c  |  7 +--
 hw/scsi/vhost-scsi.c   |  2 --
 hw/scsi/vhost-user-scsi.c  |  6 --
 hw/virtio/vdpa-dev.c   |  9 ++---
 hw/virtio/vhost-user-device.c  |  3 ---
 hw/virtio/vhost-user-fs.c  |  1 -
 hw/virtio/vhost.c  | 10 --
 10 files changed, 20 insertions(+), 29 deletions(-)

diff --git a/include/hw/virtio/vhost-user-blk.h 
b/include/hw/virtio/vhost-user-blk.h
index ea085ee1ed..479fcc2a82 100644
--- a/include/hw/virtio/vhost-user-blk.h
+++ b/include/hw/virtio/vhost-user-blk.h
@@ -37,7 +37,6 @@ struct VHostUserBlk {
 struct vhost_dev dev;
 struct vhost_inflight *inflight;
 VhostUserState vhost_user;
-struct vhost_virtqueue *vhost_vqs;
 VirtQueue **virtqs;
 
 /*
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index f7f10c8fb7..912706668a 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -82,6 +82,10 @@ struct vhost_dev {
 MemoryRegionSection *mem_sections;
 int n_tmp_sections;
 MemoryRegionSection *tmp_sections;
+/**
+ * @vqs - internal to vhost_dev, allocated based on @nvqs
+ * @nvqs - number of @vqs to allocate.
+ */
 struct vhost_virtqueue *vqs;
 unsigned int nvqs;
 /* the first virtqueue which would be used by this vhost dev */
@@ -156,6 +160,9 @@ struct vhost_net {
  * negotiation of backend interface. Configuration of the VirtIO
  * itself won't happen until the interface is started.
  *
+ * If the initialisation fails it will call vhost_dev_cleanup() to
+ * tear down the interface and free memory.
+ *
  * Return: 0 on success, non-zero on error while setting errp.
  */
 int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
@@ -165,6 +172,8 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
 /**
  * vhost_dev_cleanup() - tear down and cleanup vhost interface
  * @hdev: the common vhost_dev structure
+ *
+ * This includes freeing internals such as @vqs
  */
 void vhost_dev_cleanup(struct vhost_dev *hdev);
 
diff --git a/backends/vhost-user.c b/backends/vhost-user.c
index 94c6a82d52..05a3cf77d0 100644
--- a/backends/vhost-user.c
+++ b/backends/vhost-user.c
@@ -34,7 +34,6 @@ vhost_user_backend_dev_init(VhostUserBackend *b, VirtIODevice 
*vdev,
 
 b->vdev = vdev;
 b->dev.nvqs = nvqs;
-b->dev.vqs = g_new0(struct vhost_virtqueue, nvqs);
 
 ret = vhost_dev_init(&b->dev, &b->vhost_user, VHOST_BACKEND_TYPE_USER, 0,
  errp);
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index eecf3f7a81..9221f159ec 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -332,7 +332,6 @@ static int vhost_user_blk_connect(DeviceState *dev, Error 
**errp)
 
 s->dev.num_queues = s->num_queues;
 s->dev.nvqs = s->num_queues;
-s->dev.vqs = s->vhost_vqs;
 s->dev.vq_index = 0;
 s->dev.backend_features = 0;
 
@@ -480,7 +479,6 @@ static void vhost_user_blk_device_realize(DeviceState *dev, 
Error **errp)
 }
 
 s->inflight = g_new0(struct vhost_inflight, 1);
-s->vhost_vqs = g_new0(struct vhost_virtqueue, s->num_queues);
 
 retries = REALIZE_CONNECTION_RETRIES;
 assert(!*errp);
@@ -504,8 +502,7 @@ static void vhost_user_blk_device_realize(DeviceState *dev, 
Error **errp)
 return;
 
 virtio_err:
-g_free(s->vhost_vqs);
-s->vhost_vqs = NULL;
+vhost_dev_cleanup(&s->dev);
 g_free(s->inflight);
 s->inflight = NULL;
 for (i = 0; i < s->num_queues; i++) {
@@ -527,8 +524,6 @@ static void vhost_user_blk_device_unrealize(DeviceState 
*dev)
  NULL, NULL, NULL, false);
 vhost_dev_cleanup(&s->dev);
 vhost_dev_free_inflight(s->inflight);
-g_free(s->vhost_vqs);
-s->vhost_vqs = NULL;
 g_free(s->inflight);
 s->inflight = NULL;
 
diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
index 443f67daa4..aa25cdfcdc 100644
--- a/hw/scsi/vhost-scsi.c
+++ b/hw/scsi/vhost-scsi.c
@@ -214,8 +214,6 @@ static void vhost_scsi_realize(DeviceState *dev, Error 
**errp)
 }
 
 vsc->dev.nvqs = VHOST_SCSI_VQ_NUM_FIXED + vs->conf.num_queues;
-vqs = g_new0(struct vhost_virtqueue, vsc->dev.nvqs);
-vsc->dev.vqs = vqs;
 vsc->dev.vq_index = 0;
 vsc->dev.backend_features = 0;
 
diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
ind

[PATCH v3 02/20] include/hw: document the device_class_set_parent_* fns

2023-07-10 Thread Alex Bennée
These are useful functions for when you want proper inheritance of
functionality across realize/unrealize calls.

Signed-off-by: Alex Bennée 
---
 include/hw/qdev-core.h | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 196ebf6d91..884c726a87 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -952,9 +952,36 @@ void device_class_set_props(DeviceClass *dc, Property 
*props);
 void device_class_set_parent_reset(DeviceClass *dc,
DeviceReset dev_reset,
DeviceReset *parent_reset);
+
+/**
+ * device_class_set_parent_realize() - set up for chaining realize fns
+ * @dc: The device class
+ * @dev_realize: the device realize function
+ * @parent_realize: somewhere to save the parents realize function
+ *
+ * This is intended to be used when the new realize function will
+ * eventually call its parent realization function during creation.
+ * This requires storing the function call somewhere (usually in the
+ * instance structure) so you can eventually call
+ * dc->parent_realize(dev, errp)
+ */
 void device_class_set_parent_realize(DeviceClass *dc,
  DeviceRealize dev_realize,
  DeviceRealize *parent_realize);
+
+
+/**
+ * device_class_set_parent_unrealize() - set up for chaining unrealize fns
+ * @dc: The device class
+ * @dev_unrealize: the device realize function
+ * @parent_unrealize: somewhere to save the parents unrealize function
+ *
+ * This is intended to be used when the new unrealize function will
+ * eventually call its parent unrealization function during the
+ * unrealize phase. This requires storing the function call somewhere
+ * (usually in the instance structure) so you can eventually call
+ * dc->parent_unrealize(dev);
+ */
 void device_class_set_parent_unrealize(DeviceClass *dc,
DeviceUnrealize dev_unrealize,
DeviceUnrealize *parent_unrealize);
-- 
2.39.2




[PATCH v3 03/20] hw/virtio: fix typo in VIRTIO_CONFIG_IRQ_IDX comments

2023-07-10 Thread Alex Bennée
Fixes: 544f0278af (virtio: introduce macro VIRTIO_CONFIG_IRQ_IDX)
Signed-off-by: Alex Bennée 
---
 hw/display/vhost-user-gpu.c| 4 ++--
 hw/net/virtio-net.c| 4 ++--
 hw/virtio/vhost-user-fs.c  | 4 ++--
 hw/virtio/vhost-user-gpio.c| 2 +-
 hw/virtio/vhost-vsock-common.c | 4 ++--
 hw/virtio/virtio-crypto.c  | 4 ++--
 6 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c
index 15f9d99d09..1791797bd7 100644
--- a/hw/display/vhost-user-gpu.c
+++ b/hw/display/vhost-user-gpu.c
@@ -489,7 +489,7 @@ vhost_user_gpu_guest_notifier_pending(VirtIODevice *vdev, 
int idx)
 
 /*
  * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
- * as the Marco of configure interrupt's IDX, If this driver does not
+ * as the macro of configure interrupt's IDX, If this driver does not
  * support, the function will return
  */
 
@@ -506,7 +506,7 @@ vhost_user_gpu_guest_notifier_mask(VirtIODevice *vdev, int 
idx, bool mask)
 
 /*
  * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
- * as the Marco of configure interrupt's IDX, If this driver does not
+ * as the macro of configure interrupt's IDX, If this driver does not
  * support, the function will return
  */
 
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 04783f5b94..493afdd96b 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -3362,7 +3362,7 @@ static bool 
virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx)
 }
 /*
  * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
- * as the Marco of configure interrupt's IDX, If this driver does not
+ * as the macro of configure interrupt's IDX, If this driver does not
  * support, the function will return false
  */
 
@@ -3394,7 +3394,7 @@ static void virtio_net_guest_notifier_mask(VirtIODevice 
*vdev, int idx,
 }
 /*
  *Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
- * as the Marco of configure interrupt's IDX, If this driver does not
+ * as the macro of configure interrupt's IDX, If this driver does not
  * support, the function will return
  */
 
diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
index 83fc20e49e..49d699ffc2 100644
--- a/hw/virtio/vhost-user-fs.c
+++ b/hw/virtio/vhost-user-fs.c
@@ -161,7 +161,7 @@ static void vuf_guest_notifier_mask(VirtIODevice *vdev, int 
idx,
 
 /*
  * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
- * as the Marco of configure interrupt's IDX, If this driver does not
+ * as the macro of configure interrupt's IDX, If this driver does not
  * support, the function will return
  */
 
@@ -177,7 +177,7 @@ static bool vuf_guest_notifier_pending(VirtIODevice *vdev, 
int idx)
 
 /*
  * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
- * as the Marco of configure interrupt's IDX, If this driver does not
+ * as the macro of configure interrupt's IDX, If this driver does not
  * support, the function will return
  */
 
diff --git a/hw/virtio/vhost-user-gpio.c b/hw/virtio/vhost-user-gpio.c
index d6927b610a..3b013f2d0f 100644
--- a/hw/virtio/vhost-user-gpio.c
+++ b/hw/virtio/vhost-user-gpio.c
@@ -194,7 +194,7 @@ static void vu_gpio_guest_notifier_mask(VirtIODevice *vdev, 
int idx, bool mask)
 
 /*
  * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
- * as the Marco of configure interrupt's IDX, If this driver does not
+ * as the macro of configure interrupt's IDX, If this driver does not
  * support, the function will return
  */
 
diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c
index 321262f6b3..12ea87d7a7 100644
--- a/hw/virtio/vhost-vsock-common.c
+++ b/hw/virtio/vhost-vsock-common.c
@@ -129,7 +129,7 @@ static void 
vhost_vsock_common_guest_notifier_mask(VirtIODevice *vdev, int idx,
 
 /*
  * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
- * as the Marco of configure interrupt's IDX, If this driver does not
+ * as the macro of configure interrupt's IDX, If this driver does not
  * support, the function will return
  */
 
@@ -146,7 +146,7 @@ static bool 
vhost_vsock_common_guest_notifier_pending(VirtIODevice *vdev,
 
 /*
  * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
- * as the Marco of configure interrupt's IDX, If this driver does not
+ * as the macro of configure interrupt's IDX, If this driver does not
  * support, the function will return
  */
 
diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
index a6d7e1e8ec..44faf5a522 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -1210,7 +1210,7 @@ static void

[PATCH v3 04/20] include/hw/virtio: document virtio_notify_config

2023-07-10 Thread Alex Bennée
Signed-off-by: Alex Bennée 
---
 include/hw/virtio/virtio.h | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 0492d26900..0671989383 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -276,6 +276,13 @@ extern const VMStateInfo virtio_vmstate_info;
 
 int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id);
 
+/**
+ * virtio_notify_config() - signal a change to device config
+ * @vdev: the virtio device
+ *
+ * Assuming the virtio device is up (VIRTIO_CONFIG_S_DRIVER_OK) this
+ * will trigger a guest interrupt and update the config version.
+ */
 void virtio_notify_config(VirtIODevice *vdev);
 
 bool virtio_queue_get_notification(VirtQueue *vq);
-- 
2.39.2




[PATCH v3 05/20] include/hw/virtio: add kerneldoc for virtio_init

2023-07-10 Thread Alex Bennée
Signed-off-by: Alex Bennée 
---
 include/hw/virtio/virtio.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 0671989383..631490bda4 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -219,6 +219,12 @@ struct VirtioDeviceClass {
 void virtio_instance_init_common(Object *proxy_obj, void *data,
  size_t vdev_size, const char *vdev_name);
 
+/**
+ * virtio_init() - initialise the common VirtIODevice structure
+ * @vdev: pointer to VirtIODevice
+ * @device_id: the VirtIO device ID (see virtio_ids.h)
+ * @config_size: size of the config space
+ */
 void virtio_init(VirtIODevice *vdev, uint16_t device_id, size_t config_size);
 
 void virtio_cleanup(VirtIODevice *vdev);
-- 
2.39.2




[PATCH v3 11/20] hw/virtio: derive vhost-user-gpio from vhost-user-device

2023-07-10 Thread Alex Bennée
Now the new base class supports config handling we can take advantage
and make vhost-user-gpio a much simpler boilerplate wrapper. Also as
this doesn't require any target specific hacks we only need to build
the stubs once.

Signed-off-by: Alex Bennée 

---
v2
  - use new vhost-user-base
  - move build to common code
v3
  - fix inadvertent double link
---
 include/hw/virtio/vhost-user-gpio.h |  23 +-
 hw/virtio/vhost-user-gpio.c | 400 ++--
 hw/virtio/meson.build   |   5 +-
 3 files changed, 22 insertions(+), 406 deletions(-)

diff --git a/include/hw/virtio/vhost-user-gpio.h 
b/include/hw/virtio/vhost-user-gpio.h
index a9d3f9b049..0948654dec 100644
--- a/include/hw/virtio/vhost-user-gpio.h
+++ b/include/hw/virtio/vhost-user-gpio.h
@@ -12,33 +12,14 @@
 #include "hw/virtio/virtio.h"
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user.h"
-#include "standard-headers/linux/virtio_gpio.h"
-#include "chardev/char-fe.h"
+#include "hw/virtio/vhost-user-device.h"
 
 #define TYPE_VHOST_USER_GPIO "vhost-user-gpio-device"
 OBJECT_DECLARE_SIMPLE_TYPE(VHostUserGPIO, VHOST_USER_GPIO);
 
 struct VHostUserGPIO {
 /*< private >*/
-VirtIODevice parent_obj;
-CharBackend chardev;
-struct virtio_gpio_config config;
-struct vhost_virtqueue *vhost_vqs;
-struct vhost_dev vhost_dev;
-VhostUserState vhost_user;
-VirtQueue *command_vq;
-VirtQueue *interrupt_vq;
-/**
- * There are at least two steps of initialization of the
- * vhost-user device. The first is a "connect" step and
- * second is a "start" step. Make a separation between
- * those initialization phases by using two fields.
- *
- * @connected: see vu_gpio_connect()/vu_gpio_disconnect()
- * @started_vu: see vu_gpio_start()/vu_gpio_stop()
- */
-bool connected;
-bool started_vu;
+VHostUserBase parent;
 /*< public >*/
 };
 
diff --git a/hw/virtio/vhost-user-gpio.c b/hw/virtio/vhost-user-gpio.c
index 3b013f2d0f..9f37c25415 100644
--- a/hw/virtio/vhost-user-gpio.c
+++ b/hw/virtio/vhost-user-gpio.c
@@ -11,382 +11,25 @@
 #include "hw/qdev-properties.h"
 #include "hw/virtio/virtio-bus.h"
 #include "hw/virtio/vhost-user-gpio.h"
-#include "qemu/error-report.h"
 #include "standard-headers/linux/virtio_ids.h"
-#include "trace.h"
+#include "standard-headers/linux/virtio_gpio.h"
 
-#define REALIZE_CONNECTION_RETRIES 3
-#define VHOST_NVQS 2
-
-/* Features required from VirtIO */
-static const int feature_bits[] = {
-VIRTIO_F_VERSION_1,
-VIRTIO_F_NOTIFY_ON_EMPTY,
-VIRTIO_RING_F_INDIRECT_DESC,
-VIRTIO_RING_F_EVENT_IDX,
-VIRTIO_GPIO_F_IRQ,
-VIRTIO_F_RING_RESET,
-VHOST_INVALID_FEATURE_BIT
-};
-
-static void vu_gpio_get_config(VirtIODevice *vdev, uint8_t *config)
-{
-VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev);
-
-memcpy(config, &gpio->config, sizeof(gpio->config));
-}
-
-static int vu_gpio_config_notifier(struct vhost_dev *dev)
-{
-VHostUserGPIO *gpio = VHOST_USER_GPIO(dev->vdev);
-
-memcpy(dev->vdev->config, &gpio->config, sizeof(gpio->config));
-virtio_notify_config(dev->vdev);
-
-return 0;
-}
-
-const VhostDevConfigOps gpio_ops = {
-.vhost_dev_config_notifier = vu_gpio_config_notifier,
+static Property vgpio_properties[] = {
+DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
+DEFINE_PROP_END_OF_LIST(),
 };
 
-static int vu_gpio_start(VirtIODevice *vdev)
+static void vgpio_realize(DeviceState *dev, Error **errp)
 {
-BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev);
-struct vhost_dev *vhost_dev = &gpio->vhost_dev;
-int ret, i;
+VHostUserBase *vub = VHOST_USER_BASE(dev);
+VHostUserBaseClass *vubc = VHOST_USER_BASE_GET_CLASS(dev);
 
-if (!k->set_guest_notifiers) {
-error_report("binding does not support guest notifiers");
-return -ENOSYS;
-}
+/* Fixed for GPIO */
+vub->virtio_id = VIRTIO_ID_GPIO;
+vub->num_vqs = 2;
+vub->config_size = sizeof(struct virtio_gpio_config);
 
-ret = vhost_dev_enable_notifiers(vhost_dev, vdev);
-if (ret < 0) {
-error_report("Error enabling host notifiers: %d", ret);
-return ret;
-}
-
-ret = k->set_guest_notifiers(qbus->parent, vhost_dev->nvqs, true);
-if (ret < 0) {
-error_report("Error binding guest notifier: %d", ret);
-goto err_host_notifiers;
-}
-
-/*
- * Before we start up we need to ensure we have the final feature
- * set needed for the vhost configuration. The backend may also
- * apply backend_features when the feature set is sent.
-  

[PATCH v3 06/20] include/hw/virtio: document some more usage of notifiers

2023-07-10 Thread Alex Bennée
Lets document some more of the core VirtIODevice structure.

Signed-off-by: Alex Bennée 
---
 include/hw/virtio/virtio.h | 8 
 1 file changed, 8 insertions(+)

diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 631490bda4..c8f72850bc 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -150,10 +150,18 @@ struct VirtIODevice
 VMChangeStateEntry *vmstate;
 char *bus_name;
 uint8_t device_endian;
+/**
+ * @user_guest_notifier_mask: gate usage of ->guest_notifier_mask() 
callback.
+ * This is used to suppress the masking of guest updates for
+ * vhost-user devices which are asynchronous by design.
+ */
 bool use_guest_notifier_mask;
 AddressSpace *dma_as;
 QLIST_HEAD(, VirtQueue) *vector_queues;
 QTAILQ_ENTRY(VirtIODevice) next;
+/**
+ * @config_notifier: the event notifier that handles config events
+ */
 EventNotifier config_notifier;
 bool device_iotlb_enabled;
 };
-- 
2.39.2




[RFC PATCH v3 19/20] hw/virtio: probe backend for specs if it supports it

2023-07-10 Thread Alex Bennée
Now we have detected and validated the protocol support lets do the
probe. The empty state indicates no probe took place.

Signed-off-by: Alex Bennée 
---
 include/hw/virtio/vhost.h | 12 +++
 hw/virtio/vhost-user.c| 73 +++
 hw/virtio/vhost.c |  2 +-
 3 files changed, 79 insertions(+), 8 deletions(-)

diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index 912706668a..1d8de1c558 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -68,6 +68,13 @@ typedef struct VhostDevConfigOps {
 
 struct vhost_memory;
 
+typedef struct VhostUserBackendSpecs {
+uint32_t device_id;
+uint32_t config_size;
+uint32_t min_vqs;
+uint32_t max_vqs;
+} VhostUserBackendSpecs;
+
 /**
  * struct vhost_dev - common vhost_dev structure
  * @vhost_ops: backend specific ops
@@ -107,11 +114,15 @@ struct vhost_dev {
  * VHOST_USER_SET_FEATURES or VHOST_NET_F_VIRTIO_NET_HDR. Its
  * future use should be discouraged and the variable retired as
  * its easy to confuse with the VirtIO backend_features.
+ *
+ * @specs: the results of a GET_BACKEND_SPECS probe.
  */
 uint64_t features;
 uint64_t acked_features;
 uint64_t backend_features;
 
+VhostUserBackendSpecs specs;
+
 /**
  * @protocol_features: is the vhost-user only feature set by
  * VHOST_USER_SET_PROTOCOL_FEATURES. Protocol features are only
@@ -134,6 +145,7 @@ struct vhost_dev {
 QLIST_HEAD(, vhost_iommu) iommu_list;
 IOMMUNotifier n;
 const VhostDevConfigOps *config_ops;
+
 };
 
 extern const VhostOps kernel_ops;
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 3116b3e46a..36aa4ec2d5 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -123,6 +123,7 @@ typedef enum VhostUserRequest {
 VHOST_USER_REM_MEM_REG = 38,
 VHOST_USER_SET_STATUS = 39,
 VHOST_USER_GET_STATUS = 40,
+VHOST_USER_GET_BACKEND_SPECS = 41,
 VHOST_USER_MAX
 } VhostUserRequest;
 
@@ -204,13 +205,6 @@ typedef struct VhostUserInflight {
 uint16_t queue_size;
 } VhostUserInflight;
 
-typedef struct VhostUserBackendSpecs {
-uint32_t device_id;
-uint32_t config_size;
-uint32_t min_vqs;
-uint32_t max_vqs;
-} VhostUserBackendSpecs;
-
 typedef struct {
 VhostUserRequest request;
 
@@ -1991,6 +1985,56 @@ static int 
vhost_user_postcopy_notifier(NotifierWithReturn *notifier,
 return 0;
 }
 
+static bool vhost_user_get_backend_specs(struct vhost_dev *dev, Error **errp)
+{
+int ret;
+VhostUserMsg msg = {
+.hdr.request = VHOST_USER_GET_BACKEND_SPECS,
+.hdr.flags = VHOST_USER_VERSION,
+.hdr.size = VHOST_USER_HDR_SIZE,
+};
+
+if (!virtio_has_feature(dev->protocol_features,
+VHOST_USER_PROTOCOL_F_STANDALONE)) {
+error_setg(errp, "VHOST_USER_PROTOCOL_F_STANDALONE not supported");
+return -EINVAL;
+}
+
+ret = vhost_user_write(dev, &msg, NULL, 0);
+if (ret < 0) {
+error_setg_errno(errp, -ret, "vhost_get_backend send failed");
+return ret;
+}
+
+ret = vhost_user_read(dev, &msg);
+if (ret < 0) {
+error_setg_errno(errp, -ret, "vhost_get_backend recv failed");
+return ret;
+}
+
+if (msg.hdr.request != VHOST_USER_GET_BACKEND_SPECS) {
+error_setg(errp,
+   "Received unexpected msg type. Expected %d received %d",
+   VHOST_USER_GET_BACKEND_SPECS, msg.hdr.request);
+return -EPROTO;
+}
+
+if (msg.hdr.size != sizeof(msg.payload.specs)) {
+error_setg(errp, "Received bad msg size.");
+return -EPROTO;
+}
+
+if (msg.payload.specs.config_size && 
!virtio_has_feature(dev->protocol_features,
+ 
VHOST_USER_PROTOCOL_F_CONFIG)) {
+error_setg(errp, "VHOST_USER_PROTOCOL_F_CONFIG not supported");
+return -EPROTO;
+}
+
+dev->specs = msg.payload.specs;
+
+return 0;
+}
+
 static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque,
Error **errp)
 {
@@ -2073,6 +2117,21 @@ static int vhost_user_backend_init(struct vhost_dev 
*dev, void *opaque,
 return -EPROTO;
 }
 
+if (dev->protocol_features & (1ULL << 
VHOST_USER_PROTOCOL_F_STANDALONE)) {
+err = vhost_user_get_backend_specs(dev, errp);
+if (err < 0) {
+error_setg_errno(errp, EPROTO, "vhost_get_backend_specs 
failed");
+return -EPROTO;
+}
+/*
+ * If this was never set by the user we can now fill it in
+ * so we can continue the initialisation
+ */
+if (!dev->nvqs) {
+dev->nvqs = dev->specs.min_vqs;
+}
+}
+

  1   2   3   4   5   6   >