From nobody Sun Apr 12 04:30:38 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1772441464; cv=none; d=zohomail.com; s=zohoarc; b=MOXLIEmd0Gg4Ni+F3mLMVCl3F6ngq/sPPpemUk9KG2ENg2SiPndqaFva2w1Vt58Cm6bHzUcuSWHdGEDQdntrRayOhOfDodTQTTa8u7fY8PKnIl6BfbM9BxD2q+Pl8a6+3mjLpcTKScqSMzhErVdVFlD5u7trEHR8RDbZAzXVyKY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772441464; 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=hCNjFaHfGWm9J+niU5Zr/XHC0Ap5Ar81+fQxuYcO5Zs=; b=joPvh2EsIcaA5muFG3eWRdgHDtNF7hTzVBML27hi4dWACkFSHaC71F+kWgEAY9VG016/CHNsruZpwJp+EzcSivRr8WRTcQ7Xdt5mOXl+C1yNizqZnQlws9XbBhobhPzX1AloTccuZFbtJtfX1KZmMRwU6SxtNL6YXVuVGgQZCAI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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 1772441464216217.19320845815923; Mon, 2 Mar 2026 00:51:04 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vwyvi-0008IV-6s; Mon, 02 Mar 2026 03:47: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 1vwyup-0005NE-Fw for qemu-devel@nongnu.org; Mon, 02 Mar 2026 03:46:15 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vwyug-0001we-K1 for qemu-devel@nongnu.org; Mon, 02 Mar 2026 03:46:09 -0500 Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-587-t8nX8KSMP8-0TqSQwMG-YQ-1; Mon, 02 Mar 2026 03:45:15 -0500 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-48378c4a79fso35148685e9.0 for ; Mon, 02 Mar 2026 00:45:14 -0800 (PST) Received: from [192.168.10.48] ([151.95.144.138]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-483c3addb3asm334356175e9.0.2026.03.02.00.45.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Mar 2026 00:45:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1772441156; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hCNjFaHfGWm9J+niU5Zr/XHC0Ap5Ar81+fQxuYcO5Zs=; b=UPlTeJpVeggib4QrhqMdL9/t4f1wlZdiyogCb5Xd3UFueWC2PyZ/pHLI662c6+ojcEfOts /dlnVjjwTv7JLYOUrlsDQu8eocOtDEW+1iAVPhu8uhwwJYkVDfoNX2ynbJDF2ZxhK6qVaI FXok2QhU/Ni6EQmXmjoWG5j2NB4zKbg= X-MC-Unique: t8nX8KSMP8-0TqSQwMG-YQ-1 X-Mimecast-MFC-AGG-ID: t8nX8KSMP8-0TqSQwMG-YQ_1772441114 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1772441113; x=1773045913; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=hCNjFaHfGWm9J+niU5Zr/XHC0Ap5Ar81+fQxuYcO5Zs=; b=i8yROFo29/HApAjzV5H7OOZ9qEuUIsRShQjvCNrSBWfaHN1IkkivPa9rD7ih1MyD7H WONfv0FS7SWlc+mT2haSS04psuM6PsKuqQ5mHBwz9Xnr2F1Kte9oYMa5YMVO3o+w+j+q RRggeS/dlPoEIh9Hmgc8ucWsZCf0YDDY2V17j9q4yqP+0FY4Jx2wXmXLiv/q6YvU+iqt 1Zia2CCu9oP/7kW773TvIg2IOPBVx3Yp3cRcnxuBueyVM1UVgv807buJUz+E01ESBSUW kZCvBg6dScCXBDVw+DQGML016w0QUhl+qvqkc7hA2GtyfZlB278025AQlrPh/CxeJPUX jAPg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772441113; x=1773045913; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=hCNjFaHfGWm9J+niU5Zr/XHC0Ap5Ar81+fQxuYcO5Zs=; b=KFxheRxg+NVptrxb7MMRZepXGzh2YnSdDSQ4tlsavbAGsl62eZI7/XkhPSLbVnUC08 JXxIij8BlgR3bXMTHNWL/5CtGvsaxx0Q3DtzmKBffgc5GOiKfzB60lCiHMYgsfDurOnE Ogoyed9yJgkIoDqddMScIRq3ME68Uho2/r31HXTeqdQXloqnfYNzD+nOAkmF0M2Vo6v3 9POAXSLGNYUergH+WTIO+jptGiRdW7R/ihE9u0qnZhUR5U4uhOXqblAdmpCqnNyZERIf ggmGFur4SH+ykG3gjTVT0QuQ15MgnIY+G7g/vRiwmL0Agabf2QWIfqEa4yDcAjjqPim7 MwXQ== X-Gm-Message-State: AOJu0YxnkTnWmapHdCWMMRUSMO5z5oEFl/JaURIV2HMhhU4hsa4Gsoav I1mAlGdHjP/N1L+Kb0FF/+WqlQYQWJ54O1fIh36T6/Ua71BCJMqWcEp3ICq48uNVTKJEnYfSXTs MtuGfXRC13JttHp+wLqrqnV/EGPOwx8Uj/4DXIoWKizN3E+Fi/2mA53O+WWvLm+G0wP4Vpak1ms 3vhczNL/uA6mRcRbzHJ2TU/TWiHY8WThDjZMyd1+Tw X-Gm-Gg: ATEYQzzWga47AdnyYDTwzxHXL1jy1OyseVSTaRR8J81p0Ai1o3riN5sxZVaCJc+4Ye/ +Q7iQhzaw20syWiAdEv/DNRNxUtYItPd5xNHtf04YS4xv1c6K0Rqil8feuTBIktApUtTh6ArvJ7 OeGKNpOkq3KhwhYRZeW5qeNsOuOIhbII1Vk7Xq8jQAj3QbBySCGbqI/Jj7ueFCIZ+lbE3plrVEa Zug/TATfnfVHz29PvTBMr1/G2o0OINq874wyB8F3i03NsmoVKxBBinBIxbrDQ9gj23EfZ4XCN8S +l9weNAAvn+s/LpiR5IfmUPB0mErUxjF5UwNWCjAJpdOkemuVOzMeDlRhTDxYKH8rIleP5b8AUe /fxP7QW8lBvifKZjtUNXXrot6XUy9EpWTFp8X1uSzR9WUjwS6KKNx9ThDuXj3a2gH8t4xSvObaG L7CsemyfoHRFAB3QOM1NFPj1/dBIs= X-Received: by 2002:a05:600c:1909:b0:477:a219:cdb7 with SMTP id 5b1f17b1804b1-483c9b545e0mr218184015e9.0.1772441112403; Mon, 02 Mar 2026 00:45:12 -0800 (PST) X-Received: by 2002:a05:600c:1909:b0:477:a219:cdb7 with SMTP id 5b1f17b1804b1-483c9b545e0mr218183065e9.0.1772441111492; Mon, 02 Mar 2026 00:45:11 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Alexander Graf Subject: [PULL 034/102] accel: Add Nitro Enclaves accelerator Date: Mon, 2 Mar 2026 09:42:29 +0100 Message-ID: <20260302084338.473368-35-pbonzini@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260302084338.473368-1-pbonzini@redhat.com> References: <20260302084338.473368-1-pbonzini@redhat.com> MIME-Version: 1.0 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=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -8 X-Spam_score: -0.9 X-Spam_bar: / X-Spam_report: (-0.9 / 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, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.012, RCVD_IN_VALIDITY_RPBL_BLOCKED=1.188, SPF_HELO_PASS=-0.001, SPF_PASS=-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 @redhat.com) X-ZM-MESSAGEID: 1772441465344158500 From: Alexander Graf Nitro Enclaves are a confidential compute technology which allows a parent instance to carve out resources from itself and spawn a confidential sibling VM next to itself. Similar to other confidential compute solutions, this sibling is controlled by an underlying vmm, but still has a higher level vmm (QEMU) to implement some of its I/O functionality and lifecycle. Add an accelerator to drive this interface. In combination with follow-on patches to enhance the Nitro Enclaves machine model, this will allow users to run a Nitro Enclave using QEMU. Signed-off-by: Alexander Graf Link: https://lore.kernel.org/r/20260225220807.33092-5-graf@amazon.com Signed-off-by: Paolo Bonzini --- MAINTAINERS | 6 + meson.build | 12 ++ accel/nitro/trace.h | 2 + include/system/hw_accel.h | 1 + include/system/nitro-accel.h | 25 +++ accel/nitro/nitro-accel.c | 284 ++++++++++++++++++++++++++++++++++ accel/stubs/nitro-stub.c | 11 ++ accel/Kconfig | 3 + accel/meson.build | 1 + accel/nitro/meson.build | 3 + accel/nitro/trace-events | 6 + accel/stubs/meson.build | 1 + meson_options.txt | 2 + qemu-options.hx | 8 +- scripts/meson-buildoptions.sh | 3 + 15 files changed, 364 insertions(+), 4 deletions(-) create mode 100644 accel/nitro/trace.h create mode 100644 include/system/nitro-accel.h create mode 100644 accel/nitro/nitro-accel.c create mode 100644 accel/stubs/nitro-stub.c create mode 100644 accel/nitro/meson.build create mode 100644 accel/nitro/trace-events diff --git a/MAINTAINERS b/MAINTAINERS index d781fe59bb1..0458980d434 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -586,6 +586,12 @@ F: include/system/mshv.h F: include/hw/hyperv/hvgdk*.h F: include/hw/hyperv/hvhdk*.h =20 +Nitro Enclaves (native) +M: Alexander Graf +S: Maintained +F: accel/nitro/ +F: include/system/nitro-accel.h + X86 MSHV CPUs M: Magnus Kulke R: Wei Liu diff --git a/meson.build b/meson.build index f3ee08772d4..cbd6d90ce64 100644 --- a/meson.build +++ b/meson.build @@ -302,11 +302,13 @@ accelerator_targets +=3D { 'CONFIG_XEN': xen_targets } if cpu =3D=3D 'aarch64' accelerator_targets +=3D { 'CONFIG_HVF': ['aarch64-softmmu'], + 'CONFIG_NITRO': ['aarch64-softmmu'], 'CONFIG_WHPX': ['aarch64-softmmu'] } elif cpu =3D=3D 'x86_64' accelerator_targets +=3D { 'CONFIG_HVF': ['x86_64-softmmu'], + 'CONFIG_NITRO': ['x86_64-softmmu'], 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'], 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'], 'CONFIG_MSHV': ['x86_64-softmmu'], @@ -880,6 +882,11 @@ if get_option('hvf').allowed() endif endif =20 +nitro =3D not_found +if get_option('nitro').allowed() and host_os =3D=3D 'linux' + accelerators +=3D 'CONFIG_NITRO' +endif + nvmm =3D not_found if host_os =3D=3D 'netbsd' nvmm =3D cc.find_library('nvmm', required: get_option('nvmm')) @@ -921,6 +928,9 @@ endif if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled() error('HVF not available on this platform') endif +if 'CONFIG_NITRO' not in accelerators and get_option('nitro').enabled() + error('NITRO not available on this platform') +endif if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled() error('NVMM not available on this platform') endif @@ -3590,6 +3600,7 @@ if have_system 'accel/hvf', 'accel/kvm', 'accel/mshv', + 'accel/nitro', 'audio', 'backends', 'backends/tpm', @@ -4789,6 +4800,7 @@ endif summary_info =3D {} if have_system summary_info +=3D {'KVM support': config_all_accel.has_key('CONFIG= _KVM')} + summary_info +=3D {'Nitro support': config_all_accel.has_key('CONFIG= _NITRO')} summary_info +=3D {'HVF support': config_all_accel.has_key('CONFIG= _HVF')} summary_info +=3D {'WHPX support': config_all_accel.has_key('CONFIG= _WHPX')} summary_info +=3D {'NVMM support': config_all_accel.has_key('CONFIG= _NVMM')} diff --git a/accel/nitro/trace.h b/accel/nitro/trace.h new file mode 100644 index 00000000000..8c5564725dc --- /dev/null +++ b/accel/nitro/trace.h @@ -0,0 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "trace/trace-accel_nitro.h" diff --git a/include/system/hw_accel.h b/include/system/hw_accel.h index 628a50e066e..f0c10b6d805 100644 --- a/include/system/hw_accel.h +++ b/include/system/hw_accel.h @@ -17,6 +17,7 @@ #include "system/mshv.h" #include "system/whpx.h" #include "system/nvmm.h" +#include "system/nitro-accel.h" =20 /** * cpu_synchronize_state: diff --git a/include/system/nitro-accel.h b/include/system/nitro-accel.h new file mode 100644 index 00000000000..a93aa6fb00d --- /dev/null +++ b/include/system/nitro-accel.h @@ -0,0 +1,25 @@ +/* + * Nitro Enclaves accelerator - public interface + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef SYSTEM_NITRO_ACCEL_H +#define SYSTEM_NITRO_ACCEL_H + +#include "qemu/accel.h" + +extern bool nitro_allowed; + +static inline bool nitro_enabled(void) +{ + return nitro_allowed; +} + +#define TYPE_NITRO_ACCEL ACCEL_CLASS_NAME("nitro") + +typedef struct NitroAccelState NitroAccelState; +DECLARE_INSTANCE_CHECKER(NitroAccelState, NITRO_ACCEL, + TYPE_NITRO_ACCEL) + +#endif /* SYSTEM_NITRO_ACCEL_H */ diff --git a/accel/nitro/nitro-accel.c b/accel/nitro/nitro-accel.c new file mode 100644 index 00000000000..a1e97a9162e --- /dev/null +++ b/accel/nitro/nitro-accel.c @@ -0,0 +1,284 @@ +/* + * Nitro Enclaves accelerator + * + * Copyright =C2=A9 2026 Amazon.com, Inc. or its affiliates. All Rights Re= served. + * + * Authors: + * Alexander Graf + * + * Nitro Enclaves are a confidential compute technology which + * allows a parent instance to carve out resources from itself + * and spawn a confidential sibling VM next to itself. Similar + * to other confidential compute solutions, this sibling is + * controlled by an underlying vmm, but still has a higher level + * vmm (QEMU) to implement some of its I/O functionality and + * lifecycle. + * + * This accelerator drives /dev/nitro_enclaves to spawn a Nitro + * Enclave. It works in tandem with the nitro_enclaves machine + * which ensures the correct backend devices are available and + * that the initial seed (an EIF file) is loaded at the correct + * offset in memory. + * + * The accel starts the enclave when the machine starts, after + * all device setup is finished. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/error-report.h" +#include "qapi/error.h" +#include "qapi/visitor.h" +#include "qemu/module.h" +#include "qemu/rcu.h" +#include "qemu/accel.h" +#include "qemu/guest-random.h" +#include "qemu/main-loop.h" +#include "accel/accel-ops.h" +#include "accel/accel-cpu-ops.h" +#include "accel/dummy-cpus.h" +#include "system/cpus.h" +#include "hw/core/cpu.h" +#include "hw/core/boards.h" +#include "hw/nitro/nitro-vsock-bus.h" +#include "system/ramblock.h" +#include "system/nitro-accel.h" +#include "trace.h" + +#include +#include "standard-headers/linux/nitro_enclaves.h" + +bool nitro_allowed; + +typedef struct NitroAccelState { + AccelState parent_obj; + + int ne_fd; + int enclave_fd; + uint64_t slot_uid; + uint64_t enclave_cid; + bool debug_mode; +} NitroAccelState; + +static int nitro_init_machine(AccelState *as, MachineState *ms) +{ + NitroAccelState *s =3D NITRO_ACCEL(as); + uint64_t slot_uid =3D 0; + int ret; + + s->ne_fd =3D open("/dev/nitro_enclaves", O_RDWR | O_CLOEXEC); + if (s->ne_fd < 0) { + error_report("nitro: failed to open /dev/nitro_enclaves: %s", + strerror(errno)); + return -errno; + } + + ret =3D ioctl(s->ne_fd, NE_CREATE_VM, &slot_uid); + if (ret < 0) { + error_report("nitro: NE_CREATE_VM failed: %s", strerror(errno)); + close(s->ne_fd); + return -errno; + } + s->enclave_fd =3D ret; + s->slot_uid =3D slot_uid; + + return 0; +} + +static int nitro_donate_ram_block(RAMBlock *rb, void *opaque) +{ + NitroAccelState *s =3D opaque; + struct ne_user_memory_region region =3D { + .flags =3D 0, + .memory_size =3D rb->used_length, + .userspace_addr =3D (uint64_t)(uintptr_t)rb->host, + }; + + if (!rb->used_length) { + return 0; + } + + if (ioctl(s->enclave_fd, NE_SET_USER_MEMORY_REGION, ®ion) < 0) { + error_report("nitro: NE_SET_USER_MEMORY_REGION failed for %s " + "(%" PRIu64 " bytes): %s", rb->idstr, rb->used_length, + strerror(errno)); + return -errno; + } + return 0; +} + +/* + * Start the Enclave. At this point memory is set up and the EIF is loaded. + * This function donates memory, adds vCPUs, and starts the enclave. + */ +static void nitro_setup_post(AccelState *as) +{ + MachineState *ms =3D MACHINE(qdev_get_machine()); + NitroAccelState *s =3D NITRO_ACCEL(as); + int nr_cpus =3D ms->smp.cpus; + int i, ret; + struct ne_enclave_start_info start_info =3D { + .flags =3D s->debug_mode ? NE_ENCLAVE_DEBUG_MODE : 0, + .enclave_cid =3D s->enclave_cid, + }; + + ret =3D qemu_ram_foreach_block(nitro_donate_ram_block, s); + if (ret < 0) { + error_report("nitro: failed to donate memory"); + exit(1); + } + + for (i =3D 0; i < nr_cpus; i++) { + uint32_t cpu_id =3D 0; + if (ioctl(s->enclave_fd, NE_ADD_VCPU, &cpu_id) < 0) { + error_report("nitro: NE_ADD_VCPU failed: %s", strerror(errno)); + exit(1); + } + } + + ret =3D ioctl(s->enclave_fd, NE_START_ENCLAVE, &start_info); + if (ret < 0) { + switch (errno) { + case NE_ERR_NO_MEM_REGIONS_ADDED: + error_report("nitro: no memory regions added"); + break; + case NE_ERR_NO_VCPUS_ADDED: + error_report("nitro: no vCPUs added"); + break; + case NE_ERR_ENCLAVE_MEM_MIN_SIZE: + error_report("nitro: memory is below the minimum " + "required size. Try increasing -m"); + break; + case NE_ERR_FULL_CORES_NOT_USED: + error_report("nitro: requires full CPU cores. " + "Try increasing -smp to a multiple of threads " + "per core on this host (e.g. -smp 2)"); + break; + case NE_ERR_NOT_IN_INIT_STATE: + error_report("nitro: not in init state"); + break; + case NE_ERR_INVALID_FLAG_VALUE: + error_report("nitro: invalid flag value for NE_START_ENCLAVE"); + break; + case NE_ERR_INVALID_ENCLAVE_CID: + error_report("nitro: invalid enclave CID"); + break; + default: + error_report("nitro: NE_START_ENCLAVE failed: %s (errno %d)", + strerror(errno), errno); + break; + } + exit(1); + } + + s->enclave_cid =3D start_info.enclave_cid; + trace_nitro_enclave_started(s->enclave_cid); + + /* + * Notify all Nitro vsock bus devices that the enclave has started + * and provide them with the CID for vsock connections. + */ + { + NitroVsockBridge *bridge =3D nitro_vsock_bridge_find(); + Error *err =3D NULL; + + if (bridge) { + nitro_vsock_bridge_start_enclave(bridge, + (uint32_t)s->enclave_cid, &er= r); + if (err) { + error_report_err(err); + exit(1); + } + } + } +} + +/* QOM properties */ + +static bool nitro_get_debug_mode(Object *obj, Error **errp) +{ + return NITRO_ACCEL(obj)->debug_mode; +} + +static void nitro_set_debug_mode(Object *obj, bool value, Error **errp) +{ + NITRO_ACCEL(obj)->debug_mode =3D value; +} + +static void nitro_get_enclave_cid(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + uint64_t val =3D NITRO_ACCEL(obj)->enclave_cid; + visit_type_uint64(v, name, &val, errp); +} + +static void nitro_set_enclave_cid(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + uint64_t val; + if (visit_type_uint64(v, name, &val, errp)) { + NITRO_ACCEL(obj)->enclave_cid =3D val; + } +} + +static void nitro_accel_class_init(ObjectClass *oc, const void *data) +{ + AccelClass *ac =3D ACCEL_CLASS(oc); + ac->name =3D "Nitro"; + ac->init_machine =3D nitro_init_machine; + ac->setup_post =3D nitro_setup_post; + ac->allowed =3D &nitro_allowed; + + object_class_property_add_bool(oc, "debug-mode", + nitro_get_debug_mode, + nitro_set_debug_mode); + object_class_property_set_description(oc, "debug-mode", + "Start enclave in debug mode (enables console output)"); + + object_class_property_add(oc, "enclave-cid", "uint64", + nitro_get_enclave_cid, + nitro_set_enclave_cid, + NULL, NULL); + object_class_property_set_description(oc, "enclave-cid", + "Enclave CID (0 =3D auto-assigned by Nitro)"); +} + +static const TypeInfo nitro_accel_type =3D { + .name =3D TYPE_NITRO_ACCEL, + .parent =3D TYPE_ACCEL, + .instance_size =3D sizeof(NitroAccelState), + .class_init =3D nitro_accel_class_init, +}; +module_obj(TYPE_NITRO_ACCEL); + +static bool nitro_cpus_are_resettable(void) +{ + return false; +} + +static void nitro_accel_ops_class_init(ObjectClass *oc, const void *data) +{ + AccelOpsClass *ops =3D ACCEL_OPS_CLASS(oc); + ops->create_vcpu_thread =3D dummy_start_vcpu_thread; + ops->handle_interrupt =3D generic_handle_interrupt; + ops->cpus_are_resettable =3D nitro_cpus_are_resettable; +} + +static const TypeInfo nitro_accel_ops_type =3D { + .name =3D ACCEL_OPS_NAME("nitro"), + .parent =3D TYPE_ACCEL_OPS, + .class_init =3D nitro_accel_ops_class_init, + .abstract =3D true, +}; +module_obj(ACCEL_OPS_NAME("nitro")); + +static void nitro_type_init(void) +{ + type_register_static(&nitro_accel_type); + type_register_static(&nitro_accel_ops_type); +} + +type_init(nitro_type_init); diff --git a/accel/stubs/nitro-stub.c b/accel/stubs/nitro-stub.c new file mode 100644 index 00000000000..186c8444f86 --- /dev/null +++ b/accel/stubs/nitro-stub.c @@ -0,0 +1,11 @@ +/* + * Nitro accel stubs for QEMU + * + * Copyright =C2=A9 2026 Amazon.com, Inc. or its affiliates. All Rights Re= served. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" + +bool nitro_allowed; diff --git a/accel/Kconfig b/accel/Kconfig index a60f1149238..6d052875ee2 100644 --- a/accel/Kconfig +++ b/accel/Kconfig @@ -16,6 +16,9 @@ config KVM config MSHV bool =20 +config NITRO + bool + config XEN bool select FSDEV_9P if VIRTFS diff --git a/accel/meson.build b/accel/meson.build index 289b7420ffa..7da12b9741f 100644 --- a/accel/meson.build +++ b/accel/meson.build @@ -12,6 +12,7 @@ if have_system subdir('xen') subdir('stubs') subdir('mshv') + subdir('nitro') endif =20 # qtest diff --git a/accel/nitro/meson.build b/accel/nitro/meson.build new file mode 100644 index 00000000000..e01c1bab96d --- /dev/null +++ b/accel/nitro/meson.build @@ -0,0 +1,3 @@ +nitro_ss =3D ss.source_set() +nitro_ss.add(files('nitro-accel.c')) +system_ss.add_all(when: 'CONFIG_NITRO', if_true: nitro_ss) diff --git a/accel/nitro/trace-events b/accel/nitro/trace-events new file mode 100644 index 00000000000..9673eb5aa22 --- /dev/null +++ b/accel/nitro/trace-events @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# See docs/devel/tracing.rst for syntax documentation. + +# nitro-accel.c +nitro_enclave_started(uint64_t cid) "nitro: enclave started, CID=3D%"PRIu64 diff --git a/accel/stubs/meson.build b/accel/stubs/meson.build index 48eccd1b861..5de4a279ff9 100644 --- a/accel/stubs/meson.build +++ b/accel/stubs/meson.build @@ -3,6 +3,7 @@ system_stubs_ss.add(when: 'CONFIG_XEN', if_false: files('xe= n-stub.c')) system_stubs_ss.add(when: 'CONFIG_KVM', if_false: files('kvm-stub.c')) system_stubs_ss.add(when: 'CONFIG_TCG', if_false: files('tcg-stub.c')) system_stubs_ss.add(when: 'CONFIG_HVF', if_false: files('hvf-stub.c')) +system_stubs_ss.add(when: 'CONFIG_NITRO', if_false: files('nitro-stub.c')) system_stubs_ss.add(when: 'CONFIG_NVMM', if_false: files('nvmm-stub.c')) system_stubs_ss.add(when: 'CONFIG_WHPX', if_false: files('whpx-stub.c')) system_stubs_ss.add(when: 'CONFIG_MSHV', if_false: files('mshv-stub.c')) diff --git a/meson_options.txt b/meson_options.txt index 2836156257a..31d5916cfce 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -79,6 +79,8 @@ option('whpx', type: 'feature', value: 'auto', description: 'WHPX acceleration support') option('hvf', type: 'feature', value: 'auto', description: 'HVF acceleration support') +option('nitro', type: 'feature', value: 'auto', + description: 'Nitro acceleration support') option('nvmm', type: 'feature', value: 'auto', description: 'NVMM acceleration support') option('xen', type: 'feature', value: 'auto', diff --git a/qemu-options.hx b/qemu-options.hx index 4043e8ca22b..0da2b4d0348 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -28,7 +28,7 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \ "-machine [type=3D]name[,prop[=3Dvalue][,...]]\n" " selects emulated machine ('-machine help' for list)\n" " property accel=3Daccel1[:accel2[:...]] selects accele= rator\n" - " supported accelerators are kvm, xen, hvf, nvmm, whpx,= mshv or tcg (default: tcg)\n" + " supported accelerators are kvm, xen, hvf, nitro, nvmm= , whpx, mshv or tcg (default: tcg)\n" " vmport=3Don|off|auto controls emulation of vmport (de= fault: auto)\n" " dump-guest-core=3Don|off include guest memory in a co= re dump (default=3Don)\n" " mem-merge=3Don|off controls memory merge support (def= ault: on)\n" @@ -67,7 +67,7 @@ SRST =20 ``accel=3Daccels1[:accels2[:...]]`` This is used to enable an accelerator. Depending on the target - architecture, kvm, xen, hvf, nvmm, whpx, mshv or tcg can be + architecture, kvm, xen, hvf, nitro, nvmm, whpx, mshv or tcg can be available. By default, tcg is used. If there is more than one accelerator specified, the next one is used if the previous one fails to initialize. @@ -228,7 +228,7 @@ ERST =20 DEF("accel", HAS_ARG, QEMU_OPTION_accel, "-accel [accel=3D]accelerator[,prop[=3Dvalue][,...]]\n" - " select accelerator (kvm, xen, hvf, nvmm, whpx, mshv o= r tcg; use 'help' for a list)\n" + " select accelerator (kvm, xen, hvf, nitro, nvmm, whpx,= mshv or tcg; use 'help' for a list)\n" " igd-passthru=3Don|off (enable Xen integrated Intel gr= aphics passthrough, default=3Doff)\n" " kernel-irqchip=3Don|off|split controls accelerated ir= qchip support (default=3Don)\n" " kvm-shadow-mem=3Dsize of KVM shadow MMU in bytes\n" @@ -243,7 +243,7 @@ DEF("accel", HAS_ARG, QEMU_OPTION_accel, SRST ``-accel name[,prop=3Dvalue[,...]]`` This is used to enable an accelerator. Depending on the target - architecture, kvm, xen, hvf, nvmm, whpx, mshv or tcg can be available. + architecture, kvm, xen, hvf, nitro, nvmm, whpx, mshv or tcg can be ava= ilable. By default, tcg is used. If there is more than one accelerator specified, the next one is used if the previous one fails to initialize. diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh index e8edc5252a3..ca5b113119a 100644 --- a/scripts/meson-buildoptions.sh +++ b/scripts/meson-buildoptions.sh @@ -158,6 +158,7 @@ meson_options_help() { printf "%s\n" ' multiprocess Out of process device emulation support' printf "%s\n" ' netmap netmap network backend support' printf "%s\n" ' nettle nettle cryptography support' + printf "%s\n" ' nitro Nitro acceleration support' printf "%s\n" ' numa libnuma support' printf "%s\n" ' nvmm NVMM acceleration support' printf "%s\n" ' opengl OpenGL support' @@ -418,6 +419,8 @@ _meson_option_parse() { --disable-netmap) printf "%s" -Dnetmap=3Ddisabled ;; --enable-nettle) printf "%s" -Dnettle=3Denabled ;; --disable-nettle) printf "%s" -Dnettle=3Ddisabled ;; + --enable-nitro) printf "%s" -Dnitro=3Denabled ;; + --disable-nitro) printf "%s" -Dnitro=3Ddisabled ;; --enable-numa) printf "%s" -Dnuma=3Denabled ;; --disable-numa) printf "%s" -Dnuma=3Ddisabled ;; --enable-nvmm) printf "%s" -Dnvmm=3Denabled ;; --=20 2.53.0