master
c 98 lines 2.84 KB
Raw
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);