From patchwork Tue Sep 24 11:28:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Huang, Kai" X-Patchwork-Id: 13810828 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.8]) (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 48F101A4F36; Tue, 24 Sep 2024 11:29:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.8 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727177355; cv=none; b=aRyIKuEMNqzoF9LDopzNifzGppEtXRgGNUplqi6emvQN4dmSRgZX24p05tMCvcBMRxTdyZrpnY1HN5VEd4zkw3Img3i29LKwPuPPqpIIwZmcLaGQLlKyjPJYWegvDGK7koPlXXy+B85KyRVHvF6id/RElY3Q6DFwujeDsygQTws= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727177355; c=relaxed/simple; bh=eA1hJ0oR60Y4QEmDIU9OOIu3k0XElYh8iNnAVITJxTk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JRvNQz5Grwpr+qxw+cM5pFzDdGRgXDLebQFKoSrG/U+8UhUo5FyM7b+KEFq8F3uk+zmvsY0pGDauTIqX3lI6ZlJSYTSzM8K0aHlzM6MRXQF5vyJ37iJV6QlaXlVBvrpnCd0k+xA7IZXsG5ZzhUvbV0vOBwg1pk327+YTs6FeTdE= 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=a7XUlrJm; arc=none smtp.client-ip=192.198.163.8 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="a7XUlrJm" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1727177353; x=1758713353; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=eA1hJ0oR60Y4QEmDIU9OOIu3k0XElYh8iNnAVITJxTk=; b=a7XUlrJmtpbjTAweLS03xuA4HCHG8yNpgT0DFDnfk9eHkFMaNM40112X 91ZwGVEp3LgOS7hEWg239uROHMYPM3z/uSpb0eh8u1kDAWrgOBgObZMBm CAsfnsYDG7U0PNJL1/yJpHtvh/jHR6gZQv7DPQb93uh0jbdgpOZKnv07q 8nbnFlkLEQf0lAnj0xow/MHiGi7eA3UyFMuyMfpjFZGg89Oq8kUahennu Wj67eB7Ou7BwRHVWpndDGNOQMffOxr5lIOKjOKdZHViT2SeZLnmhLjMjq KWsNa5ceaMiGeaLLWxfnGkP/t0SzSnb7K25xGZkDpARnDcMR+rjko5Yjr g==; X-CSE-ConnectionGUID: gYk/JojKS+y4rnkzn7/GgQ== X-CSE-MsgGUID: lJ/G1Vg4R1ayhTEoISQAdg== X-IronPort-AV: E=McAfee;i="6700,10204,11204"; a="43686473" X-IronPort-AV: E=Sophos;i="6.10,254,1719903600"; d="scan'208";a="43686473" Received: from fmviesa007.fm.intel.com ([10.60.135.147]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Sep 2024 04:29:13 -0700 X-CSE-ConnectionGUID: cvNlOoRuT8KWaqm1Sd5xGA== X-CSE-MsgGUID: Ytauvr21RSSP+rD8J/F3UQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.10,254,1719903600"; d="scan'208";a="70994564" Received: from ccbilbre-mobl3.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.221.10]) by fmviesa007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Sep 2024 04:29:09 -0700 From: Kai Huang To: dave.hansen@intel.com, kirill.shutemov@linux.intel.com, tglx@linutronix.de, bp@alien8.de, peterz@infradead.org, mingo@redhat.com, hpa@zytor.com, dan.j.williams@intel.com, seanjc@google.com, pbonzini@redhat.com Cc: x86@kernel.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, rick.p.edgecombe@intel.com, isaku.yamahata@intel.com, adrian.hunter@intel.com, nik.borisov@suse.com, kai.huang@intel.com Subject: [PATCH v4 1/8] x86/virt/tdx: Rename 'struct tdx_tdmr_sysinfo' to reflect the spec better Date: Tue, 24 Sep 2024 23:28:28 +1200 Message-ID: X-Mailer: git-send-email 2.46.0 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. TDX organizes those metadata fields by "Classes" based on the meaning of those fields. E.g., for now the kernel only reads "TD Memory Region" (TDMR) related fields for module initialization. Those fields are defined under class "TDMR Info". There are both immediate needs to read more metadata fields for module initialization and near-future needs for other kernel components like KVM to run TDX guests. To meet all those requirements, the idea is the TDX host core-kernel 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. More specifically, the target is to end up with something like: struct tdx_sys_info { struct tdx_sys_info_classA a; struct tdx_sys_info_classB b; ... }; Currently the kernel organizes all fields under "TDMR Info" class in 'struct tdx_tdmr_sysinfo'. To prepare for the above target, rename the structure to 'struct tdx_sys_info_tdmr' to follow the class name better. No functional change intended. Signed-off-by: Kai Huang Reviewed-by: Adrian Hunter Reviewed-by: Dan Williams --- v3 -> v4: - "global metadata fields" -> "Global Metadata Fields" - Ardian. - "Class"es -> "Classes" - Ardian. - Add tag from Ardian and Dan. v2 -> v3: - Split out as a separate patch and place it at beginning: https://lore.kernel.org/kvm/cover.1721186590.git.kai.huang@intel.com/T/#m8fec7c429242d640cf5e756eb68e3b822e6dff8b - Rename to 'struct tdx_sys_info_tdmr': https://lore.kernel.org/kvm/cover.1721186590.git.kai.huang@intel.com/T/#md73dd9b02a492acf4a6facae63e8d030e320967d https://lore.kernel.org/kvm/cover.1721186590.git.kai.huang@intel.com/T/#m8fec7c429242d640cf5e756eb68e3b822e6dff8b --- arch/x86/virt/vmx/tdx/tdx.c | 36 ++++++++++++++++++------------------ arch/x86/virt/vmx/tdx/tdx.h | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 4e2b2e2ac9f9..e979bf442929 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -272,7 +272,7 @@ 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) + struct tdx_sys_info_tdmr *ts) { u16 *ts_member = ((void *)ts) + offset; u64 tmp; @@ -298,9 +298,9 @@ struct field_mapping { #define TD_SYSINFO_MAP(_field_id, _offset) \ { .field_id = MD_FIELD_ID_##_field_id, \ - .offset = offsetof(struct tdx_tdmr_sysinfo, _offset) } + .offset = offsetof(struct tdx_sys_info_tdmr, _offset) } -/* Map TD_SYSINFO fields into 'struct tdx_tdmr_sysinfo': */ +/* Map TD_SYSINFO fields into 'struct tdx_sys_info_tdmr': */ static const struct field_mapping fields[] = { TD_SYSINFO_MAP(MAX_TDMRS, max_tdmrs), TD_SYSINFO_MAP(MAX_RESERVED_PER_TDMR, max_reserved_per_tdmr), @@ -309,16 +309,16 @@ static const struct field_mapping fields[] = { TD_SYSINFO_MAP(PAMT_1G_ENTRY_SIZE, pamt_entry_size[TDX_PS_1G]), }; -static int get_tdx_tdmr_sysinfo(struct tdx_tdmr_sysinfo *tdmr_sysinfo) +static int get_tdx_sys_info_tdmr(struct tdx_sys_info_tdmr *sysinfo_tdmr) { int ret; int i; - /* Populate 'tdmr_sysinfo' fields using the mapping structure above: */ + /* Populate 'sysinfo_tdmr' 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); + sysinfo_tdmr); if (ret) return ret; } @@ -342,13 +342,13 @@ 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_sys_info_tdmr *sysinfo_tdmr) { size_t tdmr_sz, tdmr_array_sz; void *tdmr_array; - tdmr_sz = tdmr_size_single(tdmr_sysinfo->max_reserved_per_tdmr); - tdmr_array_sz = tdmr_sz * tdmr_sysinfo->max_tdmrs; + tdmr_sz = tdmr_size_single(sysinfo_tdmr->max_reserved_per_tdmr); + tdmr_array_sz = tdmr_sz * sysinfo_tdmr->max_tdmrs; /* * To keep things simple, allocate all TDMRs together. @@ -367,7 +367,7 @@ static int alloc_tdmr_list(struct tdmr_info_list *tdmr_list, * at a given index in the TDMR list. */ tdmr_list->tdmr_sz = tdmr_sz; - tdmr_list->max_tdmrs = tdmr_sysinfo->max_tdmrs; + tdmr_list->max_tdmrs = sysinfo_tdmr->max_tdmrs; tdmr_list->nr_consumed_tdmrs = 0; return 0; @@ -921,11 +921,11 @@ 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 @sysinfo_tdmr. */ static int construct_tdmrs(struct list_head *tmb_list, struct tdmr_info_list *tdmr_list, - struct tdx_tdmr_sysinfo *tdmr_sysinfo) + struct tdx_sys_info_tdmr *sysinfo_tdmr) { int ret; @@ -934,12 +934,12 @@ static int construct_tdmrs(struct list_head *tmb_list, return ret; ret = tdmrs_set_up_pamt_all(tdmr_list, tmb_list, - tdmr_sysinfo->pamt_entry_size); + sysinfo_tdmr->pamt_entry_size); if (ret) return ret; ret = tdmrs_populate_rsvd_areas_all(tdmr_list, tmb_list, - tdmr_sysinfo->max_reserved_per_tdmr); + sysinfo_tdmr->max_reserved_per_tdmr); if (ret) tdmrs_free_pamt_all(tdmr_list); @@ -1098,7 +1098,7 @@ static int init_tdmrs(struct tdmr_info_list *tdmr_list) static int init_tdx_module(void) { - struct tdx_tdmr_sysinfo tdmr_sysinfo; + struct tdx_sys_info_tdmr sysinfo_tdmr; int ret; /* @@ -1117,17 +1117,17 @@ static int init_tdx_module(void) if (ret) goto out_put_tdxmem; - ret = get_tdx_tdmr_sysinfo(&tdmr_sysinfo); + ret = get_tdx_sys_info_tdmr(&sysinfo_tdmr); 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); 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); 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 b701f69485d3..148f9b4d1140 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -100,7 +100,7 @@ struct tdx_memblock { }; /* "TDMR info" part of "Global Scope Metadata" for constructing TDMRs */ -struct tdx_tdmr_sysinfo { +struct tdx_sys_info_tdmr { u16 max_tdmrs; u16 max_reserved_per_tdmr; u16 pamt_entry_size[TDX_PS_NR]; From patchwork Tue Sep 24 11:28:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Huang, Kai" X-Patchwork-Id: 13810829 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.8]) (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 C3CDA1A707D; Tue, 24 Sep 2024 11:29:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.8 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727177358; cv=none; b=QQTwxixsbFTV6tOsraSgnz6xvVcgk0PIL0nSwBnFqK6nnbqjc75Ph52EQrdWgsz57PUdxWnOZrLaAmhzgph7nEgMEOka980pWc9xwHhVqTKsUCrkhhvU22hRvdaIFHxhAtnQJ/zQuP4wGJ+uU1g3Mli+CdtG0wb0QrWtKDCIsjY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727177358; c=relaxed/simple; bh=cL2uUbkxGHfoIn5hEEk5cOTINpoJa4CyuJmYcpnso8w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cFpvUuBNbfilMVw+wlaBnlrZfcW/JEwrTP3aUNtub+JAT1IJ275EmlFKvXWd5Qo7JEM6kAhS5S16+qVaZKCkwZixOtWgEjbweXXqk8LoNaAoWp3jz6nBw/HuMfIylRv//0LFKNmsSDyONNZqAq3hCf1/EaLWT4Yax0z8YUPjOz0= 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=mb6JIPK2; arc=none smtp.client-ip=192.198.163.8 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="mb6JIPK2" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1727177357; x=1758713357; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=cL2uUbkxGHfoIn5hEEk5cOTINpoJa4CyuJmYcpnso8w=; b=mb6JIPK2WYbAcdcVToEquv0oYgf4MQt0c6kyjaeXOY3FiHXdLVTmE7cA vBPmMjljn0mTWlgHnLREF80WYZxpGIS1Z0gA85EiMta7mX3xk7qqsbHJt kCIxMeiCEeFZi/XoD1bv7s482ddnUecVh4NrDtgDe8T8+WT7dGmIt2e9J UGjjumqDYoduNZUJ6FCisvhieYZ1cOm5KwzE/Ygt2D7SCXLBba0h/6qHa P1eOfZJd3rocbJ1A+ot/yxDlhEkxHTYLR7xSNoWWAXcDrlQ5MjZYQYbi6 TIdhVv/Jdy/kBDJ4Qaye44n38Cf5jnodT5GFZ1jaxH2BAG6Yry2gbyttZ g==; X-CSE-ConnectionGUID: OdlPLrRXSRq3ls5SSCJh7w== X-CSE-MsgGUID: wraUJLQtTpCWoqqkjyuW8Q== X-IronPort-AV: E=McAfee;i="6700,10204,11204"; a="43686487" X-IronPort-AV: E=Sophos;i="6.10,254,1719903600"; d="scan'208";a="43686487" Received: from fmviesa007.fm.intel.com ([10.60.135.147]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Sep 2024 04:29:17 -0700 X-CSE-ConnectionGUID: o309BYRiRqGMYYRvSXwaGA== X-CSE-MsgGUID: p6ecXfQ4S9CJ56swDYnVOQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.10,254,1719903600"; d="scan'208";a="70994585" Received: from ccbilbre-mobl3.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.221.10]) by fmviesa007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Sep 2024 04:29:13 -0700 From: Kai Huang To: dave.hansen@intel.com, kirill.shutemov@linux.intel.com, tglx@linutronix.de, bp@alien8.de, peterz@infradead.org, mingo@redhat.com, hpa@zytor.com, dan.j.williams@intel.com, seanjc@google.com, pbonzini@redhat.com Cc: x86@kernel.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, rick.p.edgecombe@intel.com, isaku.yamahata@intel.com, adrian.hunter@intel.com, nik.borisov@suse.com, kai.huang@intel.com Subject: [PATCH v4 2/8] x86/virt/tdx: Rework TD_SYSINFO_MAP to support build-time verification Date: Tue, 24 Sep 2024 23:28:29 +1200 Message-ID: <608ba48cfdffcbbd06c8505e3ba8dc623edf5b10.1727173372.git.kai.huang@intel.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Dan noticed [1] that read_sys_metadata_field16() has a runtime warning to validate that the metadata field size matches the passed in buffer size. In turns out that all the information to perform that validation is available at build time. Rework TD_SYSINFO_MAP() to stop providing runtime data to read_sys_metadata_field16() and instead just pass typed fields to read_sys_metadata_field16() and let the compiler catch any mismatches. Rename TD_SYSINFO_MAP() to READ_SYS_INFO() since it no longer stores the mapping of metadata field ID and the structure member offset. For now READ_SYS_INFO() is only used in get_tdx_sys_info_tdmr(). Future changes will need to read other metadata fields that are organized in different structures. Do #undef READ_SYS_INFO() after use so the same pattern can be used for reading other metadata fields. To avoid needing to duplicate build-time verification in each READ_SYS_INFO() in future changes, add a wrapper macro to do build-time verification and call it from READ_SYS_INFO(). The READ_SYS_INFO() has a couple quirks for readability. It requires the function that uses it to define a local variable @ret to carry the error code and set the initial value to 0. It also hard-codes the variable name of the structure pointer used in the function, but it is less code, build-time verifiable, and the same readability as the former 'struct field_mapping' approach. Link: http://lore.kernel.org/66b16121c48f4_4fc729424@dwillia2-xfh.jf.intel.com.notmuch [1] Suggested-by: Dan Williams Signed-off-by: Kai Huang --- v3 -> v4: - Rename TD_SYSINFO_MAP() to READ_SYS_INFO() - Ardian. - #undef READ_SYS_INFO() - Ardian. - Rewrite changelog based on text from Dan, with some clarification around using READ_SYS_INFO() and #undef it. - Move the BUILD_BUG_ON() out of read_sys_metadata_field16() - Dan. - Use permalink in changelog - Dan. v2 -> v3: - Remove 'struct field_mapping' and reimplement TD_SYSINFO_MAP(). --- arch/x86/virt/vmx/tdx/tdx.c | 58 ++++++++++++++----------------------- 1 file changed, 21 insertions(+), 37 deletions(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index e979bf442929..2f7e4abc1bb9 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -270,60 +270,44 @@ static int read_sys_metadata_field(u64 field_id, u64 *data) return 0; } -static int read_sys_metadata_field16(u64 field_id, - int offset, - struct tdx_sys_info_tdmr *ts) +static int __read_sys_metadata_field16(u64 field_id, u16 *val) { - u16 *ts_member = ((void *)ts) + offset; u64 tmp; int ret; - if (WARN_ON_ONCE(MD_FIELD_ID_ELE_SIZE_CODE(field_id) != - MD_FIELD_ID_ELE_SIZE_16BIT)) - return -EINVAL; - ret = read_sys_metadata_field(field_id, &tmp); if (ret) return ret; - *ts_member = tmp; + *val = tmp; return 0; } -struct field_mapping { - u64 field_id; - int offset; -}; - -#define TD_SYSINFO_MAP(_field_id, _offset) \ - { .field_id = MD_FIELD_ID_##_field_id, \ - .offset = offsetof(struct tdx_sys_info_tdmr, _offset) } - -/* Map TD_SYSINFO fields into 'struct tdx_sys_info_tdmr': */ -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]), -}; +#define read_sys_metadata_field16(_field_id, _val) \ +({ \ + BUILD_BUG_ON(MD_FIELD_ID_ELE_SIZE_CODE(_field_id) != \ + MD_FIELD_ID_ELE_SIZE_16BIT); \ + __read_sys_metadata_field16(_field_id, _val); \ +}) static int get_tdx_sys_info_tdmr(struct tdx_sys_info_tdmr *sysinfo_tdmr) { - int ret; - int i; + int ret = 0; - /* Populate 'sysinfo_tdmr' 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, - sysinfo_tdmr); - if (ret) - return ret; - } +#define READ_SYS_INFO(_field_id, _member) \ + ret = ret ?: read_sys_metadata_field16(MD_FIELD_ID_##_field_id, \ + &sysinfo_tdmr->_member) - return 0; + READ_SYS_INFO(MAX_TDMRS, max_tdmrs); + READ_SYS_INFO(MAX_RESERVED_PER_TDMR, max_reserved_per_tdmr); + READ_SYS_INFO(PAMT_4K_ENTRY_SIZE, pamt_entry_size[TDX_PS_4K]); + READ_SYS_INFO(PAMT_2M_ENTRY_SIZE, pamt_entry_size[TDX_PS_2M]); + READ_SYS_INFO(PAMT_1G_ENTRY_SIZE, pamt_entry_size[TDX_PS_1G]); + +#undef READ_SYS_INFO + + return ret; } /* Calculate the actual TDMR size */ From patchwork Tue Sep 24 11:28:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Huang, Kai" X-Patchwork-Id: 13810830 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.8]) (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 467481A7264; Tue, 24 Sep 2024 11:29:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.8 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727177361; cv=none; b=TADjCRTrUd0YJHaBukxd8/0DVzcdHEPlKNaWvaTQKcCOgFgrE+b9wuXm86K/IRkM4VsgDvcM80thIjyY5SICVjTnSi3tnmJevZkYJ/mDTKjU6R6phCqNsds97o9LLDCCsj6M5jS1dvzWF2QFg/hcy6KiR3xyIg4+iph0+6Gofd4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727177361; c=relaxed/simple; bh=jmm7W4ZtQRVxYWAMuq40hCi8DgUyQBrn8bapXyCz6BE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tn3yVPVgkXwd8ai2gtRq6oztGqPzhM7zXNq4UWd7d3ch9wm2se1kCoQU00wA73tv0IjH/nwzhn2oKlMx2G765NW/UmrGCHgzF6OoyfOtFmkSnZcKK7EiCBhrArrZXMLkzQpFSEo2MHv64te12BeEB6rTFpAPlkbrryan2nA7ZXI= 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=FXMVESHW; arc=none smtp.client-ip=192.198.163.8 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="FXMVESHW" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1727177360; x=1758713360; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=jmm7W4ZtQRVxYWAMuq40hCi8DgUyQBrn8bapXyCz6BE=; b=FXMVESHWldeY3ty9vJH+r+pMDXf1DGZETzAd5rkMq6KUZHH92YpU0nZW nU2KRazEjbvpz2HtyDnh1FL0e9Ps13hT5UEbU76z9oZCec7pSw6RHhVPe qkZkfaRdey0EjqJb2wewFv2I+5/tueKgswc2jPIqs8glplcP6QnuN+i6w P8n/kgcFRYNafQfCE9kF4pq0IL5EvXERFlEJpppa1+4WUciI9hdVeurgN uCljbdlaHqHGI+xzQ9TPCryevRSJXMMn4OG8ReIO9r/porktmLtTgunRt G21Esl0+ZD4Z4wkwrPpNEza18S37ZoSf/XHBt2ZUvkkNRerl6OgybvDOQ A==; X-CSE-ConnectionGUID: yuyQNojBTgqKq2sCimSBoA== X-CSE-MsgGUID: RXKVSxMBQ1WBosxcf+mD3g== X-IronPort-AV: E=McAfee;i="6700,10204,11204"; a="43686503" X-IronPort-AV: E=Sophos;i="6.10,254,1719903600"; d="scan'208";a="43686503" Received: from fmviesa007.fm.intel.com ([10.60.135.147]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Sep 2024 04:29:20 -0700 X-CSE-ConnectionGUID: kv/9LVWITnOcZBB0Uii5Cg== X-CSE-MsgGUID: LYDTA/H+TeOrRYronycUew== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.10,254,1719903600"; d="scan'208";a="70994603" Received: from ccbilbre-mobl3.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.221.10]) by fmviesa007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Sep 2024 04:29:17 -0700 From: Kai Huang To: dave.hansen@intel.com, kirill.shutemov@linux.intel.com, tglx@linutronix.de, bp@alien8.de, peterz@infradead.org, mingo@redhat.com, hpa@zytor.com, dan.j.williams@intel.com, seanjc@google.com, pbonzini@redhat.com Cc: x86@kernel.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, rick.p.edgecombe@intel.com, isaku.yamahata@intel.com, adrian.hunter@intel.com, nik.borisov@suse.com, kai.huang@intel.com Subject: [PATCH v4 3/8] x86/virt/tdx: Prepare to support reading other global metadata fields Date: Tue, 24 Sep 2024 23:28:30 +1200 Message-ID: <101f6f252db860ad7a7433596006da0d210dd5cb.1727173372.git.kai.huang@intel.com> X-Mailer: git-send-email 2.46.0 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. TDX supports 8/16/32/64 bits metadata field element sizes. For a given metadata field, the element size is encoded in the metadata field ID. For now the kernel only reads "TD Memory Region" (TDMR) related metadata fields and they are all 16-bit. Thus the kernel only has one primitive __read_sys_metadata_field16() to read 16-bit metadata field and the macro, read_sys_metadata_field16(), which does additional build-time check of the field ID makes sure the field is indeed 16-bit. Future changes will need to read more metadata fields with different element sizes. Choose to provide one primitive for each element size to support that. Similar to the build_mmio_read() macro, reimplement the body of __read_sys_metadata_field16() as a macro build_sysmd_read(_size) in size-agnostic way, so it can be used to generate one primitive for each element size: build_sysmd_read(8) build_sysmd_read(16) .. Also extend read_sys_metadata_field16() take the '_size' as argument (and rename it to read_sys_metadata_field() to make it size-agnostic) to allow the READ_SYS_INFO() macro to choose which primitive to use. Signed-off-by: Kai Huang --- v3 -> v4: - Change to use one primitive for each element size, similar to build_mmio_read() macro - Dan. - Rewrite changelog based on the new code. - "global metadata fields" -> "Global Metadata Fields" - Ardian. v2 -> v3: - Rename read_sys_metadata_field() to tdh_sys_rd() so the former can be used as the high level wrapper. Get rid of "stbuf_" prefix since people don't like it. - Rewrite after removing 'struct field_mapping' and reimplementing TD_SYSINFO_MAP(). --- arch/x86/virt/vmx/tdx/tdx.c | 40 ++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 2f7e4abc1bb9..b5c8dde9caf0 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -250,7 +250,7 @@ static int build_tdx_memlist(struct list_head *tmb_list) return ret; } -static int read_sys_metadata_field(u64 field_id, u64 *data) +static int tdh_sys_rd(u64 field_id, u64 *data) { struct tdx_module_args args = {}; int ret; @@ -270,25 +270,29 @@ static int read_sys_metadata_field(u64 field_id, u64 *data) return 0; } -static int __read_sys_metadata_field16(u64 field_id, u16 *val) -{ - u64 tmp; - int ret; - - ret = read_sys_metadata_field(field_id, &tmp); - if (ret) - return ret; - - *val = tmp; - - return 0; +#define build_sysmd_read(_size) \ +static int __read_sys_metadata_field##_size(u64 field_id, u##_size *val) \ +{ \ + u64 tmp; \ + int ret; \ + \ + ret = tdh_sys_rd(field_id, &tmp); \ + if (ret) \ + return ret; \ + \ + *val = tmp; \ + \ + return 0; \ } -#define read_sys_metadata_field16(_field_id, _val) \ +build_sysmd_read(16) + +#define read_sys_metadata_field(_field_id, _val, _size) \ ({ \ BUILD_BUG_ON(MD_FIELD_ID_ELE_SIZE_CODE(_field_id) != \ - MD_FIELD_ID_ELE_SIZE_16BIT); \ - __read_sys_metadata_field16(_field_id, _val); \ + MD_FIELD_ID_ELE_SIZE_##_size##BIT); \ + BUILD_BUG_ON(_size != sizeof(*_val) * 8); \ + __read_sys_metadata_field##_size(_field_id, _val); \ }) static int get_tdx_sys_info_tdmr(struct tdx_sys_info_tdmr *sysinfo_tdmr) @@ -296,8 +300,8 @@ static int get_tdx_sys_info_tdmr(struct tdx_sys_info_tdmr *sysinfo_tdmr) int ret = 0; #define READ_SYS_INFO(_field_id, _member) \ - ret = ret ?: read_sys_metadata_field16(MD_FIELD_ID_##_field_id, \ - &sysinfo_tdmr->_member) + ret = ret ?: read_sys_metadata_field(MD_FIELD_ID_##_field_id, \ + &sysinfo_tdmr->_member, 16) READ_SYS_INFO(MAX_TDMRS, max_tdmrs); READ_SYS_INFO(MAX_RESERVED_PER_TDMR, max_reserved_per_tdmr); From patchwork Tue Sep 24 11:28:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Huang, Kai" X-Patchwork-Id: 13810831 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.8]) (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 B1C241A76AB; Tue, 24 Sep 2024 11:29:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.8 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727177365; cv=none; b=BxjBjEsQ4Xt2xojuuxDVe6yr3P2m5M9CSzga0HJcNHndfaSli66AEb8OsqhwH+GdL+5CpUUAIw7A6nhI8TKkzGuVHIutaCgTtw9N9Uw5rLbCPpimMtUjTHRnmlvBM1Lgueyr/tofB8fFhG08Vkr/zxLDEd5W/N+3Nd/MB0+nzqg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727177365; c=relaxed/simple; bh=GIjj/fxfNYlKIQZ5lN1ifW+maPZJeHuzboN+LWDwryA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mCFjpTp4tesvKOjDTuk/qrSSisSzPPMnxAafA7ZSbo//hqcn+hQvWeEAuBMiWKOWxjhkHMkk82UNgPmFQDrnTXhpSbZjDgebQWDEaNpwR7JSFyyCF74YRseKa8aQUU5r4Prao7vrvA4lfMaZANY8i+u/wZY6NfEerLKte9INxno= 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=jbKBdh8P; arc=none smtp.client-ip=192.198.163.8 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="jbKBdh8P" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1727177364; x=1758713364; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=GIjj/fxfNYlKIQZ5lN1ifW+maPZJeHuzboN+LWDwryA=; b=jbKBdh8PYPKgwYsAqpqsFjCqPu9Aovs4elzL3FXW9ljevKOc7XC+l+YV FGmn+2giz87xB0exYzs1i10WOhEEt4eYoGqvo1laTH0h9bjD9h4zRX31g SQ6j5sIJijqk3NIYPdexzXzob7FAn5z4U0s27HxXDLoZpA4Rj8KWNU7aw D/ktzTG8meYpFCZLUfFXRn18jeKABR5ESzvZtqx+DFFl3nUK8wHlDPxWn Fiq3fqSv/gD0dL2J9uZ9QdCu03vD7QIUY5S4PH094RWZ9S/RnxRq+qztU LWvBtemEs9jggnznLyf4np4Bup0sn3ausv0MB69LK6emNwpfA6S3oHq+t A==; X-CSE-ConnectionGUID: bMku6jNuRbC0RZkQuYVumg== X-CSE-MsgGUID: z9WdFSzfSQml+/0ITjEbOQ== X-IronPort-AV: E=McAfee;i="6700,10204,11204"; a="43686514" X-IronPort-AV: E=Sophos;i="6.10,254,1719903600"; d="scan'208";a="43686514" Received: from fmviesa007.fm.intel.com ([10.60.135.147]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Sep 2024 04:29:24 -0700 X-CSE-ConnectionGUID: xJi3CIogSFyz3CaVaccJTw== X-CSE-MsgGUID: BRQWsiMgRFigNM83iHQUoA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.10,254,1719903600"; d="scan'208";a="70994615" Received: from ccbilbre-mobl3.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.221.10]) by fmviesa007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Sep 2024 04:29:20 -0700 From: Kai Huang To: dave.hansen@intel.com, kirill.shutemov@linux.intel.com, tglx@linutronix.de, bp@alien8.de, peterz@infradead.org, mingo@redhat.com, hpa@zytor.com, dan.j.williams@intel.com, seanjc@google.com, pbonzini@redhat.com Cc: x86@kernel.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, rick.p.edgecombe@intel.com, isaku.yamahata@intel.com, adrian.hunter@intel.com, nik.borisov@suse.com, kai.huang@intel.com Subject: [PATCH v4 4/8] x86/virt/tdx: Refine a comment to reflect the latest TDX spec Date: Tue, 24 Sep 2024 23:28:31 +1200 Message-ID: <3b9e111c2cc6ba9413f3e462448bea94947f7f01.1727173372.git.kai.huang@intel.com> X-Mailer: git-send-email 2.46.0 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 Reported-by: Nikolay Borisov Signed-off-by: Kai Huang Reviewed-by: Adrian Hunter Reviewed-by: Nikolay Borisov --- 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 148f9b4d1140..38f8656162e3 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 Tue Sep 24 11:28:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Huang, Kai" X-Patchwork-Id: 13810832 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.8]) (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 535011A76D7; Tue, 24 Sep 2024 11:29:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.8 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727177369; cv=none; b=Z0JdQ2u7/VGcCHn18aNgD0rnQ7qJAXzsqq1n5+DIPNRnoXH2Qv7cVH9MGi3M4iuUpC1agUm5zZXDXsPadA+UXfFyWqDdc0NMHDaz7LfKq/CVsOsV6/rRC+bRqImAaEle6kpWpqPmYIk6pi8LIZuISmbfR+JZCE2wuAk+Hquld9E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727177369; c=relaxed/simple; bh=bw8RH/jcX7Oy7QdzgBkOwWJ9nmgPhba0d9GXlQRAuUQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MaEXmd6G9jjRhMFv+P+slsn2P4rO9WUMDcvmggfev2TUKlKzswOaKzUHFOlsM7x8FA31PG2MREvjqFsc6ljXQ7vubl7j7hfMyy0EZlelnFsdQLEeKXuaj72y+ou7LN+LVMlZQe/IIiVyBhWI2o4Tsp7QJNrnQ9nEoU40wVIu+Bo= 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=ho/Qme1t; arc=none smtp.client-ip=192.198.163.8 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="ho/Qme1t" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1727177367; x=1758713367; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=bw8RH/jcX7Oy7QdzgBkOwWJ9nmgPhba0d9GXlQRAuUQ=; b=ho/Qme1thOiYoEbhZSjy5W7F7s6SmGMOefQrMNzhfYEbBbNAZ9DxMUeO XgZekUmlH2NfQzdfLlwmh6Mn0EoK0jYqMCgJ6fAGGfPEVEYwn8cLVl0Y4 MhLZ6B+NGSFOT9nOPKKJrkSCmcDaGz8l1HNPSY+RKE3r6Z1Zas254oOjf JcjOOIEYzaxFWjARgrfl30PGXhmS/XzuylrCjXYgoqRAVmqMq78idiWhP sCr+rfsoSipzOnHHHbtLhSUH42eJaPneV60PXdk1JSKk8DDjATnRy0lJu Jq3MmM2n2iuomMRM2Xi8JJmJHB1RS/au2iMRobCqBShSUSj9AvbOEk8rq A==; X-CSE-ConnectionGUID: F/oMBoilRJeJ1QidwBj51w== X-CSE-MsgGUID: piwq7daZS2+riReL9LVZeQ== X-IronPort-AV: E=McAfee;i="6700,10204,11204"; a="43686531" X-IronPort-AV: E=Sophos;i="6.10,254,1719903600"; d="scan'208";a="43686531" Received: from fmviesa007.fm.intel.com ([10.60.135.147]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Sep 2024 04:29:27 -0700 X-CSE-ConnectionGUID: CgHra5/wSOGJRFYmDCn7DA== X-CSE-MsgGUID: XK+Hi6ylRNqgPp1aZahHtQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.10,254,1719903600"; d="scan'208";a="70994629" Received: from ccbilbre-mobl3.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.221.10]) by fmviesa007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Sep 2024 04:29:24 -0700 From: Kai Huang To: dave.hansen@intel.com, kirill.shutemov@linux.intel.com, tglx@linutronix.de, bp@alien8.de, peterz@infradead.org, mingo@redhat.com, hpa@zytor.com, dan.j.williams@intel.com, seanjc@google.com, pbonzini@redhat.com Cc: x86@kernel.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, rick.p.edgecombe@intel.com, isaku.yamahata@intel.com, adrian.hunter@intel.com, nik.borisov@suse.com, kai.huang@intel.com Subject: [PATCH v4 5/8] x86/virt/tdx: Start to track all global metadata in one structure Date: Tue, 24 Sep 2024 23:28:32 +1200 Message-ID: <014302e0bd2f0797aa7d27ed8b730603d2859c2d.1727173372.git.kai.huang@intel.com> X-Mailer: git-send-email 2.46.0 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_sys_info' to track all global metadata fields. TDX categories global metadata fields into different "Classes". E.g., the TDMR related fields are under class "TDMR Info". Instead of making 'struct tdx_sys_info' 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 construct_tdmr() can just take the structure which contains "TDMR Info" metadata fields. Add a new function get_tdx_sys_info() as the placeholder to read all metadata fields, and call it at the beginning of init_tdx_module(). For now it only calls get_tdx_sys_info_tdmr() to read TDMR related fields. Note there is a functional change: get_tdx_sys_info_tdmr() is moved from after build_tdx_memlist() to before it, but it is fine to do so. Signed-off-by: Kai Huang Reviewed-by: Adrian Hunter --- v3 -> v4: - "global metadata fields" -> "Global Metadata Fields" - Ardian. - "Class"es -> "Classes" - Ardian. - Add tag from Ardian. v2 -> v3: - Split out the part to rename 'struct tdx_tdmr_sysinfo' to 'struct tdx_sys_info_tdmr'. --- arch/x86/virt/vmx/tdx/tdx.c | 19 ++++++++++++------- arch/x86/virt/vmx/tdx/tdx.h | 36 +++++++++++++++++++++++++++++------- 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index b5c8dde9caf0..44ef74d1fafb 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -314,6 +314,11 @@ static int get_tdx_sys_info_tdmr(struct tdx_sys_info_tdmr *sysinfo_tdmr) return ret; } +static int get_tdx_sys_info(struct tdx_sys_info *sysinfo) +{ + return get_tdx_sys_info_tdmr(&sysinfo->tdmr); +} + /* Calculate the actual TDMR size */ static int tdmr_size_single(u16 max_reserved_per_tdmr) { @@ -1086,9 +1091,13 @@ static int init_tdmrs(struct tdmr_info_list *tdmr_list) static int init_tdx_module(void) { - struct tdx_sys_info_tdmr sysinfo_tdmr; + struct tdx_sys_info sysinfo; int ret; + ret = get_tdx_sys_info(&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 @@ -1105,17 +1114,13 @@ static int init_tdx_module(void) if (ret) goto out_put_tdxmem; - ret = get_tdx_sys_info_tdmr(&sysinfo_tdmr); - if (ret) - goto err_free_tdxmem; - /* Allocate enough space for constructing TDMRs */ - ret = alloc_tdmr_list(&tdx_tdmr_list, &sysinfo_tdmr); + ret = alloc_tdmr_list(&tdx_tdmr_list, &sysinfo.tdmr); if (ret) goto err_free_tdxmem; /* Cover all TDX-usable memory regions in TDMRs */ - ret = construct_tdmrs(&tdx_memlist, &tdx_tdmr_list, &sysinfo_tdmr); + ret = construct_tdmrs(&tdx_memlist, &tdx_tdmr_list, &sysinfo.tdmr); 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 38f8656162e3..b9a89da39e1e 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -80,6 +80,35 @@ struct tdmr_info { DECLARE_FLEX_ARRAY(struct tdmr_reserved_area, reserved_areas); } __packed __aligned(TDMR_INFO_ALIGNMENT); +/* + * Data structures for "Global Scope Metadata". + * + * TDX global metadata fields are categorized by "Classes". See the + * "global_metadata.json" in the "TDX 1.5 ABI Definitions". + * + * 'struct tdx_sys_info' 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 the structure name may not exactly follow the name of the + * "Class" in the TDX spec, but the comment of that structure always + * reflect that. + * + * Also note not all metadata fields in each class are defined, only + * those used by the kernel are. + */ + +/* Class "TDMR info" */ +struct tdx_sys_info_tdmr { + u16 max_tdmrs; + u16 max_reserved_per_tdmr; + u16 pamt_entry_size[TDX_PS_NR]; +}; + +struct tdx_sys_info { + struct tdx_sys_info_tdmr tdmr; +}; + /* * Do not put any hardware-defined TDX structure representations below * this comment! @@ -99,13 +128,6 @@ struct tdx_memblock { int nid; }; -/* "TDMR info" part of "Global Scope Metadata" for constructing TDMRs */ -struct tdx_sys_info_tdmr { - 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 From patchwork Tue Sep 24 11:28:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Huang, Kai" X-Patchwork-Id: 13810833 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.8]) (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 BD4D51A7AEC; Tue, 24 Sep 2024 11:29:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.8 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727177372; cv=none; b=TqiAqc+buSzCCSWm2uOos/y6kw9R//sUsPQMYyJVqAchejVJr0G8vSAztgMSQ3JtuPE5QK/5MB+ufbdc3MPb4K19DuVmx2aljnc7/OJ2HJSHXEryqjeVbo1CA4t64JRpLPJmL9FMK6STxx0PPxYuPfJ7rX4z79wP3E8uE+AiSGo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727177372; c=relaxed/simple; bh=4GVkD78Ie9ZCNqSljs6LuDQbODZP2xkjWndNf2q63os=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jjvGtERoHVVJMKt8IyPTxNBGGuNMZwnWQMkd/n1W9Kq51JAK6IaCL61AzyXzHBl2CSqAGu9iU4uT9x+gq3z1KslTJEH8ETD3GLPLH2vJWNWLaNs0Dqp69scl3hgv1O60b5S4E8ETZl7g73h9G8sAFlhAmpVgOlFWd79nWctbI+U= 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=OHatFZSv; arc=none smtp.client-ip=192.198.163.8 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="OHatFZSv" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1727177371; x=1758713371; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=4GVkD78Ie9ZCNqSljs6LuDQbODZP2xkjWndNf2q63os=; b=OHatFZSvoqL8LLlgMB2nrayBko9MZXbh6+5gW5uoY1EHBs44CAg7TRVv K6WsbcrZCHVbcZEbTAO7kSzqu1lIQJtUggbY6Tm51SbDJHcu7PGp279bs u90GY8M8aFkni/+kT9kdUNZ5ltOfMTxuOg8frJCToEr0x72FN7GLRSkK+ yitNqMkTRmKhwYB/u79NbOgQa0aw54X4hikThKNrPXO0T6BIy0O2moXXl +mOBfxlgsSrFjRDi+f4hl0D1B+84C76umpj9isA64idM8fFFe79fmGFw9 irgK8Au0Q3GxLOOKDMTJlRSLEV4WNyMhK8CW3c6+SjoEc4PvWvXAf4bv0 w==; X-CSE-ConnectionGUID: PKxkR8GnT9C0Q5etet7q4Q== X-CSE-MsgGUID: GeTmGPGvRcuQTvB56U51mQ== X-IronPort-AV: E=McAfee;i="6700,10204,11204"; a="43686547" X-IronPort-AV: E=Sophos;i="6.10,254,1719903600"; d="scan'208";a="43686547" Received: from fmviesa007.fm.intel.com ([10.60.135.147]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Sep 2024 04:29:31 -0700 X-CSE-ConnectionGUID: QfnM4YNGSTyl/gjfiEvaIg== X-CSE-MsgGUID: SbyT1zdSRmy3cqvE/7wIRg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.10,254,1719903600"; d="scan'208";a="70994647" Received: from ccbilbre-mobl3.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.221.10]) by fmviesa007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Sep 2024 04:29:27 -0700 From: Kai Huang To: dave.hansen@intel.com, kirill.shutemov@linux.intel.com, tglx@linutronix.de, bp@alien8.de, peterz@infradead.org, mingo@redhat.com, hpa@zytor.com, dan.j.williams@intel.com, seanjc@google.com, pbonzini@redhat.com Cc: x86@kernel.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, rick.p.edgecombe@intel.com, isaku.yamahata@intel.com, adrian.hunter@intel.com, nik.borisov@suse.com, kai.huang@intel.com Subject: [PATCH v4 6/8] x86/virt/tdx: Print TDX module version Date: Tue, 24 Sep 2024 23:28:33 +1200 Message-ID: <79c256b8978310803bb4de48cd81dd373330cbc2.1727173372.git.kai.huang@intel.com> X-Mailer: git-send-email 2.46.0 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 TDX module version information. In practice such information is useful, especially to the developers. For instance: 1) When something goes wrong around using TDX, the module version is normally the first information the users want to know [1]. 2) After initializing TDX module, the users want to quickly know module version to see whether the loaded module is the expected one. Dump TDX module version. The actual dmesg will look like: virt/tdx: Initializing TDX module: 1.5.00.00.0481 (build_date 20230323). And dump right after reading global metadata, so that this information is printed no matter whether module initialization fails or not. Link: https://lore.kernel.org/lkml/4b3adb59-50ea-419e-ad02-e19e8ca20dee@intel.com/ [1] Signed-off-by: Kai Huang --- v3 -> v4: - Omit dumping TDX_FEATURES0 - Dan. - As a result, move TDX_FEATURES0 related code out to NO_MOD_RBP patch. - Update changelog accordingly. - Simplify changelog for the use case 2). - Use permalink - Dan. v2 -> v3: - 'struct tdx_sysinfo_module_info' -> 'struct tdx_sys_info_features' - 'struct tdx_sysinfo_module_version' -> 'struct tdx_sys_info_version' - Remove the 'sys_attributes' and the check of debug/production module. https://lore.kernel.org/kvm/cover.1721186590.git.kai.huang@intel.com/T/#md73dd9b02a492acf4a6facae63e8d030e320967d --- arch/x86/virt/vmx/tdx/tdx.c | 51 +++++++++++++++++++++++++++++++++++++ arch/x86/virt/vmx/tdx/tdx.h | 20 ++++++++++++++- 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 44ef74d1fafb..d599aaaa2730 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -286,6 +286,7 @@ static int __read_sys_metadata_field##_size(u64 field_id, u##_size *val) \ } build_sysmd_read(16) +build_sysmd_read(32) #define read_sys_metadata_field(_field_id, _val, _size) \ ({ \ @@ -295,6 +296,26 @@ build_sysmd_read(16) __read_sys_metadata_field##_size(_field_id, _val); \ }) +static int get_tdx_sys_info_version(struct tdx_sys_info_version *sysinfo_version) +{ + int ret = 0; + +#define READ_SYS_INFO(_field_id, _member, _size) \ + ret = ret ?: read_sys_metadata_field(MD_FIELD_ID_##_field_id, \ + &sysinfo_version->_member, _size) + + READ_SYS_INFO(MAJOR_VERSION, major, 16); + READ_SYS_INFO(MINOR_VERSION, minor, 16); + READ_SYS_INFO(UPDATE_VERSION, update, 16); + READ_SYS_INFO(INTERNAL_VERSION, internal, 16); + READ_SYS_INFO(BUILD_NUM, build_num, 16); + READ_SYS_INFO(BUILD_DATE, build_date, 32); + +#undef READ_SYS_INFO + + return ret; +} + static int get_tdx_sys_info_tdmr(struct tdx_sys_info_tdmr *sysinfo_tdmr) { int ret = 0; @@ -316,9 +337,37 @@ static int get_tdx_sys_info_tdmr(struct tdx_sys_info_tdmr *sysinfo_tdmr) static int get_tdx_sys_info(struct tdx_sys_info *sysinfo) { + int ret; + + ret = get_tdx_sys_info_version(&sysinfo->version); + if (ret) + return ret; + return get_tdx_sys_info_tdmr(&sysinfo->tdmr); } +static void print_sys_info_version(struct tdx_sys_info_version *version) +{ + /* + * 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).\n", + version->major, version->minor, version->update, + version->internal, version->build_num, + version->build_date); +} + +static void print_basic_sys_info(struct tdx_sys_info *sysinfo) +{ + print_sys_info_version(&sysinfo->version); +} + /* Calculate the actual TDMR size */ static int tdmr_size_single(u16 max_reserved_per_tdmr) { @@ -1098,6 +1147,8 @@ static int init_tdx_module(void) if (ret) return ret; + print_basic_sys_info(&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 b9a89da39e1e..a8d0ab3e5acd 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -31,6 +31,12 @@ * * See the "global_metadata.json" in the "TDX 1.5 ABI definitions". */ +#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 @@ -54,6 +60,7 @@ (((_field_id) & GENMASK_ULL(33, 32)) >> 32) #define MD_FIELD_ID_ELE_SIZE_16BIT 1 +#define MD_FIELD_ID_ELE_SIZE_32BIT 2 struct tdmr_reserved_area { u64 offset; @@ -98,6 +105,16 @@ struct tdmr_info { * those used by the kernel are. */ +/* Class "TDX Module Version" */ +struct tdx_sys_info_version { + u16 major; + u16 minor; + u16 update; + u16 internal; + u16 build_num; + u32 build_date; +}; + /* Class "TDMR info" */ struct tdx_sys_info_tdmr { u16 max_tdmrs; @@ -106,7 +123,8 @@ struct tdx_sys_info_tdmr { }; struct tdx_sys_info { - struct tdx_sys_info_tdmr tdmr; + struct tdx_sys_info_version version; + struct tdx_sys_info_tdmr tdmr; }; /* From patchwork Tue Sep 24 11:28:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Huang, Kai" X-Patchwork-Id: 13810834 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.8]) (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 592AC1AAE1A; Tue, 24 Sep 2024 11:29:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.8 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727177376; cv=none; b=LLDfUV1S7NvSsQU4iQ8NR0RC1wc5sLYIF6trJrcusXmoi1lLxuxUjzmedt1AYF6edKkIvyq/BtUd7IEpLcgG0mnaiwYa1/6kdxJUm09eDue3ZF23bRTYSvRQ+853qFqGL8g23477zIRcGdM3iIEtk9qkAV9tlGHckEJg4cilNtg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727177376; c=relaxed/simple; bh=miacDnO3dASnNLUlekjw9N6dNiCFGROLIjOydUPXs1A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ThWrre1sXRmdaFvobxLI29fYgVwyEm97uWKC29oULqVA/eKR3h0VgS5xdfEKwvdAtbViqThAMLaV2Md9fFu/CnV61p6KRQg5pNCm40KlYGC3ulr8UabH0XgUbk/TS0RH4Iaj9uEDaqGoD4VubSiFX5nDCSuPlMeiMQpMXjsOpvE= 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=BpoSq3v6; arc=none smtp.client-ip=192.198.163.8 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="BpoSq3v6" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1727177374; x=1758713374; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=miacDnO3dASnNLUlekjw9N6dNiCFGROLIjOydUPXs1A=; b=BpoSq3v6nEFEPAIqVbeTWjzluUdR4/kS1gELpPu2b4jbY3r0vJ34UYT0 K0TQmP3BvXjg1nnWH6PxC0Pilr5jx4LzT9IB/JEPUBe457Ql2VB5Zw2O0 XPTjphB8Ycp2yR3r6+4flSaOdxjzfmvlpySej19/vKSinDbZq5x3x4pQc 0djIR415XQyHUzVz37GT0o9/fNRWE7zImZTDdf9wXXWpUnc/q3zW/DYmR oAMC5UVE6qWVBtcdTZO4k66QGdbO2X5yXtru40Nb199A04Rwg67gmEc3H OlMHciLAbA17RAwNGluClLbA2T6NpuscmTxpMnVmJKQElHtUi4tkQN61f A==; X-CSE-ConnectionGUID: Y6uxfwi5RlajKUo5Ila6AA== X-CSE-MsgGUID: g/xCK50fQW6fkyEIKerICw== X-IronPort-AV: E=McAfee;i="6700,10204,11204"; a="43686569" X-IronPort-AV: E=Sophos;i="6.10,254,1719903600"; d="scan'208";a="43686569" Received: from fmviesa007.fm.intel.com ([10.60.135.147]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Sep 2024 04:29:34 -0700 X-CSE-ConnectionGUID: GP5L4izHSf+gm6NFUzQvIw== X-CSE-MsgGUID: ap6P5OIdRs6ZbdyTG2aNrg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.10,254,1719903600"; d="scan'208";a="70994669" Received: from ccbilbre-mobl3.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.221.10]) by fmviesa007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Sep 2024 04:29:31 -0700 From: Kai Huang To: dave.hansen@intel.com, kirill.shutemov@linux.intel.com, tglx@linutronix.de, bp@alien8.de, peterz@infradead.org, mingo@redhat.com, hpa@zytor.com, dan.j.williams@intel.com, seanjc@google.com, pbonzini@redhat.com Cc: x86@kernel.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, rick.p.edgecombe@intel.com, isaku.yamahata@intel.com, adrian.hunter@intel.com, nik.borisov@suse.com, kai.huang@intel.com Subject: [PATCH v4 7/8] x86/virt/tdx: Require the module to assert it has the NO_RBP_MOD mitigation Date: Tue, 24 Sep 2024 23:28:34 +1200 Message-ID: X-Mailer: git-send-email 2.46.0 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/fc0e8ab7-86d4-4428-be31-82e1ece6dd21@intel.com/ [1] Signed-off-by: Kai Huang Reviewed-by: Nikolay Borisov Reviewed-by: Adrian Hunter Reviewed-by: Dan Williams --- v3 -> v4: - Move reading TDX_FEATURES0 code to this patch. - Change patch title and use permalink - Dan. Hi Dan, Ardian, Nikolay, The code to read TDX_FEATURES0 was not included in this patch when you gave your tag. I didn't remove them. Please let me know if you want me to remove your tag. Thanks! v2 -> v3: - check_module_compatibility() -> check_features(). - Improve error message. https://lore.kernel.org/kvm/cover.1721186590.git.kai.huang@intel.com/T/#md9e2eeef927838cbf20d7b361cdbea518b8aec50 --- arch/x86/virt/vmx/tdx/tdx.c | 37 +++++++++++++++++++++++++++++++++++++ arch/x86/virt/vmx/tdx/tdx.h | 17 +++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index d599aaaa2730..cd8cca5139ac 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -287,6 +287,7 @@ static int __read_sys_metadata_field##_size(u64 field_id, u##_size *val) \ build_sysmd_read(16) build_sysmd_read(32) +build_sysmd_read(64) #define read_sys_metadata_field(_field_id, _val, _size) \ ({ \ @@ -296,6 +297,21 @@ build_sysmd_read(32) __read_sys_metadata_field##_size(_field_id, _val); \ }) +static int get_tdx_sys_info_features(struct tdx_sys_info_features *sysinfo_features) +{ + int ret = 0; + +#define READ_SYS_INFO(_field_id, _member) \ + ret = ret ?: read_sys_metadata_field(MD_FIELD_ID_##_field_id, \ + &sysinfo_features->_member, 64) + + READ_SYS_INFO(TDX_FEATURES0, tdx_features0); + +#undef READ_SYS_INFO + + return ret; +} + static int get_tdx_sys_info_version(struct tdx_sys_info_version *sysinfo_version) { int ret = 0; @@ -339,6 +355,10 @@ static int get_tdx_sys_info(struct tdx_sys_info *sysinfo) { int ret; + ret = get_tdx_sys_info_features(&sysinfo->features); + if (ret) + return ret; + ret = get_tdx_sys_info_version(&sysinfo->version); if (ret) return ret; @@ -368,6 +388,18 @@ static void print_basic_sys_info(struct tdx_sys_info *sysinfo) print_sys_info_version(&sysinfo->version); } +static int check_features(struct tdx_sys_info *sysinfo) +{ + u64 tdx_features0 = sysinfo->features.tdx_features0; + + if (!(tdx_features0 & TDX_FEATURES0_NO_RBP_MOD)) { + pr_err("frame pointer (RBP) clobber bug present, upgrade TDX module\n"); + return -EINVAL; + } + + return 0; +} + /* Calculate the actual TDMR size */ static int tdmr_size_single(u16 max_reserved_per_tdmr) { @@ -1149,6 +1181,11 @@ static int init_tdx_module(void) print_basic_sys_info(&sysinfo); + /* Check whether the kernel can support this module */ + ret = check_features(&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 a8d0ab3e5acd..9314f6ecbcb5 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -31,6 +31,7 @@ * * See the "global_metadata.json" in the "TDX 1.5 ABI definitions". */ +#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 @@ -61,6 +62,7 @@ #define MD_FIELD_ID_ELE_SIZE_16BIT 1 #define MD_FIELD_ID_ELE_SIZE_32BIT 2 +#define MD_FIELD_ID_ELE_SIZE_64BIT 3 struct tdmr_reserved_area { u64 offset; @@ -105,6 +107,20 @@ struct tdmr_info { * those used by the kernel are. */ +/* + * Class "TDX Module Info". + * + * This class also contains other fields like SYS_ATTRIBUTES and the + * NUM_TDX_FEATURES. For now only TDX_FEATURES0 is needed, but still + * keep the structure to follow the spec (and for future extension). + */ +struct tdx_sys_info_features { + u64 tdx_features0; +}; + +/* Bit definitions of TDX_FEATURES0 metadata field */ +#define TDX_FEATURES0_NO_RBP_MOD _BITULL(18) + /* Class "TDX Module Version" */ struct tdx_sys_info_version { u16 major; @@ -123,6 +139,7 @@ struct tdx_sys_info_tdmr { }; struct tdx_sys_info { + struct tdx_sys_info_features features; struct tdx_sys_info_version version; struct tdx_sys_info_tdmr tdmr; }; From patchwork Tue Sep 24 11:28:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Huang, Kai" X-Patchwork-Id: 13810835 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.8]) (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 2AC9B1AAE3D; Tue, 24 Sep 2024 11:29:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.8 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727177380; cv=none; b=dAISCB+W227kxw6qLQAisI4JS3I5S85EMYcc8WZFezfcXMCMHEBwthxlP1xfJJQqBFl1hWsr4H86QunWzyJ0hXNmQkd46PScyj1cS3vB+x7WzXxRFIeAUBB8CkKOfa1YQKsHBVXYVz8qsKZeAz6IChILXXjSFPvPe0p42zpVBGE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727177380; c=relaxed/simple; bh=b2Zpu6bNVNvwiXpYcKr+Aro9HlSAW2yxucUmtiP7yD8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dci5oYPAvqMZPvLRoLngzE5Lgx4jg8pPOSeiNQVW1flpI5wUVH7m/m2cwe/7AMC9Wovf4UIEptAmcwHE7K5yJn8ypBajq/wYFDFdPOTY7oRDGSX0vgfisNGfdJNjVlAFTA3MURhRW1E9c0hpngNjQkO086l0fQLllLfnDr8MLPc= 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=hiaSN855; arc=none smtp.client-ip=192.198.163.8 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="hiaSN855" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1727177378; x=1758713378; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=b2Zpu6bNVNvwiXpYcKr+Aro9HlSAW2yxucUmtiP7yD8=; b=hiaSN855IA+of+5sGP49URBzwMXk0dzG9LL6oB9xVpc2+TsK592PKe75 Y0rCA6da2bEEcxe1Zf59h4fsDRaGcGlKOCbn/Bbfqz3ZnqyAXkfvZhlOP YqiMLM/R5K5mgngCFhsgyS60uX7bd6CGUodA/1fxTs8FiPwVemBIwR4hW o+S0QM2tJnDy1QKffgQkItHLZ3PevPxNwk6aWOcaUj3rt7gnw8rBtseFo gzLJAhJeVkW7LkiW++YayXNHHXfwOZfTC81/gtRRSCyGubSKuykcSNZdF NQlNiPkog5hCfQCvlODNhMX7bMkPNxVVX17Mj+c8LsRpRY7U8RNfSwCaF Q==; X-CSE-ConnectionGUID: QYw4k441QhGB6eN0kM7Q5w== X-CSE-MsgGUID: 8ZX2Th8SQ8Sxsxk+eNBFqQ== X-IronPort-AV: E=McAfee;i="6700,10204,11204"; a="43686597" X-IronPort-AV: E=Sophos;i="6.10,254,1719903600"; d="scan'208";a="43686597" Received: from fmviesa007.fm.intel.com ([10.60.135.147]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Sep 2024 04:29:38 -0700 X-CSE-ConnectionGUID: obuwKZQYQCyMlZnl98vG/w== X-CSE-MsgGUID: 0Wbw5c+HS+uRb+9buEmUOQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.10,254,1719903600"; d="scan'208";a="70994703" Received: from ccbilbre-mobl3.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.221.10]) by fmviesa007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Sep 2024 04:29:34 -0700 From: Kai Huang To: dave.hansen@intel.com, kirill.shutemov@linux.intel.com, tglx@linutronix.de, bp@alien8.de, peterz@infradead.org, mingo@redhat.com, hpa@zytor.com, dan.j.williams@intel.com, seanjc@google.com, pbonzini@redhat.com Cc: x86@kernel.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, rick.p.edgecombe@intel.com, isaku.yamahata@intel.com, adrian.hunter@intel.com, nik.borisov@suse.com, kai.huang@intel.com Subject: [PATCH v4 8/8] x86/virt/tdx: Reduce TDMR's reserved areas by using CMRs to find memory holes Date: Tue, 24 Sep 2024 23:28:35 +1200 Message-ID: <708d6c9d4d3ed9d47f62760f6d8bd88a3f16dd78.1727173372.git.kai.huang@intel.com> X-Mailer: git-send-email 2.46.0 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 are marked as "reserved areas". The TDX module reports a maximum number of reserved areas that can be supported per TDMR (16). The kernel builds the "TDX-usable memory regions" based on memblocks (which reflects e820), and uses this list to find all "reserved areas" for each TDMR. It turns out that the kernel's view of memory holes is too fine grained and sometimes exceeds the number of holes that the TDX module can track per TDMR [1], resulting in the above failure. Thankfully the module also lists memory that is potentially convertible in a list of "Convertible Memory Regions" (CMRs). That coarser grained CMR list tends to track usable memory in the memory map even if it might be reserved for host usage like 'ACPI data' [2]. Use that list to relax what the kernel considers unusable memory. If it falls in a CMR no need to instantiate a hole, and rely on the fact that kernel will keep what it considers 'reserved' out of the page allocator. 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) Fixes: dde3b60d572c ("x86/virt/tdx: Designate reserved areas for all TDMRs") Signed-off-by: Kai Huang --- v3 -> v4: - Trim down changelog - Dan. - "must be marked as reserved areas" -> "are marked as reserved areas" - Ardian. - Remove all WARN_ON_ONCE() for CMR sanity checks, and clarify in the comment that CMRs are verified by MCHECK before it enables TDX so we can trust hardware. - Change CMR_BASE(i) macro back to just define CMR_BASE and do the "+i" in the code. v2 -> v3: - Add the Fixes tag, although this patch depends on previous patches. - CMR_BASE0 -> CMR_BASE(_i), CMR_SIZE0 -> CMR_SIZE(_i) to silence the build-check error. 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 | 103 ++++++++++++++++++++++++++++++------ arch/x86/virt/vmx/tdx/tdx.h | 12 +++++ 2 files changed, 99 insertions(+), 16 deletions(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index cd8cca5139ac..aac13c3c10f5 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -332,6 +332,58 @@ static int get_tdx_sys_info_version(struct tdx_sys_info_version *sysinfo_version return ret; } +/* Update the @sysinfo_cmr->num_cmrs to trim tail empty CMRs */ +static void trim_empty_tail_cmrs(struct tdx_sys_info_cmr *sysinfo_cmr) +{ + int i; + + /* + * The TDX module may 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. + * + * Note MCHECK verifies CMRs before enabling TDX on hardware. + * Skip other sanity checks (e.g., verify CMR is 4KB aligned) + * but trust MCHECK to work properly. CMRs are printed later + * anyway, and the worst case is module fails to initialize. + */ + for (i = 0; i < sysinfo_cmr->num_cmrs; i++) + if (!sysinfo_cmr->cmr_size[i]) + break; + + sysinfo_cmr->num_cmrs = i; +} + +static int get_tdx_sys_info_cmr(struct tdx_sys_info_cmr *sysinfo_cmr) +{ + int ret = 0; + u16 i; + +#define READ_SYS_INFO(_field_id, _member, _size) \ + ret = ret ?: read_sys_metadata_field(MD_FIELD_ID_##_field_id, \ + &sysinfo_cmr->_member, _size) + + READ_SYS_INFO(NUM_CMRS, num_cmrs, 16); + + if (ret) + return ret; + + for (i = 0; i < sysinfo_cmr->num_cmrs; i++) { + READ_SYS_INFO(CMR_BASE + i, cmr_base[i], 64); + READ_SYS_INFO(CMR_SIZE + i, cmr_size[i], 64); + } + + if (ret) + return ret; + + trim_empty_tail_cmrs(sysinfo_cmr); + +#undef READ_SYS_INFO + + return 0; +} + static int get_tdx_sys_info_tdmr(struct tdx_sys_info_tdmr *sysinfo_tdmr) { int ret = 0; @@ -363,6 +415,10 @@ static int get_tdx_sys_info(struct tdx_sys_info *sysinfo) if (ret) return ret; + ret = get_tdx_sys_info_cmr(&sysinfo->cmr); + if (ret) + return ret; + return get_tdx_sys_info_tdmr(&sysinfo->tdmr); } @@ -383,9 +439,23 @@ static void print_sys_info_version(struct tdx_sys_info_version *version) version->build_date); } +static void print_sys_info_cmr(struct tdx_sys_info_cmr *sysinfo_cmr) +{ + int i; + + for (i = 0; i < sysinfo_cmr->num_cmrs; i++) { + u64 cmr_base = sysinfo_cmr->cmr_base[i]; + u64 cmr_size = sysinfo_cmr->cmr_size[i]; + + pr_info("CMR[%d]: [0x%llx, 0x%llx)\n", i, cmr_base, + cmr_base + cmr_size); + } +} + static void print_basic_sys_info(struct tdx_sys_info *sysinfo) { print_sys_info_version(&sysinfo->version); + print_sys_info_cmr(&sysinfo->cmr); } static int check_features(struct tdx_sys_info *sysinfo) @@ -821,29 +891,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 @sysinfo_cmr 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_sys_info_cmr *sysinfo_cmr, 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 < sysinfo_cmr->num_cmrs; i++) { u64 start, end; - start = PFN_PHYS(tmb->start_pfn); - end = PFN_PHYS(tmb->end_pfn); + start = sysinfo_cmr->cmr_base[i]; + end = start + sysinfo_cmr->cmr_size[i]; /* Break if this region is after the TDMR */ if (start >= tdmr_end(tdmr)) @@ -944,16 +1013,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 @sysinfo_cmr) and PAMTs (via @tdmr_list). */ static int tdmr_populate_rsvd_areas(struct tdmr_info *tdmr, - struct list_head *tmb_list, + struct tdx_sys_info_cmr *sysinfo_cmr, 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(sysinfo_cmr, tdmr, &rsvd_idx, max_reserved_per_tdmr); if (ret) return ret; @@ -972,10 +1041,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 @sysinfo_cmr) and PAMTs. */ static int tdmrs_populate_rsvd_areas_all(struct tdmr_info_list *tdmr_list, - struct list_head *tmb_list, + struct tdx_sys_info_cmr *sysinfo_cmr, u16 max_reserved_per_tdmr) { int i; @@ -984,7 +1053,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); + sysinfo_cmr, tdmr_list, max_reserved_per_tdmr); if (ret) return ret; } @@ -999,7 +1068,8 @@ 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_sys_info_tdmr *sysinfo_tdmr) + struct tdx_sys_info_tdmr *sysinfo_tdmr, + struct tdx_sys_info_cmr *sysinfo_cmr) { int ret; @@ -1012,7 +1082,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, sysinfo_cmr, sysinfo_tdmr->max_reserved_per_tdmr); if (ret) tdmrs_free_pamt_all(tdmr_list); @@ -1208,7 +1278,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); + ret = construct_tdmrs(&tdx_memlist, &tdx_tdmr_list, &sysinfo.tdmr, + &sysinfo.cmr); 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 9314f6ecbcb5..b933abefe8b4 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -43,6 +43,9 @@ #define MD_FIELD_ID_PAMT_4K_ENTRY_SIZE 0x9100000100000010ULL #define MD_FIELD_ID_PAMT_2M_ENTRY_SIZE 0x9100000100000011ULL #define MD_FIELD_ID_PAMT_1G_ENTRY_SIZE 0x9100000100000012ULL +#define MD_FIELD_ID_NUM_CMRS 0x9000000100000000ULL +#define MD_FIELD_ID_CMR_BASE 0x9000000300000080ULL +#define MD_FIELD_ID_CMR_SIZE 0x9000000300000100ULL /* * Sub-field definition of metadata field ID. @@ -131,6 +134,14 @@ struct tdx_sys_info_version { u32 build_date; }; +/* Class "CMR Info" */ +#define TDX_MAX_CMRS 32 +struct tdx_sys_info_cmr { + u16 num_cmrs; + u64 cmr_base[TDX_MAX_CMRS]; + u64 cmr_size[TDX_MAX_CMRS]; +}; + /* Class "TDMR info" */ struct tdx_sys_info_tdmr { u16 max_tdmrs; @@ -141,6 +152,7 @@ struct tdx_sys_info_tdmr { struct tdx_sys_info { struct tdx_sys_info_features features; struct tdx_sys_info_version version; + struct tdx_sys_info_cmr cmr; struct tdx_sys_info_tdmr tdmr; };