@samitouri / QOSamiQemu / commits / 4953bf187d

hw/nitro: Add Nitro Vsock Bus

Add a dedicated bus for Nitro Enclave vsock devices. In Nitro Enclaves, communication between parent and enclave/hypervisor happens almost exclusively through vsock. The nitro-vsock-bus models this dependency in QEMU, which allows devices in this bus to implement individual services on top of vsock. The nitro machine spawns this bus by creating the included nitro-vsock-bridge sysbus device. The nitro accel then advertises the Enclave's CID to the bus by calling nitro_vsock_bridge_start_enclave() on the bridge device as soon as it knows the CID. Nitro vsock devices can listen to that event and learn the Enclave's CID when it is available to perform actions, such as connect to the debug serial vsock port. Suggested-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Alexander Graf <graf@amazon.com> Link: https://lore.kernel.org/r/20260225220807.33092-4-graf@amazon.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Alexander Graf committed Feb 25, 2026 at 22:07 UTC 4953bf187db08e995c3be2a47ac96332e767c434
10 files changed +187
MAINTAINERS
+6
@@ -3020,6 +3020,12 @@ F: hw/vmapple/*
3020 F: include/hw/vmapple/*
3021 F: docs/system/arm/vmapple.rst
3022
3023 +Nitro Enclaves (native)
3024 +M: Alexander Graf <graf@amazon.com>
3025 +S: Maintained
3026 +F: hw/nitro/
3027 +F: include/hw/nitro/
3028 +
3029 Subsystems
3030 ----------
3031 Overall Audio backends
hw/Kconfig
+1
@@ -22,6 +22,7 @@ source isa/Kconfig
22 source mem/Kconfig
23 source misc/Kconfig
24 source net/Kconfig
25 +source nitro/Kconfig
26 source nubus/Kconfig
27 source nvme/Kconfig
28 source nvram/Kconfig
hw/meson.build
+1
@@ -44,6 +44,7 @@ subdir('isa')
44 subdir('mem')
45 subdir('misc')
46 subdir('net')
47 +subdir('nitro')
48 subdir('nubus')
49 subdir('nvme')
50 subdir('nvram')
hw/nitro/Kconfig new
+2
@@ -0,0 +1,2 @@
1 +config NITRO_VSOCK_BUS
2 + bool
hw/nitro/meson.build new
+1
@@ -0,0 +1 @@
1 +system_ss.add(when: 'CONFIG_NITRO_VSOCK_BUS', if_true: files('nitro-vsock-bus.c'))
hw/nitro/nitro-vsock-bus.c new
+98
@@ -0,0 +1,98 @@
1 +/*
2 + * Nitro Enclave Vsock Bus
3 + *
4 + * Copyright © 2026 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5 + *
6 + * Authors:
7 + * Alexander Graf <graf@amazon.com>
8 + *
9 + * A bus for Nitro Enclave vsock devices. In Nitro Enclaves, communication
10 + * between parent and enclave/hypervisor happens almost exclusively through
11 + * vsock. The nitro-vsock-bus models this dependency in QEMU, which allows
12 + * devices in this bus to implement individual services on top of vsock.
13 + *
14 + * The nitro accel advertises the Enclave's CID to the bus by calling
15 + * nitro_vsock_bridge_start_enclave() on the bridge device as soon as it
16 + * knows the CID.
17 + *
18 + * SPDX-License-Identifier: GPL-2.0-or-later
19 + */
20 +
21 +#include "qemu/osdep.h"
22 +#include "qapi/error.h"
23 +#include "monitor/qdev.h"
24 +#include "hw/core/sysbus.h"
25 +#include "hw/nitro/nitro-vsock-bus.h"
26 +
27 +void nitro_vsock_bridge_start_enclave(NitroVsockBridge *bridge,
28 + uint32_t enclave_cid, Error **errp)
29 +{
30 + ERRP_GUARD();
31 + BusState *qbus = BUS(&bridge->bus);
32 + BusChild *kid;
33 +
34 + bridge->enclave_cid = enclave_cid;
35 +
36 + QTAILQ_FOREACH(kid, &qbus->children, sibling) {
37 + NitroVsockDevice *ndev = NITRO_VSOCK_DEVICE(kid->child);
38 + NitroVsockDeviceClass *ndc = NITRO_VSOCK_DEVICE_GET_CLASS(ndev);
39 +
40 + if (ndc->enclave_started) {
41 + ndc->enclave_started(ndev, enclave_cid, errp);
42 + if (*errp) {
43 + return;
44 + }
45 + }
46 + }
47 +}
48 +
49 +NitroVsockBridge *nitro_vsock_bridge_create(void)
50 +{
51 + DeviceState *dev = qdev_new(TYPE_NITRO_VSOCK_BRIDGE);
52 +
53 + qdev_set_id(dev, g_strdup("nitro-vsock"), &error_fatal);
54 + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
55 +
56 + return NITRO_VSOCK_BRIDGE(dev);
57 +}
58 +
59 +static void nitro_vsock_bridge_init(Object *obj)
60 +{
61 + NitroVsockBridge *s = NITRO_VSOCK_BRIDGE(obj);
62 +
63 + qbus_init(&s->bus, sizeof(s->bus), TYPE_NITRO_VSOCK_BUS,
64 + DEVICE(s), "nitro-vsock");
65 + object_property_add_uint32_ptr(obj, "enclave-cid",
66 + &s->enclave_cid, OBJ_PROP_FLAG_READ);
67 +}
68 +
69 +static void nitro_vsock_device_class_init(ObjectClass *oc, const void *data)
70 +{
71 + DeviceClass *dc = DEVICE_CLASS(oc);
72 +
73 + dc->bus_type = TYPE_NITRO_VSOCK_BUS;
74 +}
75 +
76 +static const TypeInfo nitro_vsock_bus_types[] = {
77 + {
78 + .name = TYPE_NITRO_VSOCK_BUS,
79 + .parent = TYPE_BUS,
80 + .instance_size = sizeof(NitroVsockBus),
81 + },
82 + {
83 + .name = TYPE_NITRO_VSOCK_BRIDGE,
84 + .parent = TYPE_SYS_BUS_DEVICE,
85 + .instance_size = sizeof(NitroVsockBridge),
86 + .instance_init = nitro_vsock_bridge_init,
87 + },
88 + {
89 + .name = TYPE_NITRO_VSOCK_DEVICE,
90 + .parent = TYPE_DEVICE,
91 + .instance_size = sizeof(NitroVsockDevice),
92 + .class_size = sizeof(NitroVsockDeviceClass),
93 + .class_init = nitro_vsock_device_class_init,
94 + .abstract = true,
95 + },
96 +};
97 +
98 +DEFINE_TYPES(nitro_vsock_bus_types);
hw/nitro/trace-events new
+2
@@ -0,0 +1,2 @@
1 +# See docs/devel/tracing.rst for syntax documentation.
2 +
hw/nitro/trace.h new
+4
@@ -0,0 +1,4 @@
1 +/*
2 + * SPDX-License-Identifier: GPL-2.0-or-later
3 + */
4 +#include "trace/trace-hw_nitro.h"
include/hw/nitro/nitro-vsock-bus.h new
+71
@@ -0,0 +1,71 @@
1 +/*
2 + * Nitro Enclave Vsock Bus
3 + *
4 + * SPDX-License-Identifier: GPL-2.0-or-later
5 + */
6 +
7 +#ifndef HW_NITRO_VSOCK_BUS_H
8 +#define HW_NITRO_VSOCK_BUS_H
9 +
10 +#include "hw/core/qdev.h"
11 +#include "hw/core/sysbus.h"
12 +#include "qom/object.h"
13 +
14 +#define TYPE_NITRO_VSOCK_BUS "nitro-vsock-bus"
15 +OBJECT_DECLARE_SIMPLE_TYPE(NitroVsockBus, NITRO_VSOCK_BUS)
16 +
17 +#define TYPE_NITRO_VSOCK_BRIDGE "nitro-vsock-bridge"
18 +OBJECT_DECLARE_SIMPLE_TYPE(NitroVsockBridge, NITRO_VSOCK_BRIDGE)
19 +
20 +#define TYPE_NITRO_VSOCK_DEVICE "nitro-vsock-device"
21 +OBJECT_DECLARE_TYPE(NitroVsockDevice, NitroVsockDeviceClass,
22 + NITRO_VSOCK_DEVICE)
23 +
24 +struct NitroVsockBus {
25 + BusState parent_obj;
26 +};
27 +
28 +struct NitroVsockBridge {
29 + SysBusDevice parent_obj;
30 +
31 + NitroVsockBus bus;
32 + uint32_t enclave_cid;
33 +};
34 +
35 +struct NitroVsockDevice {
36 + DeviceState parent_obj;
37 +};
38 +
39 +struct NitroVsockDeviceClass {
40 + DeviceClass parent_class;
41 +
42 + /*
43 + * Called after the enclave has been started and the CID is known.
44 + * Devices use this to establish vsock connections to the enclave.
45 + */
46 + void (*enclave_started)(NitroVsockDevice *dev, uint32_t enclave_cid,
47 + Error **errp);
48 +};
49 +
50 +/*
51 + * Machine helper to create the Nitro vsock bridge sysbus device.
52 + */
53 +NitroVsockBridge *nitro_vsock_bridge_create(void);
54 +
55 +/*
56 + * Find the Nitro vsock bridge on the sysbus.
57 + */
58 +static inline NitroVsockBridge *nitro_vsock_bridge_find(void)
59 +{
60 + return NITRO_VSOCK_BRIDGE(
61 + object_resolve_path_type("", TYPE_NITRO_VSOCK_BRIDGE, NULL));
62 +}
63 +
64 +/*
65 + * Notify the bridge that the enclave has started. Dispatches
66 + * enclave_started() to all devices on the bus.
67 + */
68 +void nitro_vsock_bridge_start_enclave(NitroVsockBridge *bridge,
69 + uint32_t enclave_cid, Error **errp);
70 +
71 +#endif /* HW_NITRO_VSOCK_BUS_H */
meson.build
+1
@@ -3620,6 +3620,7 @@ if have_system
3620 'hw/misc/macio',
3621 'hw/net',
3622 'hw/net/can',
3623 + 'hw/nitro',
3624 'hw/nubus',
3625 'hw/nvme',
3626 'hw/nvram',