From nobody Sat Nov 15 14:52:48 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1750365306; cv=none; d=zohomail.com; s=zohoarc; b=AfiUzBvcOx5cZpYF1GrWW9pS96ZsSXliFNlmZIhFWvrI+vdpwo6751CL3TSqQ9FBBJ7ZT77/Q32iFbhVf0DLVPxKYbjSHwWeYiL/sv51ZxMQzkn9K3e88cZO20zsLtSHb/ajgqNz3m0NJnoJD0hIv/NlIH0Pk50h4pbh8D7tUnM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1750365306; h=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=c0psjyOIJ8t+sVmPA16Jc6dLmv441phUHEvX7zxJTbc=; b=Lde2EAEY/XElysRwLLDnHV6yB7b1y8pwOVmExlEOBnqwBFjHDkZpEk3iyvCE8hAVJXb6tPwB1+2SnQ3/RMgNK37/AFK6QfT/mvu/cGSKhWUc+xN0a0ZE2Sf/nBd32cXyy2bqnWFWdjKyej1JpEBNpWlqsK5z0D/ijtth1NX+J1I= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1750365306872644.9889604896015; Thu, 19 Jun 2025 13:35:06 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uSLxc-0004cT-0h; Thu, 19 Jun 2025 16:34:12 -0400 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 1uSLxY-0004bT-Aa for qemu-devel@nongnu.org; Thu, 19 Jun 2025 16:34:08 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uSLxS-0004Ye-G6 for qemu-devel@nongnu.org; Thu, 19 Jun 2025 16:34:07 -0400 Received: from mail-ed1-f70.google.com (mail-ed1-f70.google.com [209.85.208.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-317-UX0KPKWgPHWAEmtkbEmSuA-1; Thu, 19 Jun 2025 16:33:59 -0400 Received: by mail-ed1-f70.google.com with SMTP id 4fb4d7f45d1cf-6097b0f5aceso1077629a12.3 for ; Thu, 19 Jun 2025 13:33:59 -0700 (PDT) Received: from [192.168.122.1] ([151.62.200.93]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ae053e7d1e8sm42893566b.5.2025.06.19.13.33.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Jun 2025 13:33:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1750365240; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=c0psjyOIJ8t+sVmPA16Jc6dLmv441phUHEvX7zxJTbc=; b=ZHEHnD62agNvTG+1aeZ06wWU85akeZAJNqBccsQGlXTzbqRHYZgCV+vpCIAqhNNy57gpaT eUNn3UdUBro96cHcqruLrNNGaxFoNTLivTGIk4+4T9ICIdqVPN5y95PB9GqwLvv1KznjsV 0NPWNXLUZLTnzO08jGW8SBizaLUCCCc= X-MC-Unique: UX0KPKWgPHWAEmtkbEmSuA-1 X-Mimecast-MFC-AGG-ID: UX0KPKWgPHWAEmtkbEmSuA_1750365238 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750365237; x=1750970037; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=c0psjyOIJ8t+sVmPA16Jc6dLmv441phUHEvX7zxJTbc=; b=t7mK7nh/vQA2g+unh54gajD6Zsa3tAboPOtuz0gSUHcQwah8YMulXrTaP3Hg41WVDv Mx+4VfQ2jECnspgft7yb95JhoPB0kw4yTVTVmyWbbs4/zeayC1E4uH+dT3Zf1aZK0qUh FTJNLyNA4HxvFMFiIH4jSl0f3+oQZycTzASYHRmuaRgRO3T1mKwNlhU/ZtDDrcEHOLGS iFVeph9nU6tMg27N2M6RTCfC52YO8hRfST8nLKwSMyXWTb997rsqv/rIVFXIPHHWDG4l P+n8/PVNwEXTDxv0UY4SJ2k1yXsekhqZQI+NOxeQTFGht1Qg+JVdzWFls12eaxMJJ/MV DfZQ== X-Gm-Message-State: AOJu0Yz1T/DKQOg8UMUA+DU+Crl/ITSbrelqV8vlQFXQm0kjvCvwo9PD oZm0KpkmUA2bnABUVsa3VWx2oPNNbqWo403fnqpjtZCfpDaXCMq6zFKBO3+oIxyCJ1OsDIn3Rk4 aAlNPUHASBBBv9ZCGr6xFgpugydZ04CBSYk3bB5pu937krWVtHY9nUQp6QzPwsfMg8q2RoOppWj PX6w+2fvn5rNM5eZdT81/TRRXFMyz9iiuCTHwoCFzE X-Gm-Gg: ASbGncv27DNrIDzM/XeX7YgoA1C6S1garfW4LY2CzCeCIr7m+g1LmsjqAqhJK6Tt64+ CcAZNk5I/jyxur+NNpuXn8bZqiLR8c4gm9iuVC7XmDSncsdwS9ivzGFikKMeYivbw+6kl0Pgj3c aDTHPen+Whq/y8se3UOniz8LUd8h+5c217FE0+ApJ4k9FIPEanzppoNtBKihbSf34TUJY7rYXYp He3zQEsnc9CDEQUA4XeJHKA2enIOUVSeYEsJp31wszQvSb7dtKH4T0wrsI2e2jHpxb13qcKJrl1 2Jc1sLuzYMJk3bBjTo7Mp844JA== X-Received: by 2002:a17:907:bd83:b0:ad5:557b:c369 with SMTP id a640c23a62f3a-ae057b6e6e3mr26193666b.33.1750365237335; Thu, 19 Jun 2025 13:33:57 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEgT0UpzulbXGh5C4cvwBhNKfG7zAr/qWj+qekC+piIVm74cRY7EUxmnX4DRciV4jypdEcRNw== X-Received: by 2002:a17:907:bd83:b0:ad5:557b:c369 with SMTP id a640c23a62f3a-ae057b6e6e3mr26190966b.33.1750365236738; Thu, 19 Jun 2025 13:33:56 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Chenyi Qiang , Xiaoyao Li , Binbin Wu , =?UTF-8?q?Daniel=20P=20=2E=20Berrang=C3=A9?= Subject: [PATCH 1/3] update Linux headers to v6.16-rc3 Date: Thu, 19 Jun 2025 22:33:49 +0200 Message-ID: <20250619203351.393786-2-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250619203351.393786-1-pbonzini@redhat.com> References: <20250619203351.393786-1-pbonzini@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -39 X-Spam_score: -4.0 X-Spam_bar: ---- X-Spam_report: (-4.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.897, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1750365309198116600 Content-Type: text/plain; charset="utf-8" Signed-off-by: Paolo Bonzini --- include/standard-headers/asm-x86/setup_data.h | 13 +- include/standard-headers/drm/drm_fourcc.h | 45 +++++++ include/standard-headers/linux/ethtool.h | 124 +++++++++--------- include/standard-headers/linux/fuse.h | 6 +- .../linux/input-event-codes.h | 3 +- include/standard-headers/linux/pci_regs.h | 12 +- include/standard-headers/linux/virtio_gpu.h | 3 +- include/standard-headers/linux/virtio_pci.h | 1 + linux-headers/asm-arm64/kvm.h | 9 +- linux-headers/asm-x86/kvm.h | 1 + linux-headers/linux/bits.h | 4 +- linux-headers/linux/kvm.h | 25 ++++ linux-headers/linux/vhost.h | 4 +- 13 files changed, 177 insertions(+), 73 deletions(-) diff --git a/include/standard-headers/asm-x86/setup_data.h b/include/standa= rd-headers/asm-x86/setup_data.h index a483d72f428..2e446c1d858 100644 --- a/include/standard-headers/asm-x86/setup_data.h +++ b/include/standard-headers/asm-x86/setup_data.h @@ -13,7 +13,8 @@ #define SETUP_CC_BLOB 7 #define SETUP_IMA 8 #define SETUP_RNG_SEED 9 -#define SETUP_ENUM_MAX SETUP_RNG_SEED +#define SETUP_KEXEC_KHO 10 +#define SETUP_ENUM_MAX SETUP_KEXEC_KHO =20 #define SETUP_INDIRECT (1<<31) #define SETUP_TYPE_MAX (SETUP_ENUM_MAX | SETUP_INDIRECT) @@ -78,6 +79,16 @@ struct ima_setup_data { uint64_t size; } QEMU_PACKED; =20 +/* + * Locations of kexec handover metadata + */ +struct kho_data { + uint64_t fdt_addr; + uint64_t fdt_size; + uint64_t scratch_addr; + uint64_t scratch_size; +} QEMU_PACKED; + #endif /* __ASSEMBLER__ */ =20 #endif /* _ASM_X86_SETUP_DATA_H */ diff --git a/include/standard-headers/drm/drm_fourcc.h b/include/standard-h= eaders/drm/drm_fourcc.h index a8b759dcbc8..c8309d378bf 100644 --- a/include/standard-headers/drm/drm_fourcc.h +++ b/include/standard-headers/drm/drm_fourcc.h @@ -421,6 +421,7 @@ extern "C" { #define DRM_FORMAT_MOD_VENDOR_ALLWINNER 0x09 #define DRM_FORMAT_MOD_VENDOR_AMLOGIC 0x0a #define DRM_FORMAT_MOD_VENDOR_MTK 0x0b +#define DRM_FORMAT_MOD_VENDOR_APPLE 0x0c =20 /* add more to the end as needed */ =20 @@ -1493,6 +1494,50 @@ drm_fourcc_canonicalize_nvidia_format_mod(uint64_t m= odifier) /* alias for the most common tiling format */ #define DRM_FORMAT_MOD_MTK_16L_32S_TILE DRM_FORMAT_MOD_MTK(MTK_FMT_MOD_TI= LE_16L32S) =20 +/* + * Apple GPU-tiled layouts. + * + * Apple GPUs support nonlinear tilings with optional lossless compression. + * + * GPU-tiled images are divided into 16KiB tiles: + * + * Bytes per pixel Tile size + * --------------- --------- + * 1 128x128 + * 2 128x64 + * 4 64x64 + * 8 64x32 + * 16 32x32 + * + * Tiles are raster-order. Pixels within a tile are interleaved (Morton or= der). + * + * Compressed images pad the body to 128-bytes and are immediately followe= d by a + * metadata section. The metadata section rounds the image dimensions to + * powers-of-two and contains 8 bytes for each 16x16 compression subtile. + * Subtiles are interleaved (Morton order). + * + * All images are 128-byte aligned. + * + * These layouts fundamentally do not have meaningful strides. No matter h= ow we + * specify strides for these layouts, userspace unaware of Apple image lay= outs + * will be unable to use correctly the specified stride for any purpose. + * Userspace aware of the image layouts do not use strides. The most "corr= ect" + * convention would be setting the image stride to 0. Unfortunately, some + * software assumes the stride is at least (width * bytes per pixel). We + * therefore require that stride equals (width * bytes per pixel). Since t= he + * stride is arbitrary here, we pick the simplest convention. + * + * Although containing two sections, compressed image layouts are treated = in + * software as a single plane. This is modelled after AFBC, a similar + * scheme. Attempting to separate the sections to be "explicit" in DRM wou= ld + * only generate more confusion, as software does not treat the image this= way. + * + * For detailed information on the hardware image layouts, see + * https://docs.mesa3d.org/drivers/asahi.html#image-layouts + */ +#define DRM_FORMAT_MOD_APPLE_GPU_TILED fourcc_mod_code(APPLE, 1) +#define DRM_FORMAT_MOD_APPLE_GPU_TILED_COMPRESSED fourcc_mod_code(APPLE, 2) + /* * AMD modifiers * diff --git a/include/standard-headers/linux/ethtool.h b/include/standard-he= aders/linux/ethtool.h index 5d1ad5fdeab..cef0d207a62 100644 --- a/include/standard-headers/linux/ethtool.h +++ b/include/standard-headers/linux/ethtool.h @@ -2295,71 +2295,75 @@ static inline int ethtool_validate_duplex(uint8_t d= uplex) #define RXH_XFRM_SYM_OR_XOR (1 << 1) #define RXH_XFRM_NO_CHANGE 0xff =20 -/* L2-L4 network traffic flow types */ -#define TCP_V4_FLOW 0x01 /* hash or spec (tcp_ip4_spec) */ -#define UDP_V4_FLOW 0x02 /* hash or spec (udp_ip4_spec) */ -#define SCTP_V4_FLOW 0x03 /* hash or spec (sctp_ip4_spec) */ -#define AH_ESP_V4_FLOW 0x04 /* hash only */ -#define TCP_V6_FLOW 0x05 /* hash or spec (tcp_ip6_spec; nfc only) */ -#define UDP_V6_FLOW 0x06 /* hash or spec (udp_ip6_spec; nfc only) */ -#define SCTP_V6_FLOW 0x07 /* hash or spec (sctp_ip6_spec; nfc only) */ -#define AH_ESP_V6_FLOW 0x08 /* hash only */ -#define AH_V4_FLOW 0x09 /* hash or spec (ah_ip4_spec) */ -#define ESP_V4_FLOW 0x0a /* hash or spec (esp_ip4_spec) */ -#define AH_V6_FLOW 0x0b /* hash or spec (ah_ip6_spec; nfc only) */ -#define ESP_V6_FLOW 0x0c /* hash or spec (esp_ip6_spec; nfc only) */ -#define IPV4_USER_FLOW 0x0d /* spec only (usr_ip4_spec) */ -#define IP_USER_FLOW IPV4_USER_FLOW -#define IPV6_USER_FLOW 0x0e /* spec only (usr_ip6_spec; nfc only) */ -#define IPV4_FLOW 0x10 /* hash only */ -#define IPV6_FLOW 0x11 /* hash only */ -#define ETHER_FLOW 0x12 /* spec only (ether_spec) */ +enum { + /* L2-L4 network traffic flow types */ + TCP_V4_FLOW =3D 0x01, /* hash or spec (tcp_ip4_spec) */ + UDP_V4_FLOW =3D 0x02, /* hash or spec (udp_ip4_spec) */ + SCTP_V4_FLOW =3D 0x03, /* hash or spec (sctp_ip4_spec) */ + AH_ESP_V4_FLOW =3D 0x04, /* hash only */ + TCP_V6_FLOW =3D 0x05, /* hash or spec (tcp_ip6_spec; nfc only) */ + UDP_V6_FLOW =3D 0x06, /* hash or spec (udp_ip6_spec; nfc only) */ + SCTP_V6_FLOW =3D 0x07, /* hash or spec (sctp_ip6_spec; nfc only) */ + AH_ESP_V6_FLOW =3D 0x08, /* hash only */ + AH_V4_FLOW =3D 0x09, /* hash or spec (ah_ip4_spec) */ + ESP_V4_FLOW =3D 0x0a, /* hash or spec (esp_ip4_spec) */ + AH_V6_FLOW =3D 0x0b, /* hash or spec (ah_ip6_spec; nfc only) */ + ESP_V6_FLOW =3D 0x0c, /* hash or spec (esp_ip6_spec; nfc only) */ + IPV4_USER_FLOW =3D 0x0d, /* spec only (usr_ip4_spec) */ + IP_USER_FLOW =3D IPV4_USER_FLOW, + IPV6_USER_FLOW =3D 0x0e, /* spec only (usr_ip6_spec; nfc only) */ + IPV4_FLOW =3D 0x10, /* hash only */ + IPV6_FLOW =3D 0x11, /* hash only */ + ETHER_FLOW =3D 0x12, /* spec only (ether_spec) */ =20 -/* Used for GTP-U IPv4 and IPv6. - * The format of GTP packets only includes - * elements such as TEID and GTP version. - * It is primarily intended for data communication of the UE. - */ -#define GTPU_V4_FLOW 0x13 /* hash only */ -#define GTPU_V6_FLOW 0x14 /* hash only */ + /* Used for GTP-U IPv4 and IPv6. + * The format of GTP packets only includes + * elements such as TEID and GTP version. + * It is primarily intended for data communication of the UE. + */ + GTPU_V4_FLOW =3D 0x13, /* hash only */ + GTPU_V6_FLOW =3D 0x14, /* hash only */ =20 -/* Use for GTP-C IPv4 and v6. - * The format of these GTP packets does not include TEID. - * Primarily expected to be used for communication - * to create sessions for UE data communication, - * commonly referred to as CSR (Create Session Request). - */ -#define GTPC_V4_FLOW 0x15 /* hash only */ -#define GTPC_V6_FLOW 0x16 /* hash only */ + /* Use for GTP-C IPv4 and v6. + * The format of these GTP packets does not include TEID. + * Primarily expected to be used for communication + * to create sessions for UE data communication, + * commonly referred to as CSR (Create Session Request). + */ + GTPC_V4_FLOW =3D 0x15, /* hash only */ + GTPC_V6_FLOW =3D 0x16, /* hash only */ =20 -/* Use for GTP-C IPv4 and v6. - * Unlike GTPC_V4_FLOW, the format of these GTP packets includes TEID. - * After session creation, it becomes this packet. - * This is mainly used for requests to realize UE handover. - */ -#define GTPC_TEID_V4_FLOW 0x17 /* hash only */ -#define GTPC_TEID_V6_FLOW 0x18 /* hash only */ + /* Use for GTP-C IPv4 and v6. + * Unlike GTPC_V4_FLOW, the format of these GTP packets includes TEID. + * After session creation, it becomes this packet. + * This is mainly used for requests to realize UE handover. + */ + GTPC_TEID_V4_FLOW =3D 0x17, /* hash only */ + GTPC_TEID_V6_FLOW =3D 0x18, /* hash only */ =20 -/* Use for GTP-U and extended headers for the PSC (PDU Session Container). - * The format of these GTP packets includes TEID and QFI. - * In 5G communication using UPF (User Plane Function), - * data communication with this extended header is performed. - */ -#define GTPU_EH_V4_FLOW 0x19 /* hash only */ -#define GTPU_EH_V6_FLOW 0x1a /* hash only */ + /* Use for GTP-U and extended headers for the PSC (PDU Session Container). + * The format of these GTP packets includes TEID and QFI. + * In 5G communication using UPF (User Plane Function), + * data communication with this extended header is performed. + */ + GTPU_EH_V4_FLOW =3D 0x19, /* hash only */ + GTPU_EH_V6_FLOW =3D 0x1a, /* hash only */ =20 -/* Use for GTP-U IPv4 and v6 PSC (PDU Session Container) extended headers. - * This differs from GTPU_EH_V(4|6)_FLOW in that it is distinguished by - * UL/DL included in the PSC. - * There are differences in the data included based on Downlink/Uplink, - * and can be used to distinguish packets. - * The functions described so far are useful when you want to - * handle communication from the mobile network in UPF, PGW, etc. - */ -#define GTPU_UL_V4_FLOW 0x1b /* hash only */ -#define GTPU_UL_V6_FLOW 0x1c /* hash only */ -#define GTPU_DL_V4_FLOW 0x1d /* hash only */ -#define GTPU_DL_V6_FLOW 0x1e /* hash only */ + /* Use for GTP-U IPv4 and v6 PSC (PDU Session Container) extended headers. + * This differs from GTPU_EH_V(4|6)_FLOW in that it is distinguished by + * UL/DL included in the PSC. + * There are differences in the data included based on Downlink/Uplink, + * and can be used to distinguish packets. + * The functions described so far are useful when you want to + * handle communication from the mobile network in UPF, PGW, etc. + */ + GTPU_UL_V4_FLOW =3D 0x1b, /* hash only */ + GTPU_UL_V6_FLOW =3D 0x1c, /* hash only */ + GTPU_DL_V4_FLOW =3D 0x1d, /* hash only */ + GTPU_DL_V6_FLOW =3D 0x1e, /* hash only */ + + __FLOW_TYPE_COUNT, +}; =20 /* Flag to enable additional fields in struct ethtool_rx_flow_spec */ #define FLOW_EXT 0x80000000 diff --git a/include/standard-headers/linux/fuse.h b/include/standard-heade= rs/linux/fuse.h index a2b5815d890..d8b2fd67e16 100644 --- a/include/standard-headers/linux/fuse.h +++ b/include/standard-headers/linux/fuse.h @@ -232,6 +232,9 @@ * * 7.43 * - add FUSE_REQUEST_TIMEOUT + * + * 7.44 + * - add FUSE_NOTIFY_INC_EPOCH */ =20 #ifndef _LINUX_FUSE_H @@ -263,7 +266,7 @@ #define FUSE_KERNEL_VERSION 7 =20 /** Minor version number of this interface */ -#define FUSE_KERNEL_MINOR_VERSION 43 +#define FUSE_KERNEL_MINOR_VERSION 44 =20 /** The node ID of the root inode */ #define FUSE_ROOT_ID 1 @@ -667,6 +670,7 @@ enum fuse_notify_code { FUSE_NOTIFY_RETRIEVE =3D 5, FUSE_NOTIFY_DELETE =3D 6, FUSE_NOTIFY_RESEND =3D 7, + FUSE_NOTIFY_INC_EPOCH =3D 8, FUSE_NOTIFY_CODE_MAX, }; =20 diff --git a/include/standard-headers/linux/input-event-codes.h b/include/s= tandard-headers/linux/input-event-codes.h index 09ba0ad8783..a82ff795e06 100644 --- a/include/standard-headers/linux/input-event-codes.h +++ b/include/standard-headers/linux/input-event-codes.h @@ -925,7 +925,8 @@ #define SW_MUTE_DEVICE 0x0e /* set =3D device disabled */ #define SW_PEN_INSERTED 0x0f /* set =3D pen inserted */ #define SW_MACHINE_COVER 0x10 /* set =3D cover closed */ -#define SW_MAX_ 0x10 +#define SW_USB_INSERT 0x11 /* set =3D USB audio device connected */ +#define SW_MAX_ 0x11 #define SW_CNT (SW_MAX_+1) =20 /* diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-h= eaders/linux/pci_regs.h index ba326710f9c..a3a3e942ded 100644 --- a/include/standard-headers/linux/pci_regs.h +++ b/include/standard-headers/linux/pci_regs.h @@ -750,7 +750,8 @@ #define PCI_EXT_CAP_ID_NPEM 0x29 /* Native PCIe Enclosure Management */ #define PCI_EXT_CAP_ID_PL_32GT 0x2A /* Physical Layer 32.0 GT/s */ #define PCI_EXT_CAP_ID_DOE 0x2E /* Data Object Exchange */ -#define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_DOE +#define PCI_EXT_CAP_ID_PL_64GT 0x31 /* Physical Layer 64.0 GT/s */ +#define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_PL_64GT =20 #define PCI_EXT_CAP_DSN_SIZEOF 12 #define PCI_EXT_CAP_MCAST_ENDPOINT_SIZEOF 40 @@ -1144,12 +1145,21 @@ #define PCI_DLF_CAP 0x04 /* Capabilities Register */ #define PCI_DLF_EXCHANGE_ENABLE 0x80000000 /* Data Link Feature Exchange= Enable */ =20 +/* Secondary PCIe Capability 8.0 GT/s */ +#define PCI_SECPCI_LE_CTRL 0x0c /* Lane Equalization Control Register */ + /* Physical Layer 16.0 GT/s */ #define PCI_PL_16GT_LE_CTRL 0x20 /* Lane Equalization Control Register */ #define PCI_PL_16GT_LE_CTRL_DSP_TX_PRESET_MASK 0x0000000F #define PCI_PL_16GT_LE_CTRL_USP_TX_PRESET_MASK 0x000000F0 #define PCI_PL_16GT_LE_CTRL_USP_TX_PRESET_SHIFT 4 =20 +/* Physical Layer 32.0 GT/s */ +#define PCI_PL_32GT_LE_CTRL 0x20 /* Lane Equalization Control Register */ + +/* Physical Layer 64.0 GT/s */ +#define PCI_PL_64GT_LE_CTRL 0x20 /* Lane Equalization Control Register */ + /* Native PCIe Enclosure Management */ #define PCI_NPEM_CAP 0x04 /* NPEM capability register */ #define PCI_NPEM_CAP_CAPABLE 0x00000001 /* NPEM Capable */ diff --git a/include/standard-headers/linux/virtio_gpu.h b/include/standard= -headers/linux/virtio_gpu.h index 6459fdb9fb5..00cd3f04af9 100644 --- a/include/standard-headers/linux/virtio_gpu.h +++ b/include/standard-headers/linux/virtio_gpu.h @@ -309,8 +309,9 @@ struct virtio_gpu_cmd_submit { =20 #define VIRTIO_GPU_CAPSET_VIRGL 1 #define VIRTIO_GPU_CAPSET_VIRGL2 2 -/* 3 is reserved for gfxstream */ +#define VIRTIO_GPU_CAPSET_GFXSTREAM_VULKAN 3 #define VIRTIO_GPU_CAPSET_VENUS 4 +#define VIRTIO_GPU_CAPSET_CROSS_DOMAIN 5 #define VIRTIO_GPU_CAPSET_DRM 6 =20 /* VIRTIO_GPU_CMD_GET_CAPSET_INFO */ diff --git a/include/standard-headers/linux/virtio_pci.h b/include/standard= -headers/linux/virtio_pci.h index 91fec6f5029..09e964e6eee 100644 --- a/include/standard-headers/linux/virtio_pci.h +++ b/include/standard-headers/linux/virtio_pci.h @@ -246,6 +246,7 @@ struct virtio_pci_cfg_cap { #define VIRTIO_ADMIN_CMD_LIST_USE 0x1 =20 /* Admin command group type. */ +#define VIRTIO_ADMIN_GROUP_TYPE_SELF 0x0 #define VIRTIO_ADMIN_GROUP_TYPE_SRIOV 0x1 =20 /* Transitional device admin command. */ diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h index 4e6aff08df8..f4d9baafa1c 100644 --- a/linux-headers/asm-arm64/kvm.h +++ b/linux-headers/asm-arm64/kvm.h @@ -419,10 +419,11 @@ enum { =20 /* Device Control API on vcpu fd */ #define KVM_ARM_VCPU_PMU_V3_CTRL 0 -#define KVM_ARM_VCPU_PMU_V3_IRQ 0 -#define KVM_ARM_VCPU_PMU_V3_INIT 1 -#define KVM_ARM_VCPU_PMU_V3_FILTER 2 -#define KVM_ARM_VCPU_PMU_V3_SET_PMU 3 +#define KVM_ARM_VCPU_PMU_V3_IRQ 0 +#define KVM_ARM_VCPU_PMU_V3_INIT 1 +#define KVM_ARM_VCPU_PMU_V3_FILTER 2 +#define KVM_ARM_VCPU_PMU_V3_SET_PMU 3 +#define KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTERS 4 #define KVM_ARM_VCPU_TIMER_CTRL 1 #define KVM_ARM_VCPU_TIMER_IRQ_VTIMER 0 #define KVM_ARM_VCPU_TIMER_IRQ_PTIMER 1 diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h index 7fb57ccb2a7..cd275ae76d2 100644 --- a/linux-headers/asm-x86/kvm.h +++ b/linux-headers/asm-x86/kvm.h @@ -843,6 +843,7 @@ struct kvm_sev_snp_launch_start { }; =20 /* Kept in sync with firmware values for simplicity. */ +#define KVM_SEV_PAGE_TYPE_INVALID 0x0 #define KVM_SEV_SNP_PAGE_TYPE_NORMAL 0x1 #define KVM_SEV_SNP_PAGE_TYPE_ZERO 0x3 #define KVM_SEV_SNP_PAGE_TYPE_UNMEASURED 0x4 diff --git a/linux-headers/linux/bits.h b/linux-headers/linux/bits.h index 58596d18f43..9243f389751 100644 --- a/linux-headers/linux/bits.h +++ b/linux-headers/linux/bits.h @@ -4,9 +4,9 @@ #ifndef _LINUX_BITS_H #define _LINUX_BITS_H =20 -#define __GENMASK(h, l) (((~_UL(0)) << (l)) & (~_UL(0) >> (BITS_PER_LONG -= 1 - (h)))) +#define __GENMASK(h, l) (((~_UL(0)) << (l)) & (~_UL(0) >> (__BITS_PER_LONG= - 1 - (h)))) =20 -#define __GENMASK_ULL(h, l) (((~_ULL(0)) << (l)) & (~_ULL(0) >> (BITS_PER_= LONG_LONG - 1 - (h)))) +#define __GENMASK_ULL(h, l) (((~_ULL(0)) << (l)) & (~_ULL(0) >> (__BITS_PE= R_LONG_LONG - 1 - (h)))) =20 #define __GENMASK_U128(h, l) \ ((_BIT128((h)) << 1) - (_BIT128(l))) diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index 99cc82a275c..0690743944b 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -178,6 +178,7 @@ struct kvm_xen_exit { #define KVM_EXIT_NOTIFY 37 #define KVM_EXIT_LOONGARCH_IOCSR 38 #define KVM_EXIT_MEMORY_FAULT 39 +#define KVM_EXIT_TDX 40 =20 /* For KVM_EXIT_INTERNAL_ERROR */ /* Emulate instruction failed. */ @@ -439,6 +440,27 @@ struct kvm_run { __u64 gpa; __u64 size; } memory_fault; + /* KVM_EXIT_TDX */ + struct { + __u64 flags; + __u64 nr; + union { + struct { + __u64 ret; + __u64 data[5]; + } unknown; + struct { + __u64 ret; + __u64 gpa; + __u64 size; + } get_quote; + struct { + __u64 ret; + __u64 leaf; + __u64 r11, r12, r13, r14; + } get_tdvmcall_info; + }; + } tdx; /* Fix the size of the union. */ char padding[256]; }; @@ -923,6 +945,9 @@ struct kvm_enable_cap { #define KVM_CAP_X86_APIC_BUS_CYCLES_NS 237 #define KVM_CAP_X86_GUEST_MODE 238 #define KVM_CAP_ARM_WRITABLE_IMP_ID_REGS 239 +#define KVM_CAP_ARM_EL2 240 +#define KVM_CAP_ARM_EL2_E2H0 241 +#define KVM_CAP_RISCV_MP_STATE_RESET 242 =20 struct kvm_irq_routing_irqchip { __u32 irqchip; diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h index b95dd84eef2..d4b3e2ae131 100644 --- a/linux-headers/linux/vhost.h +++ b/linux-headers/linux/vhost.h @@ -28,10 +28,10 @@ =20 /* Set current process as the (exclusive) owner of this file descriptor. = This * must be called before any other vhost command. Further calls to - * VHOST_OWNER_SET fail until VHOST_OWNER_RESET is called. */ + * VHOST_SET_OWNER fail until VHOST_RESET_OWNER is called. */ #define VHOST_SET_OWNER _IO(VHOST_VIRTIO, 0x01) /* Give up ownership, and reset the device to default values. - * Allows subsequent call to VHOST_OWNER_SET to succeed. */ + * Allows subsequent call to VHOST_SET_OWNER to succeed. */ #define VHOST_RESET_OWNER _IO(VHOST_VIRTIO, 0x02) =20 /* Set up/modify memory layout */ --=20 2.49.0 From nobody Sat Nov 15 14:52:48 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1750365283; cv=none; d=zohomail.com; s=zohoarc; b=IcwZX14ddb9/UwZTV/TeiO1emPOcqe8xT9CeCAv3v39TD27GsEwz26nwBcvBzXPfLcHczVgKW4TbofBeGozt22hl/c1tvP1ez1fUVkweVwMllSr+tzTOqapuX61N2jpCTrqTbtpIroxPR/FYOFrcOoDmXeZy+0u6JazxD0ypoYc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1750365283; h=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=bPyEsEyR+eeawbg8Mgoqk136AaGHZYCr52XL3CFj5p0=; b=UWlAiSTOR1jL9g9IpraNRtvKzzu2ghi+6gV8n9Or139Yhvu/m3pXfGRvR7vgEMCmo66Eb3mDlW3CCIPnxO7dnHZr+aI0OUWQhF8ynZabYj57soQ1/4xncc0h/N53CtGfZ96EXljxayanZ6w8eIf8z4L0POmT7P+9jEbrfsvCFJY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1750365283937937.586699895653; Thu, 19 Jun 2025 13:34:43 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uSLxd-0004cZ-T9; Thu, 19 Jun 2025 16:34:14 -0400 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 1uSLxZ-0004bW-1w for qemu-devel@nongnu.org; Thu, 19 Jun 2025 16:34:09 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uSLxU-0004Yn-SG for qemu-devel@nongnu.org; Thu, 19 Jun 2025 16:34:08 -0400 Received: from mail-ej1-f70.google.com (mail-ej1-f70.google.com [209.85.218.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-643-izfQ6bkgMTyqQoyAOwGJjA-1; Thu, 19 Jun 2025 16:34:02 -0400 Received: by mail-ej1-f70.google.com with SMTP id a640c23a62f3a-acb94dbd01fso119339966b.1 for ; Thu, 19 Jun 2025 13:34:02 -0700 (PDT) Received: from [192.168.122.1] ([151.62.200.93]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ae0541b752asm41145766b.127.2025.06.19.13.33.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Jun 2025 13:33:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1750365244; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=bPyEsEyR+eeawbg8Mgoqk136AaGHZYCr52XL3CFj5p0=; b=GZxm5CNjt2Y0+zxKCSUMDDZ7SGtuBLmStPLBxxulxSbgallUGxTXEvYH5Yae49PyjjYwJs V+CmEkd164044kZ9aQpenAJtkKe4vh6xOgqi6TtLqLDiAVXlKF75lHtH9DSxVLa9e2SyQv EBVtIC1LZZ8mT3ErKRZMafECRtFYp/0= X-MC-Unique: izfQ6bkgMTyqQoyAOwGJjA-1 X-Mimecast-MFC-AGG-ID: izfQ6bkgMTyqQoyAOwGJjA_1750365242 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750365239; x=1750970039; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=bPyEsEyR+eeawbg8Mgoqk136AaGHZYCr52XL3CFj5p0=; b=nGn3a9wYsPs7OZfaaYRC2TfpiEO2wwXZ4QFhf4wiQ74swuu3UIrldsxUuyqQnUafEh B+Ew7zRRwNpDfHWU64Rhir+OdUOC8WDc0QUbfAH/ix3SaVzBnKfU4iV60OvH1eiPDpmJ G0Iz3kikkjS/7/07JklNe8/pLMaGV+vYaiXSpIIx1EjSXi0YNx5jzm04620dNkFvcKxH VsjnrafAZlgOHwkgrvTMmkiX8LnImpIjlkRF0FQf50T+WcpkgCRVGj8N8+5BMjWmrIqw pwEuCIS9q+Arx2NlSOx/RS40Nf0prykK10wLUf1lJqDs614hDPDOZJh+ATKgzYrPTZEP Imlw== X-Gm-Message-State: AOJu0Yxfq1WOzV+wYCQiBGYCIsVwRoFR0W/8G6elSUrmBp15+fQnEDrH uJzOfhLG3+5YUCAa97vaiUy7uKjr8tp3JDcS0G4u5X//hEQN9fFh4AX9bDxL1P33qtpDnODorHe KJCieC6Kvbde1QAnp+Zyl88PLjGO0AqtlocbMXRBZz86kTl2MO9/4abpCepG7b8wCWr/4Ehwfyu 9D1LClZkmyilH3YEJ72aJntCCWxc9CDYqT7SpLUtJu X-Gm-Gg: ASbGncueXz5AqYrUhPpN1WXVRhnOVkTMrCb70drZWPBOGForHxLVjZRruxzJW8iiRP8 ejqSLdmthZ06ROhMVVdDDqmkuFOCvx2hjDvZr8Im9WfenlcmA7acol28jDnjHKjBq+8NdquGRwO yV5LzaHNxQ7q68/S0Xb6YlZqitJru5FBWq3q068xTHQkKipANdv3yV6uLFp7iOd4Pgk6zMG+tvk 6VDPmStLROEyioePZWWhNIYd8UuMukzm8QILzDyHTw0Uhl73limEXiTodYl2UuFoFcbpDCnLpjP 01foeBJ9fiisLQL94johYTDBoQ== X-Received: by 2002:a17:907:94d5:b0:ad8:914b:7d15 with SMTP id a640c23a62f3a-ae057ce90bbmr27097466b.7.1750365238696; Thu, 19 Jun 2025 13:33:58 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFspa6qEcbWBjcSsfoBKt9VZ8tfi8VnIPOGLQGWt4K7GlrErwK1e/N1WYI5/GndLiYNxd5G3w== X-Received: by 2002:a17:907:94d5:b0:ad8:914b:7d15 with SMTP id a640c23a62f3a-ae057ce90bbmr27094966b.7.1750365238220; Thu, 19 Jun 2025 13:33:58 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Chenyi Qiang , Xiaoyao Li , Binbin Wu , =?UTF-8?q?Daniel=20P=20=2E=20Berrang=C3=A9?= Subject: [PATCH 2/3] i386/tdx: handle TDG.VP.VMCALL Date: Thu, 19 Jun 2025 22:33:50 +0200 Message-ID: <20250619203351.393786-3-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250619203351.393786-1-pbonzini@redhat.com> References: <20250619203351.393786-1-pbonzini@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -39 X-Spam_score: -4.0 X-Spam_bar: ---- X-Spam_report: (-4.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.897, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1750365286822116600 Content-Type: text/plain; charset="utf-8" From: Binbin Wu Signed-off-by: Binbin Wu Signed-off-by: Paolo Bonzini --- target/i386/kvm/tdx.h | 9 +++++++++ target/i386/kvm/kvm.c | 12 ++++++++++++ target/i386/kvm/tdx-stub.c | 4 ++++ target/i386/kvm/tdx.c | 12 ++++++++++++ 4 files changed, 37 insertions(+) diff --git a/target/i386/kvm/tdx.h b/target/i386/kvm/tdx.h index 8dd66e90149..0dd41d5811a 100644 --- a/target/i386/kvm/tdx.h +++ b/target/i386/kvm/tdx.h @@ -21,6 +21,14 @@ typedef struct TdxGuestClass { /* TDX requires bus frequency 25MHz */ #define TDX_APIC_BUS_CYCLES_NS 40 =20 +#define TDVMCALL_GET_TD_VM_CALL_INFO 0x10000 + +#define TDG_VP_VMCALL_SUCCESS 0x0000000000000000ULL +#define TDG_VP_VMCALL_RETRY 0x0000000000000001ULL +#define TDG_VP_VMCALL_INVALID_OPERAND 0x8000000000000000ULL +#define TDG_VP_VMCALL_GPA_INUSE 0x8000000000000001ULL +#define TDG_VP_VMCALL_ALIGN_ERROR 0x8000000000000002ULL + enum TdxRamType { TDX_RAM_UNACCEPTED, TDX_RAM_ADDED, @@ -61,5 +69,6 @@ int tdx_pre_create_vcpu(CPUState *cpu, Error **errp); void tdx_set_tdvf_region(MemoryRegion *tdvf_mr); int tdx_parse_tdvf(void *flash_ptr, int size); int tdx_handle_report_fatal_error(X86CPU *cpu, struct kvm_run *run); +void tdx_handle_get_tdvmcall_info(X86CPU *cpu, struct kvm_run *run); =20 #endif /* QEMU_I386_TDX_H */ diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index 56a6b9b6381..8ef29fc1fb1 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -6170,6 +6170,18 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_ru= n *run) break; } break; + case KVM_EXIT_TDX: + /* + * run->tdx is already set up for the case where userspace + * does not handle the TDVMCALL. + */ + switch (run->tdx.nr) { + case TDVMCALL_GET_TD_VM_CALL_INFO: + tdx_handle_get_tdvmcall_info(cpu, run); + break; + } + ret =3D 0; + break; default: fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason); ret =3D -1; diff --git a/target/i386/kvm/tdx-stub.c b/target/i386/kvm/tdx-stub.c index 720a4ff046e..62a12a06775 100644 --- a/target/i386/kvm/tdx-stub.c +++ b/target/i386/kvm/tdx-stub.c @@ -18,3 +18,7 @@ int tdx_handle_report_fatal_error(X86CPU *cpu, struct kvm= _run *run) { return -EINVAL; } + +void tdx_handle_get_tdvmcall_info(X86CPU *cpu, struct kvm_run *run) +{ +} diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c index 2284167141a..ef10a193474 100644 --- a/target/i386/kvm/tdx.c +++ b/target/i386/kvm/tdx.c @@ -1120,6 +1120,18 @@ int tdx_parse_tdvf(void *flash_ptr, int size) return tdvf_parse_metadata(&tdx_guest->tdvf, flash_ptr, size); } =20 +void tdx_handle_get_tdvmcall_info(X86CPU *cpu, struct kvm_run *run) +{ + if (run->tdx.get_tdvmcall_info.leaf !=3D 1) { + return; + } + + run->tdx.get_tdvmcall_info.r11 =3D 0; + run->tdx.get_tdvmcall_info.r12 =3D 0; + run->tdx.get_tdvmcall_info.r13 =3D 0; + run->tdx.get_tdvmcall_info.r14 =3D 0; +} + static void tdx_panicked_on_fatal_error(X86CPU *cpu, uint64_t error_code, char *message, uint64_t gpa) { --=20 2.49.0 From nobody Sat Nov 15 14:52:48 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1750365283; cv=none; d=zohomail.com; s=zohoarc; b=KFjXR9Uurw42D2cCVqLJV1W5x0I1zKfxNRNtB1Guvd+TBrsITzgAJoYF/D977nQ6SC5yqasvM9l33GlwR7IhngLajPY86yQr7gKppeRCwO5jeXNo88FE/Ic/AIIN6gc75LOKmRUFpyGYGgSNWNBhQDz0rcPpayiRsjIGtlZBNC8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1750365283; h=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=nP4/xmXgoWwEeOWstM+jOCgiaO7q5I1raUinwNjCcjE=; b=RIOkijYjFqYB142+h3uHNMJSLTwE7lM9kmPWV78Kku929WPSDZxwHI5cBclcO7CpwU4akB6IL1pd8AU4zRRbhqz0ljxBCRuXDRUtdYJcDsEB4gwugwZPDeEmkay1Y3IdG8eWCnx5doIEPtOr7dB+wTrCQ9NCr8qk9ZbrzqtANyg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1750365283770867.0085148369201; Thu, 19 Jun 2025 13:34:43 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uSLxd-0004cn-TV; Thu, 19 Jun 2025 16:34:14 -0400 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 1uSLxb-0004c5-6R for qemu-devel@nongnu.org; Thu, 19 Jun 2025 16:34:11 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uSLxY-0004Z5-56 for qemu-devel@nongnu.org; Thu, 19 Jun 2025 16:34:10 -0400 Received: from mail-ej1-f69.google.com (mail-ej1-f69.google.com [209.85.218.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-147-B_GhuDD9NAOtoM7KuL8ybA-1; Thu, 19 Jun 2025 16:34:05 -0400 Received: by mail-ej1-f69.google.com with SMTP id a640c23a62f3a-ade5b98537dso117665066b.2 for ; Thu, 19 Jun 2025 13:34:05 -0700 (PDT) Received: from [192.168.122.1] ([151.62.200.93]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-60a18ce62f9sm376748a12.68.2025.06.19.13.33.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Jun 2025 13:33:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1750365246; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nP4/xmXgoWwEeOWstM+jOCgiaO7q5I1raUinwNjCcjE=; b=cHK+lKKPjvA4xqaJsxOUluPGY5MRjYKcwZYPvl27G6YsGlZZqUJQx0f9oCD8+M/qDK9XYw aCIOxzoG/Ez0vVima9pGr1t++q2k05dqHPz4XrjdqskAVbxJncBgxcW0aVnfN9C6iAF2y9 lYeLK4jvF7vI4O9DK2WSxTMAkUcyypg= X-MC-Unique: B_GhuDD9NAOtoM7KuL8ybA-1 X-Mimecast-MFC-AGG-ID: B_GhuDD9NAOtoM7KuL8ybA_1750365244 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750365244; x=1750970044; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=nP4/xmXgoWwEeOWstM+jOCgiaO7q5I1raUinwNjCcjE=; b=tcGA/3B1rDCLWG+Po2WykKaLKsyMuhmWl29xBiTVEmZCmdM7hBxZjhPVHBZy24iGBo qY0gnPHY9sgKs6gDArOlAfdBKTTD4RnbYabAij5uOsYJSFUPpV8wvgZDBwzDtzcDW+oF 2tk0M1iJFWF4SIuhO/hJzE44YNFhMnfAMa2tq6mfMmJQdSi6+5Vjz9iViZE2pQPkF6f0 yc01Qjlb8NLImjpIkj+9YFWcq8LgjbKJMH114KUWv5a/13RkpDP9/2M3K5SbAtCKLCuT 2YuUPWFCvWCvTpj75udZIY5iIUQPtPgCDfbDDY8/H5z5yklu6UgocPdnq0updeMMxHhL enIQ== X-Gm-Message-State: AOJu0YziPtvnZCkI1026bmwYi7yVq/oEb/E60sud+fjzNDgaY1DzdTUg va10MOyhrZv5/7H4r3uQbVFSQ2fAXSYsypadb2hRZPIkwk/DPLQGczvSQdT8LM8uRpsbmi96YBX R9mInux3+2mefGEPgUMnEkv8xZM97/1BaCUAjcPu25d7jbPr+BpVlHUfsCAkOJeMzCmZkwjmrE4 8skwYAG2koHfTebreCwm7MtfzcXIH3hPGPMw0ScWN4 X-Gm-Gg: ASbGncvcXn87UYmG8UxfNKgpWjreJGCLRfBDKcUberbDTlUv4yyW6JCTJyNBO+egNgc nUm1bhaM6NYeQRTKS5EbDpd7URLe3e5cG5h3uAdEqd0zRnEwA1MxZLq6fQ31p6htUecBsea4eFx 71BnnGSSt13SqPdp2vmOVGEIxtq7opgo+3RWD9RnT4TMTKbR7BHNC+Ns0h2GrxRzFCoyCUICdb7 0XgIKM8mfBMyPilEyeT2xlXfULttxWLoLI176yt2wf9CXYcRblAUHTSukDX9vnZ4O3SfcHfBasr EwRBCRsTt5ObMMIm7XUKqrzq7A== X-Received: by 2002:a05:6402:1d4b:b0:607:6057:9006 with SMTP id 4fb4d7f45d1cf-60a1ccb41c0mr368565a12.8.1750365243393; Thu, 19 Jun 2025 13:34:03 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEN3k/wv1tZk33fuLi0gCkniflHsKhzLCD2FxVPRF226cqRassukJbTqWW1pUogHC+5LKzLDA== X-Received: by 2002:a05:6402:1d4b:b0:607:6057:9006 with SMTP id 4fb4d7f45d1cf-60a1ccb41c0mr368534a12.8.1750365242694; Thu, 19 Jun 2025 13:34:02 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Chenyi Qiang , Xiaoyao Li , Binbin Wu , =?UTF-8?q?Daniel=20P=20=2E=20Berrang=C3=A9?= , Isaku Yamahata Subject: [PATCH 3/3] i386/tdx: handle TDG.VP.VMCALL Date: Thu, 19 Jun 2025 22:33:51 +0200 Message-ID: <20250619203351.393786-4-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250619203351.393786-1-pbonzini@redhat.com> References: <20250619203351.393786-1-pbonzini@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -39 X-Spam_score: -4.0 X-Spam_bar: ---- X-Spam_report: (-4.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.897, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1750365285142116600 Content-Type: text/plain; charset="utf-8" From: Isaku Yamahata Add property "quote-generation-socket" to tdx-guest, which is a property of type SocketAddress to specify Quote Generation Service(QGS). On request of GetQuote, it connects to the QGS socket, read request data from shared guest memory, send the request data to the QGS, and store the response into shared guest memory, at last notify TD guest by interrupt. command line example: qemu-system-x86_64 \ -object '{"qom-type":"tdx-guest","id":"tdx0","quote-generation-socket":= {"type":"unix", "path":"/var/run/tdx-qgs/qgs.socket"}}' \ -machine confidential-guest-support=3Dtdx0 Note, above example uses the unix socket. It can be other types, like vsock, which depends on the implementation of QGS. To avoid no response from QGS server, setup a timer for the transaction. If timeout, make it an error and interrupt guest. Define the threshold of time to 30s at present, maybe change to other value if not appropriate. Signed-off-by: Isaku Yamahata Co-developed-by: Chenyi Qiang Signed-off-by: Chenyi Qiang Co-developed-by: Xiaoyao Li Signed-off-by: Xiaoyao Li Signed-off-by: Paolo Bonzini --- qapi/qom.json | 8 +- target/i386/kvm/tdx-quote-generator.h | 82 +++++++ target/i386/kvm/tdx.h | 10 + target/i386/kvm/kvm.c | 3 + target/i386/kvm/tdx-quote-generator.c | 300 ++++++++++++++++++++++++++ target/i386/kvm/tdx-stub.c | 4 + target/i386/kvm/tdx.c | 176 ++++++++++++++- target/i386/kvm/meson.build | 2 +- 8 files changed, 582 insertions(+), 3 deletions(-) create mode 100644 target/i386/kvm/tdx-quote-generator.h create mode 100644 target/i386/kvm/tdx-quote-generator.c diff --git a/qapi/qom.json b/qapi/qom.json index 3e8debf78c2..b133b064471 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -1071,6 +1071,11 @@ # e.g., specific to the workload rather than the run-time or OS # (base64 encoded SHA384 digest). Defaults to all zeros. # +# @quote-generation-socket: socket address for Quote Generation +# Service (QGS). QGS is a daemon running on the host. Without +# it, the guest will not be able to get a TD quote for +# attestation. +# # Since: 10.1 ## { 'struct': 'TdxGuestProperties', @@ -1078,7 +1083,8 @@ '*sept-ve-disable': 'bool', '*mrconfigid': 'str', '*mrowner': 'str', - '*mrownerconfig': 'str' } } + '*mrownerconfig': 'str', + '*quote-generation-socket': 'SocketAddress' } } =20 ## # @ThreadContextProperties: diff --git a/target/i386/kvm/tdx-quote-generator.h b/target/i386/kvm/tdx-qu= ote-generator.h new file mode 100644 index 00000000000..3bd9b8ef331 --- /dev/null +++ b/target/i386/kvm/tdx-quote-generator.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef QEMU_I386_TDX_QUOTE_GENERATOR_H +#define QEMU_I386_TDX_QUOTE_GENERATOR_H + +#include "qom/object_interfaces.h" +#include "io/channel-socket.h" +#include "exec/hwaddr.h" + +#define TDX_GET_QUOTE_STRUCTURE_VERSION 1ULL + +#define TDX_VP_GET_QUOTE_SUCCESS 0ULL +#define TDX_VP_GET_QUOTE_IN_FLIGHT (-1ULL) +#define TDX_VP_GET_QUOTE_ERROR 0x8000000000000000ULL +#define TDX_VP_GET_QUOTE_QGS_UNAVAILABLE 0x8000000000000001ULL + +/* Limit to avoid resource starvation. */ +#define TDX_GET_QUOTE_MAX_BUF_LEN (128 * 1024) +#define TDX_MAX_GET_QUOTE_REQUEST 16 + +#define TDX_GET_QUOTE_HDR_SIZE 24 + +/* Format of pages shared with guest. */ +struct tdx_get_quote_header { + /* Format version: must be 1 in little endian. */ + uint64_t structure_version; + + /* + * GetQuote status code in little endian: + * Guest must set error_code to 0 to avoid information leak. + * Qemu sets this before interrupting guest. + */ + uint64_t error_code; + + /* + * in-message size in little endian: The message will follow this head= er. + * The in-message will be send to QGS. + */ + uint32_t in_len; + + /* + * out-message size in little endian: + * On request, out_len must be zero to avoid information leak. + * On return, message size from QGS. Qemu overwrites this field. + * The message will follows this header. The in-message is overwritte= n. + */ + uint32_t out_len; + + /* + * Message buffer follows. + * Guest sets message that will be send to QGS. If out_len > in_len, = guest + * should zero remaining buffer to avoid information leak. + * Qemu overwrites this buffer with a message returned from QGS. + */ +}; + +typedef struct TdxGenerateQuoteTask { + hwaddr buf_gpa; + hwaddr payload_gpa; + uint64_t payload_len; + + char *send_data; + uint64_t send_data_size; + uint64_t send_data_sent; + + char *receive_buf; + uint64_t receive_buf_received; + + uint64_t status_code; + struct tdx_get_quote_header hdr; + + QIOChannelSocket *sioc; + guint watch; + QEMUTimer timer; + + void (*completion)(struct TdxGenerateQuoteTask *task); + void *opaque; +} TdxGenerateQuoteTask; + +void tdx_generate_quote(TdxGenerateQuoteTask *task, SocketAddress *qg_sock= _addr); + +#endif /* QEMU_I386_TDX_QUOTE_GENERATOR_H */ diff --git a/target/i386/kvm/tdx.h b/target/i386/kvm/tdx.h index 0dd41d5811a..35a09c19c52 100644 --- a/target/i386/kvm/tdx.h +++ b/target/i386/kvm/tdx.h @@ -11,6 +11,8 @@ #include "cpu.h" #include "hw/i386/tdvf.h" =20 +#include "tdx-quote-generator.h" + #define TYPE_TDX_GUEST "tdx-guest" #define TDX_GUEST(obj) OBJECT_CHECK(TdxGuest, (obj), TYPE_TDX_GUEST) =20 @@ -22,6 +24,7 @@ typedef struct TdxGuestClass { #define TDX_APIC_BUS_CYCLES_NS 40 =20 #define TDVMCALL_GET_TD_VM_CALL_INFO 0x10000 +#define TDVMCALL_GET_QUOTE 0x10002 =20 #define TDG_VP_VMCALL_SUCCESS 0x0000000000000000ULL #define TDG_VP_VMCALL_RETRY 0x0000000000000001ULL @@ -29,6 +32,8 @@ typedef struct TdxGuestClass { #define TDG_VP_VMCALL_GPA_INUSE 0x8000000000000001ULL #define TDG_VP_VMCALL_ALIGN_ERROR 0x8000000000000002ULL =20 +#define TDG_VP_VMCALL_SUBFUNC_GET_QUOTE 0x0000000000000001ULL + enum TdxRamType { TDX_RAM_UNACCEPTED, TDX_RAM_ADDED, @@ -57,6 +62,10 @@ typedef struct TdxGuest { =20 uint32_t nr_ram_entries; TdxRamEntry *ram_entries; + + /* GetQuote */ + SocketAddress *qg_sock_addr; + int num; } TdxGuest; =20 #ifdef CONFIG_TDX @@ -69,6 +78,7 @@ int tdx_pre_create_vcpu(CPUState *cpu, Error **errp); void tdx_set_tdvf_region(MemoryRegion *tdvf_mr); int tdx_parse_tdvf(void *flash_ptr, int size); int tdx_handle_report_fatal_error(X86CPU *cpu, struct kvm_run *run); +void tdx_handle_get_quote(X86CPU *cpu, struct kvm_run *run); void tdx_handle_get_tdvmcall_info(X86CPU *cpu, struct kvm_run *run); =20 #endif /* QEMU_I386_TDX_H */ diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index 8ef29fc1fb1..234878c613f 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -6176,6 +6176,9 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run= *run) * does not handle the TDVMCALL. */ switch (run->tdx.nr) { + case TDVMCALL_GET_QUOTE: + tdx_handle_get_quote(cpu, run); + break; case TDVMCALL_GET_TD_VM_CALL_INFO: tdx_handle_get_tdvmcall_info(cpu, run); break; diff --git a/target/i386/kvm/tdx-quote-generator.c b/target/i386/kvm/tdx-qu= ote-generator.c new file mode 100644 index 00000000000..f59715f6175 --- /dev/null +++ b/target/i386/kvm/tdx-quote-generator.c @@ -0,0 +1,300 @@ +/* + * QEMU TDX Quote Generation Support + * + * Copyright (c) 2025 Intel Corporation + * + * Author: + * Xiaoyao Li + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/error-report.h" +#include "qapi/error.h" +#include "qapi/qapi-visit-sockets.h" + +#include "tdx-quote-generator.h" + +#define QGS_MSG_LIB_MAJOR_VER 1 +#define QGS_MSG_LIB_MINOR_VER 1 + +typedef enum _qgs_msg_type_t { + GET_QUOTE_REQ =3D 0, + GET_QUOTE_RESP =3D 1, + GET_COLLATERAL_REQ =3D 2, + GET_COLLATERAL_RESP =3D 3, + GET_PLATFORM_INFO_REQ =3D 4, + GET_PLATFORM_INFO_RESP =3D 5, + QGS_MSG_TYPE_MAX +} qgs_msg_type_t; + +typedef struct _qgs_msg_header_t { + uint16_t major_version; + uint16_t minor_version; + uint32_t type; + uint32_t size; // size of the whole message, include this= header, in byte + uint32_t error_code; // used in response only +} qgs_msg_header_t; + +typedef struct _qgs_msg_get_quote_req_t { + qgs_msg_header_t header; // header.type =3D GET_QUOTE_REQ + uint32_t report_size; // cannot be 0 + uint32_t id_list_size; // length of id_list, in byte, can be 0 +} qgs_msg_get_quote_req_t; + +typedef struct _qgs_msg_get_quote_resp_s { + qgs_msg_header_t header; // header.type =3D GET_QUOTE_RESP + uint32_t selected_id_size; // can be 0 in case only one id is sent in= request + uint32_t quote_size; // length of quote_data, in byte + uint8_t id_quote[]; // selected id followed by quote +} qgs_msg_get_quote_resp_t; + +#define HEADER_SIZE 4 + +static uint32_t decode_header(const char *buf, size_t len) { + if (len < HEADER_SIZE) { + return 0; + } + uint32_t msg_size =3D 0; + for (uint32_t i =3D 0; i < HEADER_SIZE; ++i) { + msg_size =3D msg_size * 256 + (buf[i] & 0xFF); + } + return msg_size; +} + +static void encode_header(char *buf, size_t len, uint32_t size) { + assert(len >=3D HEADER_SIZE); + buf[0] =3D ((size >> 24) & 0xFF); + buf[1] =3D ((size >> 16) & 0xFF); + buf[2] =3D ((size >> 8) & 0xFF); + buf[3] =3D (size & 0xFF); +} + +static void tdx_generate_quote_cleanup(TdxGenerateQuoteTask *task) +{ + timer_del(&task->timer); + + g_source_remove(task->watch); + qio_channel_close(QIO_CHANNEL(task->sioc), NULL); + object_unref(OBJECT(task->sioc)); + + task->completion(task); +} + +static gboolean tdx_get_quote_read(QIOChannel *ioc, GIOCondition condition, + gpointer opaque) +{ + TdxGenerateQuoteTask *task =3D opaque; + Error *err =3D NULL; + int ret; + + ret =3D qio_channel_read(ioc, task->receive_buf + task->receive_buf_re= ceived, + task->payload_len - task->receive_buf_received,= &err); + if (ret < 0) { + if (ret =3D=3D QIO_CHANNEL_ERR_BLOCK) { + return G_SOURCE_CONTINUE; + } else { + error_report_err(err); + task->status_code =3D TDX_VP_GET_QUOTE_ERROR; + goto end; + } + } + + if (ret =3D=3D 0) { + error_report("End of file before reply received"); + task->status_code =3D TDX_VP_GET_QUOTE_ERROR; + goto end; + } + + task->receive_buf_received +=3D ret; + if (task->receive_buf_received >=3D HEADER_SIZE) { + uint32_t len =3D decode_header(task->receive_buf, + task->receive_buf_received); + if (len =3D=3D 0 || + len > (task->payload_len - HEADER_SIZE)) { + error_report("Message len %u must be non-zero & less than %zu", + len, (task->payload_len - HEADER_SIZE)); + task->status_code =3D TDX_VP_GET_QUOTE_ERROR; + goto end; + } + + /* Now we know the size, shrink to fit */ + task->payload_len =3D HEADER_SIZE + len; + task->receive_buf =3D g_renew(char, + task->receive_buf, + task->payload_len); + } + + if (task->receive_buf_received >=3D (sizeof(qgs_msg_header_t) + HEADER= _SIZE)) { + qgs_msg_header_t *hdr =3D (qgs_msg_header_t *)(task->receive_buf += HEADER_SIZE); + if (hdr->major_version !=3D QGS_MSG_LIB_MAJOR_VER || + hdr->minor_version !=3D QGS_MSG_LIB_MINOR_VER) { + error_report("Invalid QGS message header version %d.%d", + hdr->major_version, + hdr->minor_version); + task->status_code =3D TDX_VP_GET_QUOTE_ERROR; + goto end; + } + if (hdr->type !=3D GET_QUOTE_RESP) { + error_report("Invalid QGS message type %d", + hdr->type); + task->status_code =3D TDX_VP_GET_QUOTE_ERROR; + goto end; + } + if (hdr->size > (task->payload_len - HEADER_SIZE)) { + error_report("QGS message size %d exceeds payload capacity %zu= ", + hdr->size, task->payload_len); + task->status_code =3D TDX_VP_GET_QUOTE_ERROR; + goto end; + } + if (hdr->error_code !=3D 0) { + error_report("QGS message error code %d", + hdr->error_code); + task->status_code =3D TDX_VP_GET_QUOTE_ERROR; + goto end; + } + } + if (task->receive_buf_received >=3D (sizeof(qgs_msg_get_quote_resp_t) = + HEADER_SIZE)) { + qgs_msg_get_quote_resp_t *msg =3D (qgs_msg_get_quote_resp_t *)(tas= k->receive_buf + HEADER_SIZE); + if (msg->selected_id_size !=3D 0) { + error_report("QGS message selected ID was %d not 0", + msg->selected_id_size); + task->status_code =3D TDX_VP_GET_QUOTE_ERROR; + goto end; + } + + if ((task->payload_len - HEADER_SIZE - sizeof(qgs_msg_get_quote_re= sp_t)) !=3D + msg->quote_size) { + error_report("QGS quote size %d should be %zu", + msg->quote_size, + (task->payload_len - sizeof(qgs_msg_get_quote_res= p_t))); + task->status_code =3D TDX_VP_GET_QUOTE_ERROR; + goto end; + } + } + + if (task->receive_buf_received =3D=3D task->payload_len) { + size_t strip =3D HEADER_SIZE + sizeof(qgs_msg_get_quote_resp_t); + memmove(task->receive_buf, + task->receive_buf + strip, + task->receive_buf_received - strip); + task->receive_buf_received -=3D strip; + task->status_code =3D TDX_VP_GET_QUOTE_SUCCESS; + goto end; + } + + return G_SOURCE_CONTINUE; + +end: + tdx_generate_quote_cleanup(task); + return G_SOURCE_REMOVE; +} + +static gboolean tdx_send_report(QIOChannel *ioc, GIOCondition condition, + gpointer opaque) +{ + TdxGenerateQuoteTask *task =3D opaque; + Error *err =3D NULL; + int ret; + + ret =3D qio_channel_write(ioc, task->send_data + task->send_data_sent, + task->send_data_size - task->send_data_sent, &= err); + if (ret < 0) { + if (ret =3D=3D QIO_CHANNEL_ERR_BLOCK) { + ret =3D 0; + } else { + error_report_err(err); + task->status_code =3D TDX_VP_GET_QUOTE_ERROR; + tdx_generate_quote_cleanup(task); + goto end; + } + } + task->send_data_sent +=3D ret; + + if (task->send_data_sent =3D=3D task->send_data_size) { + task->watch =3D qio_channel_add_watch(QIO_CHANNEL(task->sioc), G_I= O_IN, + tdx_get_quote_read, task, NULL= ); + goto end; + } + + return G_SOURCE_CONTINUE; + +end: + return G_SOURCE_REMOVE; +} + +static void tdx_quote_generator_connected(QIOTask *qio_task, gpointer opaq= ue) +{ + TdxGenerateQuoteTask *task =3D opaque; + Error *err =3D NULL; + int ret; + + ret =3D qio_task_propagate_error(qio_task, &err); + if (ret) { + error_report_err(err); + task->status_code =3D TDX_VP_GET_QUOTE_QGS_UNAVAILABLE; + tdx_generate_quote_cleanup(task); + return; + } + + task->watch =3D qio_channel_add_watch(QIO_CHANNEL(task->sioc), G_IO_OU= T, + tdx_send_report, task, NULL); +} + +#define TRANSACTION_TIMEOUT 30000 + +static void getquote_expired(void *opaque) +{ + TdxGenerateQuoteTask *task =3D opaque; + + task->status_code =3D TDX_VP_GET_QUOTE_ERROR; + tdx_generate_quote_cleanup(task); +} + +static void setup_get_quote_timer(TdxGenerateQuoteTask *task) +{ + int64_t time; + + timer_init_ms(&task->timer, QEMU_CLOCK_VIRTUAL, getquote_expired, task= ); + time =3D qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL); + timer_mod(&task->timer, time + TRANSACTION_TIMEOUT); +} + +void tdx_generate_quote(TdxGenerateQuoteTask *task, + SocketAddress *qg_sock_addr) +{ + QIOChannelSocket *sioc; + qgs_msg_get_quote_req_t msg; + + /* Prepare a QGS message prelude */ + msg.header.major_version =3D QGS_MSG_LIB_MAJOR_VER; + msg.header.minor_version =3D QGS_MSG_LIB_MINOR_VER; + msg.header.type =3D GET_QUOTE_REQ; + msg.header.size =3D sizeof(msg) + task->send_data_size; + msg.header.error_code =3D 0; + msg.report_size =3D task->send_data_size; + msg.id_list_size =3D 0; + + /* Make room to add the QGS message prelude */ + task->send_data =3D g_renew(char, + task->send_data, + task->send_data_size + sizeof(msg) + HEADER_= SIZE); + memmove(task->send_data + sizeof(msg) + HEADER_SIZE, + task->send_data, + task->send_data_size); + memcpy(task->send_data + HEADER_SIZE, + &msg, + sizeof(msg)); + encode_header(task->send_data, HEADER_SIZE, task->send_data_size + siz= eof(msg)); + task->send_data_size +=3D sizeof(msg) + HEADER_SIZE; + + sioc =3D qio_channel_socket_new(); + task->sioc =3D sioc; + + setup_get_quote_timer(task); + + qio_channel_socket_connect_async(sioc, qg_sock_addr, + tdx_quote_generator_connected, task, + NULL, NULL); +} diff --git a/target/i386/kvm/tdx-stub.c b/target/i386/kvm/tdx-stub.c index 62a12a06775..76fee49eff0 100644 --- a/target/i386/kvm/tdx-stub.c +++ b/target/i386/kvm/tdx-stub.c @@ -19,6 +19,10 @@ int tdx_handle_report_fatal_error(X86CPU *cpu, struct kv= m_run *run) return -EINVAL; } =20 +void tdx_handle_get_quote(X86CPU *cpu, struct kvm_run *run) +{ +} + void tdx_handle_get_tdvmcall_info(X86CPU *cpu, struct kvm_run *run) { } diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c index ef10a193474..e809e4b2dfa 100644 --- a/target/i386/kvm/tdx.c +++ b/target/i386/kvm/tdx.c @@ -14,12 +14,14 @@ #include "qemu/base64.h" #include "qemu/mmap-alloc.h" #include "qapi/error.h" +#include "qapi/qapi-visit-sockets.h" #include "qom/object_interfaces.h" #include "crypto/hash.h" #include "system/kvm_int.h" #include "system/runstate.h" #include "system/system.h" #include "system/ramblock.h" +#include "system/address-spaces.h" =20 #include =20 @@ -32,6 +34,7 @@ #include "hw/i386/tdvf-hob.h" #include "kvm_i386.h" #include "tdx.h" +#include "tdx-quote-generator.h" =20 #include "standard-headers/asm-x86/kvm_para.h" =20 @@ -1120,13 +1123,146 @@ int tdx_parse_tdvf(void *flash_ptr, int size) return tdvf_parse_metadata(&tdx_guest->tdvf, flash_ptr, size); } =20 +static void tdx_get_quote_completion(TdxGenerateQuoteTask *task) +{ + TdxGuest *tdx =3D task->opaque; + int ret; + + /* Maintain the number of in-flight requests. */ + qemu_mutex_lock(&tdx->lock); + tdx->num--; + qemu_mutex_unlock(&tdx->lock); + + if (task->status_code =3D=3D TDX_VP_GET_QUOTE_SUCCESS) { + ret =3D address_space_write(&address_space_memory, task->payload_g= pa, + MEMTXATTRS_UNSPECIFIED, task->receive_bu= f, + task->receive_buf_received); + if (ret !=3D MEMTX_OK) { + error_report("TDX: get-quote: failed to write quote data."); + } else { + task->hdr.out_len =3D cpu_to_le64(task->receive_buf_received); + } + } + task->hdr.error_code =3D cpu_to_le64(task->status_code); + + /* Publish the response contents before marking this request completed= . */ + smp_wmb(); + ret =3D address_space_write(&address_space_memory, task->buf_gpa, + MEMTXATTRS_UNSPECIFIED, &task->hdr, + TDX_GET_QUOTE_HDR_SIZE); + if (ret !=3D MEMTX_OK) { + error_report("TDX: get-quote: failed to update GetQuote header."); + } + + g_free(task->send_data); + g_free(task->receive_buf); + g_free(task); + object_unref(tdx); +} + +void tdx_handle_get_quote(X86CPU *cpu, struct kvm_run *run) +{ + TdxGenerateQuoteTask *task; + struct tdx_get_quote_header hdr; + hwaddr buf_gpa =3D run->tdx.get_quote.gpa; + uint64_t buf_len =3D run->tdx.get_quote.size; + + QEMU_BUILD_BUG_ON(sizeof(struct tdx_get_quote_header) !=3D TDX_GET_QUO= TE_HDR_SIZE); + + run->tdx.get_quote.ret =3D TDG_VP_VMCALL_INVALID_OPERAND; + + if (buf_len =3D=3D 0) { + return; + } + + if (!QEMU_IS_ALIGNED(buf_gpa, 4096) || !QEMU_IS_ALIGNED(buf_len, 4096)= ) { + run->tdx.get_quote.ret =3D TDG_VP_VMCALL_ALIGN_ERROR; + return; + } + + if (address_space_read(&address_space_memory, buf_gpa, MEMTXATTRS_UNSP= ECIFIED, + &hdr, TDX_GET_QUOTE_HDR_SIZE) !=3D MEMTX_OK) { + error_report("TDX: get-quote: failed to read GetQuote header."); + return; + } + + if (le64_to_cpu(hdr.structure_version) !=3D TDX_GET_QUOTE_STRUCTURE_VE= RSION) { + return; + } + + /* Only safe-guard check to avoid too large buffer size. */ + if (buf_len > TDX_GET_QUOTE_MAX_BUF_LEN || + le32_to_cpu(hdr.in_len) > buf_len - TDX_GET_QUOTE_HDR_SIZE) { + return; + } + + if (!tdx_guest->qg_sock_addr) { + hdr.error_code =3D cpu_to_le64(TDX_VP_GET_QUOTE_QGS_UNAVAILABLE); + if (address_space_write(&address_space_memory, buf_gpa, + MEMTXATTRS_UNSPECIFIED, + &hdr, TDX_GET_QUOTE_HDR_SIZE) !=3D MEMTX_O= K) { + error_report("TDX: failed to update GetQuote header."); + return; + } + run->tdx.get_quote.ret =3D TDG_VP_VMCALL_SUCCESS; + return; + } + + qemu_mutex_lock(&tdx_guest->lock); + if (tdx_guest->num >=3D TDX_MAX_GET_QUOTE_REQUEST) { + qemu_mutex_unlock(&tdx_guest->lock); + run->tdx.get_quote.ret =3D TDG_VP_VMCALL_RETRY; + return; + } + tdx_guest->num++; + qemu_mutex_unlock(&tdx_guest->lock); + + task =3D g_new(TdxGenerateQuoteTask, 1); + task->buf_gpa =3D buf_gpa; + task->payload_gpa =3D buf_gpa + TDX_GET_QUOTE_HDR_SIZE; + task->payload_len =3D buf_len - TDX_GET_QUOTE_HDR_SIZE; + task->hdr =3D hdr; + task->completion =3D tdx_get_quote_completion; + + task->send_data_size =3D le32_to_cpu(hdr.in_len); + task->send_data =3D g_malloc(task->send_data_size); + task->send_data_sent =3D 0; + + if (address_space_read(&address_space_memory, task->payload_gpa, + MEMTXATTRS_UNSPECIFIED, task->send_data, + task->send_data_size) !=3D MEMTX_OK) { + goto out_free; + } + + /* Mark the buffer in-flight. */ + hdr.error_code =3D cpu_to_le64(TDX_VP_GET_QUOTE_IN_FLIGHT); + if (address_space_write(&address_space_memory, buf_gpa, + MEMTXATTRS_UNSPECIFIED, + &hdr, TDX_GET_QUOTE_HDR_SIZE) !=3D MEMTX_OK) { + goto out_free; + } + + task->receive_buf =3D g_malloc0(task->payload_len); + task->receive_buf_received =3D 0; + task->opaque =3D tdx_guest; + + object_ref(tdx_guest); + tdx_generate_quote(task, tdx_guest->qg_sock_addr); + run->tdx.get_quote.ret =3D TDG_VP_VMCALL_SUCCESS; + return; + +out_free: + g_free(task->send_data); + g_free(task); +} + void tdx_handle_get_tdvmcall_info(X86CPU *cpu, struct kvm_run *run) { if (run->tdx.get_tdvmcall_info.leaf !=3D 1) { return; } =20 - run->tdx.get_tdvmcall_info.r11 =3D 0; + run->tdx.get_tdvmcall_info.r11 =3D TDG_VP_VMCALL_SUBFUNC_GET_QUOTE; run->tdx.get_tdvmcall_info.r12 =3D 0; run->tdx.get_tdvmcall_info.r13 =3D 0; run->tdx.get_tdvmcall_info.r14 =3D 0; @@ -1263,6 +1399,37 @@ static void tdx_guest_set_mrownerconfig(Object *obj,= const char *value, Error ** tdx->mrownerconfig =3D g_strdup(value); } =20 +static void tdx_guest_get_qgs(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + TdxGuest *tdx =3D TDX_GUEST(obj); + + if (!tdx->qg_sock_addr) { + error_setg(errp, "quote-generation-socket is not set"); + return; + } + visit_type_SocketAddress(v, name, &tdx->qg_sock_addr, errp); +} + +static void tdx_guest_set_qgs(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + TdxGuest *tdx =3D TDX_GUEST(obj); + SocketAddress *sock =3D NULL; + + if (!visit_type_SocketAddress(v, name, &sock, errp)) { + return; + } + + if (tdx->qg_sock_addr) { + qapi_free_SocketAddress(tdx->qg_sock_addr); + } + + tdx->qg_sock_addr =3D sock; +} + /* tdx guest */ OBJECT_DEFINE_TYPE_WITH_INTERFACES(TdxGuest, tdx_guest, @@ -1294,6 +1461,13 @@ static void tdx_guest_init(Object *obj) object_property_add_str(obj, "mrownerconfig", tdx_guest_get_mrownerconfig, tdx_guest_set_mrownerconfig); + + object_property_add(obj, "quote-generation-socket", "SocketAddress", + tdx_guest_get_qgs, + tdx_guest_set_qgs, + NULL, NULL); + + qemu_mutex_init(&tdx->lock); } =20 static void tdx_guest_finalize(Object *obj) diff --git a/target/i386/kvm/meson.build b/target/i386/kvm/meson.build index 3f44cdedb75..2675bf89027 100644 --- a/target/i386/kvm/meson.build +++ b/target/i386/kvm/meson.build @@ -8,7 +8,7 @@ i386_kvm_ss.add(files( =20 i386_kvm_ss.add(when: 'CONFIG_XEN_EMU', if_true: files('xen-emu.c')) =20 -i386_kvm_ss.add(when: 'CONFIG_TDX', if_true: files('tdx.c'), if_false: fil= es('tdx-stub.c')) +i386_kvm_ss.add(when: 'CONFIG_TDX', if_true: files('tdx.c', 'tdx-quote-gen= erator.c'), if_false: files('tdx-stub.c')) =20 i386_system_ss.add(when: 'CONFIG_HYPERV', if_true: files('hyperv.c'), if_f= alse: files('hyperv-stub.c')) =20 --=20 2.49.0