From nobody Wed Dec 4 18:57:25 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail header.i=@intel.com; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=intel.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1716532477185816.4579365585435; Thu, 23 May 2024 23:34:37 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 2B26C1B7F; Fri, 24 May 2024 02:34:36 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id C34DA1C78; Fri, 24 May 2024 02:26:46 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 818871A12; Fri, 24 May 2024 02:26:31 -0400 (EDT) Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 94A0C1A55 for ; Fri, 24 May 2024 02:25:51 -0400 (EDT) Received: from orviesa009.jf.intel.com ([10.64.159.149]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 May 2024 23:24:50 -0700 Received: from unknown (HELO SPR-S2600BT.bj.intel.com) ([10.240.192.124]) by orviesa009-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 May 2024 23:24:47 -0700 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1716531952; x=1748067952; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=G+LXI2Qu5H4nmKDMK96xjEqGA+B+iEQ8rqwNUSdaVck=; b=KPCdMUy1nM+05DS9LOxXq1Kwke92fItXFFVz3j9Y9pwAyClrsgx7xexm AIq0xgRWmcEWfsaGERJfpDk++Ji58uWi8UBUSuhGRtu97rt5JvQwwVeiH IcVgZcEJhrs6dCjEfB3Dga/oirLb/+KycSpP6Be9w/oYQoGVWYTW5Eesw +IsV4MUvrzJkuHzA3TjPpgZxlvLnFA3IICO+JwfQ8OYCv8KoHUWapOkE1 o6B8TZceKQOJkWgTpCPEF/L0R+alWnlpMt7tPQ1xCNXLY2cE3HadzeMdE DH2KScfaSDSscXZy/z3tQRCqvrrBzF86cguiJZZR6ofg1e6UPS9oT1Stk Q==; X-CSE-ConnectionGUID: MIO+hGcbRpqZd59Z9ycd8Q== X-CSE-MsgGUID: MRdkAjR/QjGrHiPqiJ8pgQ== X-IronPort-AV: E=McAfee;i="6600,9927,11081"; a="13081265" X-IronPort-AV: E=Sophos;i="6.08,184,1712646000"; d="scan'208";a="13081265" X-CSE-ConnectionGUID: u1t9L1VfSY2HY/mXPnXIRw== X-CSE-MsgGUID: f1IsS9AdRh6arRJ7AX1RQw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,184,1712646000"; d="scan'208";a="34033989" From: Zhenzhong Duan To: devel@lists.libvirt.org Subject: [PATCH rfcv4 08/13] Add Intel TDX Quote Generation Service(QGS) support Date: Fri, 24 May 2024 14:21:23 +0800 Message-Id: <20240524062128.523820-9-zhenzhong.duan@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240524062128.523820-1-zhenzhong.duan@intel.com> References: <20240524062128.523820-1-zhenzhong.duan@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Message-ID-Hash: HDDOYX2KTEYJNGSXL7ERS443UW3JJ4HL X-Message-ID-Hash: HDDOYX2KTEYJNGSXL7ERS443UW3JJ4HL X-MailFrom: zhenzhong.duan@intel.com X-Mailman-Rule-Hits: nonmember-moderation X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0 CC: phrdina@redhat.com, pkrempa@redhat.com, jjongsma@redhat.com, jsuchane@redhat.com, chenyi.qiang@intel.com, isaku.yamahata@intel.com, xiaoyao.li@intel.com, chao.p.peng@intel.com, Zhenzhong Duan X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1716532478808100001 Content-Type: text/plain; charset="utf-8" Add element "quoteGenerationService" to tdx launch security type. Currently it contains only one sub-element "SocketAddress". "SocketAddress" is modelized according to QEMU QAPI, supporting inet, unix, vsock and fd type and variant attributes depending on type. XML example: 0x0 xxx xxx xxx QEMU command line example: qemu-system-x86_64 \ -object '{"qom-type":"tdx-guest","id":"lsec0","sept-ve-disable":false,"= mrconfigid":"xxx","mrowner":"xxx","mrownerconfig":"xxx","quote-generation-s= ocket":{"type":"vsock","cid":"xxx","port":"xxx"}}' \ -machine pc-q35-6.0,confidential-guest-support=3Dlsec0 Signed-off-by: Zhenzhong Duan --- src/conf/domain_conf.c | 272 +++++++++++++++++++++++++++++- src/conf/domain_conf.h | 61 +++++++ src/conf/schemas/domaincommon.rng | 106 ++++++++++++ src/qemu/qemu_command.c | 106 ++++++++++++ 4 files changed, 544 insertions(+), 1 deletion(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index c557da0c65..e1ae8295e5 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1511,6 +1511,15 @@ VIR_ENUM_IMPL(virDomainLaunchSecurity, "tdx", ); =20 +VIR_ENUM_IMPL(virDomainSocketAddress, + VIR_DOMAIN_SOCKET_ADDRESS_LAST, + "", + "inet", + "unix", + "vsock", + "fd", +); + typedef enum { VIR_DOMAIN_NET_VHOSTUSER_MODE_NONE, VIR_DOMAIN_NET_VHOSTUSER_MODE_CLIENT, @@ -13654,6 +13663,190 @@ virDomainSEVDefParseXML(virDomainSEVDef *def, } =20 =20 +static int +virDomainInetSocketAddressDefParseXML(InetSocketAddress *inet, + xmlNodePtr node) +{ + int ret; + + if (!(inet->host =3D virXMLPropString(node, "host"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing host for inet socket address")); + return -1; + } + + if (!(inet->port =3D virXMLPropString(node, "port"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing port for inet socket address")); + return -1; + } + + if (virXMLPropTristateBool(node, "numeric", VIR_XML_PROP_NONE, + &inet->numeric) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("wrong attribute numeric for inet socket address"= )); + return -1; + } + + if ((ret =3D virXMLPropUInt(node, "to", 10, VIR_XML_PROP_NONE, + &inet->to)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("wrong attribute to for inet socket address")); + return -1; + } + if (!ret) + inet->has_to =3D true; + + if (virXMLPropTristateBool(node, "ipv4", VIR_XML_PROP_NONE, + &inet->ipv4) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("wrong attribute ipv4 for inet socket address")); + return -1; + } + + if (virXMLPropTristateBool(node, "ipv6", VIR_XML_PROP_NONE, + &inet->ipv6) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("wrong attribute ipv6 for inet socket address")); + return -1; + } + + if (virXMLPropTristateBool(node, "keep_alive", VIR_XML_PROP_NONE, + &inet->keep_alive) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("wrong attribute keep_alive for inet socket addre= ss")); + return -1; + } + + if (virXMLPropTristateBool(node, "mptcp", VIR_XML_PROP_NONE, + &inet->mptcp) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("wrong attribute mptcp for inet socket address")); + return -1; + } + + return 0; +} + + +static int +virDomainUnixSocketAddressDefParseXML(UnixSocketAddress *Unix, + xmlNodePtr node) +{ + if (!(Unix->path =3D virXMLPropString(node, "path"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing path for unix socket address")); + return -1; + } + + if (virXMLPropTristateBool(node, "abstract", VIR_XML_PROP_NONE, + &Unix->abstract) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("wrong attribute abstract for unix socket address= ")); + return -1; + } + + if (virXMLPropTristateBool(node, "tight", VIR_XML_PROP_NONE, + &Unix->tight) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("wrong attribute tight for unix socket address")); + return -1; + } + + return 0; +} + + +static int +virDomainVsockSocketAddressDefParseXML(VsockSocketAddress *vsock, + xmlNodePtr node) +{ + if (!(vsock->cid =3D virXMLPropString(node, "cid"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing cid for vsock socket address")); + return -1; + } + + if (!(vsock->port =3D virXMLPropString(node, "port"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing port for vsock socket address")); + return -1; + } + + return 0; +} + + +static int +virDomainFdSocketAddressDefParseXML(FdSocketAddress *fd, + xmlNodePtr node) +{ + if (!(fd->str =3D virXMLPropString(node, "str"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing fd for fd socket address")); + return -1; + } + + return 0; +} + + +static int +virDomainTDXQGSDefParseXML(virDomainTDXDef *def, xmlXPathContextPtr ctxt) +{ + g_autofree xmlNodePtr *nodes =3D NULL; + SocketAddress *sa =3D &def->qgs_sa; + xmlNodePtr node; + int n; + + if ((n =3D virXPathNodeSet("./quoteGenerationService/SocketAddress", + ctxt, &nodes)) < 0) + return -1; + + if (!n) + return 0; + + if (n > 1) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("only a single QGS element is supported")); + return -1; + } + node =3D nodes[0]; + + if (virXMLPropEnum(node, "type", virDomainSocketAddressTypeFromString, + VIR_XML_PROP_REQUIRED, &sa->type) < 0) + return -1; + + switch ((virDomainSocketAddress) def->qgs_sa.type) { + case VIR_DOMAIN_SOCKET_ADDRESS_INET: + if (virDomainInetSocketAddressDefParseXML(&sa->u.inet, node) < 0) + return -1; + break; + case VIR_DOMAIN_SOCKET_ADDRESS_UNIX: + if (virDomainUnixSocketAddressDefParseXML(&sa->u.Unix, node) < 0) + return -1; + break; + case VIR_DOMAIN_SOCKET_ADDRESS_VSOCK: + if (virDomainVsockSocketAddressDefParseXML(&sa->u.vsock, node) < 0) + return -1; + break; + case VIR_DOMAIN_SOCKET_ADDRESS_FD: + if (virDomainFdSocketAddressDefParseXML(&sa->u.fd, node) < 0) + return -1; + break; + case VIR_DOMAIN_SOCKET_ADDRESS_NONE: + case VIR_DOMAIN_SOCKET_ADDRESS_LAST: + default: + virReportError(VIR_ERR_XML_ERROR, + _("unsupported socket address type '%1$s'"), + virDomainSocketAddressTypeToString(def->qgs_sa.type= )); + return -1; + } + + return 0; +} + + static int virDomainTDXDefParseXML(virDomainTDXDef *def, xmlXPathContextPtr ctxt) @@ -13668,7 +13861,7 @@ virDomainTDXDefParseXML(virDomainTDXDef *def, def->mrowner =3D virXPathString("string(./mrOwner)", ctxt); def->mrownerconfig =3D virXPathString("string(./mrOwnerConfig)", ctxt); =20 - return 0; + return virDomainTDXQGSDefParseXML(def, ctxt); } =20 =20 @@ -26652,6 +26845,82 @@ virDomainKeyWrapDefFormat(virBuffer *buf, virDomai= nKeyWrapDef *keywrap) } =20 =20 +static void +virDomainTDXQGSDefFormat(virBuffer *buf, virDomainTDXDef *tdx) +{ + SocketAddress *sa =3D &tdx->qgs_sa; + + if (sa->type =3D=3D VIR_DOMAIN_SOCKET_ADDRESS_NONE) + return; + + virBufferAddLit(buf, "\n"); + virBufferAdjustIndent(buf, 2); + virBufferAsprintf(buf, "type)); + + switch ((virDomainSocketAddress) sa->type) { + case VIR_DOMAIN_SOCKET_ADDRESS_INET: + { + InetSocketAddress *inet =3D &sa->u.inet; + + virBufferAsprintf(buf, " host=3D'%s' port=3D'%s'", inet->host, ine= t->port); + if (inet->numeric !=3D VIR_TRISTATE_BOOL_ABSENT) + virBufferAsprintf(buf, " numeric=3D'%s'", + virTristateBoolTypeToString(inet->numeric)); + if (inet->to) + virBufferAsprintf(buf, " to=3D'%d'", inet->to); + if (inet->ipv4 !=3D VIR_TRISTATE_BOOL_ABSENT) + virBufferAsprintf(buf, " ipv4=3D'%s'", + virTristateBoolTypeToString(inet->ipv4)); + if (inet->ipv6 !=3D VIR_TRISTATE_BOOL_ABSENT) + virBufferAsprintf(buf, " ipv6=3D'%s'", + virTristateBoolTypeToString(inet->ipv6)); + if (inet->keep_alive !=3D VIR_TRISTATE_BOOL_ABSENT) + virBufferAsprintf(buf, " keep_alive=3D'%s'", + virTristateBoolTypeToString(inet->keep_alive= )); + if (inet->mptcp !=3D VIR_TRISTATE_BOOL_ABSENT) + virBufferAsprintf(buf, " mptcp=3D'%s'", + virTristateBoolTypeToString(inet->mptcp)); + break; + } + case VIR_DOMAIN_SOCKET_ADDRESS_UNIX: + { + UnixSocketAddress *Unix =3D &sa->u.Unix; + + virBufferAsprintf(buf, " path=3D'%s'", Unix->path); + if (Unix->abstract !=3D VIR_TRISTATE_BOOL_ABSENT) + virBufferAsprintf(buf, " abstract=3D'%s'", + virTristateBoolTypeToString(Unix->abstract)); + if (Unix->tight !=3D VIR_TRISTATE_BOOL_ABSENT) + virBufferAsprintf(buf, " tight=3D'%s'", + virTristateBoolTypeToString(Unix->tight)); + break; + } + case VIR_DOMAIN_SOCKET_ADDRESS_VSOCK: + { + VsockSocketAddress *vsock =3D &sa->u.vsock; + + virBufferAsprintf(buf, " cid=3D'%s' port=3D'%s'", vsock->cid, vsoc= k->port); + break; + } + case VIR_DOMAIN_SOCKET_ADDRESS_FD: + { + FdSocketAddress *fd =3D &sa->u.fd; + + virBufferAsprintf(buf, " str=3D'%s'", fd->str); + break; + } + case VIR_DOMAIN_SOCKET_ADDRESS_NONE: + case VIR_DOMAIN_SOCKET_ADDRESS_LAST: + default: + break; + } + virBufferAddLit(buf, "/>\n"); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); +} + + static void virDomainSecDefFormat(virBuffer *buf, virDomainSecDef *sec) { @@ -26699,6 +26968,7 @@ virDomainSecDefFormat(virBuffer *buf, virDomainSecD= ef *sec) virBufferEscapeString(&childBuf, "%s\n", td= x->mrowner); if (tdx->mrownerconfig) virBufferEscapeString(&childBuf, "%s\n", tdx->mrownerconfig); + virDomainTDXQGSDefFormat(&childBuf, tdx); =20 break; } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index bb4973fce8..15cdb3e0e6 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2852,6 +2852,55 @@ struct _virDomainKeyWrapDef { virTristateSwitch dea; }; =20 +typedef enum { + VIR_DOMAIN_SOCKET_ADDRESS_NONE, + VIR_DOMAIN_SOCKET_ADDRESS_INET, + VIR_DOMAIN_SOCKET_ADDRESS_UNIX, + VIR_DOMAIN_SOCKET_ADDRESS_VSOCK, + VIR_DOMAIN_SOCKET_ADDRESS_FD, + + VIR_DOMAIN_SOCKET_ADDRESS_LAST +} virDomainSocketAddress; + +typedef struct _InetSocketAddress InetSocketAddress; +typedef struct _UnixSocketAddress UnixSocketAddress; +typedef struct _VsockSocketAddress VsockSocketAddress; +typedef struct _FdSocketAddress FdSocketAddress; + +struct _InetSocketAddress { + char *host; + char *port; + bool has_numeric; + virTristateBool numeric; + bool has_to; + unsigned int to; + bool has_ipv4; + virTristateBool ipv4; + bool has_ipv6; + virTristateBool ipv6; + bool has_keep_alive; + virTristateBool keep_alive; + bool has_mptcp; + virTristateBool mptcp; +}; + +struct _UnixSocketAddress { + char *path; + bool has_abstract; + virTristateBool abstract; + bool has_tight; + virTristateBool tight; +}; + +struct _VsockSocketAddress { + char *cid; + char *port; +}; + +struct _FdSocketAddress { + char *str; +}; + typedef enum { VIR_DOMAIN_LAUNCH_SECURITY_NONE, VIR_DOMAIN_LAUNCH_SECURITY_SEV, @@ -2873,11 +2922,22 @@ struct _virDomainSEVDef { virTristateBool kernel_hashes; }; =20 +typedef struct SocketAddress { + virDomainSocketAddress type; + union { + InetSocketAddress inet; + UnixSocketAddress Unix; + VsockSocketAddress vsock; + FdSocketAddress fd; + } u; +} SocketAddress; + struct _virDomainTDXDef { unsigned long long policy; char *mrconfigid; char *mrowner; char *mrownerconfig; + SocketAddress qgs_sa; }; =20 #define VIR_DOMAIN_TDX_POLICY_DEBUG 0x1 @@ -4258,6 +4318,7 @@ VIR_ENUM_DECL(virDomainCryptoBackend); VIR_ENUM_DECL(virDomainShmemModel); VIR_ENUM_DECL(virDomainShmemRole); VIR_ENUM_DECL(virDomainLaunchSecurity); +VIR_ENUM_DECL(virDomainSocketAddress); /* from libvirt.h */ VIR_ENUM_DECL(virDomainState); VIR_ENUM_DECL(virDomainNostateReason); diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincom= mon.rng index f6e1782b33..e8cc78992a 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -591,9 +591,115 @@ + + + + + =20 + + + + + + + + + + + + + + + + + + + + + + inet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + unix + + + + + + + + + + + + + + + + + + + vsock + + + + + + + + + + + + fd + + + + + +