From nobody Sun Apr 12 05:58:00 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass header.i=@amazon.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=amazon.com ARC-Seal: i=1; a=rsa-sha256; t=1772057404; cv=none; d=zohomail.com; s=zohoarc; b=KiquG8HOVHRYR44C/4QasTaJeDyE+aDuJBEsrvsXcBivmEfI3b4VFyxeK4YfSGdLk7C5E1832v4xkQ1Sk+yOIgUb/05YEOsKsd25fKqOSzU34UjDSUvGTQiPtI2pDwEZuZSv8vEm1KV4AgoMJAnmVVtD5UvD6VA9B8FY3bHfxcw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772057404; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=ehsU0Bf5A0MlZP4W91d1tbV1iHCoQYnxLfebYzHP7Dw=; b=JUFQbzM/I+gpsoHh8Qsj0jM8kPynHL31HMFZqQozdYJ9Dynqku7WsR63akaO5PvVbXqg4LqR0nBPd4ko43ZQ+0BfjGnM/5aFGdItG4g+DWoaRB8dgOKH1fnnRZjLhRgJGPYc9c5hMW9h2onewdE7EO5brgA0hr22T1az8IdRnOU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=@amazon.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1772057404651596.9967314125682; Wed, 25 Feb 2026 14:10:04 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vvN4P-0007J5-Ay; Wed, 25 Feb 2026 17:09:25 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vvN4J-00079d-3g; Wed, 25 Feb 2026 17:09:20 -0500 Received: from pdx-out-003.esa.us-west-2.outbound.mail-perimeter.amazon.com ([44.246.68.102]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vvN4H-00011K-5R; Wed, 25 Feb 2026 17:09:18 -0500 Received: from ip-10-5-12-219.us-west-2.compute.internal (HELO smtpout.naws.us-west-2.prod.farcaster.email.amazon.dev) ([10.5.12.219]) by internal-pdx-out-003.esa.us-west-2.outbound.mail-perimeter.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Feb 2026 22:09:12 +0000 Received: from EX19MTAUWC001.ant.amazon.com [205.251.233.105:30796] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.7.80:2525] with esmtp (Farcaster) id 6f16a4b1-11c9-43e0-91ea-165e29d8721d; Wed, 25 Feb 2026 22:09:12 +0000 (UTC) Received: from EX19D020UWC004.ant.amazon.com (10.13.138.149) by EX19MTAUWC001.ant.amazon.com (10.250.64.174) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.2562.37; Wed, 25 Feb 2026 22:09:10 +0000 Received: from ip-10-253-83-51.amazon.com (172.19.99.218) by EX19D020UWC004.ant.amazon.com (10.13.138.149) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.2562.37; Wed, 25 Feb 2026 22:09:08 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.com; i=@amazon.com; q=dns/txt; s=amazoncorp2; t=1772057357; x=1803593357; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ehsU0Bf5A0MlZP4W91d1tbV1iHCoQYnxLfebYzHP7Dw=; b=C8PqKBBAkn4KKAdSWztYtZublCNo8z0rFkEGhXOwFs3xKER45qWLy7xF EBRQfINNO2Cih0OEFbg0l3Wx6HQSb8oN85HNHikNphdStFyuY5OusMwDw aDGB9jA8u5NfZFUhwP7CZGqWHaqbOhQJMx8VXCsmS4NKfhK0zZTp1UERl i34DMzpV0i4Ag88IdbZKJjg/stm26eUcC54M6JP5HsgUTMUd1suht738q 7g2a/bK9uYI5aOgHf3g6jMMcIzkYHcqx5BpQTwDkgFz6fXix1bSKY/HP3 +U4vaJHdDtuofNk0XZrOMaDq0pXcsxI6UmK3KXXIRJCnTaBru2+kmI1tJ w==; X-CSE-ConnectionGUID: mNR/wwCEQNGxh+7rSKmu7g== X-CSE-MsgGUID: H4RJkLfrRmCtomi0YoTaHw== X-IronPort-AV: E=Sophos;i="6.21,311,1763424000"; d="scan'208";a="13815872" X-Farcaster-Flow-ID: 6f16a4b1-11c9-43e0-91ea-165e29d8721d From: Alexander Graf To: CC: , Peter Maydell , "Thomas Huth" , , , , , Cornelia Huck , , Dorjoy Chowdhury , Pierrick Bouvier , Paolo Bonzini , Tyler Fanelli , , Subject: [PATCH v3 06/11] hw/nitro: Introduce Nitro Enclave Heartbeat device Date: Wed, 25 Feb 2026 22:08:00 +0000 Message-ID: <20260225220807.33092-7-graf@amazon.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20260225220807.33092-1-graf@amazon.com> References: <20260225220807.33092-1-graf@amazon.com> MIME-Version: 1.0 X-Originating-IP: [172.19.99.218] X-ClientProxiedBy: EX19D036UWB001.ant.amazon.com (10.13.139.133) To EX19D020UWC004.ant.amazon.com (10.13.138.149) Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=44.246.68.102; envelope-from=prvs=509822c20=graf@amazon.de; helo=pdx-out-003.esa.us-west-2.outbound.mail-perimeter.amazon.com X-Spam_score_int: -1 X-Spam_score: -0.2 X-Spam_bar: / X-Spam_report: (-0.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.734, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.78, SPF_HELO_NONE=0.001, T_SPF_PERMERROR=0.01, UNPARSEABLE_RELAY=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @amazon.com) X-ZM-MESSAGEID: 1772057406989158500 Nitro Enclaves expect the parent instance to host a vsock heartbeat listener at port 9000. To host a Nitro Enclave with the nitro accel in QEMU, add such a heartbeat listener as device model, so that the machine can easily instantiate it. Signed-off-by: Alexander Graf --- v1 -> v2: - Convert to nitro-vsock-device --- hw/nitro/Kconfig | 4 ++ hw/nitro/heartbeat.c | 115 +++++++++++++++++++++++++++++++++++ hw/nitro/meson.build | 1 + hw/nitro/trace-events | 4 ++ include/hw/nitro/heartbeat.h | 24 ++++++++ 5 files changed, 148 insertions(+) create mode 100644 hw/nitro/heartbeat.c create mode 100644 include/hw/nitro/heartbeat.h diff --git a/hw/nitro/Kconfig b/hw/nitro/Kconfig index ce24c09c21..d3fbc7b683 100644 --- a/hw/nitro/Kconfig +++ b/hw/nitro/Kconfig @@ -4,3 +4,7 @@ config NITRO_VSOCK_BUS config NITRO_SERIAL_VSOCK bool depends on NITRO_VSOCK_BUS + +config NITRO_HEARTBEAT + bool + depends on NITRO_VSOCK_BUS diff --git a/hw/nitro/heartbeat.c b/hw/nitro/heartbeat.c new file mode 100644 index 0000000000..dc41323266 --- /dev/null +++ b/hw/nitro/heartbeat.c @@ -0,0 +1,115 @@ +/* + * Nitro Enclave Heartbeat device + * + * Copyright =C2=A9 2026 Amazon.com, Inc. or its affiliates. All Rights Re= served. + * + * Authors: + * Alexander Graf + * + * The Nitro Enclave init process sends a heartbeat byte (0xB7) to + * CID 3 (parent) port 9000 on boot to signal it reached initramfs. + * The parent must accept the connection, read the byte, and echo it + * back. If the enclave init cannot reach the listener, it exits. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "chardev/char.h" +#include "chardev/char-fe.h" +#include "hw/nitro/heartbeat.h" +#include "trace.h" + +#define HEARTBEAT_PORT 9000 +#define VMADDR_CID_ANY_STR "4294967295" + +static int nitro_heartbeat_can_read(void *opaque) +{ + NitroHeartbeatState *s =3D opaque; + + /* One-shot protocol: stop reading after the first heartbeat */ + return s->done ? 0 : 1; +} + +static void nitro_heartbeat_read(void *opaque, const uint8_t *buf, int siz= e) +{ + NitroHeartbeatState *s =3D opaque; + + if (s->done || size < 1) { + return; + } + + /* Echo the heartbeat byte back and disconnect */ + qemu_chr_fe_write_all(&s->vsock, buf, 1); + s->done =3D true; + qemu_chr_fe_deinit(&s->vsock, true); + + trace_nitro_heartbeat_done(); +} + +static void nitro_heartbeat_event(void *opaque, QEMUChrEvent event) +{ + trace_nitro_heartbeat_event(event); +} + +static void nitro_heartbeat_realize(DeviceState *dev, Error **errp) +{ + NitroHeartbeatState *s =3D NITRO_HEARTBEAT(dev); + g_autofree char *chardev_id =3D NULL; + Chardev *chr; + ChardevBackend *backend; + ChardevSocket *sock; + + chardev_id =3D g_strdup_printf("nitro-heartbeat"); + + backend =3D g_new0(ChardevBackend, 1); + backend->type =3D CHARDEV_BACKEND_KIND_SOCKET; + sock =3D backend->u.socket.data =3D g_new0(ChardevSocket, 1); + sock->addr =3D g_new0(SocketAddressLegacy, 1); + sock->addr->type =3D SOCKET_ADDRESS_TYPE_VSOCK; + sock->addr->u.vsock.data =3D g_new0(VsockSocketAddress, 1); + sock->addr->u.vsock.data->cid =3D g_strdup(VMADDR_CID_ANY_STR); + sock->addr->u.vsock.data->port =3D g_strdup_printf("%u", HEARTBEAT_POR= T); + sock->server =3D true; + sock->has_server =3D true; + sock->wait =3D false; + sock->has_wait =3D true; + + chr =3D qemu_chardev_new(chardev_id, TYPE_CHARDEV_SOCKET, + backend, NULL, errp); + if (!chr) { + return; + } + + if (!qemu_chr_fe_init(&s->vsock, chr, errp)) { + return; + } + + qemu_chr_fe_set_handlers(&s->vsock, + nitro_heartbeat_can_read, + nitro_heartbeat_read, + nitro_heartbeat_event, + NULL, s, NULL, true); +} + +static void nitro_heartbeat_class_init(ObjectClass *oc, const void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(oc); + + dc->realize =3D nitro_heartbeat_realize; +} + +static const TypeInfo nitro_heartbeat_info =3D { + .name =3D TYPE_NITRO_HEARTBEAT, + .parent =3D TYPE_NITRO_VSOCK_DEVICE, + .instance_size =3D sizeof(NitroHeartbeatState), + .class_init =3D nitro_heartbeat_class_init, +}; + +static void nitro_heartbeat_register(void) +{ + type_register_static(&nitro_heartbeat_info); +} + +type_init(nitro_heartbeat_register); diff --git a/hw/nitro/meson.build b/hw/nitro/meson.build index 76399d4265..381c1ee6c1 100644 --- a/hw/nitro/meson.build +++ b/hw/nitro/meson.build @@ -1,2 +1,3 @@ system_ss.add(when: 'CONFIG_NITRO_VSOCK_BUS', if_true: files('nitro-vsock-= bus.c')) system_ss.add(when: 'CONFIG_NITRO_SERIAL_VSOCK', if_true: files('serial-vs= ock.c')) +system_ss.add(when: 'CONFIG_NITRO_HEARTBEAT', if_true: files('heartbeat.c'= )) diff --git a/hw/nitro/trace-events b/hw/nitro/trace-events index 20617a024a..311ab78e69 100644 --- a/hw/nitro/trace-events +++ b/hw/nitro/trace-events @@ -2,3 +2,7 @@ =20 # serial-vsock.c nitro_serial_vsock_event(int event) "event %d" + +# heartbeat.c +nitro_heartbeat_event(int event) "event %d" +nitro_heartbeat_done(void) "enclave heartbeat received" diff --git a/include/hw/nitro/heartbeat.h b/include/hw/nitro/heartbeat.h new file mode 100644 index 0000000000..6b9271a47d --- /dev/null +++ b/include/hw/nitro/heartbeat.h @@ -0,0 +1,24 @@ +/* + * Nitro Heartbeat device + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_MISC_NITRO_HEARTBEAT_H +#define HW_MISC_NITRO_HEARTBEAT_H + +#include "hw/nitro/nitro-vsock-bus.h" +#include "chardev/char-fe.h" +#include "qom/object.h" + +#define TYPE_NITRO_HEARTBEAT "nitro-heartbeat" +OBJECT_DECLARE_SIMPLE_TYPE(NitroHeartbeatState, NITRO_HEARTBEAT) + +struct NitroHeartbeatState { + NitroVsockDevice parent_obj; + + CharFrontend vsock; /* vsock server chardev for heartbeat */ + bool done; +}; + +#endif /* HW_MISC_NITRO_HEARTBEAT_H */ --=20 2.47.1 Amazon Web Services Development Center Germany GmbH Tamara-Danz-Str. 13 10243 Berlin Geschaeftsfuehrung: Christof Hellmis, Andreas Stieger Eingetragen am Amtsgericht Charlottenburg unter HRB 257764 B Sitz: Berlin Ust-ID: DE 365 538 597