From nobody Sun Apr 12 04:35:59 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=1771379574; cv=none; d=zohomail.com; s=zohoarc; b=QWtJ3Gy2sKgfteoNzToubkYMGfywk9PEGGvdBog5dPRo46+NRlTmTA6v9AjDNXYnhuSIYCIRdp85Jjv8BtunPQhP0F6Gq6xuJfArThtuDsYKG1AmXxWEj1v9GY06LErvE3XPjwVPNo98x1M2d119qUG4+LLvji5vRmw0fhRf1YI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771379574; 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=KCela8AQkLSev7ljQRFJIF4piqXcUABB/3Y09CBj+Qw=; b=NyvG6gCP3c2cF0auVimsFaEw6Y747mc/mv0A16669RC144t5oZCIqvrGJHJlVlUsy+bf5NnOmHsx6+VRmQ/OOkiXMQ9+oN9NFCKDggL8Umi+za7iCSvS7D4xS554EM2RhXl113rPT3Tef1NqEIVKYW6fZJciTvFGvh/D8OZk3Gg= 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 1771379574369450.53313485988053; Tue, 17 Feb 2026 17:52:54 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vsWjd-00078S-PE; Tue, 17 Feb 2026 20:52:14 -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 1vsWjX-00077C-Ue; Tue, 17 Feb 2026 20:52:07 -0500 Received: from pdx-out-008.esa.us-west-2.outbound.mail-perimeter.amazon.com ([52.42.203.116]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vsWjW-0004Yc-FK; Tue, 17 Feb 2026 20:52:07 -0500 Received: from ip-10-5-6-203.us-west-2.compute.internal (HELO smtpout.naws.us-west-2.prod.farcaster.email.amazon.dev) ([10.5.6.203]) by internal-pdx-out-008.esa.us-west-2.outbound.mail-perimeter.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Feb 2026 01:52:01 +0000 Received: from EX19MTAUWC002.ant.amazon.com [205.251.233.111:17239] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.31.172:2525] with esmtp (Farcaster) id ebc48b88-5297-4f9a-b24c-93ae3726705f; Wed, 18 Feb 2026 01:52:01 +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:51:58 +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:51:55 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.com; i=@amazon.com; q=dns/txt; s=amazoncorp2; t=1771379526; x=1802915526; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=KCela8AQkLSev7ljQRFJIF4piqXcUABB/3Y09CBj+Qw=; b=qI06WgzAD05VvYOYBy9QkwEwpCnXtbprIPupK7LPMBJ98LYoU4I2Ur5/ 1ouba5pW00TFDDJOIEs5GnnZAT8ne0tgjQrCP6B/V+3KxXQq3efq3a2/f Yg1PlbYi/ldxkcUSVtyUNjinpCpvMNV0i+UsbocpTQ4KZj195rlzC2akc DOL49o9DIhbgitqPN5glDeM/rWKIj3UdPJxJLEa9L+BH7ig33RPdvmbDp F4vx03LF/3LMjrnou5IkGJtQaq6aHclrjCj3LfMQrF3Y8hIx0V1SnE6n7 SrTcXsjPsyQiSNmNaOoKU7J/TLqbTAahfr87yuKeBt8jqQDRDxvD0OiY8 w==; X-CSE-ConnectionGUID: aaDjGUVHTKCa6ysA55d1Zg== X-CSE-MsgGUID: dRogNnXWTeW1NoHKtcgtag== X-IronPort-AV: E=Sophos;i="6.21,297,1763424000"; d="scan'208";a="13254036" X-Farcaster-Flow-ID: ebc48b88-5297-4f9a-b24c-93ae3726705f From: Alexander Graf To: CC: , Peter Maydell , "Thomas Huth" , , , , , Cornelia Huck , , Dorjoy Chowdhury , Pierrick Bouvier , Paolo Bonzini , Tyler Fanelli , , Subject: [PATCH 01/10] scripts/update-linux-headers: Add Nitro Enclaves header Date: Wed, 18 Feb 2026 01:51:41 +0000 Message-ID: <20260218015151.4052-2-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: EX19D046UWA001.ant.amazon.com (10.13.139.112) To EX19D020UWC004.ant.amazon.com (10.13.138.149) 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.42.203.116; envelope-from=prvs=502105d20=graf@amazon.de; helo=pdx-out-008.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: 1771379576138158500 Content-Type: text/plain; charset="utf-8" We want to enable QEMU to drive the /dev/nitro_enclaves device node. Add its UAPI header into our kernel sync so we have all defines we need to drive it. Signed-off-by: Alexander Graf --- scripts/update-linux-headers.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers= .sh index d09d8cf4c6..386d7a38e7 100755 --- a/scripts/update-linux-headers.sh +++ b/scripts/update-linux-headers.sh @@ -254,6 +254,7 @@ for i in "$hdrdir"/include/linux/*virtio*.h \ "$hdrdir/include/linux/kvm_para.h" \ "$hdrdir/include/linux/vhost_types.h" \ "$hdrdir/include/linux/vmclock-abi.h" \ + "$hdrdir/include/linux/nitro_enclaves.h" \ "$hdrdir/include/linux/sysinfo.h"; do cp_portable "$i" "$output/include/standard-headers/linux" done --=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 From nobody Sun Apr 12 04:35:59 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=1771379612; cv=none; d=zohomail.com; s=zohoarc; b=eIvIhGUBvZh4F94Q9EEWW/NrfJ+W1a4FoQFoGyOLUcHZz3rNBl82OrFw9kf/uchb9zOVOUla7cGOijePi8ULOSpDOXUGy8xB0asCBX/TkHLra3fM2hHulnomXeAFanwCNzqicfaDqv0NFaEQ3ArK4x24hyNx+gcKkmhs8dTxPGc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771379612; 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=yGwpH6mNXADUzH7l283Vcqo8pTgMS9qPjwIVA1ZPJ58=; b=M+cPT01d0b2dAz2SNERpblghppPhyP5VJPWqT6cVELd6V23PB6FumhEDxnFHAnNNbhMEAgb2CLd1Fw5G6s0Bk4kCmsvMHyFn0mUtEA62LNjYJVHmAarcfl0Bq7q/q4igiiLVkKESIEPc9TFg9TTCe6k6A1UytYOwObgUkbuTJbY= 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 1771379612170882.5255523448328; Tue, 17 Feb 2026 17:53:32 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vsWjk-0007Aj-Dl; Tue, 17 Feb 2026 20:52:20 -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 1vsWjY-00077l-TN; Tue, 17 Feb 2026 20:52:10 -0500 Received: from pdx-out-005.esa.us-west-2.outbound.mail-perimeter.amazon.com ([52.13.214.179]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vsWjW-0004Yi-Da; Tue, 17 Feb 2026 20:52:08 -0500 Received: from ip-10-5-0-115.us-west-2.compute.internal (HELO smtpout.naws.us-west-2.prod.farcaster.email.amazon.dev) ([10.5.0.115]) by internal-pdx-out-005.esa.us-west-2.outbound.mail-perimeter.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Feb 2026 01:52:01 +0000 Received: from EX19MTAUWA001.ant.amazon.com [205.251.233.182:1796] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.14.39:2525] with esmtp (Farcaster) id 5097c958-82f7-4ad6-b0fd-8686e47214c8; Wed, 18 Feb 2026 01:52:01 +0000 (UTC) Received: from EX19D020UWC004.ant.amazon.com (10.13.138.149) by EX19MTAUWA001.ant.amazon.com (10.250.64.204) 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:00 +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:51:58 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.com; i=@amazon.com; q=dns/txt; s=amazoncorp2; t=1771379526; x=1802915526; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=yGwpH6mNXADUzH7l283Vcqo8pTgMS9qPjwIVA1ZPJ58=; b=HGNKdO3IhkUHGD8WlAcm16esybqRAf13/jjrGHFY7JxI6PJYQ772bxRO Vuph6zyvj2FPBrdF5C+6Tzfus44kS2c/7Rjy8EA0EFHaMpHEJv/QeO5WP 5yXQe9yvfWMDlNLTChO/YW9/GsyatdDH87OmMP2NOoV+cBfkVgWs51c3I A5Ft5YpMghAah7qI7fuGi1VoP/2/XaiCt+AqeCOM/GF+7QpeO5cOxO6LF RkwaMLAKVuAUcA6TmDiwNKq7mCdXNBkP6k4eYtCJdGRyr3ZFJKP7t7XM4 2OGjmNrXOkzUrK51lVqFAhD+whs/4rQewAazfAaU5i9xSRG/hQh1GCOza g==; X-CSE-ConnectionGUID: RNK+XsRQT1iCEso/DI0gHA== X-CSE-MsgGUID: NS7BQMwZS5GwenlipWFxpQ== X-IronPort-AV: E=Sophos;i="6.21,297,1763424000"; d="scan'208";a="13261378" X-Farcaster-Flow-ID: 5097c958-82f7-4ad6-b0fd-8686e47214c8 From: Alexander Graf To: CC: , Peter Maydell , "Thomas Huth" , , , , , Cornelia Huck , , Dorjoy Chowdhury , Pierrick Bouvier , Paolo Bonzini , Tyler Fanelli , , Subject: [PATCH 02/10] linux-headers: Add nitro_enclaves.h Date: Wed, 18 Feb 2026 01:51:42 +0000 Message-ID: <20260218015151.4052-3-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: EX19D046UWA001.ant.amazon.com (10.13.139.112) To EX19D020UWC004.ant.amazon.com (10.13.138.149) 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.13.214.179; envelope-from=prvs=502105d20=graf@amazon.de; helo=pdx-out-005.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: 1771379614468154100 Content-Type: text/plain; charset="utf-8" QEMU is learning to drive the /dev/nitro_enclaves device node. Include its UAPI header into our local copy of kernel headers so it has all defines we need to drive it. Signed-off-by: Alexander Graf --- .../standard-headers/linux/nitro_enclaves.h | 359 ++++++++++++++++++ 1 file changed, 359 insertions(+) create mode 100644 include/standard-headers/linux/nitro_enclaves.h diff --git a/include/standard-headers/linux/nitro_enclaves.h b/include/stan= dard-headers/linux/nitro_enclaves.h new file mode 100644 index 0000000000..5545267dd9 --- /dev/null +++ b/include/standard-headers/linux/nitro_enclaves.h @@ -0,0 +1,359 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * Copyright 2020-2021 Amazon.com, Inc. or its affiliates. All Rights Rese= rved. + */ + +#ifndef _LINUX_NITRO_ENCLAVES_H_ +#define _LINUX_NITRO_ENCLAVES_H_ + +#include "standard-headers/linux/types.h" + +/** + * DOC: Nitro Enclaves (NE) Kernel Driver Interface + */ + +/** + * NE_CREATE_VM - The command is used to create a slot that is associated = with + * an enclave VM. + * The generated unique slot id is an output parameter. + * The ioctl can be invoked on the /dev/nitro_enclaves fd, before + * setting any resources, such as memory and vCPUs, for an + * enclave. Memory and vCPUs are set for the slot mapped to an enclave. + * A NE CPU pool has to be set before calling this function. The + * pool can be set after the NE driver load, using + * /sys/module/nitro_enclaves/parameters/ne_cpus. + * Its format is the detailed in the cpu-lists section: + * https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters= .html + * CPU 0 and its siblings have to remain available for the + * primary / parent VM, so they cannot be set for enclaves. Full + * CPU core(s), from the same NUMA node, need(s) to be included + * in the CPU pool. + * + * Context: Process context. + * Return: + * * Enclave file descriptor - Enclave file descriptor used with + * ioctl calls to set vCPUs and memory + * regions, then start the enclave. + * * -1 - There was a failure in the ioctl logic. + * On failure, errno is set to: + * * EFAULT - copy_to_user() failure. + * * ENOMEM - Memory allocation failure for internal + * bookkeeping variables. + * * NE_ERR_NO_CPUS_AVAIL_IN_POOL - No NE CPU pool set / no CPUs available + * in the pool. + * * Error codes from get_unused_fd_flags() and anon_inode_getfile(). + * * Error codes from the NE PCI device request. + */ +#define NE_CREATE_VM _IOR(0xAE, 0x20, uint64_t) + +/** + * NE_ADD_VCPU - The command is used to set a vCPU for an enclave. The vCP= U can + * be auto-chosen from the NE CPU pool or it can be set by the + * caller, with the note that it needs to be available in the NE + * CPU pool. Full CPU core(s), from the same NUMA node, need(s) to + * be associated with an enclave. + * The vCPU id is an input / output parameter. If its value is 0, + * then a CPU is chosen from the enclave CPU pool and returned via + * this parameter. + * The ioctl can be invoked on the enclave fd, before an enclave + * is started. + * + * Context: Process context. + * Return: + * * 0 - Logic successfully completed. + * * -1 - There was a failure in the ioctl logic. + * On failure, errno is set to: + * * EFAULT - copy_from_user() / copy_to_user() failure. + * * ENOMEM - Memory allocation failure for internal + * bookkeeping variables. + * * EIO - Current task mm is not the same as the one + * that created the enclave. + * * NE_ERR_NO_CPUS_AVAIL_IN_POOL - No CPUs available in the NE CPU pool. + * * NE_ERR_VCPU_ALREADY_USED - The provided vCPU is already used. + * * NE_ERR_VCPU_NOT_IN_CPU_POOL - The provided vCPU is not available in t= he + * NE CPU pool. + * * NE_ERR_VCPU_INVALID_CPU_CORE - The core id of the provided vCPU is in= valid + * or out of range. + * * NE_ERR_NOT_IN_INIT_STATE - The enclave is not in init state + * (init =3D before being started). + * * NE_ERR_INVALID_VCPU - The provided vCPU is not in the available + * CPUs range. + * * Error codes from the NE PCI device request. + */ +#define NE_ADD_VCPU _IOWR(0xAE, 0x21, uint32_t) + +/** + * NE_GET_IMAGE_LOAD_INFO - The command is used to get information needed = for + * in-memory enclave image loading e.g. offset in + * enclave memory to start placing the enclave image. + * The image load info is an input / output parameter. + * It includes info provided by the caller - flags - + * and returns the offset in enclave memory where to + * start placing the enclave image. + * The ioctl can be invoked on the enclave fd, before + * an enclave is started. + * + * Context: Process context. + * Return: + * * 0 - Logic successfully completed. + * * -1 - There was a failure in the ioctl logic. + * On failure, errno is set to: + * * EFAULT - copy_from_user() / copy_to_user() failure. + * * NE_ERR_NOT_IN_INIT_STATE - The enclave is not in init state (init =3D + * before being started). + * * NE_ERR_INVALID_FLAG_VALUE - The value of the provided flag is invalid. + */ +#define NE_GET_IMAGE_LOAD_INFO _IOWR(0xAE, 0x22, struct ne_image_load_inf= o) + +/** + * NE_SET_USER_MEMORY_REGION - The command is used to set a memory region = for an + * enclave, given the allocated memory from the + * userspace. Enclave memory needs to be from the + * same NUMA node as the enclave CPUs. + * The user memory region is an input parameter. It + * includes info provided by the caller - flags, + * memory size and userspace address. + * The ioctl can be invoked on the enclave fd, + * before an enclave is started. + * + * Context: Process context. + * Return: + * * 0 - Logic successfully completed. + * * -1 - There was a failure in the ioctl logic. + * On failure, errno is set to: + * * EFAULT - copy_from_user() failure. + * * EINVAL - Invalid physical memory region(s) e.g. + * unaligned address. + * * EIO - Current task mm is not the same as + * the one that created the enclave. + * * ENOMEM - Memory allocation failure for internal + * bookkeeping variables. + * * NE_ERR_NOT_IN_INIT_STATE - The enclave is not in init state + * (init =3D before being started). + * * NE_ERR_INVALID_MEM_REGION_SIZE - The memory size of the region is not + * multiple of 2 MiB. + * * NE_ERR_INVALID_MEM_REGION_ADDR - Invalid user space address given. + * * NE_ERR_UNALIGNED_MEM_REGION_ADDR - Unaligned user space address given. + * * NE_ERR_MEM_REGION_ALREADY_USED - The memory region is already used. + * * NE_ERR_MEM_NOT_HUGE_PAGE - The memory region is not backed by + * huge pages. + * * NE_ERR_MEM_DIFFERENT_NUMA_NODE - The memory region is not from the sa= me + * NUMA node as the CPUs. + * * NE_ERR_MEM_MAX_REGIONS - The number of memory regions set for + * the enclave reached maximum. + * * NE_ERR_INVALID_PAGE_SIZE - The memory region is not backed by + * pages multiple of 2 MiB. + * * NE_ERR_INVALID_FLAG_VALUE - The value of the provided flag is invali= d. + * * Error codes from get_user_pages(). + * * Error codes from the NE PCI device request. + */ +#define NE_SET_USER_MEMORY_REGION _IOW(0xAE, 0x23, struct ne_user_memory_r= egion) + +/** + * NE_START_ENCLAVE - The command is used to trigger enclave start after t= he + * enclave resources, such as memory and CPU, have been set. + * The enclave start info is an input / output parameter. It + * includes info provided by the caller - enclave cid and + * flags - and returns the cid (if input cid is 0). + * The ioctl can be invoked on the enclave fd, after an + * enclave slot is created and resources, such as memory and + * vCPUs are set for an enclave. + * + * Context: Process context. + * Return: + * * 0 - Logic successfully completed. + * * -1 - There was a failure in the ioctl logic. + * On failure, errno is set to: + * * EFAULT - copy_from_user() / copy_to_user() failure. + * * NE_ERR_NOT_IN_INIT_STATE - The enclave is not in init state + * (init =3D before being started). + * * NE_ERR_NO_MEM_REGIONS_ADDED - No memory regions are set. + * * NE_ERR_NO_VCPUS_ADDED - No vCPUs are set. + * * NE_ERR_FULL_CORES_NOT_USED - Full core(s) not set for the enclave. + * * NE_ERR_ENCLAVE_MEM_MIN_SIZE - Enclave memory is less than minimum + * memory size (64 MiB). + * * NE_ERR_INVALID_FLAG_VALUE - The value of the provided flag is invali= d. + * * NE_ERR_INVALID_ENCLAVE_CID - The provided enclave CID is invalid. + * * Error codes from the NE PCI device request. + */ +#define NE_START_ENCLAVE _IOWR(0xAE, 0x24, struct ne_enclave_start_info) + +/** + * DOC: NE specific error codes + */ + +/** + * NE_ERR_VCPU_ALREADY_USED - The provided vCPU is already used. + */ +#define NE_ERR_VCPU_ALREADY_USED (256) +/** + * NE_ERR_VCPU_NOT_IN_CPU_POOL - The provided vCPU is not available in the + * NE CPU pool. + */ +#define NE_ERR_VCPU_NOT_IN_CPU_POOL (257) +/** + * NE_ERR_VCPU_INVALID_CPU_CORE - The core id of the provided vCPU is inva= lid + * or out of range of the NE CPU pool. + */ +#define NE_ERR_VCPU_INVALID_CPU_CORE (258) +/** + * NE_ERR_INVALID_MEM_REGION_SIZE - The user space memory region size is n= ot + * multiple of 2 MiB. + */ +#define NE_ERR_INVALID_MEM_REGION_SIZE (259) +/** + * NE_ERR_INVALID_MEM_REGION_ADDR - The user space memory region address r= ange + * is invalid. + */ +#define NE_ERR_INVALID_MEM_REGION_ADDR (260) +/** + * NE_ERR_UNALIGNED_MEM_REGION_ADDR - The user space memory region address= is + * not aligned. + */ +#define NE_ERR_UNALIGNED_MEM_REGION_ADDR (261) +/** + * NE_ERR_MEM_REGION_ALREADY_USED - The user space memory region is alread= y used. + */ +#define NE_ERR_MEM_REGION_ALREADY_USED (262) +/** + * NE_ERR_MEM_NOT_HUGE_PAGE - The user space memory region is not backed by + * contiguous physical huge page(s). + */ +#define NE_ERR_MEM_NOT_HUGE_PAGE (263) +/** + * NE_ERR_MEM_DIFFERENT_NUMA_NODE - The user space memory region is backed= by + * pages from different NUMA nodes than the CPUs. + */ +#define NE_ERR_MEM_DIFFERENT_NUMA_NODE (264) +/** + * NE_ERR_MEM_MAX_REGIONS - The supported max memory regions per enclaves = has + * been reached. + */ +#define NE_ERR_MEM_MAX_REGIONS (265) +/** + * NE_ERR_NO_MEM_REGIONS_ADDED - The command to start an enclave is trigge= red + * and no memory regions are added. + */ +#define NE_ERR_NO_MEM_REGIONS_ADDED (266) +/** + * NE_ERR_NO_VCPUS_ADDED - The command to start an enclave is triggered an= d no + * vCPUs are added. + */ +#define NE_ERR_NO_VCPUS_ADDED (267) +/** + * NE_ERR_ENCLAVE_MEM_MIN_SIZE - The enclave memory size is lower than the + * minimum supported. + */ +#define NE_ERR_ENCLAVE_MEM_MIN_SIZE (268) +/** + * NE_ERR_FULL_CORES_NOT_USED - The command to start an enclave is trigger= ed and + * full CPU cores are not set. + */ +#define NE_ERR_FULL_CORES_NOT_USED (269) +/** + * NE_ERR_NOT_IN_INIT_STATE - The enclave is not in init state when setting + * resources or triggering start. + */ +#define NE_ERR_NOT_IN_INIT_STATE (270) +/** + * NE_ERR_INVALID_VCPU - The provided vCPU is out of range of the availabl= e CPUs. + */ +#define NE_ERR_INVALID_VCPU (271) +/** + * NE_ERR_NO_CPUS_AVAIL_IN_POOL - The command to create an enclave is trig= gered + * and no CPUs are available in the pool. + */ +#define NE_ERR_NO_CPUS_AVAIL_IN_POOL (272) +/** + * NE_ERR_INVALID_PAGE_SIZE - The user space memory region is not backed b= y pages + * multiple of 2 MiB. + */ +#define NE_ERR_INVALID_PAGE_SIZE (273) +/** + * NE_ERR_INVALID_FLAG_VALUE - The provided flag value is invalid. + */ +#define NE_ERR_INVALID_FLAG_VALUE (274) +/** + * NE_ERR_INVALID_ENCLAVE_CID - The provided enclave CID is invalid, either + * being a well-known value or the CID of the + * parent / primary VM. + */ +#define NE_ERR_INVALID_ENCLAVE_CID (275) + +/** + * DOC: Image load info flags + */ + +/** + * NE_EIF_IMAGE - Enclave Image Format (EIF) + */ +#define NE_EIF_IMAGE (0x01) + +#define NE_IMAGE_LOAD_MAX_FLAG_VAL (0x02) + +/** + * struct ne_image_load_info - Info necessary for in-memory enclave image + * loading (in / out). + * @flags: Flags to determine the enclave image type + * (e.g. Enclave Image Format - EIF) (in). + * @memory_offset: Offset in enclave memory where to start placing the + * enclave image (out). + */ +struct ne_image_load_info { + uint64_t flags; + uint64_t memory_offset; +}; + +/** + * DOC: User memory region flags + */ + +/** + * NE_DEFAULT_MEMORY_REGION - Memory region for enclave general usage. + */ +#define NE_DEFAULT_MEMORY_REGION (0x00) + +#define NE_MEMORY_REGION_MAX_FLAG_VAL (0x01) + +/** + * struct ne_user_memory_region - Memory region to be set for an enclave (= in). + * @flags: Flags to determine the usage for the memory region (in). + * @memory_size: The size, in bytes, of the memory region to be set for + * an enclave (in). + * @userspace_addr: The start address of the userspace allocated memory of + * the memory region to set for an enclave (in). + */ +struct ne_user_memory_region { + uint64_t flags; + uint64_t memory_size; + uint64_t userspace_addr; +}; + +/** + * DOC: Enclave start info flags + */ + +/** + * NE_ENCLAVE_PRODUCTION_MODE - Start enclave in production mode. + */ +#define NE_ENCLAVE_PRODUCTION_MODE (0x00) +/** + * NE_ENCLAVE_DEBUG_MODE - Start enclave in debug mode. + */ +#define NE_ENCLAVE_DEBUG_MODE (0x01) + +#define NE_ENCLAVE_START_MAX_FLAG_VAL (0x02) + +/** + * struct ne_enclave_start_info - Setup info necessary for enclave start (= in / out). + * @flags: Flags for the enclave to start with (e.g. debug mode) (in). + * @enclave_cid: Context ID (CID) for the enclave vsock device. If 0 as + * input, the CID is autogenerated by the hypervisor and + * returned back as output by the driver (in / out). + */ +struct ne_enclave_start_info { + uint64_t flags; + uint64_t enclave_cid; +}; + +#endif /* _LINUX_NITRO_ENCLAVES_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 From nobody Sun Apr 12 04:35:59 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=1771379647; cv=none; d=zohomail.com; s=zohoarc; b=MJPRRrG1eHDwuecwoxvi+eAWL8fAfcob1A7Gsu9IpHxGE3KSF+ufqvOi/V0owU4jw0xuoGH3UuUlU8BsSS5Zv0mqLiJZFj21h/qfDvA7+Yhvh+uqC5l4AZo7z7z6qBgziR1D6aXoXB06gmuvoLi3xq7sKu4ExhgzVvvVqMvoGM8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771379647; 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=QNgMYQG55uLndwuZXf+YFr1Fjz5BDXtiyzmiHn4qOg4=; b=BhLiBGM42GsgwIXMIISGPjjmTXNIOfU/i5GEsa0snVo8udPuyTPaA4EUFE8aRb9Aus7/kJOoWNvVZjeouXz0ejIUpJgMncuGXAZ5yDNM8n8AAFl1uHhPR0eL45noKhE5pfjSqhVAb4iyAHAYpBoJKp0DwH/w284SJvq6AqQBeO0= 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 1771379647028454.7612910100087; Tue, 17 Feb 2026 17:54:07 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vsWjy-0007CQ-02; Tue, 17 Feb 2026 20:52:34 -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 1vsWjv-0007Bz-DA; Tue, 17 Feb 2026 20:52:31 -0500 Received: from pdx-out-005.esa.us-west-2.outbound.mail-perimeter.amazon.com ([52.13.214.179]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vsWjs-0005F9-4A; Tue, 17 Feb 2026 20:52:31 -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-005.esa.us-west-2.outbound.mail-perimeter.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Feb 2026 01:52:26 +0000 Received: from EX19MTAUWC001.ant.amazon.com [205.251.233.105:6549] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.55.107:2525] with esmtp (Farcaster) id 5b767f59-cd1d-4935-9b4e-fd445c0e6f0b; Wed, 18 Feb 2026 01:52:25 +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.35; Wed, 18 Feb 2026 01:52:25 +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:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.com; i=@amazon.com; q=dns/txt; s=amazoncorp2; t=1771379548; x=1802915548; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=QNgMYQG55uLndwuZXf+YFr1Fjz5BDXtiyzmiHn4qOg4=; b=AWGLGh93EZAcbI71/YqFlkb1dmvjde+4ByKJ019GVaIJVaIt1JjsOBVF WewjQaSeh8tJM8RQESgfnNpJCIzPnI25BZcpVP0vYfgT35upShChhvryt PGQNKzbVOgTC/njh6hc/sVVOgaxSK/Spa9kSJudQwqOouL7XxFCFpr/ud 1X417bRHGhBQPmLSXk+udyMJht9SSquFD0ZyafMGtMpSkgLC9hqnfi1qx J+gUCRyASLUj1xXqOFnXVirRMY4Q6hNyDqmNBioyDWfPjq/Qv/OMVAPlE 1OVoqkXxIdAshJYnThgqst91c12N2o9is5/1icdedBYjeESm257YQiaaB A==; X-CSE-ConnectionGUID: TexyZQ3/Qwmk3xMtDLGaJg== X-CSE-MsgGUID: SZJ2Hq4CSYufZky05Y/AbA== X-IronPort-AV: E=Sophos;i="6.21,297,1763424000"; d="scan'208";a="13261392" X-Farcaster-Flow-ID: 5b767f59-cd1d-4935-9b4e-fd445c0e6f0b From: Alexander Graf To: CC: , Peter Maydell , "Thomas Huth" , , , , , Cornelia Huck , , Dorjoy Chowdhury , Pierrick Bouvier , Paolo Bonzini , Tyler Fanelli , , Subject: [PATCH 03/10] accel: Add Nitro Enclaves accelerator Date: Wed, 18 Feb 2026 01:51:43 +0000 Message-ID: <20260218015151.4052-4-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: EX19D043UWC001.ant.amazon.com (10.13.139.202) 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.13.214.179; envelope-from=prvs=502105d20=graf@amazon.de; helo=pdx-out-005.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: 1771379649034154100 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 --- MAINTAINERS | 6 + accel/Kconfig | 3 + accel/meson.build | 1 + accel/nitro/meson.build | 3 + accel/nitro/nitro-accel.c | 333 ++++++++++++++++++++++++++++++++++ accel/nitro/trace-events | 6 + accel/nitro/trace.h | 2 + accel/stubs/meson.build | 1 + accel/stubs/nitro-stub.c | 11 ++ include/system/hw_accel.h | 1 + include/system/nitro-accel.h | 25 +++ meson.build | 11 ++ meson_options.txt | 2 + qemu-options.hx | 8 +- scripts/meson-buildoptions.sh | 3 + 15 files changed, 412 insertions(+), 4 deletions(-) create mode 100644 accel/nitro/meson.build create mode 100644 accel/nitro/nitro-accel.c create mode 100644 accel/nitro/trace-events create mode 100644 accel/nitro/trace.h create mode 100644 accel/stubs/nitro-stub.c create mode 100644 include/system/nitro-accel.h diff --git a/MAINTAINERS b/MAINTAINERS index d3aa6d6732..3d002143ae 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -583,6 +583,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/accel/Kconfig b/accel/Kconfig index a60f114923..6d052875ee 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 289b7420ff..7da12b9741 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 0000000000..e01c1bab96 --- /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/nitro-accel.c b/accel/nitro/nitro-accel.c new file mode 100644 index 0000000000..bea76fcd0b --- /dev/null +++ b/accel/nitro/nitro-accel.c @@ -0,0 +1,333 @@ +/* + * 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 on first vCPU 0 main loop entry, + * to ensure that all device setup is finished and that we have + * a working vCPU loop. + * + * 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 "system/cpus.h" +#include "hw/core/cpu.h" +#include "hw/core/boards.h" +#include "hw/core/sysbus.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. This gets called when the first vCPU 0 enters its ma= in + * loop. At this point memory is set up and the EIF is loaded. This functi= on + * donates memory, adds vCPUs, and starts the enclave. + */ +static void nitro_do_start(NitroAccelState *s) +{ + MachineState *ms =3D MACHINE(qdev_get_machine()); + 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); + + /* + * Push enclave CID to all devices that need it. + * Each device handles its own connection (console, heartbeat). + */ + { + BusState *sysbus =3D sysbus_get_default(); + BusChild *kid; + + QTAILQ_FOREACH(kid, &sysbus->children, sibling) { + DeviceState *dev =3D kid->child; + if (object_property_find(OBJECT(dev), "enclave-cid")) { + object_property_set_uint(OBJECT(dev), "enclave-cid", + s->enclave_cid, NULL); + } + } + } +} + +/* + * vCPU dummy thread function. The real vCPUs run inside the enclave. + * + * Based on dummy_cpu_thread_fn() from accel/dummy-cpus.c. + */ +static void *nitro_vcpu_thread_fn(void *arg) +{ + CPUState *cpu =3D arg; + NitroAccelState *s =3D NITRO_ACCEL(current_accel()); + sigset_t waitset; + + rcu_register_thread(); + + bql_lock(); + qemu_thread_get_self(cpu->thread); + cpu->thread_id =3D qemu_get_thread_id(); + current_cpu =3D cpu; + + sigemptyset(&waitset); + sigaddset(&waitset, SIG_IPI); + + cpu_thread_signal_created(cpu); + qemu_guest_random_seed_thread_part2(cpu->random_seed); + + /* vCPU 0 starts the enclave on first entry */ + if (cpu->cpu_index =3D=3D 0) { + nitro_do_start(s); + } + + do { + qemu_process_cpu_events(cpu); + bql_unlock(); + { + int sig; + while (sigwait(&waitset, &sig) =3D=3D -1 && + (errno =3D=3D EAGAIN || errno =3D=3D EINTR)) { + /* retry */ + } + } + bql_lock(); + } while (!cpu->unplug); + + bql_unlock(); + rcu_unregister_thread(); + return NULL; +} + +static void nitro_start_vcpu_thread(CPUState *cpu) +{ + char thread_name[VCPU_THREAD_NAME_SIZE]; + + snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/Nitro", + cpu->cpu_index); + qemu_thread_create(cpu->thread, thread_name, nitro_vcpu_thread_fn, + cpu, QEMU_THREAD_JOINABLE); +} + +/* 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->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 void nitro_accel_ops_class_init(ObjectClass *oc, const void *data) +{ + AccelOpsClass *ops =3D ACCEL_OPS_CLASS(oc); + ops->create_vcpu_thread =3D nitro_start_vcpu_thread; + ops->handle_interrupt =3D generic_handle_interrupt; +} + +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/nitro/trace-events b/accel/nitro/trace-events new file mode 100644 index 0000000000..9673eb5aa2 --- /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/nitro/trace.h b/accel/nitro/trace.h new file mode 100644 index 0000000000..8c5564725d --- /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/accel/stubs/meson.build b/accel/stubs/meson.build index 48eccd1b86..5de4a279ff 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/accel/stubs/nitro-stub.c b/accel/stubs/nitro-stub.c new file mode 100644 index 0000000000..186c8444f8 --- /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/include/system/hw_accel.h b/include/system/hw_accel.h index 628a50e066..f0c10b6d80 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 0000000000..a93aa6fb00 --- /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/meson.build b/meson.build index 4af32c3e1f..bdeee65db2 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'], @@ -881,6 +883,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')) @@ -922,6 +929,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 @@ -3593,6 +3603,7 @@ if have_system 'accel/hvf', 'accel/kvm', 'accel/mshv', + 'accel/nitro', 'audio', 'backends', 'backends/tpm', diff --git a/meson_options.txt b/meson_options.txt index 2836156257..31d5916cfc 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 33fcfe7ce6..9b6fb247f7 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 e8edc5252a..ca5b113119 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.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 From nobody Sun Apr 12 04:35:59 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=1771379634; cv=none; d=zohomail.com; s=zohoarc; b=M1Av9SQ6xMGXSbH0on6Q5jVyXbg1nV9sF4IT8Pg/O/NLNN9Brr4NY+TCJRS4rlywvtnO/FwhTELqLoxXwJU8fO0tRsGXqWXXGoVvq9SAfv07iH64r/pgZHPBaZl7LDCQHYcWAYVJ6l63XkQRCzVqsrJyt1i6H9JrhQVjF0mDds4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771379634; 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=QVGSh6QomGasFEgLBMFo/YmaboU2VJXN/YN9VZOxI5s=; b=J/tNyVP8YzOK7GTvpdWwvwzu4CHx9CjMyxXz4aRtqZfSWdd1SHujnCrWjNjYNPW/jXoHcqayax1HampWFHXWnWHW4luqigjZ9ws9J0F9NVv2mWeZ3NofjeFe3omqKQG4ywDmKPWP7ktetPjOgkCvMjYnr5aJ8HqM4M5QxFreOoQ= 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 177137963447746.0234111304336; Tue, 17 Feb 2026 17:53:54 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vsWk0-0007E8-KP; Tue, 17 Feb 2026 20:52:36 -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 1vsWjy-0007D5-Kq; Tue, 17 Feb 2026 20:52:34 -0500 Received: from pdx-out-010.esa.us-west-2.outbound.mail-perimeter.amazon.com ([52.12.53.23]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vsWjw-0005GB-Hi; Tue, 17 Feb 2026 20:52:34 -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-010.esa.us-west-2.outbound.mail-perimeter.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Feb 2026 01:52:28 +0000 Received: from EX19MTAUWB002.ant.amazon.com [205.251.233.48:31640] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.55.107:2525] with esmtp (Farcaster) id 415e14a0-c25f-4b68-92fd-684b081b5a96; Wed, 18 Feb 2026 01:52:27 +0000 (UTC) Received: from EX19D020UWC004.ant.amazon.com (10.13.138.149) by EX19MTAUWB002.ant.amazon.com (10.250.64.231) 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:27 +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:25 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.com; i=@amazon.com; q=dns/txt; s=amazoncorp2; t=1771379552; x=1802915552; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=QVGSh6QomGasFEgLBMFo/YmaboU2VJXN/YN9VZOxI5s=; b=k/Pu82E8T0hox3JXGYDfA+5rmYDpwh5d2MS0Dr+v13eY35PMAJpZNzMi 0q3jDu69pBei5LrXEiwJu4vrIE+d2UOjMcvUsQSlFlGGgmffED4MYFT9h hCtvlS+EZkNEfv0JP75sA3iUOR65ZTGth3lzf17qO+QDsh01K8i/6rEMV JYkaBpXKUOU7TDQMWCafrpg5LjP4I5ag13Y+y42iNMnvMki77sfnOX87U /QPFZYTIAsJEq5SepFwtB3Vva7wR7sMSLGuUBQboQi2f1vOIsBUZ3JT+K qxm5Pa0fPeGVVzypOQ3EwDXpuMOHzFRo/joTS7tN4yvMOROCZu9wzayrn w==; X-CSE-ConnectionGUID: JaUHGOg3QVKPhJFJtHZSHw== X-CSE-MsgGUID: atKWgTiwTpKoGKsb9VXQbg== X-IronPort-AV: E=Sophos;i="6.21,297,1763424000"; d="scan'208";a="13134030" X-Farcaster-Flow-ID: 415e14a0-c25f-4b68-92fd-684b081b5a96 From: Alexander Graf To: CC: , Peter Maydell , "Thomas Huth" , , , , , Cornelia Huck , , Dorjoy Chowdhury , Pierrick Bouvier , Paolo Bonzini , Tyler Fanelli , , Subject: [PATCH 04/10] hw/nitro/nitro-serial-vsock: Nitro Enclaves vsock console Date: Wed, 18 Feb 2026 01:51:44 +0000 Message-ID: <20260218015151.4052-5-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: EX19D043UWC001.ant.amazon.com (10.13.139.202) 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.12.53.23; envelope-from=prvs=502105d20=graf@amazon.de; helo=pdx-out-010.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: 1771379635860158500 Nitro Enclaves support a special "debug" mode. When in debug mode, the Nitro Hypervisor provides a vsock port that the parent can connect to to receive serial console output of the Enclave. Add a new nitro-serial-vsock driver that implements short-circuit logic to establish the vsock connection to that port and feed its data into a chardev, so that a machine model can use it as serial device. Signed-off-by: Alexander Graf --- MAINTAINERS | 6 ++ hw/Kconfig | 1 + hw/meson.build | 1 + hw/nitro/Kconfig | 3 + hw/nitro/meson.build | 1 + hw/nitro/serial-vsock.c | 154 ++++++++++++++++++++++++++++++++ hw/nitro/trace-events | 4 + hw/nitro/trace.h | 4 + include/hw/nitro/serial-vsock.h | 26 ++++++ meson.build | 1 + 10 files changed, 201 insertions(+) create mode 100644 hw/nitro/Kconfig create mode 100644 hw/nitro/meson.build create mode 100644 hw/nitro/serial-vsock.c create mode 100644 hw/nitro/trace-events create mode 100644 hw/nitro/trace.h create mode 100644 include/hw/nitro/serial-vsock.h diff --git a/MAINTAINERS b/MAINTAINERS index 3d002143ae..53ce075e9a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3022,6 +3022,12 @@ F: hw/vmapple/* F: include/hw/vmapple/* F: docs/system/arm/vmapple.rst =20 +Nitro Enclaves (native) +M: Alexander Graf +S: Maintained +F: hw/nitro/ +F: include/hw/nitro/ + Subsystems ---------- Overall Audio backends diff --git a/hw/Kconfig b/hw/Kconfig index f8f92b5d03..b3ce1520a6 100644 --- a/hw/Kconfig +++ b/hw/Kconfig @@ -22,6 +22,7 @@ source isa/Kconfig source mem/Kconfig source misc/Kconfig source net/Kconfig +source nitro/Kconfig source nubus/Kconfig source nvme/Kconfig source nvram/Kconfig diff --git a/hw/meson.build b/hw/meson.build index 66e46b8090..36da5322f7 100644 --- a/hw/meson.build +++ b/hw/meson.build @@ -44,6 +44,7 @@ subdir('isa') subdir('mem') subdir('misc') subdir('net') +subdir('nitro') subdir('nubus') subdir('nvme') subdir('nvram') diff --git a/hw/nitro/Kconfig b/hw/nitro/Kconfig new file mode 100644 index 0000000000..86c817c766 --- /dev/null +++ b/hw/nitro/Kconfig @@ -0,0 +1,3 @@ +config NITRO_SERIAL_VSOCK + bool + depends on NITRO diff --git a/hw/nitro/meson.build b/hw/nitro/meson.build new file mode 100644 index 0000000000..d95ed8dd79 --- /dev/null +++ b/hw/nitro/meson.build @@ -0,0 +1 @@ +system_ss.add(when: 'CONFIG_NITRO_SERIAL_VSOCK', if_true: files('serial-vs= ock.c')) diff --git a/hw/nitro/serial-vsock.c b/hw/nitro/serial-vsock.c new file mode 100644 index 0000000000..12d6804a33 --- /dev/null +++ b/hw/nitro/serial-vsock.c @@ -0,0 +1,154 @@ +/* + * Nitro Enclave Vsock Serial + * + * Copyright =C2=A9 2026 Amazon.com, Inc. or its affiliates. All Rights Re= served. + * + * Authors: + * Alexander Graf + * + * With Nitro Enclaves in debug mode, the Nitro Hypervisor provides a vsock + * port that the parent can connect to to receive serial console output of + * the Enclave. This driver implements short-circuit logic to establish the + * vsock connection to that port and feed its data into a chardev, so that + * a machine model can use it as serial device. + * + * 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 "chardev/char.h" +#include "chardev/char-fe.h" +#include "hw/core/qdev-properties.h" +#include "hw/core/qdev-properties-system.h" +#include "hw/core/sysbus.h" +#include "hw/nitro/serial-vsock.h" +#include "trace.h" + +#define CONSOLE_PORT_START 10000 +#define VMADDR_CID_HYPERVISOR_STR "0" + +static int nitro_serial_vsock_can_read(void *opaque) +{ + NitroSerialVsockState *s =3D opaque; + + /* Refuse vsock input until the output backend is ready */ + return qemu_chr_fe_backend_open(&s->output) ? 4096 : 0; +} + +static void nitro_serial_vsock_read(void *opaque, const uint8_t *buf, int = size) +{ + NitroSerialVsockState *s =3D opaque; + + /* Forward all vsock data to the output chardev */ + qemu_chr_fe_write_all(&s->output, buf, size); +} + +static void nitro_serial_vsock_event(void *opaque, QEMUChrEvent event) +{ + /* No need to action on connect/disconnect events, but trace for debug= */ + trace_nitro_serial_vsock_event(event); +} + +static void nitro_serial_vsock_set_cid(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + NitroSerialVsockState *s =3D NITRO_SERIAL_VSOCK(obj); + uint32_t cid, port; + g_autofree char *chardev_id =3D NULL; + Chardev *chr; + ChardevBackend *backend; + ChardevSocket *sock; + + if (!visit_type_uint32(v, name, &cid, errp)) { + return; + } + + s->cid =3D cid; + port =3D cid + CONSOLE_PORT_START; + + /* + * We know the Enclave CID to connect to now. Create a vsock + * client chardev that connects to the Enclave's console. + */ + chardev_id =3D g_strdup_printf("nitro-console-%u", cid); + + 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_HYPERVISOR_STR); + sock->addr->u.vsock.data->port =3D g_strdup_printf("%u", port); + sock->server =3D false; + sock->has_server =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_serial_vsock_can_read, + nitro_serial_vsock_read, + nitro_serial_vsock_event, + NULL, s, NULL, true); +} + +static void nitro_serial_vsock_get_cid(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + NitroSerialVsockState *s =3D NITRO_SERIAL_VSOCK(obj); + uint32_t cid =3D s->cid; + + visit_type_uint32(v, name, &cid, errp); +} + +static void nitro_serial_vsock_realize(DeviceState *dev, Error **errp) +{ + /* + * At realize we don't know the Enclave CID yet, because the nitro acc= el + * first needs to launch the Enclave. Delay creation of the connection + * until the nitro accel pushes the CID as QOM property. + */ +} + +static const Property nitro_serial_vsock_props[] =3D { + DEFINE_PROP_CHR("chardev", NitroSerialVsockState, output), +}; + +static void nitro_serial_vsock_class_init(ObjectClass *oc, const void *dat= a) +{ + DeviceClass *dc =3D DEVICE_CLASS(oc); + dc->realize =3D nitro_serial_vsock_realize; + device_class_set_props(dc, nitro_serial_vsock_props); + + object_class_property_add(oc, "enclave-cid", "uint32", + nitro_serial_vsock_get_cid, + nitro_serial_vsock_set_cid, + NULL, NULL); +} + +static const TypeInfo nitro_serial_vsock_info =3D { + .name =3D TYPE_NITRO_SERIAL_VSOCK, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(NitroSerialVsockState), + .class_init =3D nitro_serial_vsock_class_init, +}; + +static void nitro_serial_vsock_register(void) +{ + type_register_static(&nitro_serial_vsock_info); +} + +type_init(nitro_serial_vsock_register); diff --git a/hw/nitro/trace-events b/hw/nitro/trace-events new file mode 100644 index 0000000000..20617a024a --- /dev/null +++ b/hw/nitro/trace-events @@ -0,0 +1,4 @@ +# See docs/devel/tracing.rst for syntax documentation. + +# serial-vsock.c +nitro_serial_vsock_event(int event) "event %d" diff --git a/hw/nitro/trace.h b/hw/nitro/trace.h new file mode 100644 index 0000000000..b455d6c17b --- /dev/null +++ b/hw/nitro/trace.h @@ -0,0 +1,4 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#include "trace/trace-hw_nitro.h" diff --git a/include/hw/nitro/serial-vsock.h b/include/hw/nitro/serial-vsoc= k.h new file mode 100644 index 0000000000..92c9374eeb --- /dev/null +++ b/include/hw/nitro/serial-vsock.h @@ -0,0 +1,26 @@ +/* + * Nitro Enclave Serial (vsock) + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_CHAR_NITRO_SERIAL_VSOCK_H +#define HW_CHAR_NITRO_SERIAL_VSOCK_H + +#include "hw/core/qdev.h" +#include "hw/core/sysbus.h" +#include "chardev/char-fe.h" +#include "qom/object.h" + +#define TYPE_NITRO_SERIAL_VSOCK "nitro-serial-vsock" +OBJECT_DECLARE_SIMPLE_TYPE(NitroSerialVsockState, NITRO_SERIAL_VSOCK) + +struct NitroSerialVsockState { + SysBusDevice parent_obj; + + CharFrontend output; /* chardev to write console output to */ + CharFrontend vsock; /* vsock chardev to enclave console */ + uint32_t cid; +}; + +#endif /* HW_CHAR_NITRO_SERIAL_VSOCK_H */ diff --git a/meson.build b/meson.build index bdeee65db2..3c6fa7a55a 100644 --- a/meson.build +++ b/meson.build @@ -3634,6 +3634,7 @@ if have_system 'hw/misc/macio', 'hw/net', 'hw/net/can', + 'hw/nitro', 'hw/nubus', 'hw/nvme', 'hw/nvram', --=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 From nobody Sun Apr 12 04:35:59 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=1771379642; cv=none; d=zohomail.com; s=zohoarc; b=V7dHo8knAXGMV329ypLW01bk4U7bfJlAynkIKvzT8UzUuidhW5385H/m8E8S0141v9QkW/BWUcUpeLAn83Rni39wHKrCYjzCdpgd4V5m9TdtDY8Y3dpJSrdpogdjMJcDBgj0KjOVUx4As/EUOFfp6sfxg+XN02cbEYbA1zaxC6c= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771379642; 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=+ywOER5w8TwL0tvTjS30yhRwjSLriESD5O4Ff5/Ir0A=; b=mcTR40SRn63d23jkrZ4ELJEeAUHnfdebvfQpbUgM0Qa0unZF6/D6I+fnQggEyH5eYWFsELWTUh2rvaklnOYbvyHV9vol6J0TpBtkyv8f+Fac/RYrxuIlr94xf6QkGbPwxtFuO4tvvHixoPrxaSuS2GLkS/WKjIrLjyyogJHruBc= 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 1771379642333244.94606973705618; Tue, 17 Feb 2026 17:54:02 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vsWk0-0007DZ-5g; Tue, 17 Feb 2026 20:52:36 -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 1vsWjy-0007Ch-4M; Tue, 17 Feb 2026 20:52:34 -0500 Received: from pdx-out-005.esa.us-west-2.outbound.mail-perimeter.amazon.com ([52.13.214.179]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vsWjw-0005F9-8M; Tue, 17 Feb 2026 20:52:33 -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-005.esa.us-west-2.outbound.mail-perimeter.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Feb 2026 01:52:30 +0000 Received: from EX19MTAUWA002.ant.amazon.com [205.251.233.178:6876] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.11.41:2525] with esmtp (Farcaster) id ca057405-e70c-4233-bf8a-611952cc798d; Wed, 18 Feb 2026 01:52:30 +0000 (UTC) Received: from EX19D020UWC004.ant.amazon.com (10.13.138.149) by EX19MTAUWA002.ant.amazon.com (10.250.64.202) 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:30 +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:27 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.com; i=@amazon.com; q=dns/txt; s=amazoncorp2; t=1771379552; x=1802915552; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=+ywOER5w8TwL0tvTjS30yhRwjSLriESD5O4Ff5/Ir0A=; b=KU5FscUrBkvD7G+zwwsWXsnQOQkVN9lcyNnj6O+7T+BGT+d20vwNQrpX kMlXHAPiQdyFD0nD20a9iwNyw4YW10K+jv7MykLtPNtD5NUKUpDMHssPO oSWxBTNtxdUui/b6TuF2t4dKffrEa/WmJmeHpvS3FLgsJm5YXi8CNJzsZ i4rXaaotE+cY5vrAHqsRWgT20SeDobvaIarDuAk8Ji0O3XfovW+svmHfr 268yS+8PsDT6CN4Tg6Rd9sG6XJfbf6zkYTH4H3agD6Bijb4niSJ33IIiE SLGbz00YS9MKwlw1Z1Xe9EbYFsSjYiBIhaKhoGnqoupyu/hn57jmu5rJt g==; X-CSE-ConnectionGUID: YH57NK7PQpGG/VxtznZkfg== X-CSE-MsgGUID: s/CFC8JTSqOlx1Id+lLljQ== X-IronPort-AV: E=Sophos;i="6.21,297,1763424000"; d="scan'208";a="13261398" X-Farcaster-Flow-ID: ca057405-e70c-4233-bf8a-611952cc798d From: Alexander Graf To: CC: , Peter Maydell , "Thomas Huth" , , , , , Cornelia Huck , , Dorjoy Chowdhury , Pierrick Bouvier , Paolo Bonzini , Tyler Fanelli , , Subject: [PATCH 05/10] hw/nitro: Introduce Nitro Enclave Heartbeat device Date: Wed, 18 Feb 2026 01:51:45 +0000 Message-ID: <20260218015151.4052-6-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: EX19D043UWC001.ant.amazon.com (10.13.139.202) 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.13.214.179; envelope-from=prvs=502105d20=graf@amazon.de; helo=pdx-out-005.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: 1771379643657158500 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 --- hw/nitro/Kconfig | 4 ++ hw/nitro/heartbeat.c | 115 +++++++++++++++++++++++++++++++++++ hw/nitro/meson.build | 1 + hw/nitro/trace-events | 4 ++ include/hw/nitro/heartbeat.h | 25 ++++++++ 5 files changed, 149 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 86c817c766..6fe050d35d 100644 --- a/hw/nitro/Kconfig +++ b/hw/nitro/Kconfig @@ -1,3 +1,7 @@ config NITRO_SERIAL_VSOCK bool depends on NITRO + +config NITRO_HEARTBEAT + bool + depends on NITRO diff --git a/hw/nitro/heartbeat.c b/hw/nitro/heartbeat.c new file mode 100644 index 0000000000..3d2a371098 --- /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_SYS_BUS_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 d95ed8dd79..b921da2b97 100644 --- a/hw/nitro/meson.build +++ b/hw/nitro/meson.build @@ -1 +1,2 @@ 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..3ed4d40bac --- /dev/null +++ b/include/hw/nitro/heartbeat.h @@ -0,0 +1,25 @@ +/* + * 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/core/qdev.h" +#include "hw/core/sysbus.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 { + SysBusDevice 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 From nobody Sun Apr 12 04:35:59 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=JlrP1fbQm94qNkXiUxc8VQdVp9ChGNOXSnWeYDk66hMjxR869HMnSVEJ/6BNvBMVbydq9BQp5DEuyWxcW2DDRAGMHu//1BFqk/PNvKSNCZ5Ej51JX7Uk0cYA/HurP0HaMhN6aCljCgwZ28/+7wTRTgJbgSoyZUeyXrJHJb3uEgk= 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=uVNVDznm7NxQ+bwTqP9jZD0VXeg2067NIquqLqqPp8k=; b=X9lsI1KfZPczyYawP5E93XVrenDnw94t8kRMsOc1FkhP3c7TUs0y5Y+eDQqKJlRdmDO0bLuzIIWvGFrdHYnhg5PHeKyTFC6Xab8VN378My1s3jgPfkQfXjzq6mt7ERLJ0SAcBk5moKxbmzAVPNVWkWmH9+QV51I8tPa+U+lMyKg= 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 1771379606970387.764983846508; 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 1vsWkS-0007wN-Q0; Tue, 17 Feb 2026 20:53:04 -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 1vsWkR-0007m1-BT; Tue, 17 Feb 2026 20:53:03 -0500 Received: from pdx-out-011.esa.us-west-2.outbound.mail-perimeter.amazon.com ([52.35.192.45]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vsWkP-0005MY-Lx; Tue, 17 Feb 2026 20:53:03 -0500 Received: from ip-10-5-6-203.us-west-2.compute.internal (HELO smtpout.naws.us-west-2.prod.farcaster.email.amazon.dev) ([10.5.6.203]) by internal-pdx-out-011.esa.us-west-2.outbound.mail-perimeter.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Feb 2026 01:52:54 +0000 Received: from EX19MTAUWB001.ant.amazon.com [205.251.233.51:16402] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.55.107:2525] with esmtp (Farcaster) id 37763521-d57a-4bf4-8565-5edb81b6cdf3; Wed, 18 Feb 2026 01:52:54 +0000 (UTC) Received: from EX19D020UWC004.ant.amazon.com (10.13.138.149) by EX19MTAUWB001.ant.amazon.com (10.250.64.248) 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 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:51 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.com; i=@amazon.com; q=dns/txt; s=amazoncorp2; t=1771379581; x=1802915581; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=uVNVDznm7NxQ+bwTqP9jZD0VXeg2067NIquqLqqPp8k=; b=UXRY5C0G990DBgrw/dvKvQujZca4G5QBODoCfh1ikdtEG9cTAbVUlRZ9 SZnv1lYQn3U/RuD1Lw7nmAiZUW3iTt8xd5WLMB2m8vhX/32zil0GfdpPS iU67TWv6lRkG1leUY8k+U5vr1PIfxn4ZG6oHe84Tu6TvECqnoKhbp9pAa GZkJsSFqlUSRFlFrhqdzepIi/qC1T0D2tEqKJUb0VGuP2NgzzxMQmRdaD Zqb1dbRi1Sh0zOMg+Er9bF3CvUvjy77tALU5Y+uFaXObSvZ3Y8zUH8mAi 3fP0k0ed0Raw0u29596c5q587ee6HWLdaA1Ztc9LRr17rJ01zIbzrHHeN g==; X-CSE-ConnectionGUID: ec2gWyq0ToGqRTSbtgy7Gw== X-CSE-MsgGUID: CyXLfvGWR6OfJac8E+6vEQ== X-IronPort-AV: E=Sophos;i="6.21,297,1763424000"; d="scan'208";a="13037355" X-Farcaster-Flow-ID: 37763521-d57a-4bf4-8565-5edb81b6cdf3 From: Alexander Graf To: CC: , Peter Maydell , "Thomas Huth" , , , , , Cornelia Huck , , Dorjoy Chowdhury , Pierrick Bouvier , Paolo Bonzini , Tyler Fanelli , , Subject: [PATCH 06/10] target/arm/cpu64: Allow -host for nitro Date: Wed, 18 Feb 2026 01:51:46 +0000 Message-ID: <20260218015151.4052-7-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-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.35.192.45; envelope-from=prvs=502105d20=graf@amazon.de; helo=pdx-out-011.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: 1771379610559154100 Content-Type: text/plain; charset="utf-8" The nitro accel does not actually make use of CPU emulation or details: It always uses the host CPU regardless of configuration. Machines for the nitro accel select the host CPU type as default to have a clear statement of the above and to have a unified cpu type across all supported architectures. The arm64 logic on Linux currently only allows -cpu host for KVM based virtual machines. Add a special case for nitro so that when the nitro accel is active, it allows use of the host cpu type. Signed-off-by: Alexander Graf --- target/arm/cpu64.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 5d7c6b7fbb..c01051f038 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -765,6 +765,14 @@ static void aarch64_a53_initfn(Object *obj) static void aarch64_host_initfn(Object *obj) { ARMCPU *cpu =3D ARM_CPU(obj); + +#if defined(CONFIG_NITRO) + if (nitro_enabled()) { + /* The nitro accel uses -cpu host, but does not actually consume i= t */ + return; + } +#endif + #if defined(CONFIG_KVM) kvm_arm_set_cpu_features_from_host(cpu); if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { --=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 From nobody Sun Apr 12 04:35:59 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 From nobody Sun Apr 12 04:35:59 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=1771379650; cv=none; d=zohomail.com; s=zohoarc; b=KKAKCoyBdJn0Xf6caM8A6U70adUeQjDjECtheZAFt78HPkIjCwhVFL+EFFDo4YrevDgoqiPFg+AHLzdDsLIH43apTvnBT3+Jdojl7jNg0uv2HtNrJz4HLY2wZlnNzA/bO7NY9HKDv3TautLKlUcNxEcLZ3iEKQ4u6Gr7Jwpb5mU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771379650; 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=txAK976ulrDqiv5ZANEFUx5CISRFuFCg+v/SRZmWc98=; b=Tg5VtXUcO0JIl32xKP1sug0Ij9g40s0+jrzk42BI5hQt3nt6bhIV2m9a2cVQt5KpaYzevr7sK7vZPc9oMT2CddnX/Vy/vwz6nxHgr5oUcjlTU0AOa0zvrIlfueg57FznhId9tnllZXi0fL2OgjYTcmCsilvt66lviUtUi7B89es= 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 1771379650533139.55279316969597; Tue, 17 Feb 2026 17:54:10 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vsWkb-0008Os-1l; Tue, 17 Feb 2026 20:53:13 -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 1vsWkZ-0008IO-FV; Tue, 17 Feb 2026 20:53:11 -0500 Received: from pdx-out-002.esa.us-west-2.outbound.mail-perimeter.amazon.com ([44.246.1.125]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vsWkX-0005Np-Mt; Tue, 17 Feb 2026 20:53:11 -0500 Received: from ip-10-5-0-115.us-west-2.compute.internal (HELO smtpout.naws.us-west-2.prod.farcaster.email.amazon.dev) ([10.5.0.115]) by internal-pdx-out-002.esa.us-west-2.outbound.mail-perimeter.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Feb 2026 01:53:04 +0000 Received: from EX19MTAUWA001.ant.amazon.com [205.251.233.182:20099] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.0.130:2525] with esmtp (Farcaster) id 478f3760-1228-4186-a2be-98a433dc0f3a; Wed, 18 Feb 2026 01:53:04 +0000 (UTC) Received: from EX19D020UWC004.ant.amazon.com (10.13.138.149) by EX19MTAUWA001.ant.amazon.com (10.250.64.204) 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:59 +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:56 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.com; i=@amazon.com; q=dns/txt; s=amazoncorp2; t=1771379589; x=1802915589; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=txAK976ulrDqiv5ZANEFUx5CISRFuFCg+v/SRZmWc98=; b=UX5cU6Tgc0ErvN/ZR74BqRTw93QESkyTXENKm+ylLUiPRYototq1WGwD 2JkAfua9uvXJzYhgh0s4rbxia8dewepQdrOb9tErpI2FcmS2nnYisuQcT OH1YEMUUrFa9lhyj8iAsMf6kfqaJdvHti7Hfmo1GkHjECwHSKCVkJ7bWD TEBefmc54fgQ4Pj1u746qd4BYn15kDyAiIfHSgiiXzR3hySyx4NkbIBqF kg7zBTC72Is6BrIkZffwZmBloOlgTCGhLTr9zF3opDGXNYWjKyGjfzH7e 6BvED03zFjED5B1DXGXQ0PJYcGsx8ltWm/wlWhk41SyLB1Y9DPYq9vVLo A==; X-CSE-ConnectionGUID: iYHG5GhqSDaRhs0neP8KRQ== X-CSE-MsgGUID: GZBGa8S1TPOtSK/S1+Rwjg== X-IronPort-AV: E=Sophos;i="6.21,297,1763424000"; d="scan'208";a="13259296" X-Farcaster-Flow-ID: 478f3760-1228-4186-a2be-98a433dc0f3a From: Alexander Graf To: CC: , Peter Maydell , "Thomas Huth" , , , , , Cornelia Huck , , Dorjoy Chowdhury , Pierrick Bouvier , Paolo Bonzini , Tyler Fanelli , , Subject: [PATCH 08/10] hw/core/eif: Move definitions to header Date: Wed, 18 Feb 2026 01:51:48 +0000 Message-ID: <20260218015151.4052-9-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-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.1.125; envelope-from=prvs=502105d20=graf@amazon.de; helo=pdx-out-002.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: 1771379651626158500 Content-Type: text/plain; charset="utf-8" In follow-up patches we need some EIF file definitions that are currently in the eif.c file, but want to access them from a separate device. Move them into the header instead. Signed-off-by: Alexander Graf Reviewed-by: Dorjoy Chowdhury --- hw/core/eif.c | 38 -------------------------------------- hw/core/eif.h | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/hw/core/eif.c b/hw/core/eif.c index 513caec6b4..96f1d76578 100644 --- a/hw/core/eif.c +++ b/hw/core/eif.c @@ -18,44 +18,6 @@ =20 #include "hw/core/eif.h" =20 -#define MAX_SECTIONS 32 - -/* members are ordered according to field order in .eif file */ -typedef struct EifHeader { - uint8_t magic[4]; /* must be .eif in ascii i.e., [46, 101, 105, 102] = */ - uint16_t version; - uint16_t flags; - uint64_t default_memory; - uint64_t default_cpus; - uint16_t reserved; - uint16_t section_cnt; - uint64_t section_offsets[MAX_SECTIONS]; - uint64_t section_sizes[MAX_SECTIONS]; - uint32_t unused; - uint32_t eif_crc32; -} QEMU_PACKED EifHeader; - -/* members are ordered according to field order in .eif file */ -typedef struct EifSectionHeader { - /* - * 0 =3D invalid, 1 =3D kernel, 2 =3D cmdline, 3 =3D ramdisk, 4 =3D si= gnature, - * 5 =3D metadata - */ - uint16_t section_type; - uint16_t flags; - uint64_t section_size; -} QEMU_PACKED EifSectionHeader; - -enum EifSectionTypes { - EIF_SECTION_INVALID =3D 0, - EIF_SECTION_KERNEL =3D 1, - EIF_SECTION_CMDLINE =3D 2, - EIF_SECTION_RAMDISK =3D 3, - EIF_SECTION_SIGNATURE =3D 4, - EIF_SECTION_METADATA =3D 5, - EIF_SECTION_MAX =3D 6, -}; - static const char *section_type_to_string(uint16_t type) { const char *str; diff --git a/hw/core/eif.h b/hw/core/eif.h index fed3cb5514..a3412377a9 100644 --- a/hw/core/eif.h +++ b/hw/core/eif.h @@ -11,6 +11,44 @@ #ifndef HW_CORE_EIF_H #define HW_CORE_EIF_H =20 +#define MAX_SECTIONS 32 + +/* members are ordered according to field order in .eif file */ +typedef struct EifHeader { + uint8_t magic[4]; /* must be .eif in ascii i.e., [46, 101, 105, 102] = */ + uint16_t version; + uint16_t flags; + uint64_t default_memory; + uint64_t default_cpus; + uint16_t reserved; + uint16_t section_cnt; + uint64_t section_offsets[MAX_SECTIONS]; + uint64_t section_sizes[MAX_SECTIONS]; + uint32_t unused; + uint32_t eif_crc32; +} QEMU_PACKED EifHeader; + +/* members are ordered according to field order in .eif file */ +typedef struct EifSectionHeader { + /* + * 0 =3D invalid, 1 =3D kernel, 2 =3D cmdline, 3 =3D ramdisk, 4 =3D si= gnature, + * 5 =3D metadata + */ + uint16_t section_type; + uint16_t flags; + uint64_t section_size; +} QEMU_PACKED EifSectionHeader; + +enum EifSectionTypes { + EIF_SECTION_INVALID =3D 0, + EIF_SECTION_KERNEL =3D 1, + EIF_SECTION_CMDLINE =3D 2, + EIF_SECTION_RAMDISK =3D 3, + EIF_SECTION_SIGNATURE =3D 4, + EIF_SECTION_METADATA =3D 5, + EIF_SECTION_MAX =3D 6, +}; + bool read_eif_file(const char *eif_path, const char *machine_initrd, char **kernel_path, char **initrd_path, char **kernel_cmdline, uint8_t *image_sha384, --=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 From nobody Sun Apr 12 04:35:59 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=1771379628; cv=none; d=zohomail.com; s=zohoarc; b=Ek2xVhYQL/2MGMzH6cqTvWPs4HZAYT1yxFoLhe5tpCOSEuFAejotYL/IA2k9rn2UIpnXDilj0jpS5zY58TTcoS4b09i71Lt8gJYPnMXMTTm/Y1+5IVUGPWZ3IayHPYfa3Bb1ebHHW4BY/029wmZ+SmVhmpVOtkZcX/wEwXUn9zE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771379628; 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=vGUcozSGDe3LdA51buWeDnWuA1XOyLH+O+KdKgLB5Pc=; b=RPkp6dBCKwjYO/l5r13oayAHz0XGS+7TY65FAv6svKEANDciOn9GzpxmZYDLEMH4AEIgN2M4RHZ89gi9lHFVwc8+TS/MtyA4j/qtUVK3h98z5uPU1rHKk2gNUO2OVwrlwxhPybwA/6q36MWEUEVJGa3Hlr56pkqlfvff/ghL6N0= 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 1771379628899566.2979973577532; Tue, 17 Feb 2026 17:53:48 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vsWku-0000W1-Me; Tue, 17 Feb 2026 20:53:32 -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-0000RL-GX; Tue, 17 Feb 2026 20:53:30 -0500 Received: from pdx-out-014.esa.us-west-2.outbound.mail-perimeter.amazon.com ([35.83.148.184]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vsWkq-0005hY-Mq; Tue, 17 Feb 2026 20:53:30 -0500 Received: from ip-10-5-6-203.us-west-2.compute.internal (HELO smtpout.naws.us-west-2.prod.farcaster.email.amazon.dev) ([10.5.6.203]) by internal-pdx-out-014.esa.us-west-2.outbound.mail-perimeter.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Feb 2026 01:53:24 +0000 Received: from EX19MTAUWC001.ant.amazon.com [205.251.233.105:30148] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.45.241:2525] with esmtp (Farcaster) id 0c8131c5-47b6-420c-ad7d-5afbafb4ae0e; Wed, 18 Feb 2026 01:53:23 +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.35; Wed, 18 Feb 2026 01:53:23 +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:53:20 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.com; i=@amazon.com; q=dns/txt; s=amazoncorp2; t=1771379608; x=1802915608; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=vGUcozSGDe3LdA51buWeDnWuA1XOyLH+O+KdKgLB5Pc=; b=S1elGRZYfYi6eeLSA2ZbHPAvKxbrFZUe9HNijDZ+AIxE006rvcw8K3uG +uqZ6gwrUU975KYvUQJjyMoetT518uGs0q5kdZeAo90dZYNsj1ZjeRHVq r95HXvOcn3QQX+vibiL7QFEKZSgt6wkRprT1YG42cDztl8e349KrU6B8V K5xwQdjIT5eWpgCNt9E5CEBt6UQ/8MYJsZpK66CqkTlm7wVMHZM84N6ew O1Pwtpw6pnh5uKmgpH0G7JquvUStob4qQ9ZOG3SwSRyKWeoBihajB8oVv JIej/CwTp+xVwwvWvojxoChlNKOHuzr3QZAXFbxaXVMZzluuDE2QGgyUi A==; X-CSE-ConnectionGUID: 6RaYNiU/T8y49rRrUjpGMA== X-CSE-MsgGUID: Pxs3kH1ESw2hw1KvXZzSRg== X-IronPort-AV: E=Sophos;i="6.21,297,1763424000"; d="scan'208";a="13037688" X-Farcaster-Flow-ID: 0c8131c5-47b6-420c-ad7d-5afbafb4ae0e From: Alexander Graf To: CC: , Peter Maydell , "Thomas Huth" , , , , , Cornelia Huck , , Dorjoy Chowdhury , Pierrick Bouvier , Paolo Bonzini , Tyler Fanelli , , Subject: [PATCH 09/10] hw/nitro: Enable direct kernel boot Date: Wed, 18 Feb 2026 01:51:49 +0000 Message-ID: <20260218015151.4052-10-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: EX19D032UWA004.ant.amazon.com (10.13.139.56) To EX19D020UWC004.ant.amazon.com (10.13.138.149) 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=35.83.148.184; envelope-from=prvs=502105d20=graf@amazon.de; helo=pdx-out-014.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: 1771379630948154100 Content-Type: text/plain; charset="utf-8" Nitro Enclaves can only boot EIF files which are a combination of kernel, initramfs and cmdline in a single file. When the kernel image is not an EIF, treat it like a kernel image and assemble an EIF image on the fly. This way, users can call QEMU with a direct kernel/initrd/cmdline combination and everything "just works". Signed-off-by: Alexander Graf --- hw/core/eif.h | 3 ++ hw/nitro/machine.c | 116 +++++++++++++++++++++++++++++++++++++++++++ hw/nitro/meson.build | 2 +- 3 files changed, 120 insertions(+), 1 deletion(-) diff --git a/hw/core/eif.h b/hw/core/eif.h index a3412377a9..0c432dbc2d 100644 --- a/hw/core/eif.h +++ b/hw/core/eif.h @@ -12,6 +12,7 @@ #define HW_CORE_EIF_H =20 #define MAX_SECTIONS 32 +#define EIF_HDR_ARCH_ARM64 0x1 =20 /* members are ordered according to field order in .eif file */ typedef struct EifHeader { @@ -49,6 +50,8 @@ enum EifSectionTypes { EIF_SECTION_MAX =3D 6, }; =20 +#define EIF_MAGIC { '.', 'e', 'i', 'f' } + bool read_eif_file(const char *eif_path, const char *machine_initrd, char **kernel_path, char **initrd_path, char **kernel_cmdline, uint8_t *image_sha384, diff --git a/hw/nitro/machine.c b/hw/nitro/machine.c index 197adfbdb5..33b0749288 100644 --- a/hw/nitro/machine.c +++ b/hw/nitro/machine.c @@ -32,9 +32,104 @@ #include "system/nitro-accel.h" #include "qemu/accel.h" #include "hw/arm/machines-qom.h" +#include "hw/core/eif.h" +#include /* for crc32 */ =20 #define EIF_LOAD_ADDR (8 * 1024 * 1024) =20 +static bool is_eif(char *eif, gsize len) +{ + const char eif_magic[] =3D EIF_MAGIC; + + return len >=3D sizeof(eif_magic) && + !memcmp(eif, eif_magic, sizeof(eif_magic)); +} + +static void build_eif_section(EifHeader *hdr, GByteArray *buf, uint16_t ty= pe, + const char *data, uint64_t size) +{ + uint16_t section =3D be16_to_cpu(hdr->section_cnt); + EifSectionHeader shdr =3D { + .section_type =3D cpu_to_be16(type), + .flags =3D 0, + .section_size =3D cpu_to_be64(size), + }; + + hdr->section_offsets[section] =3D cpu_to_be64(buf->len); + hdr->section_sizes[section] =3D cpu_to_be64(size); + + g_byte_array_append(buf, (const uint8_t *)&shdr, sizeof(shdr)); + if (size) { + g_byte_array_append(buf, (const uint8_t *)data, size); + } + + hdr->section_cnt =3D cpu_to_be16(section + 1); +} + +/* + * Nitro Enclaves only support loading EIF files. When the user provides + * a Linux kernel, initrd and cmdline, convert them into EIF format. + */ +static char *build_eif(const char *kernel_data, gsize kernel_size, + const char *initrd_path, const char *cmdline, + gsize *out_size, Error **errp) +{ + g_autofree char *initrd_data =3D NULL; + static const char metadata[] =3D "{}"; + size_t metadata_len =3D sizeof(metadata) - 1; + gsize initrd_size =3D 0; + GByteArray *buf; + EifHeader hdr; + uint32_t crc =3D 0; + size_t cmdline_len; + + if (initrd_path) { + if (!g_file_get_contents(initrd_path, &initrd_data, + &initrd_size, NULL)) { + error_setg(errp, "Failed to read initrd '%s'", initrd_path); + return NULL; + } + } + + buf =3D g_byte_array_new(); + + cmdline_len =3D cmdline ? strlen(cmdline) : 0; + + hdr =3D (EifHeader) { + .magic =3D EIF_MAGIC, + .version =3D cpu_to_be16(4), + .flags =3D cpu_to_be16(target_aarch64() ? EIF_HDR_ARCH_ARM64 : 0), + }; + + g_byte_array_append(buf, (const uint8_t *)&hdr, sizeof(hdr)); + + /* Kernel */ + build_eif_section(&hdr, buf, EIF_SECTION_KERNEL, kernel_data, kernel_s= ize); + + /* Command line */ + build_eif_section(&hdr, buf, EIF_SECTION_CMDLINE, cmdline, cmdline_len= ); + + /* Initramfs */ + build_eif_section(&hdr, buf, EIF_SECTION_RAMDISK, initrd_data, initrd_= size); + + /* Metadata */ + build_eif_section(&hdr, buf, EIF_SECTION_METADATA, metadata, metadata_= len); + + /* + * Patch the header into the buffer first (with real section offsets + * and sizes), then compute CRC over everything except the CRC field. + */ + memcpy(buf->data, &hdr, sizeof(hdr)); + crc =3D crc32(crc, buf->data, offsetof(EifHeader, eif_crc32)); + crc =3D crc32(crc, &buf->data[sizeof(hdr)], buf->len - sizeof(hdr)); + + /* Finally write the CRC into the in-buffer header */ + ((EifHeader *)buf->data)->eif_crc32 =3D cpu_to_be32(crc); + + *out_size =3D buf->len; + return (char *)g_byte_array_free(buf, false); +} + static void nitro_create_cpu(const char *cpu_type, int index) { Object *obj =3D object_new(cpu_type); @@ -87,6 +182,27 @@ static void nitro_machine_init(MachineState *machine) error_report("nitro: failed to read EIF '%s'", eif_path); exit(1); } + + if (!is_eif(eif_data, eif_size)) { + char *kernel_data =3D eif_data; + gsize kernel_size =3D eif_size; + Error *err =3D NULL; + + /* + * The user gave us a non-EIF kernel, likely a Linux kernel image. + * Assemble an EIF file from it, the -initrd and the -append argum= ents, + * so that users can perform a natural direct kernel boot. + */ + eif_data =3D build_eif(kernel_data, kernel_size, machine->initrd_f= ilename, + machine->kernel_cmdline, &eif_size, &err); + if (!eif_data) { + error_report_err(err); + exit(1); + } + + g_free(kernel_data); + } + address_space_write(&address_space_memory, EIF_LOAD_ADDR, MEMTXATTRS_UNSPECIFIED, eif_data, eif_size); =20 diff --git a/hw/nitro/meson.build b/hw/nitro/meson.build index 813f5a9c87..7b23f71d5a 100644 --- a/hw/nitro/meson.build +++ b/hw/nitro/meson.build @@ -1,3 +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')) +system_ss.add(when: 'CONFIG_NITRO_MACHINE', if_true: [files('machine.c'), = zlib]) --=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 From nobody Sun Apr 12 04:35:59 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=1771379634; cv=none; d=zohomail.com; s=zohoarc; b=bop6U39eKKgKceFmPmFuulmKeuEfdovJN5FV5FlaorCMuflSZtbCnpbdmwMIGupkgoZuhB6t8LumLC3nP68dhNz3qEKGsKSMpYnzZhmSJMDxCDX8BUUh94+UTwtQFRkBKo4wwrEG+laiwi6u4B9LgCVsa8b8PFDFue1oTsHd0nU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771379634; 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=3hLOH/1PH9KgMpnJK/l9v0L+U9NxjDuT0ZDVOs230+4=; b=CoSmwRphEX360TbRyyQCMzVfxNgsN1xguEa7V9XWonSvK97M70DqHtm6xVcC1gLSrj5rmcJ3h6Qbe8U3EvdvhPeyW5ZJZjns/YZcCe4+417iwDY6/lZSXuchiO0TgPskBnV0TxtabSDzGXKWdUVyivDfDQw9uCAtBlo/p2akZ1k= 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 1771379634221637.162302174648; Tue, 17 Feb 2026 17:53:54 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vsWkw-0000a2-Lu; Tue, 17 Feb 2026 20:53:34 -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 1vsWkv-0000YJ-Cg; Tue, 17 Feb 2026 20:53:33 -0500 Received: from pdx-out-014.esa.us-west-2.outbound.mail-perimeter.amazon.com ([35.83.148.184]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vsWkt-0005hY-BT; Tue, 17 Feb 2026 20:53:33 -0500 Received: from ip-10-5-6-203.us-west-2.compute.internal (HELO smtpout.naws.us-west-2.prod.farcaster.email.amazon.dev) ([10.5.6.203]) by internal-pdx-out-014.esa.us-west-2.outbound.mail-perimeter.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Feb 2026 01:53:26 +0000 Received: from EX19MTAUWB002.ant.amazon.com [205.251.233.48:7051] by smtpin.naws.us-west-2.prod.farcaster.email.amazon.dev [10.0.11.41:2525] with esmtp (Farcaster) id 38446c7a-17e8-442f-be23-a47edb0fb50d; Wed, 18 Feb 2026 01:53:26 +0000 (UTC) Received: from EX19D020UWC004.ant.amazon.com (10.13.138.149) by EX19MTAUWB002.ant.amazon.com (10.250.64.231) 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:53:26 +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:53:23 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.com; i=@amazon.com; q=dns/txt; s=amazoncorp2; t=1771379611; x=1802915611; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=3hLOH/1PH9KgMpnJK/l9v0L+U9NxjDuT0ZDVOs230+4=; b=b8pikC+6cFajKK4rpfUDa5OfTGHbW/BzeDSBQXrQUhHaHpcjiIDw0HdZ 887aGuywIwItqBJf3uCGmzXkQ1Dp/neIEQ+ucnUtawM15aPm2Mt2ta+rG fcZA3ifgct6WwLzQyTuVbZjcUHo1abGl5Ps/mbZ4paQrqKlkTClsUpUUJ C9iVWOGCyzvZOKJtazYXjfWXEOaueo2dF3p+WdD94S3mIRbD2H7VJImmQ vgULR9iu3eclXudxpWx1yMX6OF0R4yDy3rBSpXu0u107xsyCMukx8Bl7B tXyMJnPciAUAscyqffPb0gSzO5e61hI2qG4shxqSvWpppfckrZctMc9Lb A==; X-CSE-ConnectionGUID: ziCxB2d/SJaHTzwBHvIBww== X-CSE-MsgGUID: 9r57eOH5Rtqe9eS9qu958w== X-IronPort-AV: E=Sophos;i="6.21,297,1763424000"; d="scan'208";a="13037692" X-Farcaster-Flow-ID: 38446c7a-17e8-442f-be23-a47edb0fb50d From: Alexander Graf To: CC: , Peter Maydell , "Thomas Huth" , , , , , Cornelia Huck , , Dorjoy Chowdhury , Pierrick Bouvier , Paolo Bonzini , Tyler Fanelli , , Subject: [PATCH 10/10] docs: Add Nitro Enclaves documentation Date: Wed, 18 Feb 2026 01:51:50 +0000 Message-ID: <20260218015151.4052-11-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: EX19D032UWA004.ant.amazon.com (10.13.139.56) To EX19D020UWC004.ant.amazon.com (10.13.138.149) 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=35.83.148.184; envelope-from=prvs=502105d20=graf@amazon.de; helo=pdx-out-014.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: 1771379636719154100 Content-Type: text/plain; charset="utf-8" Now that all pieces are in place to spawn Nitro Enclaves using a special purpose accelerator and machine model, document how to use it. Signed-off-by: Alexander Graf --- MAINTAINERS | 1 + docs/system/confidential-guest-support.rst | 1 + docs/system/index.rst | 1 + docs/system/nitro.rst | 128 +++++++++++++++++++++ 4 files changed, 131 insertions(+) create mode 100644 docs/system/nitro.rst diff --git a/MAINTAINERS b/MAINTAINERS index 53ce075e9a..5e9e429530 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3027,6 +3027,7 @@ M: Alexander Graf S: Maintained F: hw/nitro/ F: include/hw/nitro/ +F: docs/system/nitro.rst =20 Subsystems ---------- diff --git a/docs/system/confidential-guest-support.rst b/docs/system/confi= dential-guest-support.rst index 66129fbab6..562a7c3c28 100644 --- a/docs/system/confidential-guest-support.rst +++ b/docs/system/confidential-guest-support.rst @@ -41,5 +41,6 @@ Currently supported confidential guest mechanisms are: * Intel Trust Domain Extension (TDX) (see :doc:`i386/tdx`) * POWER Protected Execution Facility (PEF) (see :ref:`power-papr-protected= -execution-facility-pef`) * s390x Protected Virtualization (PV) (see :doc:`s390x/protvirt`) +* AWS Nitro Enclaves (see :doc:`nitro`) =20 Other mechanisms may be supported in future. diff --git a/docs/system/index.rst b/docs/system/index.rst index 427b020483..d297a95282 100644 --- a/docs/system/index.rst +++ b/docs/system/index.rst @@ -39,5 +39,6 @@ or Hypervisor.Framework. multi-process confidential-guest-support igvm + nitro vm-templating sriov diff --git a/docs/system/nitro.rst b/docs/system/nitro.rst new file mode 100644 index 0000000000..ebf118a108 --- /dev/null +++ b/docs/system/nitro.rst @@ -0,0 +1,128 @@ +AWS Nitro Enclaves +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +`AWS Nitro Enclaves `_ +are isolated compute environments that run alongside EC2 instances. +They are created by partitioning CPU and memory resources from a parent +instance and launching a signed Enclave Image Format (EIF) file inside +a confidential VM managed by the Nitro Hypervisor. + +QEMU supports launching Nitro Enclaves on EC2 instances that have +enclave support enabled, using the ``nitro`` accelerator and the +``nitro`` machine type. + +Prerequisites +------------- + +* An EC2 instance with Nitro Enclaves enabled +* The ``nitro_enclaves`` kernel module loaded (provides ``/dev/nitro_encla= ves``) +* CPU cores allocated to the Nitro Enclaves pool via ``nitro-enclaves-allo= cator`` +* Huge pages allocated for Nitro Enclaves via ``nitro-enclaves-allocator`` + +Quick Start +----------- + +Launch a Nitro Enclave from a pre-built EIF file:: + + $ qemu-system-x86_64 -accel nitro,debug-mode=3Don -M nitro -nographic \ + -smp 2 -m 512M -kernel enclave.eif + +Launch an enclave from individual kernel and initrd files:: + + $ qemu-system-x86_64 -accel nitro,debug-mode=3Don -M nitro -nographic \ + -smp 2 -m 512M -kernel vmlinuz -initrd initrd.cpio \ + -append "console=3DttyS0" + +The same commands work with ``qemu-system-aarch64`` on Graviton based EC2 +instances. + +Accelerator +----------- + +The ``nitro`` accelerator (``-accel nitro``) drives the +``/dev/nitro_enclaves`` device to create and manage a Nitro Enclave. +It handles: + +* Creating the enclave VM slot +* Donating memory regions (must be huge page backed) +* Adding vCPUs (must be full physical cores) +* Starting the enclave +* Forwarding the enclave CID to devices that need it + +Accelerator options: + +``debug-mode=3Don|off`` + Enable debug mode. When enabled, the Nitro Hypervisor exposes the + enclave's serial console output via a vsock port that the machine + model automatically connects to. In debug mode, PCR values are zero. + Default is ``off``. + +Machine +------- + +The ``nitro`` machine (``-M nitro``) is a minimal, architecture-independent +machine that provides only what a Nitro Enclave needs: + +* RAM (huge page backed via memfd) +* vCPUs (defaults to ``host`` CPU type) +* A heartbeat device (vsock server on port 9000) +* A serial console bridge (vsock client, debug mode only) + +Communication to the Nitro Enclave is limited to virtio-vsock. The Enclave +is allocated a CID at launch at which it is reachable. The CID is available +as QOM property in the accelerator and as a trace event. + +EIF Image Format +^^^^^^^^^^^^^^^^ + +Nitro Enclaves boot from EIF (Enclave Image Format) files. When +``-kernel`` points to an EIF file (detected by the ``.eif`` magic +bytes), it is loaded directly into guest memory. + +When ``-kernel`` points to a regular kernel image (e.g. a bzImage or +Image), the machine automatically assembles a minimal EIF on the fly +from ``-kernel``, ``-initrd``, and ``-append``. This allows standard +direct kernel boot without external EIF tooling. + +CPU Requirements +^^^^^^^^^^^^^^^^ + +Nitro Enclaves require full physical CPU cores. On hyperthreaded +systems, this means ``-smp`` must be a multiple of the threads per +core (typically 2). + +Nitro Enclaves can only consume cores that are donated to the Nitro Enclave +CPU pool. You can configure the CPU pool using the ``nitro-enclaves-alloca= tor`` +tool or manually by writing to the nitro_enclaves cpu pool parameter. To +allocate vCPUs 1, 2 and 3, you can call:: + + $ echo 1,2,3 | sudo tee /sys/module/nitro_enclaves/parameters/ne_cpus + +Beware that on x86-64 systems, hyperthread siblings are not consecutive +and must be added in pairs to the pool. Consult tools like ``lstopo`` +or ``lscpu`` for details about your instance's CPU topology. + +Memory Requirements +^^^^^^^^^^^^^^^^^^^ + +Enclave memory must be huge page backed. The machine automatically +creates a memfd memory backend with huge pages enabled. To make the +huge page allocation work, ensure that huge pages are reserved in +the system. To reserve 1 GiB of memory on a 4 KiB PAGE_SIZE system, +you can call:: + + $ echo 512 | sudo tee /proc/sys/vm/nr_hugepages + +Emulated Nitro Enclaves +----------------------- + +In addition to the native Nitro Enclaves invocation, you can also use +the emulated nitro-enclave machine target (see :doc:`i386/nitro-enclave`) +which implements the x86 Nitro Enclave device model. While -M nitro +delegates virtual machine device emulation to the Nitro Hypervisor, -M +nitro-enclave implements all devices itself, which means it also works +on non-EC2 instances. + +If you require NSM based attestation backed by valid AWS certificates, +you must use -M nitro. The -M nitro-enclave model does not provide +you with an AWS signed attestation document. --=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