From nobody Sun Apr 12 06:07:42 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=1771379606; cv=none; d=zohomail.com; s=zohoarc; b=gLmEFLYWEcWq5SpIUAtmoLBENNu39Ouz/uDscK2Bdb/cDXqbAY50sauWbYSqK+x80CehIZRIOvM3YLpz+RdHl1Y1irU1I+4ZjFpADTiJrZPUauBfxx09uC9j32jTjB+1p6a4tfqB0UkllfyNGwJU8lin3D4W7V5GfGuJSpd7vgw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771379606; 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=bEUY4fw2pSBs47CRXjbvno7ZwAwzhf7d45scl3+ZioI=; b=d4DDYZR5gh4Akf/77g5MMseO55LHG8gAzkicGfcKAjfr05DBLCOh/FJrBwJt7FrIhhXLEb88Zjo5l2nhWWafz5kMhV0nVvr48je9tqxBKg95EFEH1y57AZo0N6Fgl2avMewrWqPBvziShYp4DPpecJAnFs7vd+vWKsE7YJ1oSDs= 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 1771379606973178.47416916885834; Tue, 17 Feb 2026 17:53:26 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vsWkU-00086Y-Bs; Tue, 17 Feb 2026 20:53:06 -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 1vsWkS-0007ul-Js; Tue, 17 Feb 2026 20:53:04 -0500 Received: from pdx-out-007.esa.us-west-2.outbound.mail-perimeter.amazon.com ([52.34.181.151]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vsWkQ-0005Mh-I5; Tue, 17 Feb 2026 20:53:04 -0500 Received: from ip-10-5-9-48.us-west-2.compute.internal (HELO smtpout.naws.us-west-2.prod.farcaster.email.amazon.dev) ([10.5.9.48]) by internal-pdx-out-007.esa.us-west-2.outbound.mail-perimeter.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Feb 2026 01:52:58 +0000 Received: from EX19MTAUWC002.ant.amazon.com [205.251.233.111:29963] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.0.130:2525] with esmtp (Farcaster) id 20c66c80-36cd-4714-b2e8-62c87725b16d; Wed, 18 Feb 2026 01:52:57 +0000 (UTC) Received: from EX19D020UWC004.ant.amazon.com (10.13.138.149) by EX19MTAUWC002.ant.amazon.com (10.250.64.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.2562.35; Wed, 18 Feb 2026 01:52:56 +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.35; Wed, 18 Feb 2026 01:52:54 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.com; i=@amazon.com; q=dns/txt; s=amazoncorp2; t=1771379582; x=1802915582; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=bEUY4fw2pSBs47CRXjbvno7ZwAwzhf7d45scl3+ZioI=; b=V5r6/x8qRlH+cNlK5Wi1AOfRe/jo8qYfnK8R50lFbXstY8dlSv2s8cE4 D2PZuzTBIUB30uLS7KzElDXgdbdRyPQfzdmSBlcfiV+Lcpk09XW12ZPwB epH00C0vqGgx9cBTx8+OuRjCC7O/eorfmfDAXNtNxpBaC/5U6zQiBTnmO YFA177qairFWP0qqES4CK5Dn2NjB/38a5BY7b69kvfzy9uSVh5Yj48TpM yxHVbliDSvirUYxl6w34jHE+GsBjJzGrZLk6+P5nDgfLencZ6N1u4Z2E1 OZLriWcZGgGw2YjtuM8MpRa0EDQEA32iyKL4YPOqi3/5f0a7eLrR3bBr8 w==; X-CSE-ConnectionGUID: tIGKpSJZTUiaxq8SDuCVQA== X-CSE-MsgGUID: W5/WHuQ6RLugrgeBCmUOlg== X-IronPort-AV: E=Sophos;i="6.21,297,1763424000"; d="scan'208";a="13256458" X-Farcaster-Flow-ID: 20c66c80-36cd-4714-b2e8-62c87725b16d From: Alexander Graf To: CC: , Peter Maydell , "Thomas Huth" , , , , , Cornelia Huck , , Dorjoy Chowdhury , Pierrick Bouvier , Paolo Bonzini , Tyler Fanelli , , Subject: [PATCH 07/10] hw/nitro: Add nitro machine Date: Wed, 18 Feb 2026 01:51:47 +0000 Message-ID: <20260218015151.4052-8-graf@amazon.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20260218015151.4052-1-graf@amazon.com> References: <20260218015151.4052-1-graf@amazon.com> MIME-Version: 1.0 X-Originating-IP: [172.19.99.218] X-ClientProxiedBy: EX19D032UWA001.ant.amazon.com (10.13.139.62) 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=52.34.181.151; envelope-from=prvs=502105d20=graf@amazon.de; helo=pdx-out-007.esa.us-west-2.outbound.mail-perimeter.amazon.com X-Spam_score_int: -19 X-Spam_score: -2.0 X-Spam_bar: -- X-Spam_report: (-2.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, T_SPF_PERMERROR=0.01, UNPARSEABLE_RELAY=0.001 autolearn=ham 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: 1771379610677154100 Add a machine model to spawn a Nitro Enclave. Unlike the existing -M nitro-enclave, this machine model works exclusively with the -accel nitro accelerator to drive real Nitro Enclave creation. It supports memory allocation, number of CPU selection, both x86_64 as well as aarch64, implements the Enclave heartbeat logic and debug serial console. To use it, create an EIF file and run $ qemu-system-x86_64 -accel nitro,debug-mode=3Don -M nitro -nographic \ -kernel test.eif or $ qemu-system-aarch64 -accel nitro,debug-mode=3Don -M nitro -nographic \ -kernel test.eif Signed-off-by: Alexander Graf --- hw/nitro/Kconfig | 7 ++ hw/nitro/machine.c | 180 +++++++++++++++++++++++++++++++++++++ hw/nitro/meson.build | 1 + include/hw/nitro/machine.h | 20 +++++ 4 files changed, 208 insertions(+) create mode 100644 hw/nitro/machine.c create mode 100644 include/hw/nitro/machine.h diff --git a/hw/nitro/Kconfig b/hw/nitro/Kconfig index 6fe050d35d..910068c23c 100644 --- a/hw/nitro/Kconfig +++ b/hw/nitro/Kconfig @@ -5,3 +5,10 @@ config NITRO_SERIAL_VSOCK config NITRO_HEARTBEAT bool depends on NITRO + +config NITRO_MACHINE + bool + default y + depends on NITRO + select NITRO_HEARTBEAT + select NITRO_SERIAL_VSOCK diff --git a/hw/nitro/machine.c b/hw/nitro/machine.c new file mode 100644 index 0000000000..197adfbdb5 --- /dev/null +++ b/hw/nitro/machine.c @@ -0,0 +1,180 @@ +/* + * Nitro Enclaves (accel) machine + * + * Copyright =C2=A9 2026 Amazon.com, Inc. or its affiliates. All Rights Re= served. + * + * Authors: + * Alexander Graf + * + * Nitro Enclaves machine model for -accel nitro. This machine behaves + * like the nitro-enclave machine, but uses the real Nitro Enclaves + * backend to launch the virtual machine. It requires use of the -accel + * nitro. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/error-report.h" +#include "qapi/error.h" +#include "qom/object_interfaces.h" +#include "chardev/char.h" +#include "hw/core/boards.h" +#include "hw/core/cpu.h" +#include "hw/core/sysbus.h" +#include "hw/core/qdev-properties-system.h" +#include "hw/nitro/heartbeat.h" +#include "hw/nitro/machine.h" +#include "hw/nitro/serial-vsock.h" +#include "system/address-spaces.h" +#include "system/hostmem.h" +#include "system/system.h" +#include "system/nitro-accel.h" +#include "qemu/accel.h" +#include "hw/arm/machines-qom.h" + +#define EIF_LOAD_ADDR (8 * 1024 * 1024) + +static void nitro_create_cpu(const char *cpu_type, int index) +{ + Object *obj =3D object_new(cpu_type); + + /* x86 CPUs require an apic-id before realize */ + if (object_property_find(obj, "apic-id")) { + object_property_set_int(obj, "apic-id", index, &error_fatal); + } + + qdev_realize(DEVICE(obj), NULL, &error_fatal); +} + +static void nitro_machine_init(MachineState *machine) +{ + const char *eif_path =3D machine->kernel_filename; + const char *cpu_type =3D machine->cpu_type; + g_autofree char *eif_data =3D NULL; + gsize eif_size; + int i; + + if (!nitro_enabled()) { + error_report("The 'nitro' machine requires -accel nitro"); + exit(1); + } + + if (!cpu_type) { + ObjectClass *oc =3D cpu_class_by_name(target_cpu_type(), "host"); + + if (!oc) { + error_report("nitro: no 'host' CPU available"); + exit(1); + } + cpu_type =3D object_class_get_name(oc); + } + + if (!eif_path) { + error_report("nitro: -kernel is required"); + exit(1); + } + + /* Expose memory as normal QEMU RAM. Needs to be huge page backed. */ + memory_region_add_subregion(get_system_memory(), 0, machine->ram); + + /* + * Load EIF (-kernel) as raw blob at the EIF_LOAD_ADDR into guest RAM. + * The Nitro Hypervisor will extract its contents and bootstrap the + * Enclave from it. + */ + if (!g_file_get_contents(eif_path, &eif_data, &eif_size, NULL)) { + error_report("nitro: failed to read EIF '%s'", eif_path); + exit(1); + } + address_space_write(&address_space_memory, EIF_LOAD_ADDR, + MEMTXATTRS_UNSPECIFIED, eif_data, eif_size); + + /* Nitro Enclaves require a heartbeat device. Provide one. */ + sysbus_realize_and_unref(SYS_BUS_DEVICE(qdev_new(TYPE_NITRO_HEARTBEAT)= ), + &error_fatal); + + /* + * In debug mode, Nitro Enclaves expose the guest's serial output via + * vsock. When the accel is in debug mode, wire the vsock serial to + * the machine's serial port so that -nographic automatically works + */ + if (object_property_get_bool(OBJECT(current_accel()), "debug-mode", NU= LL)) { + Chardev *chr =3D serial_hd(0); + + if (chr) { + DeviceState *dev =3D qdev_new(TYPE_NITRO_SERIAL_VSOCK); + + qdev_prop_set_chr(dev, "chardev", chr); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + } + } + + /* + * Spawn vCPUs. While the real Nitro Enclaves CPUs are owned by the + * underlying hypervisor, we still want to maintain a local view of + * them to trigger VM creation when vCPU 0 starts and to give us an + * object to interact with. + */ + for (i =3D 0; i < machine->smp.cpus; i++) { + nitro_create_cpu(cpu_type, i); + } +} + +static bool nitro_create_memfd_backend(MachineState *ms, const char *path, + Error **errp) +{ + MachineClass *mc =3D MACHINE_GET_CLASS(ms); + Object *root =3D object_get_objects_root(); + Object *obj; + bool r =3D false; + + obj =3D object_new(TYPE_MEMORY_BACKEND_MEMFD); + + /* Nitro Enclaves require huge page backing */ + if (!object_property_set_int(obj, "size", ms->ram_size, errp) || + !object_property_set_bool(obj, "hugetlb", true, errp)) { + goto out; + } + + object_property_add_child(root, mc->default_ram_id, obj); + + if (!user_creatable_complete(USER_CREATABLE(obj), errp)) { + goto out; + } + r =3D object_property_set_link(OBJECT(ms), "memory-backend", obj, errp= ); + +out: + object_unref(obj); + return r; +} + +static void nitro_machine_class_init(ObjectClass *oc, const void *data) +{ + MachineClass *mc =3D MACHINE_CLASS(oc); + + mc->desc =3D "Nitro Enclave"; + mc->init =3D nitro_machine_init; + mc->create_default_memdev =3D nitro_create_memfd_backend; + mc->default_ram_id =3D "ram"; + mc->max_cpus =3D 4096; +} + +static const TypeInfo nitro_machine_info =3D { + .name =3D TYPE_NITRO_MACHINE, + .parent =3D TYPE_MACHINE, + .instance_size =3D sizeof(NitroMachineState), + .class_init =3D nitro_machine_class_init, + .interfaces =3D (const InterfaceInfo[]) { + /* x86_64 and aarch64 only */ + { TYPE_TARGET_AARCH64_MACHINE }, + { } + }, +}; + +static void nitro_machine_register(void) +{ + type_register_static(&nitro_machine_info); +} + +type_init(nitro_machine_register); diff --git a/hw/nitro/meson.build b/hw/nitro/meson.build index b921da2b97..813f5a9c87 100644 --- a/hw/nitro/meson.build +++ b/hw/nitro/meson.build @@ -1,2 +1,3 @@ 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'= )) +system_ss.add(when: 'CONFIG_NITRO_MACHINE', if_true: files('machine.c')) diff --git a/include/hw/nitro/machine.h b/include/hw/nitro/machine.h new file mode 100644 index 0000000000..d78ba7d6dc --- /dev/null +++ b/include/hw/nitro/machine.h @@ -0,0 +1,20 @@ +/* + * Nitro Enclaves (accel) machine + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_NITRO_MACHINE_H +#define HW_NITRO_MACHINE_H + +#include "hw/core/boards.h" +#include "qom/object.h" + +#define TYPE_NITRO_MACHINE MACHINE_TYPE_NAME("nitro") +OBJECT_DECLARE_SIMPLE_TYPE(NitroMachineState, NITRO_MACHINE) + +struct NitroMachineState { + MachineState parent; +}; + +#endif /* HW_NITRO_MACHINE_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