From patchwork Wed Jul 17 03:40:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Huang, Kai" X-Patchwork-Id: 13735035 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 15CB3748A; Wed, 17 Jul 2024 03:40:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721187641; cv=none; b=q4WsxPawCsGsqx6D8TAqyqCGUOui6QQoMY7Xon+DBDPrSrwGRnv+CYbZaJUzgjVcR+yaGoINw5f9NmOUlr8VPAG5OYTvHOate/jXTf8dUCxq+n0kIVHsNve9mEtKmlz4+3GEFgRKylqf24loMw6e0XrJXrwfePksFiiGnVwt/0Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721187641; c=relaxed/simple; bh=jhvvjas5iv8XJQqpFKAiIxzIfcajgUN9jOtwbSWIbUg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ErQ7v2Styd1vEXUm1GxrxuciZzMKkFq+um0pEQkDmQhpHbgLxidb43Vp4cdvlsSfK3n2WOVxQ4TZGrWGDmGGgRjoYTCWqN5o9QkEyxUwSNcTIqkxbZj/vPjBYA3wRn8bLO+3zRt4paF/75UnAOeESyVbA7eIaqYvadyykeioFjM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=H2JmuWWR; arc=none smtp.client-ip=198.175.65.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="H2JmuWWR" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1721187640; x=1752723640; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=jhvvjas5iv8XJQqpFKAiIxzIfcajgUN9jOtwbSWIbUg=; b=H2JmuWWR7PL2qHc+RjLZAPbgdzhTw0zIwzhaW8k+M+mYDq4AMpQlr4be NIjfdQpVi3WLM6iARbdG3VT/nCw0VFswiWn/tJkPu5YjaaUQTr1nJmrIc fumYzdlgKmICrdwE/Sop2Oy9ydgSYiMa4qGrDHwOv5448xoW7G1vgqIkL pRUADGmeUp6LFAJpHxjcURYOPGA3YJfTrC+bNmJbK0hnD6Jrg1c5vNlq0 YU8jKvVhTcqznZaxH+pI5ZWCwMkLrGetzfxM+/y14nCzUrlicRZTdWR4h rvoe/K7QY5U9akL7zjDwwIcXS0rurYXw/sLtvLZzyO43PczdDCSX/VLCk A==; X-CSE-ConnectionGUID: biuuzD+jQ7Kc4Vkn6jlP2A== X-CSE-MsgGUID: WVxVER1LTjiPoENOp12GVg== X-IronPort-AV: E=McAfee;i="6700,10204,11135"; a="18512341" X-IronPort-AV: E=Sophos;i="6.09,213,1716274800"; d="scan'208";a="18512341" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jul 2024 20:40:40 -0700 X-CSE-ConnectionGUID: 4gy3/WoORn6HuPmEQo6UXA== X-CSE-MsgGUID: bObMJpj4ToG8CwEajK35GA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,213,1716274800"; d="scan'208";a="54566690" Received: from rfrazer-mobl3.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.222.184]) by fmviesa005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jul 2024 20:40:36 -0700 From: Kai Huang To: dave.hansen@intel.com, kirill.shutemov@linux.intel.com, bp@alien8.de, tglx@linutronix.de, peterz@infradead.org, mingo@redhat.com, hpa@zytor.com, seanjc@google.com, pbonzini@redhat.com, dan.j.williams@intel.com Cc: x86@kernel.org, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, rick.p.edgecombe@intel.com, isaku.yamahata@intel.com, chao.gao@intel.com, binbin.wu@linux.intel.com, kai.huang@intel.com Subject: [PATCH v2 01/10] x86/virt/tdx: Rename _offset to _member for TD_SYSINFO_MAP() macro Date: Wed, 17 Jul 2024 15:40:08 +1200 Message-ID: X-Mailer: git-send-email 2.45.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 TD_SYSINFO_MAP() macro actually takes the member of the 'struct tdx_tdmr_sysinfo' as the second argument and uses the offsetof() to calculate the offset for that member. Rename the macro argument _offset to _member to reflect this. Signed-off-by: Kai Huang Reviewed-by: Kirill A. Shutemov Reviewed-by: Binbin Wu Reviewed-by: Dan Williams --- arch/x86/virt/vmx/tdx/tdx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 49a1c6890b55..d8fa9325bf5e 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -296,9 +296,9 @@ struct field_mapping { int offset; }; -#define TD_SYSINFO_MAP(_field_id, _offset) \ +#define TD_SYSINFO_MAP(_field_id, _member) \ { .field_id = MD_FIELD_ID_##_field_id, \ - .offset = offsetof(struct tdx_tdmr_sysinfo, _offset) } + .offset = offsetof(struct tdx_tdmr_sysinfo, _member) } /* Map TD_SYSINFO fields into 'struct tdx_tdmr_sysinfo': */ static const struct field_mapping fields[] = { From patchwork Wed Jul 17 03:40:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Huang, Kai" X-Patchwork-Id: 13735036 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 904C4125AC; Wed, 17 Jul 2024 03:40:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721187645; cv=none; b=d6Qus/uAGx2uZhXEqmGls6H01AQW2UU29zgbHFNJ+g+bex1dk8i5mmCU3ESpg4I15JB9oAjW12EMeR0C7BUrTYDTkJRty+5FmVq6HDS+J19S/0ndSqhVmfT2XcunlY5aJf1i4Uw5D+NYpz28/mBMAJT2+ehkp6C8TBZOKzOvZ50= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721187645; c=relaxed/simple; bh=aXjCxwWAWxkPZeuSGjcrZZHRngrEEyvMgErSCYqnP/Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EUOGUlBqiRQJF7JkIOrN5QUeVvWZvdCFT/wMrXcTB84RotFcr2aOMRMfQGyfhsUpZdm62ACLjRjv0vAcLqbEcmugn9Mjr4XzIt3JZwk4jXsTyLpdFpn24JiSmZaWXATGtUkjj4B4/FDqCa/+FFEwYDixV2nfIjPS8fqfqfgzwgw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=RAsOETya; arc=none smtp.client-ip=198.175.65.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="RAsOETya" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1721187643; x=1752723643; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=aXjCxwWAWxkPZeuSGjcrZZHRngrEEyvMgErSCYqnP/Y=; b=RAsOETya8nDWCSCzeJnkT/1Btoqe9sXs6Yd17ChrH32FTSj4+M+rNt85 GaYYcoWsLYX1a5ebKutsYdGjE/XrG7Sc8hwCrYYNKY18AHcJSqhgx1xXh Qf8UgX+boeMv/1T1NMY9B02bg9EH196qaCIBpTaxk7vQImlYFo2ntqRgU k1fvEr3fWPdoSt4VgJmoagSvFxiecqEZlVnmUNG0kvTb+uBIa7+06bS1z bxFzWVlDs97aC5bEEz7qcRVjzmg+t02Ady/Etd+GzZxl3KwBhmw6iyGNu 8oz9axCAmcRqdCezHx/RzflRLDH0YexuiXkP3EY6PYUpgu7h86Yv6zVqO g==; X-CSE-ConnectionGUID: 08+/jOMvTmK7lp4d+Wlxwg== X-CSE-MsgGUID: rrDG3P92TCGIVUZcnsNVeA== X-IronPort-AV: E=McAfee;i="6700,10204,11135"; a="18512352" X-IronPort-AV: E=Sophos;i="6.09,213,1716274800"; d="scan'208";a="18512352" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jul 2024 20:40:43 -0700 X-CSE-ConnectionGUID: 1cvbUM8KQOmGpOdjSHM4CQ== X-CSE-MsgGUID: n1x8nad1QBeFFAUkzDDVwQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,213,1716274800"; d="scan'208";a="54566698" Received: from rfrazer-mobl3.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.222.184]) by fmviesa005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jul 2024 20:40:39 -0700 From: Kai Huang To: dave.hansen@intel.com, kirill.shutemov@linux.intel.com, bp@alien8.de, tglx@linutronix.de, peterz@infradead.org, mingo@redhat.com, hpa@zytor.com, seanjc@google.com, pbonzini@redhat.com, dan.j.williams@intel.com Cc: x86@kernel.org, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, rick.p.edgecombe@intel.com, isaku.yamahata@intel.com, chao.gao@intel.com, binbin.wu@linux.intel.com, kai.huang@intel.com Subject: [PATCH v2 02/10] x86/virt/tdx: Unbind global metadata read with 'struct tdx_tdmr_sysinfo' Date: Wed, 17 Jul 2024 15:40:09 +1200 Message-ID: <7af2b06ec26e2964d8d5da21e2e9fa412e4ed6f8.1721186590.git.kai.huang@intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The TDX module provides a set of "global metadata fields". They report things like TDX module version, supported features, and fields related to create/run TDX guests and so on. For now the kernel only reads "TD Memory Region" (TDMR) related global metadata fields to a 'struct tdx_tdmr_sysinfo' for initializing the TDX module, and the metadata reading code can only work with that structure. Future changes will need to read other metadata fields that don't make sense to populate to the "struct tdx_tdmr_sysinfo". It's essential to provide a generic metadata read infrastructure which is not bound to any specific structure. To start providing such infrastructure, unbind the metadata reading code with the 'struct tdx_tdmr_sysinfo'. Note the kernel has a helper macro, TD_SYSINFO_MAP(), for marshaling the metadata into the 'struct tdx_tdmr_sysinfo', and currently the macro hardcodes the structure name. As part of unbinding the metadata reading code with 'struct tdx_tdmr_sysinfo', it is extended to accept different structures. Unfortunately, this will result in the usage of TD_SYSINFO_MAP() for populating 'struct tdx_tdmr_sysinfo' to be changed to use the structure name explicitly for each structure member and make the code longer. Add a wrapper macro which hides the 'struct tdx_tdmr_sysinfo' internally to make the code shorter thus better readability. Signed-off-by: Kai Huang Reviewed-by: Kirill A. Shutemov Reviewed-by: Binbin Wu --- v1 -> v2: - 'st_member' -> 'member'. (Nikolay) --- arch/x86/virt/vmx/tdx/tdx.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index d8fa9325bf5e..2ce03c3ea017 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -272,9 +272,9 @@ static int read_sys_metadata_field(u64 field_id, u64 *data) static int read_sys_metadata_field16(u64 field_id, int offset, - struct tdx_tdmr_sysinfo *ts) + void *stbuf) { - u16 *ts_member = ((void *)ts) + offset; + u16 *member = stbuf + offset; u64 tmp; int ret; @@ -286,7 +286,7 @@ static int read_sys_metadata_field16(u64 field_id, if (ret) return ret; - *ts_member = tmp; + *member = tmp; return 0; } @@ -296,17 +296,20 @@ struct field_mapping { int offset; }; -#define TD_SYSINFO_MAP(_field_id, _member) \ - { .field_id = MD_FIELD_ID_##_field_id, \ - .offset = offsetof(struct tdx_tdmr_sysinfo, _member) } +#define TD_SYSINFO_MAP(_field_id, _struct, _member) \ + { .field_id = MD_FIELD_ID_##_field_id, \ + .offset = offsetof(_struct, _member) } + +#define TD_SYSINFO_MAP_TDMR_INFO(_field_id, _member) \ + TD_SYSINFO_MAP(_field_id, struct tdx_tdmr_sysinfo, _member) /* Map TD_SYSINFO fields into 'struct tdx_tdmr_sysinfo': */ static const struct field_mapping fields[] = { - TD_SYSINFO_MAP(MAX_TDMRS, max_tdmrs), - TD_SYSINFO_MAP(MAX_RESERVED_PER_TDMR, max_reserved_per_tdmr), - TD_SYSINFO_MAP(PAMT_4K_ENTRY_SIZE, pamt_entry_size[TDX_PS_4K]), - TD_SYSINFO_MAP(PAMT_2M_ENTRY_SIZE, pamt_entry_size[TDX_PS_2M]), - TD_SYSINFO_MAP(PAMT_1G_ENTRY_SIZE, pamt_entry_size[TDX_PS_1G]), + TD_SYSINFO_MAP_TDMR_INFO(MAX_TDMRS, max_tdmrs), + TD_SYSINFO_MAP_TDMR_INFO(MAX_RESERVED_PER_TDMR, max_reserved_per_tdmr), + TD_SYSINFO_MAP_TDMR_INFO(PAMT_4K_ENTRY_SIZE, pamt_entry_size[TDX_PS_4K]), + TD_SYSINFO_MAP_TDMR_INFO(PAMT_2M_ENTRY_SIZE, pamt_entry_size[TDX_PS_2M]), + TD_SYSINFO_MAP_TDMR_INFO(PAMT_1G_ENTRY_SIZE, pamt_entry_size[TDX_PS_1G]), }; static int get_tdx_tdmr_sysinfo(struct tdx_tdmr_sysinfo *tdmr_sysinfo) From patchwork Wed Jul 17 03:40:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Huang, Kai" X-Patchwork-Id: 13735037 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AAABA18E11; Wed, 17 Jul 2024 03:40:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721187661; cv=none; b=rc8x6l6xjVKAtHPD5WxLYvWc5NgjVTOGKEYrqiKn5AllPdxuyKGYqkOHen4hGkyL+ykCcJEYg9YeF1/ZQ6WZjnPI50Ngl2SoBUYGgEHr8lU5rkdaEW/EkAzE+kHOi/g7vv1xASKprmT/ER3ASFYK4bqa7KdODZo4uwMWBCOd4bg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721187661; c=relaxed/simple; bh=Ut9pLSIKiegISfQ+j0qPxLsFEctC+3z6lvxXveQnzk4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=imOl3F68OD6WnWjFKnezDMGjTuD/Jqj8UfvZn3SjC5VFYydV4TXMaBbV7dkUvbxvR1djXdEtImN2RIvLlLs8AgQSW35wJEbYvcv/j1FngQqT0SLfMX0CRYd2jHnJUhXzmG7QOZMSRAJXJAJggpSzfk+7qDTsi3OKeohqGzKr6A4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=N0QF5mPR; arc=none smtp.client-ip=198.175.65.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="N0QF5mPR" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1721187660; x=1752723660; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Ut9pLSIKiegISfQ+j0qPxLsFEctC+3z6lvxXveQnzk4=; b=N0QF5mPRAt8AGQD70HgBnrv5slwPkVbizYh6XGAMixAK2n7K7hlvZ//F Hltg3BB3H9w+UCjeg4OgfMIyx7dQZAtYiLXpVPmxetrOQlEf6jVVaKCJI LRdoD70RgKiw4qHabf4lyT/PzvHPwvVDqINcAt1HIDm6Hd2BBqlBQCiUt njl7pNas1Ep5d6Yr4ncKoYePCfTbpfaUjyXnzpKpf7p7/IqCEaBZNdRzD a0CAn873OnhA/Bbas9nU8XRn7e6GV/0eFEFix92bn2PLpztGtg7F4cmwq skHaIo1Rck+s9m0lCIOPO4ohHE2PkwZgfUPNQz/wHaz5jaofDzcWJ1yEM A==; X-CSE-ConnectionGUID: 8Ol4otLhRjWM5XRTBjykcA== X-CSE-MsgGUID: 8kA1doYbQemxhzxr5HwSOQ== X-IronPort-AV: E=McAfee;i="6700,10204,11135"; a="18512373" X-IronPort-AV: E=Sophos;i="6.09,213,1716274800"; d="scan'208";a="18512373" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jul 2024 20:40:47 -0700 X-CSE-ConnectionGUID: zmI4Ic3XQv2JIWkmvQV/DA== X-CSE-MsgGUID: aJq1d8YeTaK0KQZhh69+EA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,213,1716274800"; d="scan'208";a="54566710" Received: from rfrazer-mobl3.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.222.184]) by fmviesa005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jul 2024 20:40:43 -0700 From: Kai Huang To: dave.hansen@intel.com, kirill.shutemov@linux.intel.com, bp@alien8.de, tglx@linutronix.de, peterz@infradead.org, mingo@redhat.com, hpa@zytor.com, seanjc@google.com, pbonzini@redhat.com, dan.j.williams@intel.com Cc: x86@kernel.org, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, rick.p.edgecombe@intel.com, isaku.yamahata@intel.com, chao.gao@intel.com, binbin.wu@linux.intel.com, kai.huang@intel.com Subject: [PATCH v2 03/10] x86/virt/tdx: Support global metadata read for all element sizes Date: Wed, 17 Jul 2024 15:40:10 +1200 Message-ID: <442637364b55c8a721f72a201e838eb5c271e0eb.1721186590.git.kai.huang@intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The TDX module provides "global metadata fields" for software to query. Each metadata field is accessible by a unique "metadata field ID". TDX supports 8/16/32/64 bits metadata element sizes. The size of each metadata field is encoded in its associated metadata field ID. For now the kernel only reads "TD Memory Region" (TDMR) related global metadata fields for module initialization. All these metadata fields are 16-bit, and the kernel only supports reading 16-bit fields. Future changes will need to read more metadata fields with other element sizes. To resolve this once for all, extend the existing metadata reading code to support reading all element sizes. Signed-off-by: Kai Huang Reviewed-by: Kirill A. Shutemov --- v1 -> v2 (Nikolay): - MD_FIELD_BYTES() -> MD_FIELD_ELE_SIZE(). - 'bytes' -> 'size' in stbuf_read_sysmd_field(). --- arch/x86/virt/vmx/tdx/tdx.c | 29 ++++++++++++++++------------- arch/x86/virt/vmx/tdx/tdx.h | 3 ++- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 2ce03c3ea017..4644b324ff86 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -270,23 +270,25 @@ static int read_sys_metadata_field(u64 field_id, u64 *data) return 0; } -static int read_sys_metadata_field16(u64 field_id, - int offset, - void *stbuf) +/* + * Read one global metadata field and store the data to a location of a + * given buffer specified by the offset and size (in bytes). + */ +static int stbuf_read_sysmd_field(u64 field_id, void *stbuf, int offset, + int size) { - u16 *member = stbuf + offset; + void *member = stbuf + offset; u64 tmp; int ret; - if (WARN_ON_ONCE(MD_FIELD_ID_ELE_SIZE_CODE(field_id) != - MD_FIELD_ID_ELE_SIZE_16BIT)) + if (WARN_ON_ONCE(MD_FIELD_ELE_SIZE(field_id) != size)) return -EINVAL; ret = read_sys_metadata_field(field_id, &tmp); if (ret) return ret; - *member = tmp; + memcpy(member, &tmp, size); return 0; } @@ -294,11 +296,13 @@ static int read_sys_metadata_field16(u64 field_id, struct field_mapping { u64 field_id; int offset; + int size; }; -#define TD_SYSINFO_MAP(_field_id, _struct, _member) \ - { .field_id = MD_FIELD_ID_##_field_id, \ - .offset = offsetof(_struct, _member) } +#define TD_SYSINFO_MAP(_field_id, _struct, _member) \ + { .field_id = MD_FIELD_ID_##_field_id, \ + .offset = offsetof(_struct, _member), \ + .size = sizeof(typeof(((_struct *)0)->_member)) } #define TD_SYSINFO_MAP_TDMR_INFO(_field_id, _member) \ TD_SYSINFO_MAP(_field_id, struct tdx_tdmr_sysinfo, _member) @@ -319,9 +323,8 @@ static int get_tdx_tdmr_sysinfo(struct tdx_tdmr_sysinfo *tdmr_sysinfo) /* Populate 'tdmr_sysinfo' fields using the mapping structure above: */ for (i = 0; i < ARRAY_SIZE(fields); i++) { - ret = read_sys_metadata_field16(fields[i].field_id, - fields[i].offset, - tdmr_sysinfo); + ret = stbuf_read_sysmd_field(fields[i].field_id, tdmr_sysinfo, + fields[i].offset, fields[i].size); if (ret) return ret; } diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h index b701f69485d3..fdb879ef6c45 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -53,7 +53,8 @@ #define MD_FIELD_ID_ELE_SIZE_CODE(_field_id) \ (((_field_id) & GENMASK_ULL(33, 32)) >> 32) -#define MD_FIELD_ID_ELE_SIZE_16BIT 1 +#define MD_FIELD_ELE_SIZE(_field_id) \ + (1 << MD_FIELD_ID_ELE_SIZE_CODE(_field_id)) struct tdmr_reserved_area { u64 offset; From patchwork Wed Jul 17 03:40:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Huang, Kai" X-Patchwork-Id: 13735038 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A7F2818EBF; Wed, 17 Jul 2024 03:41:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721187662; cv=none; b=iIDYNWGEdO9KNwhppxDPd2hLV7bll76VUnAzGz4/A8n89IfWCqnemac8A7Z/8FRI+2TwyGb00Le05DEanjdSLxwP8TcXsNlWzl6qhcTEuhse/n+JUUiJHCObpwRuDfP/pSCKyuejesjADt3WuGPxRjhFTH5IG1USJHG7fKdl918= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721187662; c=relaxed/simple; bh=h3e8pjgzVwqyW4ZTTNX7wyIE8YhVs1gALZoIAPRddgE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ho3U85kmmUhrtQtGK7me7PlftnY9bqh8DxXvNYVm38pr8SW0ERjRNaxcL8yqlYamsQXU9ia/S+4dKGcgYEFORpqyBL8oNdUAZquhStupq+60fWzocHTAs/RorkD5S2GWy6X5LW70zDTr3pZkMsXpQLRN/BvLbq+w2+aYbg+lXYI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=Qdbqqj9e; arc=none smtp.client-ip=198.175.65.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="Qdbqqj9e" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1721187661; x=1752723661; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=h3e8pjgzVwqyW4ZTTNX7wyIE8YhVs1gALZoIAPRddgE=; b=Qdbqqj9eKD+1SV/Xj+jBVJ1tz7KPq+4BsSbyTGXfjQRdGe+a7EQH1IXc M3iMNoyOWaAri31gUaN5NAWeZIOYVWDJzngpeG7XbIGx5WfGrUx7XOq8R Za3Yc13PZtTJj6efYyCeRx84eP4tKQRq1ZTGrqqA59HLPY+yY33bXVpWY 4+hieSfO1Vf421qSAdqju3nrrnCQmAnDWlIIXyLArTegP9Mrn+CbzC3/h rpdK+cPAY0b+8oC1HmGhFs1FDQu2CcsjXQsRl0ERgJYLMS2H0HhlKJSSs +JocmHxW3ukyh/ilxpT3dzaqipflp3dd3RvI0YSY45okSYNxmA8fZEckq w==; X-CSE-ConnectionGUID: 1QcLF/+RQCS8j4M1OTvfqQ== X-CSE-MsgGUID: 32ccVNu0RqmfI6oD0iMv2g== X-IronPort-AV: E=McAfee;i="6700,10204,11135"; a="18512391" X-IronPort-AV: E=Sophos;i="6.09,213,1716274800"; d="scan'208";a="18512391" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jul 2024 20:40:50 -0700 X-CSE-ConnectionGUID: U+FkLDI9RqaMxLH1+YUJnA== X-CSE-MsgGUID: I0nfvcbFSAeTPjfSUY0Efg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,213,1716274800"; d="scan'208";a="54566719" Received: from rfrazer-mobl3.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.222.184]) by fmviesa005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jul 2024 20:40:46 -0700 From: Kai Huang To: dave.hansen@intel.com, kirill.shutemov@linux.intel.com, bp@alien8.de, tglx@linutronix.de, peterz@infradead.org, mingo@redhat.com, hpa@zytor.com, seanjc@google.com, pbonzini@redhat.com, dan.j.williams@intel.com Cc: x86@kernel.org, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, rick.p.edgecombe@intel.com, isaku.yamahata@intel.com, chao.gao@intel.com, binbin.wu@linux.intel.com, kai.huang@intel.com Subject: [PATCH v2 04/10] x86/virt/tdx: Abstract reading multiple global metadata fields as a helper Date: Wed, 17 Jul 2024 15:40:11 +1200 Message-ID: X-Mailer: git-send-email 2.45.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 For now the kernel only reads "TD Memory Region" (TDMR) related global metadata fields to a 'struct tdx_tdmr_sysinfo' for initializing the TDX module. Future changes will need to read other metadata fields that don't make sense to populate to the "struct tdx_tdmr_sysinfo". Now the code in get_tdx_tdmr_sysinfo() to read multiple global metadata fields is not bound to the 'struct tdx_tdmr_sysinfo', and can support reading all metadata element sizes. Abstract this code as a helper for future use. Signed-off-by: Kai Huang --- arch/x86/virt/vmx/tdx/tdx.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 4644b324ff86..50d49c539e63 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -304,6 +304,21 @@ struct field_mapping { .offset = offsetof(_struct, _member), \ .size = sizeof(typeof(((_struct *)0)->_member)) } +static int stbuf_read_sysmd_multi(const struct field_mapping *fields, + int nr_fields, void *stbuf) +{ + int i, ret; + + for (i = 0; i < nr_fields; i++) { + ret = stbuf_read_sysmd_field(fields[i].field_id, stbuf, + fields[i].offset, fields[i].size); + if (ret) + return ret; + } + + return 0; +} + #define TD_SYSINFO_MAP_TDMR_INFO(_field_id, _member) \ TD_SYSINFO_MAP(_field_id, struct tdx_tdmr_sysinfo, _member) @@ -318,18 +333,8 @@ static const struct field_mapping fields[] = { static int get_tdx_tdmr_sysinfo(struct tdx_tdmr_sysinfo *tdmr_sysinfo) { - int ret; - int i; - /* Populate 'tdmr_sysinfo' fields using the mapping structure above: */ - for (i = 0; i < ARRAY_SIZE(fields); i++) { - ret = stbuf_read_sysmd_field(fields[i].field_id, tdmr_sysinfo, - fields[i].offset, fields[i].size); - if (ret) - return ret; - } - - return 0; + return stbuf_read_sysmd_multi(fields, ARRAY_SIZE(fields), tdmr_sysinfo); } /* Calculate the actual TDMR size */ From patchwork Wed Jul 17 03:40:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Huang, Kai" X-Patchwork-Id: 13735039 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 693CB6FC5; Wed, 17 Jul 2024 03:41:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721187663; cv=none; b=q7pEkCaY+dPzKjSwk5/SdNax8lpgnlDGWIyuB43kqDdVvX0Mt7A9a9PmZKwsQuJrkW8eeZizNwSod+gy7dQiXsl3xmR1vjmcllN7kVLuH27WHTMtmj9rpY5pum2uT3xPcUIVshbbiYvhTfLI2nOZUFs0GLiQTmLwYh/NJaJ60UQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721187663; c=relaxed/simple; bh=zkpzPQBW+wdkw7+sGa7f8TPFwfRx7djCUEW7k3GcdvA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GR0PbfAf7/SHkzqTVchnVjAJdIS6OEuEhhHGBfbwJqb13fN3c9fTT0Z84ywzk32cY5V+/iNCEeBENSYQYuf5LXJeW6jpOIF6dQpi5sEzDXzRZwNcuxRKJT+Gb1mFq2ADfh/Uq6OVkz1O7S+FclgbeOwg5mXEdy91OiCuioDPXV4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=ZqGVdW2o; arc=none smtp.client-ip=198.175.65.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="ZqGVdW2o" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1721187661; x=1752723661; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=zkpzPQBW+wdkw7+sGa7f8TPFwfRx7djCUEW7k3GcdvA=; b=ZqGVdW2oA2MXYQQX8B6VovKXApCnAprzSKWIDqPx1OLGBE8tOEYlQ91i 5uSORMcVgYpCMLSJgRaeqILr1/0y3U2uBvvjRq8Itm8/anBpW4S8gK/XR 3N1teAoFZT2ezqIpOHooanwiKRgI5R0SdKeWZ32Y4mXnZ22YAlKeayv+v m72YzDdAvFHJCQihcFTxwJFXYO7PSZHL023sM7hG8KMbVj/Lj3kLBSisA 1xUP1Ne9/fDeim/WmQNv6RPtidi2krhyvDXeprDh/VDJbK4T14UtiNb/Z oQuc5EWlR8y2FSGJnOtw1H3Rm1Ou8o3hm3Tw/KuF7MSURVAUrfIawWVHD w==; X-CSE-ConnectionGUID: JSnaBXvXRHyRZSmRsycyqA== X-CSE-MsgGUID: d10l9H7PRuOhoHxMBHX/oQ== X-IronPort-AV: E=McAfee;i="6700,10204,11135"; a="18512406" X-IronPort-AV: E=Sophos;i="6.09,213,1716274800"; d="scan'208";a="18512406" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jul 2024 20:40:53 -0700 X-CSE-ConnectionGUID: jmg1LbMrQPyzEqZ1SkAeGw== X-CSE-MsgGUID: +SodeNgaRzuaXflU9ago+g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,213,1716274800"; d="scan'208";a="54566729" Received: from rfrazer-mobl3.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.222.184]) by fmviesa005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jul 2024 20:40:50 -0700 From: Kai Huang To: dave.hansen@intel.com, kirill.shutemov@linux.intel.com, bp@alien8.de, tglx@linutronix.de, peterz@infradead.org, mingo@redhat.com, hpa@zytor.com, seanjc@google.com, pbonzini@redhat.com, dan.j.williams@intel.com Cc: x86@kernel.org, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, rick.p.edgecombe@intel.com, isaku.yamahata@intel.com, chao.gao@intel.com, binbin.wu@linux.intel.com, kai.huang@intel.com Subject: [PATCH v2 05/10] x86/virt/tdx: Move field mapping table of getting TDMR info to function local Date: Wed, 17 Jul 2024 15:40:12 +1200 Message-ID: <5fae6d65a9fe68ac85799164866c25305c7a93be.1721186590.git.kai.huang@intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 For now the kernel only reads "TD Memory Region" (TDMR) related global metadata fields to a 'struct tdx_tdmr_sysinfo' for initializing the TDX module. The kernel populates the relevant metadata fields into the structure using a "field mapping table" of metadata field IDs and the structure members. Currently the scope of this "field mapping table" is the entire C file. Future changes will need to read more global metadata fields that will be organized in other structures and use this kind of field mapping tables for other structures too. Move the field mapping table to the function local to limit its scope so that the same name can also be used by other functions. Signed-off-by: Kai Huang Reviewed-by: Nikolay Borisov --- v1 -> v2: - Added Nikolay's tag. --- arch/x86/virt/vmx/tdx/tdx.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 50d49c539e63..86c47db64e42 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -322,17 +322,17 @@ static int stbuf_read_sysmd_multi(const struct field_mapping *fields, #define TD_SYSINFO_MAP_TDMR_INFO(_field_id, _member) \ TD_SYSINFO_MAP(_field_id, struct tdx_tdmr_sysinfo, _member) -/* Map TD_SYSINFO fields into 'struct tdx_tdmr_sysinfo': */ -static const struct field_mapping fields[] = { - TD_SYSINFO_MAP_TDMR_INFO(MAX_TDMRS, max_tdmrs), - TD_SYSINFO_MAP_TDMR_INFO(MAX_RESERVED_PER_TDMR, max_reserved_per_tdmr), - TD_SYSINFO_MAP_TDMR_INFO(PAMT_4K_ENTRY_SIZE, pamt_entry_size[TDX_PS_4K]), - TD_SYSINFO_MAP_TDMR_INFO(PAMT_2M_ENTRY_SIZE, pamt_entry_size[TDX_PS_2M]), - TD_SYSINFO_MAP_TDMR_INFO(PAMT_1G_ENTRY_SIZE, pamt_entry_size[TDX_PS_1G]), -}; - static int get_tdx_tdmr_sysinfo(struct tdx_tdmr_sysinfo *tdmr_sysinfo) { + /* Map TD_SYSINFO fields into 'struct tdx_tdmr_sysinfo': */ + static const struct field_mapping fields[] = { + TD_SYSINFO_MAP_TDMR_INFO(MAX_TDMRS, max_tdmrs), + TD_SYSINFO_MAP_TDMR_INFO(MAX_RESERVED_PER_TDMR, max_reserved_per_tdmr), + TD_SYSINFO_MAP_TDMR_INFO(PAMT_4K_ENTRY_SIZE, pamt_entry_size[TDX_PS_4K]), + TD_SYSINFO_MAP_TDMR_INFO(PAMT_2M_ENTRY_SIZE, pamt_entry_size[TDX_PS_2M]), + TD_SYSINFO_MAP_TDMR_INFO(PAMT_1G_ENTRY_SIZE, pamt_entry_size[TDX_PS_1G]), + }; + /* Populate 'tdmr_sysinfo' fields using the mapping structure above: */ return stbuf_read_sysmd_multi(fields, ARRAY_SIZE(fields), tdmr_sysinfo); } From patchwork Wed Jul 17 03:40:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Huang, Kai" X-Patchwork-Id: 13735040 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 583A3AD2C; Wed, 17 Jul 2024 03:41:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721187663; cv=none; b=Ie/BykuTQlrda5qoEmAWaYkBInvJ0LVq99usiS0S0oK5oFApNEFG3/dQIbtKiP8Wa67xTEnFVR0dW7xz6IWwWl/aq/W5Egq0nx/LUNO360z0zUPT3wTmFAtpPel1RXcIMLFUkkDcJIA9JLDxngsWitK2M0SpUKIS6PCL+qn8WxU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721187663; c=relaxed/simple; bh=124x/MqvBsrRYg0ox7CppLxwII2xa0F+WTjidwG/HJw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PrNKFDJvQvPh8k3ChzMd8SzsMwyXCpifDnuQsEPfUrqNUBoK3XMYr6N9DMN8HggdxddGSahYEhxUjGBA0Ye5gGg1quEIWLBLLKwdCkWBNsKHUbKRbo8jsdarb/LuV/B5IfVcdJUQPbuoDKNp6MbJWcfL5RxWQke+DHFw16ALoEQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=Dk6CHko9; arc=none smtp.client-ip=198.175.65.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="Dk6CHko9" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1721187662; x=1752723662; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=124x/MqvBsrRYg0ox7CppLxwII2xa0F+WTjidwG/HJw=; b=Dk6CHko9gIT9e0ew+jYP68NanUO0jJCcq/ORRjoVqJS1tdirAW5vpQIQ qgKGy90o3Cw2/iUuSiF0ncFq/A61vLvcdpkLw4SFW356vAzCY9+orsgX7 ogiuRsM7OSpeO5dZd9msHn93faEdlUpq2T714gesd7fApCU21SC8su0kV zY5Q/u8rZnASb+BGO88n9G5XhCTmDhgRh2P/P8XrkdoteXeaH4AYxU7yi dOlMXflJ/YOfuSOlEgBIdTkZo0JY+jrNmwCTzM5trQa8MCzdBPe0iIQqE jhp5cVJvxplFnkyculQL2/wFaVOm4JyaPeu0WWTsovbUwBggpl6tnFOo1 g==; X-CSE-ConnectionGUID: /Ii+FpKGT3Om+hBXuDjkWA== X-CSE-MsgGUID: 9aP2+Q8WTuyCGaO6qWIDqw== X-IronPort-AV: E=McAfee;i="6700,10204,11135"; a="18512418" X-IronPort-AV: E=Sophos;i="6.09,213,1716274800"; d="scan'208";a="18512418" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jul 2024 20:40:57 -0700 X-CSE-ConnectionGUID: uqEnXocaSNSIY4bCX2Fq6A== X-CSE-MsgGUID: krRfDGP4RlKqSCjOsaArHA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,213,1716274800"; d="scan'208";a="54566737" Received: from rfrazer-mobl3.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.222.184]) by fmviesa005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jul 2024 20:40:53 -0700 From: Kai Huang To: dave.hansen@intel.com, kirill.shutemov@linux.intel.com, bp@alien8.de, tglx@linutronix.de, peterz@infradead.org, mingo@redhat.com, hpa@zytor.com, seanjc@google.com, pbonzini@redhat.com, dan.j.williams@intel.com Cc: x86@kernel.org, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, rick.p.edgecombe@intel.com, isaku.yamahata@intel.com, chao.gao@intel.com, binbin.wu@linux.intel.com, kai.huang@intel.com Subject: [PATCH v2 06/10] x86/virt/tdx: Refine a comment to reflect the latest TDX spec Date: Wed, 17 Jul 2024 15:40:13 +1200 Message-ID: X-Mailer: git-send-email 2.45.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The old versions of "Intel TDX Module v1.5 ABI Specification" contain the definitions of all global metadata field IDs directly in a table. However, the latest spec moves those definitions to a dedicated 'global_metadata.json' file as part of a new (separate) "Intel TDX Module v1.5 ABI definitions" [1]. Update the comment to reflect this. [1]: https://cdrdv2.intel.com/v1/dl/getContent/795381 Signed-off-by: Kai Huang --- v1 -> v2: - New patch to fix a comment spotted by Nikolay. --- arch/x86/virt/vmx/tdx/tdx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h index fdb879ef6c45..4e43cec19917 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -29,7 +29,7 @@ /* * Global scope metadata field ID. * - * See Table "Global Scope Metadata", TDX module 1.5 ABI spec. + * See the "global_metadata.json" in the "TDX 1.5 ABI definitions". */ #define MD_FIELD_ID_MAX_TDMRS 0x9100000100000008ULL #define MD_FIELD_ID_MAX_RESERVED_PER_TDMR 0x9100000100000009ULL From patchwork Wed Jul 17 03:40:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Huang, Kai" X-Patchwork-Id: 13735041 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5B0791B5A4; Wed, 17 Jul 2024 03:41:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721187665; cv=none; b=e0Ox9yiUtSOiF3u6jAXsrWu1sAOxmnp7+UomVNwSeWsm+Q1MZHNwP+/blwtmo4VYYKOdVR4xLG6kSTptXewMCsP/av2S/O+oYIG/qv4rAJ2Gq7lPGOrHrU6sJochW0fROC20qe4oRi5K4Bl5DOtZJs1ITnY9QPlolUa8I78CIOc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721187665; c=relaxed/simple; bh=i0wgO63rXikDOYBQPNzbg/gYjeP6zKdB0pk5XTYyPpE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dk7Zh/F33FMZ+VcVKvEU+s9b+IC8Y5Q5EHA4nTsrtlJqmguWA1J0iaqhVhekoZRKhH7rdz8xHohAc2G05aDBbw5RTxBA9isPBdDWXVSwo4NQLPjL09scveRoBobVtVf+ikNdZPZ/KbQOpIkytqWN18DbWzgBHxFwGwcb8kaqfKw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=UemADL5x; arc=none smtp.client-ip=198.175.65.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="UemADL5x" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1721187663; x=1752723663; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=i0wgO63rXikDOYBQPNzbg/gYjeP6zKdB0pk5XTYyPpE=; b=UemADL5xc/MdGkTOSXqE8zIIpgtkB1PUz4mjo4szCnlWxkZnpLh3Adud JDBS9Uu+Qfhy4jp2/ZAofB+mnlviLokYvknuWAJq9040vgzfVMurHrDxB mmnz86WkxX16ssn1Q+UAcfeP5+zFFmZXGTVeZc/bEv/w4CIFkAtc3cqdO woapWi1X3AxH4ewiV4LJUqMZWDMP2B2xgxHKNM9v4d9c3nxSe1dBTNV65 bmDiqyjyBTVIqVDo5XPE3lu97lWd6eex3MYYtYA3nWV0ROMbTWBqPU3X8 8tgobP+fLnn341CJDTtxW80UQFOIbJ5CSypPqrn2oKWn6jhDHeadUffON g==; X-CSE-ConnectionGUID: ipu4gMhdS+epQv0zDjat3g== X-CSE-MsgGUID: ZppBlLxEQv++SkHeYVkEnQ== X-IronPort-AV: E=McAfee;i="6700,10204,11135"; a="18512432" X-IronPort-AV: E=Sophos;i="6.09,213,1716274800"; d="scan'208";a="18512432" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jul 2024 20:41:00 -0700 X-CSE-ConnectionGUID: abeYhN4bRrWYDFgHOKjPmw== X-CSE-MsgGUID: b5w72BBoR1CNNMmcl7u61Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,213,1716274800"; d="scan'208";a="54566749" Received: from rfrazer-mobl3.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.222.184]) by fmviesa005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jul 2024 20:40:57 -0700 From: Kai Huang To: dave.hansen@intel.com, kirill.shutemov@linux.intel.com, bp@alien8.de, tglx@linutronix.de, peterz@infradead.org, mingo@redhat.com, hpa@zytor.com, seanjc@google.com, pbonzini@redhat.com, dan.j.williams@intel.com Cc: x86@kernel.org, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, rick.p.edgecombe@intel.com, isaku.yamahata@intel.com, chao.gao@intel.com, binbin.wu@linux.intel.com, kai.huang@intel.com Subject: [PATCH v2 07/10] x86/virt/tdx: Start to track all global metadata in one structure Date: Wed, 17 Jul 2024 15:40:14 +1200 Message-ID: <3d75e730cc514adfc9ac3200da5abd4d5e5d1bad.1721186590.git.kai.huang@intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The TDX module provides a set of "global metadata fields". They report things like TDX module version, supported features, and fields related to create/run TDX guests and so on. Currently the kernel only reads "TD Memory Region" (TDMR) related fields for module initialization. There are immediate needs which require the TDX module initialization to read more global metadata including module version, supported features and "Convertible Memory Regions" (CMRs). Also, KVM will need to read more metadata fields to support baseline TDX guests. In the longer term, other TDX features like TDX Connect (which supports assigning trusted IO devices to TDX guest) may also require other kernel components such as pci/vt-d to access global metadata. To meet all those requirements, the idea is the TDX host core-kernel to to provide a centralized, canonical, and read-only structure for the global metadata that comes out from the TDX module for all kernel components to use. As the first step, introduce a new 'struct tdx_sysinfo' to track all global metadata fields. TDX categories global metadata fields into different "Class"es. E.g., the current TDMR related fields are under class "TDMR Info". Instead of making 'struct tdx_sysinfo' a plain structure to contain all metadata fields, organize them in smaller structures based on the "Class". This allows those metadata fields to be used in finer granularity thus makes the code more clear. E.g., the current construct_tdmr() can just take the structure which contains "TDMR Info" metadata fields. Start with moving 'struct tdx_tdmr_sysinfo' to 'struct tdx_sysinfo', and rename 'struct tdx_tdmr_sysinfo' to 'struct tdx_sysinfo_tdmr_info' to make it consistent with the "class name". Add a new function get_tdx_sysinfo() as the place to read all metadata fields, and call it at the beginning of init_tdx_module(). Move the existing get_tdx_tdmr_sysinfo() to get_tdx_sysinfo(). Note there is a functional change: get_tdx_tdmr_sysinfo() is moved from after build_tdx_memlist() to before it, but it is fine to do so. Signed-off-by: Kai Huang --- arch/x86/virt/vmx/tdx/tdx.c | 29 +++++++++++++++++------------ arch/x86/virt/vmx/tdx/tdx.h | 32 +++++++++++++++++++++++++------- 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 86c47db64e42..3253cdfa5207 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -320,11 +320,11 @@ static int stbuf_read_sysmd_multi(const struct field_mapping *fields, } #define TD_SYSINFO_MAP_TDMR_INFO(_field_id, _member) \ - TD_SYSINFO_MAP(_field_id, struct tdx_tdmr_sysinfo, _member) + TD_SYSINFO_MAP(_field_id, struct tdx_sysinfo_tdmr_info, _member) -static int get_tdx_tdmr_sysinfo(struct tdx_tdmr_sysinfo *tdmr_sysinfo) +static int get_tdx_tdmr_sysinfo(struct tdx_sysinfo_tdmr_info *tdmr_sysinfo) { - /* Map TD_SYSINFO fields into 'struct tdx_tdmr_sysinfo': */ + /* Map TD_SYSINFO fields into 'struct tdx_sysinfo_tdmr_info': */ static const struct field_mapping fields[] = { TD_SYSINFO_MAP_TDMR_INFO(MAX_TDMRS, max_tdmrs), TD_SYSINFO_MAP_TDMR_INFO(MAX_RESERVED_PER_TDMR, max_reserved_per_tdmr), @@ -337,6 +337,11 @@ static int get_tdx_tdmr_sysinfo(struct tdx_tdmr_sysinfo *tdmr_sysinfo) return stbuf_read_sysmd_multi(fields, ARRAY_SIZE(fields), tdmr_sysinfo); } +static int get_tdx_sysinfo(struct tdx_sysinfo *sysinfo) +{ + return get_tdx_tdmr_sysinfo(&sysinfo->tdmr_info); +} + /* Calculate the actual TDMR size */ static int tdmr_size_single(u16 max_reserved_per_tdmr) { @@ -353,7 +358,7 @@ static int tdmr_size_single(u16 max_reserved_per_tdmr) } static int alloc_tdmr_list(struct tdmr_info_list *tdmr_list, - struct tdx_tdmr_sysinfo *tdmr_sysinfo) + struct tdx_sysinfo_tdmr_info *tdmr_sysinfo) { size_t tdmr_sz, tdmr_array_sz; void *tdmr_array; @@ -936,7 +941,7 @@ static int tdmrs_populate_rsvd_areas_all(struct tdmr_info_list *tdmr_list, */ static int construct_tdmrs(struct list_head *tmb_list, struct tdmr_info_list *tdmr_list, - struct tdx_tdmr_sysinfo *tdmr_sysinfo) + struct tdx_sysinfo_tdmr_info *tdmr_sysinfo) { int ret; @@ -1109,9 +1114,13 @@ static int init_tdmrs(struct tdmr_info_list *tdmr_list) static int init_tdx_module(void) { - struct tdx_tdmr_sysinfo tdmr_sysinfo; + struct tdx_sysinfo sysinfo; int ret; + ret = get_tdx_sysinfo(&sysinfo); + if (ret) + return ret; + /* * To keep things simple, assume that all TDX-protected memory * will come from the page allocator. Make sure all pages in the @@ -1128,17 +1137,13 @@ static int init_tdx_module(void) if (ret) goto out_put_tdxmem; - ret = get_tdx_tdmr_sysinfo(&tdmr_sysinfo); - if (ret) - goto err_free_tdxmem; - /* Allocate enough space for constructing TDMRs */ - ret = alloc_tdmr_list(&tdx_tdmr_list, &tdmr_sysinfo); + ret = alloc_tdmr_list(&tdx_tdmr_list, &sysinfo.tdmr_info); if (ret) goto err_free_tdxmem; /* Cover all TDX-usable memory regions in TDMRs */ - ret = construct_tdmrs(&tdx_memlist, &tdx_tdmr_list, &tdmr_sysinfo); + ret = construct_tdmrs(&tdx_memlist, &tdx_tdmr_list, &sysinfo.tdmr_info); if (ret) goto err_free_tdmrs; diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h index 4e43cec19917..b5eb7c35f1dc 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -100,13 +100,6 @@ struct tdx_memblock { int nid; }; -/* "TDMR info" part of "Global Scope Metadata" for constructing TDMRs */ -struct tdx_tdmr_sysinfo { - u16 max_tdmrs; - u16 max_reserved_per_tdmr; - u16 pamt_entry_size[TDX_PS_NR]; -}; - /* Warn if kernel has less than TDMR_NR_WARN TDMRs after allocation */ #define TDMR_NR_WARN 4 @@ -119,4 +112,29 @@ struct tdmr_info_list { int max_tdmrs; /* How many 'tdmr_info's are allocated */ }; +/* + * Kernel-defined structures to contain "Global Scope Metadata". + * + * TDX global metadata fields are categorized by "Class". See the + * "global_metadata.json" in the "TDX 1.5 ABI Definitions". + * + * 'struct tdx_sysinfo' is the main structure to contain all metadata + * used by the kernel. It contains sub-structures with each reflecting + * the "Class" in the 'global_metadata.json'. + * + * Note not all metadata fields in each class are defined, only those + * used by the kernel are. + */ + +/* Class "TDMR Info" */ +struct tdx_sysinfo_tdmr_info { + u16 max_tdmrs; + u16 max_reserved_per_tdmr; + u16 pamt_entry_size[TDX_PS_NR]; +}; + +struct tdx_sysinfo { + struct tdx_sysinfo_tdmr_info tdmr_info; +}; + #endif From patchwork Wed Jul 17 03:40:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Huang, Kai" X-Patchwork-Id: 13735042 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A83CEFBEA; Wed, 17 Jul 2024 03:41:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721187674; cv=none; b=CfU6DIvWqj6ToRjSFSgEr/bu5orQNZ8C/9ZM7/t6ao6+9Cp+hPO6C+ikM/S78QH8hfs+v9oIsHxja+prE0Eg6opGwZkQfDzNFeFDBELbq6ZV6xV+C6vtRjgGPYRVQn3fSsdwFSqVkbQCZWlmpTvDefkOWB4OimCGf4Jflg0nc88= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721187674; c=relaxed/simple; bh=6ijwVBE78YFDivz/d8+zBvfY9v8iI1faK1uvaOKYN2E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mJqrsLSC+Hjhx50URx5zc08B3CcBkI+tMdjw297HOxb5xRAmKha4kVrL4JK7ZheePdOeSmGGw5Q6v5uy933zWakbs31QZjWJQ9Lsi14VRFWFX4wq0UzBMxf2hHi0hSh0iqyLWSKVacAXU5bl/UCqGM9D1T/H1/Gc+6O+cRugfb8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=File3HTL; arc=none smtp.client-ip=198.175.65.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="File3HTL" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1721187673; x=1752723673; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=6ijwVBE78YFDivz/d8+zBvfY9v8iI1faK1uvaOKYN2E=; b=File3HTLmVAxePV2Pmi1vpDI+Qc+mMDrwFanviQ2mRV7YYJIT1osTKQ7 X4IuRCMID2tna9eHaXGMMTq1rS1i27zJzbaXbOoUzs82bBl3AyQJ9br3c 3hxJY5YfBvdCeYPkMlvWynDWEtgHBqJAFPsmX+p6Jzjtjj8OqTt048HB/ OxxIQOik8RrhquNPwiGf5w6Zp10arjj6iT1T+GHxb1S3WANIvqZMSVWzQ 1ZQjuzeaJTXuv2dMw/spXAYWWh5he+ILD8+Gog0EmE+0T+eRukQQMHXiF yILgewIFPiTYhwBUk71n45lkXHdxZBl2SqJ/NJcoFdIIHEzGRgVefkFXo Q==; X-CSE-ConnectionGUID: +Pd1sMtnRJyfTN3HOfRZsQ== X-CSE-MsgGUID: MSc5eIzdTMygivhwA+SYRw== X-IronPort-AV: E=McAfee;i="6700,10204,11135"; a="18512471" X-IronPort-AV: E=Sophos;i="6.09,213,1716274800"; d="scan'208";a="18512471" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jul 2024 20:41:12 -0700 X-CSE-ConnectionGUID: Z/cDHmnAQ+GJwtomkO9Hsg== X-CSE-MsgGUID: hNOLH89WS+mJ5djd5euveg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,213,1716274800"; d="scan'208";a="54566761" Received: from rfrazer-mobl3.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.222.184]) by fmviesa005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jul 2024 20:41:00 -0700 From: Kai Huang To: dave.hansen@intel.com, kirill.shutemov@linux.intel.com, bp@alien8.de, tglx@linutronix.de, peterz@infradead.org, mingo@redhat.com, hpa@zytor.com, seanjc@google.com, pbonzini@redhat.com, dan.j.williams@intel.com Cc: x86@kernel.org, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, rick.p.edgecombe@intel.com, isaku.yamahata@intel.com, chao.gao@intel.com, binbin.wu@linux.intel.com, kai.huang@intel.com Subject: [PATCH v2 08/10] x86/virt/tdx: Print TDX module basic information Date: Wed, 17 Jul 2024 15:40:15 +1200 Message-ID: <1e71406eec47ae7f6a47f8be3beab18c766ff5a7.1721186590.git.kai.huang@intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Currently the kernel doesn't print any information regarding the TDX module itself, e.g. module version. In practice such information is useful, especially to the developers. For instance, there are a couple of use cases for dumping module basic information: 1) When something goes wrong around using TDX, the information like TDX module version, supported features etc could be helpful [1][2]. 2) For Linux, when the user wants to update the TDX module, one needs to replace the old module in a specific location in the EFI partition with the new one so that after reboot the BIOS can load it. However, after kernel boots, currently the user has no way to verify it is indeed the new module that gets loaded and initialized (e.g., error could happen when replacing the old module). With the module version dumped the user can verify this easily. So dump the basic TDX module information: - TDX module version, and the build date. - TDX module type: Debug or Production. - TDX_FEATURES0: Supported TDX features. And dump the information right after reading global metadata, so that this information is printed no matter whether module initialization fails or not. The actual dmesg will look like: virt/tdx: Initializing TDX module: 1.5.00.00.0481 (build_date 20230323, Production module), TDX_FEATURES0 0xfbf Link: https://lore.kernel.org/lkml/e2d844ad-182a-4fc0-a06a-d609c9cbef74@suse.com/T/#m352829aedf6680d4628c7e40dc40b332eda93355 [1] Link: https://lore.kernel.org/lkml/e2d844ad-182a-4fc0-a06a-d609c9cbef74@suse.com/T/#m351ebcbc006d2e5bc3e7650206a087cb2708d451 [2] Signed-off-by: Kai Huang --- v1 -> v2 (Nikolay): - Change the format to dump TDX basic info. - Slightly improve changelog. --- arch/x86/virt/vmx/tdx/tdx.c | 64 +++++++++++++++++++++++++++++++++++++ arch/x86/virt/vmx/tdx/tdx.h | 33 ++++++++++++++++++- 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 3253cdfa5207..5ac0c411f4f7 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -319,6 +319,58 @@ static int stbuf_read_sysmd_multi(const struct field_mapping *fields, return 0; } +#define TD_SYSINFO_MAP_MOD_INFO(_field_id, _member) \ + TD_SYSINFO_MAP(_field_id, struct tdx_sysinfo_module_info, _member) + +static int get_tdx_module_info(struct tdx_sysinfo_module_info *modinfo) +{ + static const struct field_mapping fields[] = { + TD_SYSINFO_MAP_MOD_INFO(SYS_ATTRIBUTES, sys_attributes), + TD_SYSINFO_MAP_MOD_INFO(TDX_FEATURES0, tdx_features0), + }; + + return stbuf_read_sysmd_multi(fields, ARRAY_SIZE(fields), modinfo); +} + +#define TD_SYSINFO_MAP_MOD_VERSION(_field_id, _member) \ + TD_SYSINFO_MAP(_field_id, struct tdx_sysinfo_module_version, _member) + +static int get_tdx_module_version(struct tdx_sysinfo_module_version *modver) +{ + static const struct field_mapping fields[] = { + TD_SYSINFO_MAP_MOD_VERSION(MAJOR_VERSION, major), + TD_SYSINFO_MAP_MOD_VERSION(MINOR_VERSION, minor), + TD_SYSINFO_MAP_MOD_VERSION(UPDATE_VERSION, update), + TD_SYSINFO_MAP_MOD_VERSION(INTERNAL_VERSION, internal), + TD_SYSINFO_MAP_MOD_VERSION(BUILD_NUM, build_num), + TD_SYSINFO_MAP_MOD_VERSION(BUILD_DATE, build_date), + }; + + return stbuf_read_sysmd_multi(fields, ARRAY_SIZE(fields), modver); +} + +static void print_basic_sysinfo(struct tdx_sysinfo *sysinfo) +{ + struct tdx_sysinfo_module_version *modver = &sysinfo->module_version; + struct tdx_sysinfo_module_info *modinfo = &sysinfo->module_info; + bool debug = modinfo->sys_attributes & TDX_SYS_ATTR_DEBUG_MODULE; + + /* + * TDX module version encoding: + * + * .... + * + * When printed as text, and are 1-digit, + * and are 2-digits and + * is 4-digits. + */ + pr_info("Initializing TDX module: %u.%u.%02u.%02u.%04u (build_date %u, %s module), TDX_FEATURES0 0x%llx\n", + modver->major, modver->minor, modver->update, + modver->internal, modver->build_num, + modver->build_date, debug ? "Debug" : "Production", + modinfo->tdx_features0); +} + #define TD_SYSINFO_MAP_TDMR_INFO(_field_id, _member) \ TD_SYSINFO_MAP(_field_id, struct tdx_sysinfo_tdmr_info, _member) @@ -339,6 +391,16 @@ static int get_tdx_tdmr_sysinfo(struct tdx_sysinfo_tdmr_info *tdmr_sysinfo) static int get_tdx_sysinfo(struct tdx_sysinfo *sysinfo) { + int ret; + + ret = get_tdx_module_info(&sysinfo->module_info); + if (ret) + return ret; + + ret = get_tdx_module_version(&sysinfo->module_version); + if (ret) + return ret; + return get_tdx_tdmr_sysinfo(&sysinfo->tdmr_info); } @@ -1121,6 +1183,8 @@ static int init_tdx_module(void) if (ret) return ret; + print_basic_sysinfo(&sysinfo); + /* * To keep things simple, assume that all TDX-protected memory * will come from the page allocator. Make sure all pages in the diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h index b5eb7c35f1dc..861ddf2c2e88 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -31,6 +31,15 @@ * * See the "global_metadata.json" in the "TDX 1.5 ABI definitions". */ +#define MD_FIELD_ID_SYS_ATTRIBUTES 0x0A00000200000000ULL +#define MD_FIELD_ID_TDX_FEATURES0 0x0A00000300000008ULL +#define MD_FIELD_ID_BUILD_DATE 0x8800000200000001ULL +#define MD_FIELD_ID_BUILD_NUM 0x8800000100000002ULL +#define MD_FIELD_ID_MINOR_VERSION 0x0800000100000003ULL +#define MD_FIELD_ID_MAJOR_VERSION 0x0800000100000004ULL +#define MD_FIELD_ID_UPDATE_VERSION 0x0800000100000005ULL +#define MD_FIELD_ID_INTERNAL_VERSION 0x0800000100000006ULL + #define MD_FIELD_ID_MAX_TDMRS 0x9100000100000008ULL #define MD_FIELD_ID_MAX_RESERVED_PER_TDMR 0x9100000100000009ULL #define MD_FIELD_ID_PAMT_4K_ENTRY_SIZE 0x9100000100000010ULL @@ -124,8 +133,28 @@ struct tdmr_info_list { * * Note not all metadata fields in each class are defined, only those * used by the kernel are. + * + * Also note the "bit definitions" are architectural. */ +/* Class "TDX Module Info" */ +struct tdx_sysinfo_module_info { + u32 sys_attributes; + u64 tdx_features0; +}; + +#define TDX_SYS_ATTR_DEBUG_MODULE 0x1 + +/* Class "TDX Module Version" */ +struct tdx_sysinfo_module_version { + u16 major; + u16 minor; + u16 update; + u16 internal; + u16 build_num; + u32 build_date; +}; + /* Class "TDMR Info" */ struct tdx_sysinfo_tdmr_info { u16 max_tdmrs; @@ -134,7 +163,9 @@ struct tdx_sysinfo_tdmr_info { }; struct tdx_sysinfo { - struct tdx_sysinfo_tdmr_info tdmr_info; + struct tdx_sysinfo_module_info module_info; + struct tdx_sysinfo_module_version module_version; + struct tdx_sysinfo_tdmr_info tdmr_info; }; #endif From patchwork Wed Jul 17 03:40:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Huang, Kai" X-Patchwork-Id: 13735043 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 64FCE1F95E; Wed, 17 Jul 2024 03:41:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721187678; cv=none; b=at8UJIww+1KWHrGByEfXOTKL8J9xcIt6/YDyIE0TMprFthHmwthFGjb9jOk3r+4ICBoFbWbktvsjdKYWGdz3AUtsg3Mzmjx0T7R6COdHRPClf3iUgOTk7ybP7hC3U4lrs1oeDbURn3GoIdkgsunzolTMd8qJ1Arc5SUhqPvs6uY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721187678; c=relaxed/simple; bh=omsHwj0X7BH66iJj+RL2DFUqA8reoIN6AdLHNWLvsRw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=avh6KTgcbS/qfvDM80LXFNLmUN5zuwURCRBc/ggesSrAYkTvUFAF/I8UqGWs1ki8eJfeDS3D8a2y6Xiu0DXRdMZu39dMmrG6BeeCcguouH3TdXn4cAFfNmpTKQtRwYLloz93c26tu1Z9EyqBHYPGVrr74+AJ9DVtQTOeFWiQ2Z4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=WaFLygsM; arc=none smtp.client-ip=198.175.65.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="WaFLygsM" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1721187676; x=1752723676; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=omsHwj0X7BH66iJj+RL2DFUqA8reoIN6AdLHNWLvsRw=; b=WaFLygsMyeydIK9iLoFUbOL1XuQAnpWkn8+6rOnI7H2t4YW6x92n4oFR pFuT15jZocYAOJM27o/3QZbYy/+ntYQoo1dPUtxeu67W+OzAYYCaVg6P7 VWq6MgRuDKx/axNli9f4pSCaE6RUS5D0QzzckfRO0FWkxuGqhljY94HeY 7FNl+3wJPtRvQyGC4gDJ3qfzmCluBH+4Vot2GZwR4EnufPUC0Ed1aIcuk UL6wqTsD9yOijbkycRjFEvlvyNg4nOKnyxAhDGENPsjQmwL/5LWY2Scod yz15e/UQ3dMMdxj/6fEN7JkotOsZTohGk9bdRkRlGlnG7dgUV+j/5IGIg g==; X-CSE-ConnectionGUID: JxzjbWgMQFmmRqCPVvf8zw== X-CSE-MsgGUID: mzm8C8NZT6S6InORlIflAg== X-IronPort-AV: E=McAfee;i="6700,10204,11135"; a="18512474" X-IronPort-AV: E=Sophos;i="6.09,213,1716274800"; d="scan'208";a="18512474" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jul 2024 20:41:12 -0700 X-CSE-ConnectionGUID: gxPOXPLGQr29jWYrcj8eEw== X-CSE-MsgGUID: qHP3OpFoQOy3t8WyKmUqZA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,213,1716274800"; d="scan'208";a="54566766" Received: from rfrazer-mobl3.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.222.184]) by fmviesa005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jul 2024 20:41:07 -0700 From: Kai Huang To: dave.hansen@intel.com, kirill.shutemov@linux.intel.com, bp@alien8.de, tglx@linutronix.de, peterz@infradead.org, mingo@redhat.com, hpa@zytor.com, seanjc@google.com, pbonzini@redhat.com, dan.j.williams@intel.com Cc: x86@kernel.org, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, rick.p.edgecombe@intel.com, isaku.yamahata@intel.com, chao.gao@intel.com, binbin.wu@linux.intel.com, kai.huang@intel.com Subject: [PATCH v2 09/10] x86/virt/tdx: Reduce TDMR's reserved areas by using CMRs to find memory holes Date: Wed, 17 Jul 2024 15:40:16 +1200 Message-ID: <39c7ffb3a6d5d4075017a1c0931f85486d64e9f7.1721186590.git.kai.huang@intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 A TDX module initialization failure was reported on a Emerald Rapids platform: virt/tdx: initialization failed: TDMR [0x0, 0x80000000): reserved areas exhausted. virt/tdx: module initialization failed (-28) As part of initializing the TDX module, the kernel informs the TDX module of all "TDX-usable memory regions" using an array of TDX defined structure "TD Memory Region" (TDMR). Each TDMR must be in 1GB aligned and in 1GB granularity, and all "non-TDX-usable memory holes" within a given TDMR must be marked as "reserved areas". The TDX module reports a maximum number of reserved areas that can be supported per TDMR. Currently, the kernel finds those "non-TDX-usable memory holes" within a given TDMR by walking over a list of "TDX-usable memory regions", which essentially reflects the "usable" regions in the e820 table (w/o memory hotplug operations precisely, but this is not relevant here). As shown above, the root cause of this failure is when the kernel tries to construct a TDMR to cover address range [0x0, 0x80000000), there are too many memory holes within that range and the number of memory holes exceeds the maximum number of reserved areas. The E820 table of that platform (see [1] below) reflects this: the number of memory holes among e820 "usable" entries exceeds 16, which is the maximum number of reserved areas TDX module supports in practice. === Fix === There are two options to fix this: 1) reduce the number of memory holes when constructing a TDMR to save "reserved areas"; 2) reduce the TDMR's size to cover fewer memory regions, thus fewer memory holes. Option 1) is possible, and in fact is easier and preferable: TDX actually has a concept of "Convertible Memory Regions" (CMRs). TDX reports a list of CMRs that meet TDX's security requirements on memory. TDX requires all the "TDX-usable memory regions" that the kernel passes to the module via TDMRs, a.k.a, all the "non-reserved regions in TDMRs", must be convertible memory. In other words, if a memory hole is indeed CMR, then it's not mandatory for the kernel to add it to the reserved areas. By doing so, the number of consumed reserved areas can be reduced w/o having any functional impact. The kernel still allocates TDX memory from the page allocator. There's no harm if the kernel tells the TDX module some memory regions are "TDX-usable" but they will never be allocated by the kernel as TDX memory. Note this doesn't have any security impact either because the kernel is out of TDX's TCB anyway. This is feasible because in practice the CMRs just reflect the nature of whether the RAM can indeed be used by TDX, thus each CMR tends to be a large, uninterrupted range of memory, i.e., unlike the e820 table which contains numerous "ACPI *" entries in the first 2G range. Refer to [2] for CMRs reported on the problematic platform using off-tree TDX code. So for this particular module initialization failure, the memory holes that are within [0x0, 0x80000000) are mostly indeed CMR. By not adding them to the reserved areas, the number of consumed reserved areas for the TDMR [0x0, 0x80000000) can be dramatically reduced. Option 2) is also theoretically feasible, but it is not desired: It requires more complicated logic to handle splitting TDMR into smaller ones, which isn't trivial. There are limitations to splitting TDMR too, thus it may not always work: 1) The smallest TDMR is 1GB, and it cannot be split any further; 2) This also increases the total number of TDMRs, which also has a maximum value limited by the TDX module. So, fix this issue by using option 1): 1) reading out the CMRs from the TDX module global metadata, and 2) changing to find memory holes for a given TDMR based on CMRs, but not based on the list of "TDX-usable memory regions". Also dump the CMRs in dmesg. They are helpful when something goes wrong around "constructing the TDMRs and configuring the TDX module with them". Note there are no existing userspace tools that the user can get CMRs since they can only be read via SEAMCALL (no CPUID, MSR etc). [1] BIOS-E820 table of the problematic platform: BIOS-e820: [mem 0x0000000000000000-0x000000000009efff] usable BIOS-e820: [mem 0x000000000009f000-0x00000000000fffff] reserved BIOS-e820: [mem 0x0000000000100000-0x000000005d168fff] usable BIOS-e820: [mem 0x000000005d169000-0x000000005d22afff] ACPI data BIOS-e820: [mem 0x000000005d22b000-0x000000005d3cefff] usable BIOS-e820: [mem 0x000000005d3cf000-0x000000005d469fff] reserved BIOS-e820: [mem 0x000000005d46a000-0x000000005e5b2fff] usable BIOS-e820: [mem 0x000000005e5b3000-0x000000005e5c2fff] reserved BIOS-e820: [mem 0x000000005e5c3000-0x000000005e5d2fff] usable BIOS-e820: [mem 0x000000005e5d3000-0x000000005e5e4fff] reserved BIOS-e820: [mem 0x000000005e5e5000-0x000000005eb57fff] usable BIOS-e820: [mem 0x000000005eb58000-0x0000000061357fff] ACPI NVS BIOS-e820: [mem 0x0000000061358000-0x000000006172afff] usable BIOS-e820: [mem 0x000000006172b000-0x0000000061794fff] ACPI data BIOS-e820: [mem 0x0000000061795000-0x00000000617fefff] usable BIOS-e820: [mem 0x00000000617ff000-0x0000000061912fff] ACPI data BIOS-e820: [mem 0x0000000061913000-0x0000000061998fff] usable BIOS-e820: [mem 0x0000000061999000-0x00000000619dffff] ACPI data BIOS-e820: [mem 0x00000000619e0000-0x00000000619e1fff] usable BIOS-e820: [mem 0x00000000619e2000-0x00000000619e9fff] reserved BIOS-e820: [mem 0x00000000619ea000-0x0000000061a26fff] usable BIOS-e820: [mem 0x0000000061a27000-0x0000000061baefff] ACPI data BIOS-e820: [mem 0x0000000061baf000-0x00000000623c2fff] usable BIOS-e820: [mem 0x00000000623c3000-0x0000000062471fff] reserved BIOS-e820: [mem 0x0000000062472000-0x0000000062823fff] usable BIOS-e820: [mem 0x0000000062824000-0x0000000063a24fff] reserved BIOS-e820: [mem 0x0000000063a25000-0x0000000063d57fff] usable BIOS-e820: [mem 0x0000000063d58000-0x0000000064157fff] reserved BIOS-e820: [mem 0x0000000064158000-0x0000000064158fff] usable BIOS-e820: [mem 0x0000000064159000-0x0000000064194fff] reserved BIOS-e820: [mem 0x0000000064195000-0x000000006e9cefff] usable BIOS-e820: [mem 0x000000006e9cf000-0x000000006eccefff] reserved BIOS-e820: [mem 0x000000006eccf000-0x000000006f6fefff] ACPI NVS BIOS-e820: [mem 0x000000006f6ff000-0x000000006f7fefff] ACPI data BIOS-e820: [mem 0x000000006f7ff000-0x000000006f7fffff] usable BIOS-e820: [mem 0x000000006f800000-0x000000008fffffff] reserved ...... [2] Convertible Memory Regions of the problematic platform: virt/tdx: CMR: [0x100000, 0x6f800000) virt/tdx: CMR: [0x100000000, 0x107a000000) virt/tdx: CMR: [0x1080000000, 0x207c000000) virt/tdx: CMR: [0x2080000000, 0x307c000000) virt/tdx: CMR: [0x3080000000, 0x407c000000) Signed-off-by: Kai Huang --- v1 -> v2: - Change to walk over CMRs directly to find out memory holes, instead of walking over TDX memory blocks and explicitly check whether a hole is subregion of CMR. (Chao) - Mention any constant macro definitions in global metadata structures are TDX architectural. (Binbin) - Slightly improve the changelog. --- arch/x86/virt/vmx/tdx/tdx.c | 116 ++++++++++++++++++++++++++++++------ arch/x86/virt/vmx/tdx/tdx.h | 15 ++++- 2 files changed, 113 insertions(+), 18 deletions(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 5ac0c411f4f7..3c19295f1f8f 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -293,6 +293,10 @@ static int stbuf_read_sysmd_field(u64 field_id, void *stbuf, int offset, return 0; } +/* Wrapper to read one metadata field to u8/u16/u32/u64 */ +#define stbuf_read_sysmd_single(_field_id, _pdata) \ + stbuf_read_sysmd_field(_field_id, _pdata, 0, sizeof(typeof(*(_pdata)))) + struct field_mapping { u64 field_id; int offset; @@ -349,6 +353,76 @@ static int get_tdx_module_version(struct tdx_sysinfo_module_version *modver) return stbuf_read_sysmd_multi(fields, ARRAY_SIZE(fields), modver); } +/* Update the @cmr_info->num_cmrs to trim tail empty CMRs */ +static void trim_empty_tail_cmrs(struct tdx_sysinfo_cmr_info *cmr_info) +{ + int i; + + for (i = 0; i < cmr_info->num_cmrs; i++) { + u64 cmr_base = cmr_info->cmr_base[i]; + u64 cmr_size = cmr_info->cmr_size[i]; + + if (!cmr_size) { + WARN_ON_ONCE(cmr_base); + break; + } + + /* TDX architecture: CMR must be 4KB aligned */ + WARN_ON_ONCE(!PAGE_ALIGNED(cmr_base) || + !PAGE_ALIGNED(cmr_size)); + } + + cmr_info->num_cmrs = i; +} + +#define TD_SYSINFO_MAP_CMR_INFO(_field_id, _member) \ + TD_SYSINFO_MAP(_field_id, struct tdx_sysinfo_cmr_info, _member) + +static int get_tdx_cmr_info(struct tdx_sysinfo_cmr_info *cmr_info) +{ + int i, ret; + + ret = stbuf_read_sysmd_single(MD_FIELD_ID_NUM_CMRS, + &cmr_info->num_cmrs); + if (ret) + return ret; + + for (i = 0; i < cmr_info->num_cmrs; i++) { + const struct field_mapping fields[] = { + TD_SYSINFO_MAP_CMR_INFO(CMR_BASE0 + i, cmr_base[i]), + TD_SYSINFO_MAP_CMR_INFO(CMR_SIZE0 + i, cmr_size[i]), + }; + + ret = stbuf_read_sysmd_multi(fields, ARRAY_SIZE(fields), + cmr_info); + if (ret) + return ret; + } + + /* + * The TDX module may just report the maximum number of CMRs that + * TDX architecturally supports as the actual number of CMRs, + * despite the latter is smaller. In this case all the tail + * CMRs will be empty. Trim them away. + */ + trim_empty_tail_cmrs(cmr_info); + + return 0; +} + +static void print_cmr_info(struct tdx_sysinfo_cmr_info *cmr_info) +{ + int i; + + for (i = 0; i < cmr_info->num_cmrs; i++) { + u64 cmr_base = cmr_info->cmr_base[i]; + u64 cmr_size = cmr_info->cmr_size[i]; + + pr_info("CMR[%d]: [0x%llx, 0x%llx)\n", i, cmr_base, + cmr_base + cmr_size); + } +} + static void print_basic_sysinfo(struct tdx_sysinfo *sysinfo) { struct tdx_sysinfo_module_version *modver = &sysinfo->module_version; @@ -369,6 +443,8 @@ static void print_basic_sysinfo(struct tdx_sysinfo *sysinfo) modver->internal, modver->build_num, modver->build_date, debug ? "Debug" : "Production", modinfo->tdx_features0); + + print_cmr_info(&sysinfo->cmr_info); } #define TD_SYSINFO_MAP_TDMR_INFO(_field_id, _member) \ @@ -401,6 +477,10 @@ static int get_tdx_sysinfo(struct tdx_sysinfo *sysinfo) if (ret) return ret; + ret = get_tdx_cmr_info(&sysinfo->cmr_info); + if (ret) + return ret; + return get_tdx_tdmr_sysinfo(&sysinfo->tdmr_info); } @@ -825,29 +905,28 @@ static int tdmr_add_rsvd_area(struct tdmr_info *tdmr, int *p_idx, u64 addr, } /* - * Go through @tmb_list to find holes between memory areas. If any of + * Go through all CMRs in @cmr_info to find memory holes. If any of * those holes fall within @tdmr, set up a TDMR reserved area to cover * the hole. */ -static int tdmr_populate_rsvd_holes(struct list_head *tmb_list, +static int tdmr_populate_rsvd_holes(struct tdx_sysinfo_cmr_info *cmr_info, struct tdmr_info *tdmr, int *rsvd_idx, u16 max_reserved_per_tdmr) { - struct tdx_memblock *tmb; u64 prev_end; - int ret; + int i, ret; /* * Start looking for reserved blocks at the * beginning of the TDMR. */ prev_end = tdmr->base; - list_for_each_entry(tmb, tmb_list, list) { + for (i = 0; i < cmr_info->num_cmrs; i++) { u64 start, end; - start = PFN_PHYS(tmb->start_pfn); - end = PFN_PHYS(tmb->end_pfn); + start = cmr_info->cmr_base[i]; + end = start + cmr_info->cmr_size[i]; /* Break if this region is after the TDMR */ if (start >= tdmr_end(tdmr)) @@ -948,16 +1027,16 @@ static int rsvd_area_cmp_func(const void *a, const void *b) /* * Populate reserved areas for the given @tdmr, including memory holes - * (via @tmb_list) and PAMTs (via @tdmr_list). + * (via @cmr_info) and PAMTs (via @tdmr_list). */ static int tdmr_populate_rsvd_areas(struct tdmr_info *tdmr, - struct list_head *tmb_list, + struct tdx_sysinfo_cmr_info *cmr_info, struct tdmr_info_list *tdmr_list, u16 max_reserved_per_tdmr) { int ret, rsvd_idx = 0; - ret = tdmr_populate_rsvd_holes(tmb_list, tdmr, &rsvd_idx, + ret = tdmr_populate_rsvd_holes(cmr_info, tdmr, &rsvd_idx, max_reserved_per_tdmr); if (ret) return ret; @@ -976,10 +1055,10 @@ static int tdmr_populate_rsvd_areas(struct tdmr_info *tdmr, /* * Populate reserved areas for all TDMRs in @tdmr_list, including memory - * holes (via @tmb_list) and PAMTs. + * holes (via @cmr_info) and PAMTs. */ static int tdmrs_populate_rsvd_areas_all(struct tdmr_info_list *tdmr_list, - struct list_head *tmb_list, + struct tdx_sysinfo_cmr_info *cmr_info, u16 max_reserved_per_tdmr) { int i; @@ -988,7 +1067,7 @@ static int tdmrs_populate_rsvd_areas_all(struct tdmr_info_list *tdmr_list, int ret; ret = tdmr_populate_rsvd_areas(tdmr_entry(tdmr_list, i), - tmb_list, tdmr_list, max_reserved_per_tdmr); + cmr_info, tdmr_list, max_reserved_per_tdmr); if (ret) return ret; } @@ -999,11 +1078,13 @@ static int tdmrs_populate_rsvd_areas_all(struct tdmr_info_list *tdmr_list, /* * Construct a list of TDMRs on the preallocated space in @tdmr_list * to cover all TDX memory regions in @tmb_list based on the TDX module - * TDMR global information in @tdmr_sysinfo. + * TDMR global information in @tdmr_sysinfo and CMR information in + * @cmr_info. */ static int construct_tdmrs(struct list_head *tmb_list, struct tdmr_info_list *tdmr_list, - struct tdx_sysinfo_tdmr_info *tdmr_sysinfo) + struct tdx_sysinfo_tdmr_info *tdmr_sysinfo, + struct tdx_sysinfo_cmr_info *cmr_info) { int ret; @@ -1016,7 +1097,7 @@ static int construct_tdmrs(struct list_head *tmb_list, if (ret) return ret; - ret = tdmrs_populate_rsvd_areas_all(tdmr_list, tmb_list, + ret = tdmrs_populate_rsvd_areas_all(tdmr_list, cmr_info, tdmr_sysinfo->max_reserved_per_tdmr); if (ret) tdmrs_free_pamt_all(tdmr_list); @@ -1207,7 +1288,8 @@ static int init_tdx_module(void) goto err_free_tdxmem; /* Cover all TDX-usable memory regions in TDMRs */ - ret = construct_tdmrs(&tdx_memlist, &tdx_tdmr_list, &sysinfo.tdmr_info); + ret = construct_tdmrs(&tdx_memlist, &tdx_tdmr_list, &sysinfo.tdmr_info, + &sysinfo.cmr_info); if (ret) goto err_free_tdmrs; diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h index 861ddf2c2e88..4b43eb774ffa 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -40,6 +40,10 @@ #define MD_FIELD_ID_UPDATE_VERSION 0x0800000100000005ULL #define MD_FIELD_ID_INTERNAL_VERSION 0x0800000100000006ULL +#define MD_FIELD_ID_NUM_CMRS 0x9000000100000000ULL +#define MD_FIELD_ID_CMR_BASE0 0x9000000300000080ULL +#define MD_FIELD_ID_CMR_SIZE0 0x9000000300000100ULL + #define MD_FIELD_ID_MAX_TDMRS 0x9100000100000008ULL #define MD_FIELD_ID_MAX_RESERVED_PER_TDMR 0x9100000100000009ULL #define MD_FIELD_ID_PAMT_4K_ENTRY_SIZE 0x9100000100000010ULL @@ -134,7 +138,7 @@ struct tdmr_info_list { * Note not all metadata fields in each class are defined, only those * used by the kernel are. * - * Also note the "bit definitions" are architectural. + * Also note the "bit/constant definitions" are architectural. */ /* Class "TDX Module Info" */ @@ -155,6 +159,14 @@ struct tdx_sysinfo_module_version { u32 build_date; }; +/* Class "CMR Info" */ +#define TDX_MAX_CMRS 32 +struct tdx_sysinfo_cmr_info { + u16 num_cmrs; + u64 cmr_base[TDX_MAX_CMRS]; + u64 cmr_size[TDX_MAX_CMRS]; +}; + /* Class "TDMR Info" */ struct tdx_sysinfo_tdmr_info { u16 max_tdmrs; @@ -165,6 +177,7 @@ struct tdx_sysinfo_tdmr_info { struct tdx_sysinfo { struct tdx_sysinfo_module_info module_info; struct tdx_sysinfo_module_version module_version; + struct tdx_sysinfo_cmr_info cmr_info; struct tdx_sysinfo_tdmr_info tdmr_info; }; From patchwork Wed Jul 17 03:40:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Huang, Kai" X-Patchwork-Id: 13735044 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A6861FBEA; Wed, 17 Jul 2024 03:41:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.19 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721187680; cv=none; b=dEDVjns6DSKwc+xMKQkhpVJb4sclG/vm1tX7eh6GmWCenzNSaNXv2G3sQBoE2oQyQPUlWW8Ci5WmV3yQOdI9X/WIH+U2SA5UH3AXslhKkjCyOKqp8eCZ1ZW/WA4voswyIGzcPAZeED+rft7OvGxXXPFd3IJOC3qp4btINQogea4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721187680; c=relaxed/simple; bh=7hG+uRTOF5VT/BVJAB9g4uCVmdMHl/IaV9iSHLeVdZg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uQFZAO+G0nBHClkxlBGHstL5BGdMOQEX4kumWGKu+6jLwiJQlFhLzM2YLaw+c8Atf8q4vN+bndFNp7V0ZNgsTDlzxpRlTzpw5B8ALEQ+PUcAcdDY9x77ViGZ25n6vCse9jy6XcGcaOA5c2hU8oXF7MewDmijFx+uGaptfjF688o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=TG0v/cqH; arc=none smtp.client-ip=198.175.65.19 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="TG0v/cqH" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1721187679; x=1752723679; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=7hG+uRTOF5VT/BVJAB9g4uCVmdMHl/IaV9iSHLeVdZg=; b=TG0v/cqHkZrnzqWfgS8cLghcYQcNk/X6ya4enai8xusOOV7d6JzDfDk6 QMBIlrGAhoxHcm0RFjfFvv3n6Ksdcn7K26WszY4/2DuxN+DZ5N5k2na94 97hLx+MFWM1t4cZf8fa3RB3z/9QQr+yJmjRFUG8tMyR4fSRQSVX8QlO77 IYjsHsnMhqYhB4QgsS/WFnK80sCCNS1frllHSAiSHx2s1AiLHLpS8j7Lk dn2ziX6RD7dMK9Uzvmff4TZZ5nIPnC9UJACYkubWWnJkOt7VOaGzC8LIt sO1MrLSpTHeND7WwmftZLAIc1EQ3mkRCxaDwW4PUWlQ7NAp2whsNfm05F w==; X-CSE-ConnectionGUID: W0kGoxpVQLukTfiJe5L70g== X-CSE-MsgGUID: viLFhnx9TzS7eFCL26bAGA== X-IronPort-AV: E=McAfee;i="6700,10204,11135"; a="18512479" X-IronPort-AV: E=Sophos;i="6.09,213,1716274800"; d="scan'208";a="18512479" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jul 2024 20:41:16 -0700 X-CSE-ConnectionGUID: Jv6nFXSATyGC2o0DgcuVkg== X-CSE-MsgGUID: KNQmO0T+QQiYyCRPqZew1Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,213,1716274800"; d="scan'208";a="54566771" Received: from rfrazer-mobl3.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.222.184]) by fmviesa005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jul 2024 20:41:10 -0700 From: Kai Huang To: dave.hansen@intel.com, kirill.shutemov@linux.intel.com, bp@alien8.de, tglx@linutronix.de, peterz@infradead.org, mingo@redhat.com, hpa@zytor.com, seanjc@google.com, pbonzini@redhat.com, dan.j.williams@intel.com Cc: x86@kernel.org, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, rick.p.edgecombe@intel.com, isaku.yamahata@intel.com, chao.gao@intel.com, binbin.wu@linux.intel.com, kai.huang@intel.com Subject: [PATCH v2 10/10] x86/virt/tdx: Don't initialize module that doesn't support NO_RBP_MOD feature Date: Wed, 17 Jul 2024 15:40:17 +1200 Message-ID: X-Mailer: git-send-email 2.45.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Old TDX modules can clobber RBP in the TDH.VP.ENTER SEAMCALL. However RBP is used as frame pointer in the x86_64 calling convention, and clobbering RBP could result in bad things like being unable to unwind the stack if any non-maskable exceptions (NMI, #MC etc) happens in that gap. A new "NO_RBP_MOD" feature was introduced to more recent TDX modules to not clobber RBP. This feature is reported in the TDX_FEATURES0 global metadata field via bit 18. Don't initialize the TDX module if this feature is not supported [1]. Link: https://lore.kernel.org/all/c0067319-2653-4cbd-8fee-1ccf21b1e646@suse.com/T/#mef98469c51e2382ead2c537ea189752360bd2bef [1] Signed-off-by: Kai Huang Reviewed-by: Nikolay Borisov --- v1 -> v2: - Add tag from Nikolay. --- arch/x86/virt/vmx/tdx/tdx.c | 17 +++++++++++++++++ arch/x86/virt/vmx/tdx/tdx.h | 1 + 2 files changed, 18 insertions(+) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 3c19295f1f8f..ec6156728423 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -484,6 +484,18 @@ static int get_tdx_sysinfo(struct tdx_sysinfo *sysinfo) return get_tdx_tdmr_sysinfo(&sysinfo->tdmr_info); } +static int check_module_compatibility(struct tdx_sysinfo *sysinfo) +{ + u64 tdx_features0 = sysinfo->module_info.tdx_features0; + + if (!(tdx_features0 & TDX_FEATURES0_NO_RBP_MOD)) { + pr_err("NO_RBP_MOD feature is not supported\n"); + return -EINVAL; + } + + return 0; +} + /* Calculate the actual TDMR size */ static int tdmr_size_single(u16 max_reserved_per_tdmr) { @@ -1266,6 +1278,11 @@ static int init_tdx_module(void) print_basic_sysinfo(&sysinfo); + /* Check whether the kernel can support this module */ + ret = check_module_compatibility(&sysinfo); + if (ret) + return ret; + /* * To keep things simple, assume that all TDX-protected memory * will come from the page allocator. Make sure all pages in the diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h index 4b43eb774ffa..20fd7cb5937a 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -148,6 +148,7 @@ struct tdx_sysinfo_module_info { }; #define TDX_SYS_ATTR_DEBUG_MODULE 0x1 +#define TDX_FEATURES0_NO_RBP_MOD _BITULL(18) /* Class "TDX Module Version" */ struct tdx_sysinfo_module_version {