From: "Daniel P. Berrangé" <berrange@redhat.com>
To: Dorjoy Chowdhury <dorjoychy111@gmail.com>
Cc: qemu-devel@nongnu.org, graf@amazon.com, agraf@csgraf.de,
stefanha@redhat.com, pbonzini@redhat.com, slp@redhat.com,
richard.henderson@linaro.org, eduardo@habkost.net,
mst@redhat.com, marcel.apfelbaum@gmail.com, philmd@linaro.org
Subject: Re: [PATCH v3 2/5] machine/nitro-enclave: Add vhost-user-vsock device
Date: Mon, 12 Aug 2024 15:24:20 +0100 [thread overview]
Message-ID: <ZrobFFVV4tN6dueh@redhat.com> (raw)
In-Reply-To: <20240810164502.19693-3-dorjoychy111@gmail.com>
On Sat, Aug 10, 2024 at 10:44:59PM +0600, Dorjoy Chowdhury wrote:
> AWS Nitro Enclaves have built-in vhost-vsock device support which
> enables applications in enclave VMs to communicate with the parent
> EC2 VM over vsock. The enclave VMs have dynamic CID while the parent
> always has CID 3. In QEMU, the vsock emulation for nitro enclave is
> added using vhost-user-vsock as opposed to vhost-vsock. vhost-vsock
> doesn't support sibling VM communication which is needed for nitro
> enclaves.
>
> In QEMU's nitro-enclave emulation, for the vsock communication to CID
> 3 to work, another process that does the vsock emulation in userspace
> must be run, for example, vhost-device-vsock[1] from rust-vmm, with
> necessary vsock communication support in another guest VM with CID 3.
> A new mandatory nitro-enclave machine option 'vsock' has been added.
> The value for this option should be the chardev id from the '-chardev'
> option for the vhost-user-vsock device to work.
>
> Using vhost-user-vsock also enables the possibility to implement some
> proxying support in the vhost-user-vsock daemon that will forward all
> the packets to the host machine instead of CID 3 so that users of
> nitro-enclave can run the necessary applications in their host machine
> instead of running another whole VM with CID 3.
>
> [1] https://github.com/rust-vmm/vhost-device/tree/main/vhost-device-vsock
>
> Signed-off-by: Dorjoy Chowdhury <dorjoychy111@gmail.com>
> ---
> backends/hostmem-memfd.c | 2 -
> hw/core/machine.c | 71 +++++++++---------
> hw/i386/Kconfig | 1 +
> hw/i386/nitro_enclave.c | 123 ++++++++++++++++++++++++++++++++
> include/hw/boards.h | 2 +
> include/hw/i386/nitro_enclave.h | 8 +++
> include/sysemu/hostmem.h | 2 +
> 7 files changed, 174 insertions(+), 35 deletions(-)
>
> diff --git a/hw/i386/nitro_enclave.c b/hw/i386/nitro_enclave.c
> index 98690c6373..280ab4cc9b 100644
> --- a/hw/i386/nitro_enclave.c
> +++ b/hw/i386/nitro_enclave.c
> @@ -11,11 +11,81 @@
> #include "qemu/osdep.h"
> #include "qemu/error-report.h"
> #include "qapi/error.h"
> +#include "qom/object_interfaces.h"
>
> +#include "chardev/char.h"
> +#include "hw/sysbus.h"
> #include "hw/core/eif.h"
> #include "hw/i386/x86.h"
> #include "hw/i386/microvm.h"
> #include "hw/i386/nitro_enclave.h"
> +#include "hw/virtio/virtio-mmio.h"
> +#include "hw/virtio/vhost-user-vsock.h"
> +#include "sysemu/hostmem.h"
> +
> +static BusState *find_free_virtio_mmio_bus(void)
> +{
> + BusChild *kid;
> + BusState *bus = sysbus_get_default();
> +
> + QTAILQ_FOREACH(kid, &bus->children, sibling) {
> + DeviceState *dev = kid->child;
> + if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MMIO)) {
> + VirtIOMMIOProxy *mmio = VIRTIO_MMIO(OBJECT(dev));
> + VirtioBusState *mmio_virtio_bus = &mmio->bus;
> + BusState *mmio_bus = &mmio_virtio_bus->parent_obj;
> + if (QTAILQ_EMPTY(&mmio_bus->children)) {
> + return mmio_bus;
> + }
> + }
> + }
> +
> + return NULL;
> +}
> +
> +static void vhost_user_vsock_init(NitroEnclaveMachineState *nems)
> +{
> + DeviceState *dev = qdev_new(TYPE_VHOST_USER_VSOCK);
> + VHostUserVSock *vsock = VHOST_USER_VSOCK(dev);
> + BusState *bus;
> +
> + if (!nems->vsock) {
> + error_report("A valid chardev id for vhost-user-vsock device must be "
> + "provided using the 'vsock' machine option");
> + exit(1);
> + }
> +
> + bus = find_free_virtio_mmio_bus();
> + if (!bus) {
> + error_report("Failed to find bus for vhost-user-vsock device");
> + exit(1);
> + }
> +
> + Chardev *chardev = qemu_chr_find(nems->vsock);
> + if (!chardev) {
> + error_report("Failed to find chardev with id %s", nems->vsock);
> + exit(1);
> + }
> +
> + vsock->conf.chardev.chr = chardev;
> +
> + qdev_realize_and_unref(dev, bus, &error_fatal);
> +}
Why does this machine need to create the vhost-user-vsock device itself ?
Doing it this way prevents the mgmt app from changing any of the other
vsock device settings beyond 'chardev'. The entity creating QEMU can use
-device to create the vsock device.
> +
> +static void nitro_enclave_devices_init(NitroEnclaveMachineState *nems)
> +{
> + vhost_user_vsock_init(nems);
> +}
> +
> +static void nitro_enclave_machine_state_init(MachineState *machine)
> +{
> + NitroEnclaveMachineClass *ne_class =
> + NITRO_ENCLAVE_MACHINE_GET_CLASS(machine);
> + NitroEnclaveMachineState *ne_state = NITRO_ENCLAVE_MACHINE(machine);
> +
> + ne_class->parent_init(machine);
> + nitro_enclave_devices_init(ne_state);
> +}
>
> static void nitro_enclave_machine_initfn(Object *obj)
> {
> @@ -66,15 +136,68 @@ static void x86_load_eif(X86MachineState *x86ms, FWCfgState *fw_cfg,
> return;
> }
>
> +static bool create_memfd_backend(MachineState *ms, const char *path,
> + Error **errp)
> +{
> + Object *obj;
> + MachineClass *mc = MACHINE_GET_CLASS(ms);
> + bool r = false;
> +
> + obj = object_new(TYPE_MEMORY_BACKEND_MEMFD);
> + if (!object_property_set_int(obj, "size", ms->ram_size, errp)) {
> + goto out;
> + }
> + object_property_add_child(object_get_objects_root(), mc->default_ram_id,
> + obj);
> +
> + if (!user_creatable_complete(USER_CREATABLE(obj), errp)) {
> + goto out;
> + }
> + r = object_property_set_link(OBJECT(ms), "memory-backend", obj, errp);
> +
> +out:
> + object_unref(obj);
> + return r;
> +}
> +
> +static char *nitro_enclave_get_vsock_chardev_id(Object *obj, Error **errp)
> +{
> + NitroEnclaveMachineState *nems = NITRO_ENCLAVE_MACHINE(obj);
> +
> + return g_strdup(nems->vsock);
> +}
> +
> +static void nitro_enclave_set_vsock_chardev_id(Object *obj, const char *value,
> + Error **errp)
> +{
> + NitroEnclaveMachineState *nems = NITRO_ENCLAVE_MACHINE(obj);
> +
> + g_free(nems->vsock);
> + nems->vsock = g_strdup(value);
> +}
> +
> static void nitro_enclave_class_init(ObjectClass *oc, void *data)
> {
> MachineClass *mc = MACHINE_CLASS(oc);
> MicrovmMachineClass *mmc = MICROVM_MACHINE_CLASS(oc);
> + NitroEnclaveMachineClass *nemc = NITRO_ENCLAVE_MACHINE_CLASS(oc);
>
> mmc->x86_load_linux = x86_load_eif;
>
> mc->family = "nitro_enclave_i386";
> mc->desc = "AWS Nitro Enclave";
> +
> + nemc->parent_init = mc->init;
> + mc->init = nitro_enclave_machine_state_init;
> +
> + mc->create_default_memdev = create_memfd_backend;
> +
> + object_class_property_add_str(oc, NITRO_ENCLAVE_VSOCK_CHARDEV_ID,
> + nitro_enclave_get_vsock_chardev_id,
> + nitro_enclave_set_vsock_chardev_id);
> + object_class_property_set_description(oc, NITRO_ENCLAVE_VSOCK_CHARDEV_ID,
> + "Set chardev id for vhost-user-vsock "
> + "device");
> }
>
> static const TypeInfo nitro_enclave_machine_info = {
> diff --git a/include/hw/boards.h b/include/hw/boards.h
> index 48ff6d8b93..c268e7f005 100644
> --- a/include/hw/boards.h
> +++ b/include/hw/boards.h
> @@ -308,6 +308,8 @@ struct MachineClass {
> int64_t (*get_default_cpu_node_id)(const MachineState *ms, int idx);
> ram_addr_t (*fixup_ram_size)(ram_addr_t size);
> uint64_t smbios_memory_device_size;
> + bool (*create_default_memdev)(MachineState *ms, const char *path,
> + Error **errp);
> };
>
> /**
> diff --git a/include/hw/i386/nitro_enclave.h b/include/hw/i386/nitro_enclave.h
> index a1dada9371..3e302de851 100644
> --- a/include/hw/i386/nitro_enclave.h
> +++ b/include/hw/i386/nitro_enclave.h
> @@ -14,12 +14,20 @@
> #include "hw/i386/microvm.h"
> #include "qom/object.h"
>
> +/* Machine type options */
> +#define NITRO_ENCLAVE_VSOCK_CHARDEV_ID "vsock"
> +
> struct NitroEnclaveMachineClass {
> MicrovmMachineClass parent;
> +
> + void (*parent_init)(MachineState *state);
> };
>
> struct NitroEnclaveMachineState {
> MicrovmMachineState parent;
> +
> + /* Machine type options */
> + char *vsock;
> };
>
> #define TYPE_NITRO_ENCLAVE_MACHINE MACHINE_TYPE_NAME("nitro-enclave")
> diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h
> index de47ae59e4..67f45abe39 100644
> --- a/include/sysemu/hostmem.h
> +++ b/include/sysemu/hostmem.h
> @@ -39,6 +39,8 @@ OBJECT_DECLARE_TYPE(HostMemoryBackend, HostMemoryBackendClass,
> */
> #define TYPE_MEMORY_BACKEND_FILE "memory-backend-file"
>
> +#define TYPE_MEMORY_BACKEND_MEMFD "memory-backend-memfd"
> +
>
> /**
> * HostMemoryBackendClass:
> --
> 2.39.2
>
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
next prev parent reply other threads:[~2024-08-12 14:25 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-10 16:44 [PATCH v3 0/5] AWS Nitro Enclave emulation support Dorjoy Chowdhury
2024-08-10 16:44 ` [PATCH v3 1/5] machine/nitro-enclave: New machine type for AWS Nitro Enclaves Dorjoy Chowdhury
2024-08-12 13:56 ` Alexander Graf
2024-08-10 16:44 ` [PATCH v3 2/5] machine/nitro-enclave: Add vhost-user-vsock device Dorjoy Chowdhury
2024-08-12 14:24 ` Daniel P. Berrangé [this message]
2024-08-13 18:02 ` Dorjoy Chowdhury
2024-08-14 8:17 ` Alexander Graf
2024-08-10 16:45 ` [PATCH v3 3/5] device/virtio-nsm: Support for Nitro Secure Module device Dorjoy Chowdhury
2024-08-12 14:15 ` Daniel P. Berrangé
2024-08-13 12:54 ` Alexander Graf
2024-08-10 16:45 ` [PATCH v3 4/5] machine/nitro-enclave: Add built-in " Dorjoy Chowdhury
2024-08-12 13:51 ` Alexander Graf
2024-08-12 14:00 ` Daniel P. Berrangé
2024-08-12 13:55 ` Alexander Graf
2024-08-12 14:07 ` Daniel P. Berrangé
2024-08-16 12:50 ` Dorjoy Chowdhury
2024-08-16 12:57 ` Daniel P. Berrangé
2024-08-16 13:34 ` Dorjoy Chowdhury
2024-08-13 12:57 ` Alexander Graf
2024-08-10 16:45 ` [PATCH v3 5/5] docs/nitro-enclave: Documentation for nitro-enclave machine type Dorjoy Chowdhury
2024-08-18 11:51 ` [PATCH v3 0/5] AWS Nitro Enclave emulation support Dorjoy Chowdhury
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZrobFFVV4tN6dueh@redhat.com \
--to=berrange@redhat.com \
--cc=agraf@csgraf.de \
--cc=dorjoychy111@gmail.com \
--cc=eduardo@habkost.net \
--cc=graf@amazon.com \
--cc=marcel.apfelbaum@gmail.com \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=philmd@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
--cc=slp@redhat.com \
--cc=stefanha@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.