From nobody Wed Nov 27 02:39:28 2024 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) (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 59C0119D8B5; Mon, 14 Oct 2024 11:32:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.12 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728905537; cv=none; b=m1stGtOUIr8wSdvUikxVBbgaoKviyWDKQ2LUOELQ2bFg/hyTILMeoJjiu0A2PQQOaTXNKkfIvwksYcZ7ivZZnf5OLJQvu1fcCVnFCISi7dLWHedkfaZS1aEYrLiW8bz06suAlO/HIMHbuodSpN7Pbc1s9bEDHywHTz1+DdGnc6o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728905537; c=relaxed/simple; bh=cQAl2DIUCEYx9ze1aKAOpRrIGrQdcbonzNi6afsmBjs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CrpF6JI6E0Pu1B2nleH31es8xuztxBFqbeQHq6l7UvdnFFLYOar5akhQY+JzoSlr2oCudFdxYHwiGpXeAoSiNXLTGbkOTG6HhXjwJjCNZzE8iR6cv+qh9rI5uNo7oyognCL/fLHaRsToNfGvH2MPYbwrs2zIYuGCQiWYeGxfq9M= 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=LRTN+i8V; arc=none smtp.client-ip=192.198.163.12 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="LRTN+i8V" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1728905535; x=1760441535; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=cQAl2DIUCEYx9ze1aKAOpRrIGrQdcbonzNi6afsmBjs=; b=LRTN+i8VwQzEqj9st+pvU7N/Lwd9JSfV0zRaNx6bIYjmjESw9u0HvOWc 9kUJzr26HuSDzn0cuegRwlFbjZ0DOPtlL0P1J35B9riQfWPS9a/Wz5DL4 0hK5Ete7wNIvuVryQmTI73bvECkssHcG3cURS12X7INP+DtDtwWwI+O1G MPGgDIUIm2RgqfzjtkXyHGdSlsdmpZ/dGdeSQxQxUQT2ixXFlBgkUXouU +bC8tcUMvqHWWfsV5LmIij6NcBqUAYybw6UnvZ3RsWqVyCq32iv1/a7sz rcK9/KTm5GP7QQLRTBvMyu3KwSD7tgH4YDZaWOeJPhRiM6udA2b56j8HP g==; X-CSE-ConnectionGUID: NzkThZwCQ4qXd247iMo8Ww== X-CSE-MsgGUID: pEzMt5NWR7iTsc6cTaZUsg== X-IronPort-AV: E=McAfee;i="6700,10204,11224"; a="32166460" X-IronPort-AV: E=Sophos;i="6.11,202,1725346800"; d="scan'208";a="32166460" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Oct 2024 04:32:15 -0700 X-CSE-ConnectionGUID: vOzFU7frQG2rHn7c7FSwTg== X-CSE-MsgGUID: RhVeU4SlRuqw9OldBQt5nQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,202,1725346800"; d="scan'208";a="82117462" Received: from jdoman-desk1.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.220.204]) by fmviesa005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Oct 2024 04:32:12 -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 v5 1/8] x86/virt/tdx: Rename 'struct tdx_tdmr_sysinfo' to reflect the spec better Date: Tue, 15 Oct 2024 00:31:48 +1300 Message-ID: <610e4030201c337d5e9b4f3a13d3da565f7ed6c7.1728903647.git.kai.huang@intel.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 --- v4 -> v5: - No change 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 =20 - 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 *d= ata) =20 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 =3D ((void *)ts) + offset; u64 tmp; @@ -298,9 +298,9 @@ struct field_mapping { =20 #define TD_SYSINFO_MAP(_field_id, _offset) \ { .field_id =3D MD_FIELD_ID_##_field_id, \ - .offset =3D offsetof(struct tdx_tdmr_sysinfo, _offset) } + .offset =3D offsetof(struct tdx_sys_info_tdmr, _offset) } =20 -/* 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[] =3D { 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[] =3D { TD_SYSINFO_MAP(PAMT_1G_ENTRY_SIZE, pamt_entry_size[TDX_PS_1G]), }; =20 -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; =20 - /* Populate 'tdmr_sysinfo' fields using the mapping structure above: */ + /* Populate 'sysinfo_tdmr' fields using the mapping structure above: */ for (i =3D 0; i < ARRAY_SIZE(fields); i++) { ret =3D 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) } =20 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; =20 - tdmr_sz =3D tdmr_size_single(tdmr_sysinfo->max_reserved_per_tdmr); - tdmr_array_sz =3D tdmr_sz * tdmr_sysinfo->max_tdmrs; + tdmr_sz =3D tdmr_size_single(sysinfo_tdmr->max_reserved_per_tdmr); + tdmr_array_sz =3D tdmr_sz * sysinfo_tdmr->max_tdmrs; =20 /* * 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 =3D tdmr_sz; - tdmr_list->max_tdmrs =3D tdmr_sysinfo->max_tdmrs; + tdmr_list->max_tdmrs =3D sysinfo_tdmr->max_tdmrs; tdmr_list->nr_consumed_tdmrs =3D 0; =20 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; =20 @@ -934,12 +934,12 @@ static int construct_tdmrs(struct list_head *tmb_list, return ret; =20 ret =3D tdmrs_set_up_pamt_all(tdmr_list, tmb_list, - tdmr_sysinfo->pamt_entry_size); + sysinfo_tdmr->pamt_entry_size); if (ret) return ret; =20 ret =3D 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); =20 @@ -1098,7 +1098,7 @@ static int init_tdmrs(struct tdmr_info_list *tdmr_lis= t) =20 static int init_tdx_module(void) { - struct tdx_tdmr_sysinfo tdmr_sysinfo; + struct tdx_sys_info_tdmr sysinfo_tdmr; int ret; =20 /* @@ -1117,17 +1117,17 @@ static int init_tdx_module(void) if (ret) goto out_put_tdxmem; =20 - ret =3D get_tdx_tdmr_sysinfo(&tdmr_sysinfo); + ret =3D get_tdx_sys_info_tdmr(&sysinfo_tdmr); if (ret) goto err_free_tdxmem; =20 /* Allocate enough space for constructing TDMRs */ - ret =3D alloc_tdmr_list(&tdx_tdmr_list, &tdmr_sysinfo); + ret =3D alloc_tdmr_list(&tdx_tdmr_list, &sysinfo_tdmr); if (ret) goto err_free_tdxmem; =20 /* Cover all TDX-usable memory regions in TDMRs */ - ret =3D construct_tdmrs(&tdx_memlist, &tdx_tdmr_list, &tdmr_sysinfo); + ret =3D construct_tdmrs(&tdx_memlist, &tdx_tdmr_list, &sysinfo_tdmr); if (ret) goto err_free_tdmrs; =20 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 { }; =20 /* "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]; --=20 2.46.2 From nobody Wed Nov 27 02:39:28 2024 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) (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 D3CC119E97E; Mon, 14 Oct 2024 11:32:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.12 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728905540; cv=none; b=oI4mVPK3pcVnYuiPKAv/l+mQTg4Aqm6rnozeevRMa8XdBnnJay33R1EgaTW/7tgqEeqC04UDIxO0BFuePX33kgSpTQm4q/YEirjpBq7Yc9r5b5o0Fdhc6d37tdgWG2i9XR90ZcoOQzOcVLAjK5XE9VOOUDbpzfIc3IZD+WNbphk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728905540; c=relaxed/simple; bh=kg+pNFVdA4tldjlYTz75xDec+r7A8psHaU6GXFZ00M4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VhLB6MPUm9lpmRuRUQjjkr3i9QtwnBeHW1MGMl0GJlcWDDHPy9OAF9xVUtlF4tGo+Od8UhIbohenc9J6sqIrWj1+LD6OojwuBIis4xz/Is1CelfsDcC/Bt3pEdd2j0AKLIqbSn3E169OSSYeo5c9nSFEC9PpnUQojhxAZ4tE0vc= 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=dRmCekC8; arc=none smtp.client-ip=192.198.163.12 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="dRmCekC8" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1728905539; x=1760441539; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=kg+pNFVdA4tldjlYTz75xDec+r7A8psHaU6GXFZ00M4=; b=dRmCekC8IsQIzi4vk9YBgOOSeQ/33gpn4A7bMMCcXByv0DfZoycSP2Me Zuwwh7hhUYvJJ+ZNbnbSIc3ywwKuymFokLMrTE3pcgrfbPt8mh4ay/CWe e6VU6AQY7nYBtPQrMuz8+qqRw+/XU/j19uVbFUr+xwAkYuPB6JyGQicyB BkOB9ysC4VpWfwjRG3mFScynFxkCfN2CQ6gpYFU0FK1Xo3CrMfSLubulZ mYYuYvfd2iDr8A7YA4Q4rkpteZeFWgPiKWcx4nNMXV2QUrgnVPAgSiEZm 9E9/DhvGuVSOkRDs776gtYJmfHyuCbIyCGrin5LmKUpdE6IjQjTCVtEN4 Q==; X-CSE-ConnectionGUID: PMa0pwiyRDOf+id9ikW1vA== X-CSE-MsgGUID: LRMCL1rvQRWp+9AN2p5HPw== X-IronPort-AV: E=McAfee;i="6700,10204,11224"; a="32166473" X-IronPort-AV: E=Sophos;i="6.11,202,1725346800"; d="scan'208";a="32166473" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Oct 2024 04:32:18 -0700 X-CSE-ConnectionGUID: 1yvhmhPyROCYFaFfQtJIVw== X-CSE-MsgGUID: YXu4fNejSY+7idNP3IwNRA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,202,1725346800"; d="scan'208";a="82117469" Received: from jdoman-desk1.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.220.204]) by fmviesa005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Oct 2024 04:32:15 -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 v5 2/8] x86/virt/tdx: Rework TD_SYSINFO_MAP to support build-time verification Date: Tue, 15 Oct 2024 00:31:49 +1300 Message-ID: X-Mailer: git-send-email 2.46.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 --- v4 -> v5: - No change 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; } =20 -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 =3D ((void *)ts) + offset; u64 tmp; int ret; =20 - if (WARN_ON_ONCE(MD_FIELD_ID_ELE_SIZE_CODE(field_id) !=3D - MD_FIELD_ID_ELE_SIZE_16BIT)) - return -EINVAL; - ret =3D read_sys_metadata_field(field_id, &tmp); if (ret) return ret; =20 - *ts_member =3D tmp; + *val =3D tmp; =20 return 0; } =20 -struct field_mapping { - u64 field_id; - int offset; -}; - -#define TD_SYSINFO_MAP(_field_id, _offset) \ - { .field_id =3D MD_FIELD_ID_##_field_id, \ - .offset =3D offsetof(struct tdx_sys_info_tdmr, _offset) } - -/* Map TD_SYSINFO fields into 'struct tdx_sys_info_tdmr': */ -static const struct field_mapping fields[] =3D { - 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) !=3D \ + MD_FIELD_ID_ELE_SIZE_16BIT); \ + __read_sys_metadata_field16(_field_id, _val); \ +}) =20 static int get_tdx_sys_info_tdmr(struct tdx_sys_info_tdmr *sysinfo_tdmr) { - int ret; - int i; + int ret =3D 0; =20 - /* Populate 'sysinfo_tdmr' fields using the mapping structure above: */ - for (i =3D 0; i < ARRAY_SIZE(fields); i++) { - ret =3D 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 =3D ret ?: read_sys_metadata_field16(MD_FIELD_ID_##_field_id, \ + &sysinfo_tdmr->_member) =20 - 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; } =20 /* Calculate the actual TDMR size */ --=20 2.46.2 From nobody Wed Nov 27 02:39:28 2024 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) (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 5FFAA1A3BA1; Mon, 14 Oct 2024 11:32:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.12 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728905544; cv=none; b=dzzxVqAYLuIBRncQNI3TDBCCD1IpWsNjHJjYEFMDATfMjwF/xL/9vdyAag8xGeEvgPOfxu5MaGzdESBPXh1fWSGQTX4V3jiuv7mc2Gh5J8MhShkSEecX7sdXBnmtB4bViQHTdoYEFA+fHZJnTr/UB4tbFOGtJ83ofrMbS2t/0cA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728905544; c=relaxed/simple; bh=GVy0J6oqeO5Tjm5jFsozOB8vjW3stLXFbkNZMEBBxtE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=LOp6VoDOLrnERZ6a6wOtgjvES5gPpGGTs9N89XQyuWno0f0iL4FhJL7EUPZCpBB6186t+y+ShmXithf+b1HNf2ObCgMLmuLeQ6YUK/pIV4KhoKSRe8/LyLD0W/qkj4qBicLuWWqFVrsEwco4UAwohda3HcIQ1FzuE4AYxf9CspQ= 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=OnkvDVYe; arc=none smtp.client-ip=192.198.163.12 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="OnkvDVYe" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1728905542; x=1760441542; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=GVy0J6oqeO5Tjm5jFsozOB8vjW3stLXFbkNZMEBBxtE=; b=OnkvDVYe24ohi97OImdVxLXldBZamZD9xCwX4nRYRyxSx/jQsh5JA1A8 aNUJktClkqAW699Xu3S3T1pYEGUnNogWN2gFhaNiTgJywYCCTlpX8YGhM fUV3MMUbpppIzyewR0E3xGw1a3NMKyv8nThz76Imqv/4sfgbIrDVoswdj dOJ7uku5gq9VwtKnvzf+Qgnj8NrpOlk3fCpc9po3HuajzxsPdLxsVz71Y iFU7zkdjyFH+TokDQbdCVGG3jBFP5Yg06RZ5MXbTtdsRZbUaBx1WoHq0j MdbtyvY9xoAwcy+opV0qGHHwfmXb+U2bGe+NFIfIXhzHimN5nzp+aC1RT A==; X-CSE-ConnectionGUID: UuNnM5UUTuSzSFAFakvW1w== X-CSE-MsgGUID: YsOGs7+OReWIeoPGOGeDNA== X-IronPort-AV: E=McAfee;i="6700,10204,11224"; a="32166488" X-IronPort-AV: E=Sophos;i="6.11,202,1725346800"; d="scan'208";a="32166488" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Oct 2024 04:32:22 -0700 X-CSE-ConnectionGUID: MBCaP5UcQDWpBd4I4eCClA== X-CSE-MsgGUID: nFv1Ihp7QgO2i1dbwP53EQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,202,1725346800"; d="scan'208";a="82117474" Received: from jdoman-desk1.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.220.204]) by fmviesa005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Oct 2024 04:32:19 -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 v5 3/8] x86/virt/tdx: Prepare to support reading other global metadata fields Date: Tue, 15 Oct 2024 00:31:50 +1300 Message-ID: X-Mailer: git-send-email 2.46.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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. Rework the {__}read_sys_metadata_field16() primitives to work with all 8/16/32/64 element sizes. Note the new primitive __read_sys_metadata_field() takes 'void *buf' and 'int size' and explicitly uses memcpy() to copy the SEAMCALL returned data (u64) to a pointer of u8/u16/u32/u64, instead of depending on the compiler to know the size and copy. But this is fine since the wrapper read_sys_metadata_field(), which works with a pointer to u8/u16/32/u64, passes the sizeof() to the __read_sys_metadata_field() internally. And it has BUILD_BUG_ON() to verify the metadata element size encoded in the field ID indeed matches the size passed to __read_sys_metadata_field(). This ensures the users of read_sys_metadata_field() will never screw up. Also add a comment to point out __read_sys_metadata_field() should not be used directly. Signed-off-by: Kai Huang --- v4 -> v5: - Change back to what Dave suggested and update changelog: https://lore.kernel.org/lkml/408dee3f-a466-4746-92d3-adf54d35ec7c@intel.= com/ =20 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. =20 - Rewrite after removing 'struct field_mapping' and reimplementing TD_SYSINFO_MAP(). =20 --- arch/x86/virt/vmx/tdx/tdx.c | 21 +++++++++++---------- arch/x86/virt/vmx/tdx/tdx.h | 3 ++- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 2f7e4abc1bb9..d63efb2d50d1 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; } =20 -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 =3D {}; int ret; @@ -270,25 +270,26 @@ static int read_sys_metadata_field(u64 field_id, u64 = *data) return 0; } =20 -static int __read_sys_metadata_field16(u64 field_id, u16 *val) +/* Don't use this directly, but use read_sys_metadata_field() instead. */ +static int __read_sys_metadata_field(u64 field_id, void *val, int size) { u64 tmp; int ret; =20 - ret =3D read_sys_metadata_field(field_id, &tmp); + ret =3D tdh_sys_rd(field_id, &tmp); if (ret) return ret; =20 - *val =3D tmp; + memcpy(val, &tmp, size); =20 return 0; } =20 -#define read_sys_metadata_field16(_field_id, _val) \ -({ \ - BUILD_BUG_ON(MD_FIELD_ID_ELE_SIZE_CODE(_field_id) !=3D \ - MD_FIELD_ID_ELE_SIZE_16BIT); \ - __read_sys_metadata_field16(_field_id, _val); \ +/* @_val must be a pointer to u8/u16/u32/u64 */ +#define read_sys_metadata_field(_field_id, _val) \ +({ \ + BUILD_BUG_ON(MD_FIELD_ELE_SIZE(_field_id) !=3D sizeof(*(_val))); \ + __read_sys_metadata_field(_field_id, _val, sizeof(*(_val))); \ }) =20 static int get_tdx_sys_info_tdmr(struct tdx_sys_info_tdmr *sysinfo_tdmr) @@ -296,7 +297,7 @@ static int get_tdx_sys_info_tdmr(struct tdx_sys_info_td= mr *sysinfo_tdmr) int ret =3D 0; =20 #define READ_SYS_INFO(_field_id, _member) \ - ret =3D ret ?: read_sys_metadata_field16(MD_FIELD_ID_##_field_id, \ + ret =3D ret ?: read_sys_metadata_field(MD_FIELD_ID_##_field_id, \ &sysinfo_tdmr->_member) =20 READ_SYS_INFO(MAX_TDMRS, max_tdmrs); diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h index 148f9b4d1140..7a8204a05bf7 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) =20 -#define MD_FIELD_ID_ELE_SIZE_16BIT 1 +#define MD_FIELD_ELE_SIZE(_field_id) \ + (1 << MD_FIELD_ID_ELE_SIZE_CODE(_field_id)) =20 struct tdmr_reserved_area { u64 offset; --=20 2.46.2 From nobody Wed Nov 27 02:39:28 2024 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) (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 E8B01199FC9; Mon, 14 Oct 2024 11:32:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.12 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728905547; cv=none; b=EX663VA3HWiouTFurRY/hAv70a2uG6LL6xmtfMPwFcVH0bn2i+lLwN8iZXNujdZdsSkW0p5s0Y9nQlPBCjaDkqft+Gyp+PLbj/yZQr9eQUbTrWN7TIpLcQ417YraCCznK4tK1AfciLwsahopnCRag1pmQFUGBLJ9whaHo0T/Umg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728905547; c=relaxed/simple; bh=PNGHYl26Z+AOnJWsvbC2lB6vddHl8DJkpeMOxdEnyBo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nsrbvNGXZ9h+EvzZfLSZ++kZLoAOi27Gb4seTzItbe8BWmhHlp8mq67O9Q0hj2Obc/LMtuRhLKQadreY1EXDVis7EgazNUNmOndxTSvn6AybjzySzD0F7m+xPCKA56WwJAoHEui4yzIMUeN7j8fAXvO7TOvwiZrZiz6zFouOkr4= 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=Po16YDKZ; arc=none smtp.client-ip=192.198.163.12 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="Po16YDKZ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1728905546; x=1760441546; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=PNGHYl26Z+AOnJWsvbC2lB6vddHl8DJkpeMOxdEnyBo=; b=Po16YDKZZnFJvfdDsL4RXScSqBmic9jLuDGnpj/F4iht/4nbBtej4ZHZ MLV1O1wwjajCLToA0smYHJ9A0+iFeHxiYD4z7mmrwa2CpIdRJPnP5hCR9 FGUZBw+UKl7tstR4gB3UMtN4w6py58yOoxSBgkvyTCOxUgouhDmFS3r3o f9JWrJ618qToErUaA38qNlXvBw9PCes//hBqzYokzC4NyR8r4p9mLkWDh fJQ5IYa1Lnvgc/99R2xAGYXAeAkel6bAhI27U0zhGNvcyPuoa4KwG1S/t m4kLwYR3qRKn3SKE8jRdBiDfobdaeGlJi4osw/YyBQS2Sc8jK8qF/31DQ w==; X-CSE-ConnectionGUID: KgoLduWXQL+Jzyv4aKqrzQ== X-CSE-MsgGUID: UTkdX0oDT+OuHkchJZSsjw== X-IronPort-AV: E=McAfee;i="6700,10204,11224"; a="32166502" X-IronPort-AV: E=Sophos;i="6.11,202,1725346800"; d="scan'208";a="32166502" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Oct 2024 04:32:25 -0700 X-CSE-ConnectionGUID: Y/JODufOSgiLF/j4/tX0bQ== X-CSE-MsgGUID: 1G3g5VoERbShPG09sfmj+g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,202,1725346800"; d="scan'208";a="82117479" Received: from jdoman-desk1.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.220.204]) by fmviesa005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Oct 2024 04:32:22 -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 v5 4/8] x86/virt/tdx: Refine a comment to reflect the latest TDX spec Date: Tue, 15 Oct 2024 00:31:51 +1300 Message-ID: <9a5adc84bf8de51e0340300903c7ea048686077e.1728903647.git.kai.huang@intel.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 7a8204a05bf7..8345ae1f7fb1 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 --=20 2.46.2 From nobody Wed Nov 27 02:39:28 2024 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) (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 805161A724B; Mon, 14 Oct 2024 11:32:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.12 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728905551; cv=none; b=fY23MmKPCXOn+0XLBB1EHnbocKl+07wylSL9ofOylTnrgtRXoS+y7jnCxJCXbVhKPbLejUbpSGfYEj6JGVPkitOkRl6HPJNQLVFaXtRL0STkY+5Bnfp/45hywxMylJj1Yp2JFNIrPg0Mo/6YbbxX2prL2eXT62LwDQFMKGuwg5s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728905551; c=relaxed/simple; bh=tmloiPHkSiYU29S44SW51h+fO8fsbKe9hH9Xlss47aU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Zxlv5GWuvfHQnaxzNYZ9qqRkPyrmHt2s6AYNPzfbjj9aZ+jQlx3CK4i8sTKidcqqU8P39XKGDr8EdQoE9f1Pj8ou/tqdNLBwr9wMRKjtuzf/+iV1xfSrPKQ7X2I6WchKO+sXRmDZR/vppECS6QUDWsV4z07q3qshQnCo7E7WhQQ= 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=g1VY8idI; arc=none smtp.client-ip=192.198.163.12 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="g1VY8idI" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1728905549; x=1760441549; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=tmloiPHkSiYU29S44SW51h+fO8fsbKe9hH9Xlss47aU=; b=g1VY8idIIsVOBI6zlOaU9ys89qqn18pmbDv4QBn4hgkg7LcuAjukURL1 sUlULZBTMzUHGkbi3pDarr4An4NroJjcZ/1LCk9hMbMydtMDWdvDwHT/z d9ekMtfU1SKK0EjwrWD2zYuO1/zvPNGhlUYaqm6mqn17zTgRPz4u2d9Ya Ok+842Ti5gAUXpv39/dXpm8xpPAaovkXvnz7kFuIdUHkkGKMu2h72Lq9S HJUHWaUMzhwSKpnZuLpzgEqcyTgRVkTkF8IK9umGQSVfdZTxmOEfwcEvx SuTSU64IL+WzrvgyGmaC1rcMRCNvNUajj4cLA4+CewM1V03D4X2OC5kkX w==; X-CSE-ConnectionGUID: WZgvcMJaR4GkXiFAOsKBzg== X-CSE-MsgGUID: gZ7a8ZneSS20ULs4VBGk1Q== X-IronPort-AV: E=McAfee;i="6700,10204,11224"; a="32166518" X-IronPort-AV: E=Sophos;i="6.11,202,1725346800"; d="scan'208";a="32166518" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Oct 2024 04:32:29 -0700 X-CSE-ConnectionGUID: uEsSURAKRsimCJboM+QThA== X-CSE-MsgGUID: MUOpB2bQQDmIcE0VKavKAw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,202,1725346800"; d="scan'208";a="82117483" Received: from jdoman-desk1.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.220.204]) by fmviesa005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Oct 2024 04:32:26 -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 v5 5/8] x86/virt/tdx: Start to track all global metadata in one structure Date: Tue, 15 Oct 2024 00:31:52 +1300 Message-ID: <93dbca28787da38e60d972d122ca6900cd1caf32.1728903647.git.kai.huang@intel.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 --- v4 -> v5: - Rebase due to patch 3 change. 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 d63efb2d50d1..a4496c4c765f 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -311,6 +311,11 @@ static int get_tdx_sys_info_tdmr(struct tdx_sys_info_t= dmr *sysinfo_tdmr) return ret; } =20 +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) { @@ -1083,9 +1088,13 @@ static int init_tdmrs(struct tdmr_info_list *tdmr_li= st) =20 static int init_tdx_module(void) { - struct tdx_sys_info_tdmr sysinfo_tdmr; + struct tdx_sys_info sysinfo; int ret; =20 + ret =3D 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 @@ -1102,17 +1111,13 @@ static int init_tdx_module(void) if (ret) goto out_put_tdxmem; =20 - ret =3D get_tdx_sys_info_tdmr(&sysinfo_tdmr); - if (ret) - goto err_free_tdxmem; - /* Allocate enough space for constructing TDMRs */ - ret =3D alloc_tdmr_list(&tdx_tdmr_list, &sysinfo_tdmr); + ret =3D alloc_tdmr_list(&tdx_tdmr_list, &sysinfo.tdmr); if (ret) goto err_free_tdxmem; =20 /* Cover all TDX-usable memory regions in TDMRs */ - ret =3D construct_tdmrs(&tdx_memlist, &tdx_tdmr_list, &sysinfo_tdmr); + ret =3D construct_tdmrs(&tdx_memlist, &tdx_tdmr_list, &sysinfo.tdmr); if (ret) goto err_free_tdmrs; =20 diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h index 8345ae1f7fb1..4c924124347c 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -81,6 +81,35 @@ struct tdmr_info { DECLARE_FLEX_ARRAY(struct tdmr_reserved_area, reserved_areas); } __packed __aligned(TDMR_INFO_ALIGNMENT); =20 +/* + * 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! @@ -100,13 +129,6 @@ struct tdx_memblock { int nid; }; =20 -/* "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 =20 --=20 2.46.2 From nobody Wed Nov 27 02:39:28 2024 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) (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 0367B1A76AF; Mon, 14 Oct 2024 11:32:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.12 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728905554; cv=none; b=sxGVVtrXM11qh3jfzd4xvZQP3KL2V4MmLW/m5NgurRw3xz6JUf4hBbEwVyR323e3NoG+/mGUeE3ZFe9+o6jTWcstgIzQL4PDMd1UVScmGsPjRiPXqpeaI+SOwz1cbdoGG2BarpOKPIWjcE8BXLNBzTXmY31wS/y65cQWsk7yJdQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728905554; c=relaxed/simple; bh=4Fm73YRK8btjeCJoC8b2q7zZE+d4ai5nfnHJTIpJLpk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VuqmkEPySj0yFtKdr5n7FVlXa5aJ8q5HqTfwEqii3r8zBm/YQUNSt15IQ+qdD2CatcuyHuFQRoXTXZsaBdH5JlgL6WUft+cq5UahWf886ikSjkaej7YlrKSe6wcg7/iFvtZMM2GGbiodA5FpGr9mGczyLvNXCoOrXWIMYyU13jM= 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=gcDzNFap; arc=none smtp.client-ip=192.198.163.12 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="gcDzNFap" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1728905553; x=1760441553; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=4Fm73YRK8btjeCJoC8b2q7zZE+d4ai5nfnHJTIpJLpk=; b=gcDzNFapyU+cLvHXL+VhveuRlOWoomWrpXdpD2ohhIfmhJXJT9dwSITY W4MCTwQlKjAu0ffW9J6O8rKZxEQSCffLn3QvidIn0WwgduwYQqz7j2vgg TvsDZb+KUuUFXYFMqW+Xr1H7+CCo93KhYd9nPQpFgIBtmHrscMPgcciO5 jLN7IREsVXvgSrsCoGK3B96Alsm7iBFG//M81PbHY4gcpi3/3H6wWwIHz exWPQXvZjUwCHzlRn2XhW8S+oC4fAqBHvgDYpNP119Mej2JwWn+rK2TM1 ASTTO6aSl72lJd8m8SfQrpqxPTHR17VFuGj7Pz+mCNIIWx689QDnSDwwD Q==; X-CSE-ConnectionGUID: Suz+dMYaSxSfmDoMzhqZRA== X-CSE-MsgGUID: a/i3yukxRw6HFnBG6elevg== X-IronPort-AV: E=McAfee;i="6700,10204,11224"; a="32166538" X-IronPort-AV: E=Sophos;i="6.11,202,1725346800"; d="scan'208";a="32166538" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Oct 2024 04:32:32 -0700 X-CSE-ConnectionGUID: aHVh/2d/SG6km5sXbeFbAg== X-CSE-MsgGUID: aqDDsD71Rq6s9urIDjEyzA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,202,1725346800"; d="scan'208";a="82117491" Received: from jdoman-desk1.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.220.204]) by fmviesa005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Oct 2024 04:32:29 -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 v5 6/8] x86/virt/tdx: Print TDX module version Date: Tue, 15 Oct 2024 00:31:53 +1300 Message-ID: <08ed3b23b24b81089b02276c55d71aaa7d2a4bd5.1728903647.git.kai.huang@intel.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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@int= el.com/ [1] Signed-off-by: Kai Huang --- v4 -> v5: - Rebase due to patch 3 change. 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/#md= 73dd9b02a492acf4a6facae63e8d030e320967d --- arch/x86/virt/vmx/tdx/tdx.c | 50 +++++++++++++++++++++++++++++++++++++ arch/x86/virt/vmx/tdx/tdx.h | 19 +++++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index a4496c4c765f..130ddac47f64 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -292,6 +292,26 @@ static int __read_sys_metadata_field(u64 field_id, voi= d *val, int size) __read_sys_metadata_field(_field_id, _val, sizeof(*(_val))); \ }) =20 +static int get_tdx_sys_info_version(struct tdx_sys_info_version *sysinfo_v= ersion) +{ + int ret =3D 0; + +#define READ_SYS_INFO(_field_id, _member) \ + ret =3D ret ?: read_sys_metadata_field(MD_FIELD_ID_##_field_id, \ + &sysinfo_version->_member) + + READ_SYS_INFO(MAJOR_VERSION, major); + READ_SYS_INFO(MINOR_VERSION, minor); + READ_SYS_INFO(UPDATE_VERSION, update); + READ_SYS_INFO(INTERNAL_VERSION, internal); + READ_SYS_INFO(BUILD_NUM, build_num); + READ_SYS_INFO(BUILD_DATE, build_date); + +#undef READ_SYS_INFO + + return ret; +} + static int get_tdx_sys_info_tdmr(struct tdx_sys_info_tdmr *sysinfo_tdmr) { int ret =3D 0; @@ -313,9 +333,37 @@ static int get_tdx_sys_info_tdmr(struct tdx_sys_info_t= dmr *sysinfo_tdmr) =20 static int get_tdx_sys_info(struct tdx_sys_info *sysinfo) { + int ret; + + ret =3D get_tdx_sys_info_version(&sysinfo->version); + if (ret) + return ret; + return get_tdx_sys_info_tdmr(&sysinfo->tdmr); } =20 +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) { @@ -1095,6 +1143,8 @@ static int init_tdx_module(void) if (ret) return ret; =20 + 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 4c924124347c..0203528da024 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 @@ -99,6 +105,16 @@ struct tdmr_info { * those used by the kernel are. */ =20 +/* 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; @@ -107,7 +123,8 @@ struct tdx_sys_info_tdmr { }; =20 struct tdx_sys_info { - struct tdx_sys_info_tdmr tdmr; + struct tdx_sys_info_version version; + struct tdx_sys_info_tdmr tdmr; }; =20 /* --=20 2.46.2 From nobody Wed Nov 27 02:39:28 2024 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) (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 888F31AA786; Mon, 14 Oct 2024 11:32:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.12 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728905558; cv=none; b=FpG98h57mJqOa5gL9JrGb5PWQupGI7LOJijinZQbIG2VLg+iQmuRKOrmI4lzmKIyz97skBEYd5FM2oH2MKwiOp5bvlTTA3l8zu6JF4EyWbLIJuYVzOVebHIVgi6xwtjNchgZonsjR9h0225dgbNFsh+27UAHhCvZtkwjhHq2nRA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728905558; c=relaxed/simple; bh=G8yBT7WdIx28fuQzQTlC+Q/DNMdS5bKfXBVXPUHC2XI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZKdBpxWKiLUj7lZLITJBOOgmxupFDmqV+5Y9vzi/A1nqRvi/+X5fKaJIM+o1pPtXs/L0OHsGwcWBM4eKgFzjJiycvF7oD4XOv4K87pDolh+mVzkInt91yY7vJGH2eyj0lGZbummWBaHsM3/JVwuD+pZvxvq9lirwGvkjiGvrf7I= 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=UWhoGFDw; arc=none smtp.client-ip=192.198.163.12 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="UWhoGFDw" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1728905556; x=1760441556; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=G8yBT7WdIx28fuQzQTlC+Q/DNMdS5bKfXBVXPUHC2XI=; b=UWhoGFDwGzTEfAZtvPbKO4XltwxVTytJwy+Z+tDPrWkGh9gMVDLSBfxb ExzFvDGuV5gbaGUwwvmdIXNhDaxPDX93jrY/tnY//YCcDnBoTXqmPLxC4 M9/I9mwpWOoQ+3gI0JAXpqRxSr24MGvl4hwdjvzyWsbCV4ivCj7l8ShHJ 4og1YBhK9yNv+5qP40J8FdLGbUyezNPF6L41o1hBGduj89SwGEZx/DXMB TqkYz/Lzkzm5469NU9g2v8pyuhyktO5YfAT/+VhubyCy8MAOodQHOdvbE LAE4qUStGmBGA8ShrKfok4MjUdcy42Qsgh5sG+eMAhRSWcfBcL5ehB12p w==; X-CSE-ConnectionGUID: 7T+v/586Rp2QN8V3Gt3kCw== X-CSE-MsgGUID: 6Ox25bb5TC2hSZPNRllIUA== X-IronPort-AV: E=McAfee;i="6700,10204,11224"; a="32166555" X-IronPort-AV: E=Sophos;i="6.11,202,1725346800"; d="scan'208";a="32166555" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Oct 2024 04:32:36 -0700 X-CSE-ConnectionGUID: Lw2pRwCKTwmon6nN5nQtPw== X-CSE-MsgGUID: 7e3kRGAsQUWN8WsOcpIo9Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,202,1725346800"; d="scan'208";a="82117498" Received: from jdoman-desk1.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.220.204]) by fmviesa005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Oct 2024 04:32:33 -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 v5 7/8] x86/virt/tdx: Require the module to assert it has the NO_RBP_MOD mitigation Date: Tue, 15 Oct 2024 00:31:54 +1300 Message-ID: X-Mailer: git-send-email 2.46.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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@inte= l.com/ [1] Signed-off-by: Kai Huang Reviewed-by: Nikolay Borisov Reviewed-by: Adrian Hunter Reviewed-by: Dan Williams --- v4 -> v5: - Rebase due to patch 3 change. 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/#md= 9e2eeef927838cbf20d7b361cdbea518b8aec50 --- arch/x86/virt/vmx/tdx/tdx.c | 36 ++++++++++++++++++++++++++++++++++++ arch/x86/virt/vmx/tdx/tdx.h | 16 ++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 130ddac47f64..c877d02ca057 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -292,6 +292,21 @@ static int __read_sys_metadata_field(u64 field_id, voi= d *val, int size) __read_sys_metadata_field(_field_id, _val, sizeof(*(_val))); \ }) =20 +static int get_tdx_sys_info_features(struct tdx_sys_info_features *sysinfo= _features) +{ + int ret =3D 0; + +#define READ_SYS_INFO(_field_id, _member) \ + ret =3D ret ?: read_sys_metadata_field(MD_FIELD_ID_##_field_id, \ + &sysinfo_features->_member) + + 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_v= ersion) { int ret =3D 0; @@ -335,6 +350,10 @@ static int get_tdx_sys_info(struct tdx_sys_info *sysin= fo) { int ret; =20 + ret =3D get_tdx_sys_info_features(&sysinfo->features); + if (ret) + return ret; + ret =3D get_tdx_sys_info_version(&sysinfo->version); if (ret) return ret; @@ -364,6 +383,18 @@ static void print_basic_sys_info(struct tdx_sys_info *= sysinfo) print_sys_info_version(&sysinfo->version); } =20 +static int check_features(struct tdx_sys_info *sysinfo) +{ + u64 tdx_features0 =3D 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) { @@ -1145,6 +1176,11 @@ static int init_tdx_module(void) =20 print_basic_sys_info(&sysinfo); =20 + /* Check whether the kernel can support this module */ + ret =3D 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 0203528da024..18c54e1e3a4a 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 @@ -105,6 +106,20 @@ struct tdmr_info { * those used by the kernel are. */ =20 +/* + * 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 +138,7 @@ struct tdx_sys_info_tdmr { }; =20 struct tdx_sys_info { + struct tdx_sys_info_features features; struct tdx_sys_info_version version; struct tdx_sys_info_tdmr tdmr; }; --=20 2.46.2 From nobody Wed Nov 27 02:39:28 2024 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) (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 A2A841AA7BF; Mon, 14 Oct 2024 11:32:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.12 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728905562; cv=none; b=gHZsiXdGNwSa7+X56jvwwwnaIZR1/q+5r9M68XIBriO3oW2TSJRKZ09DpM7+jF2MtxDlMRDKabzWqXj3DvU1AKBqNTOGEYd2p1l64nfNQSV1owomTrHaP5pgJozeMgGDlc1LNoMwO0s4GdNlrNsAtB1VSzFoCQHBYMhieOg7Th0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728905562; c=relaxed/simple; bh=wwCoQVJY0cFSNxaU4p/NlRzSKSJS3jn/L43L9AyUbx4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XsYl4CHbcBk0CqsRhUtQV2owpwypfAN0N0HHquMPct17FvXhpp+ecWdPbqX6vIFE6LsLRvB+euwWSR5XxaButzSI3XehOzqRWXP6xXUsd9mrp82NLQpyBqLr0Cw4Em60IVzxd06yzYjb9b6VRx2ucaK684EduwGvOlnHPvI0dME= 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=doUJQ+X2; arc=none smtp.client-ip=192.198.163.12 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="doUJQ+X2" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1728905560; x=1760441560; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=wwCoQVJY0cFSNxaU4p/NlRzSKSJS3jn/L43L9AyUbx4=; b=doUJQ+X2yevFpIVlOluJNb2XweASeu2AmplZAwahKZHSm6kd/B7TQz3G Wf2y3sii5BNQCz4XApEiso6gmiwsQzrEInxu2vQv2bY6TseKy//52dN9c 3gxO7RLyv3gTrBpKPwXZUCa3b8UyY4UGOimkPvt/3m+YudwN6MKSFCdus rR5cMTaXb2uLBQLVcr70guTfavl24HsRj2xQZYmUQfPVxWdgUms8ozY0M i4wxmKav43WFCyHy4A5T3OcPB5oo2l2Z08a9FI0Qfj1YJQQgq0/OjVPip IDQvExThHu3Xgo8jJaeD8aQ5eFMzcvupY4qIyCuV8JKs5DedXb2JtH0Ob w==; X-CSE-ConnectionGUID: hlBNg6QATv+KYr3IIfmzKg== X-CSE-MsgGUID: J4FO+iwxTrCZwQX1MDDL/Q== X-IronPort-AV: E=McAfee;i="6700,10204,11224"; a="32166566" X-IronPort-AV: E=Sophos;i="6.11,202,1725346800"; d="scan'208";a="32166566" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Oct 2024 04:32:40 -0700 X-CSE-ConnectionGUID: G+P7xwZyR2uWw14ITbBF3g== X-CSE-MsgGUID: n5tZqCKRTnKi+sm+qeE9Pg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,202,1725346800"; d="scan'208";a="82117507" Received: from jdoman-desk1.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.220.204]) by fmviesa005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Oct 2024 04:32:36 -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 v5 8/8] x86/virt/tdx: Reduce TDMR's reserved areas by using CMRs to find memory holes Date: Tue, 15 Oct 2024 00:31:55 +1300 Message-ID: <0a3db9e979fec7546607b3b0b37dc2b6f1ab2302.1728903647.git.kai.huang@intel.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" A TDX module initialization failure was reported on a Emerald Rapids platform: virt/tdx: initialization failed: TDMR [0x0, 0x80000000): reserved areas e= xhausted. 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 --- v4 -> v5: - Rebase due to patch 3 change. v3 -> v4: - Trim down changelog - Dan. - "must be marked as reserved areas" -> "are marked as reserved areas" - A= rdian. - 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 c877d02ca057..b1e419765ed7 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -327,6 +327,58 @@ static int get_tdx_sys_info_version(struct tdx_sys_inf= o_version *sysinfo_version return ret; } =20 +/* 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 =3D 0; i < sysinfo_cmr->num_cmrs; i++) + if (!sysinfo_cmr->cmr_size[i]) + break; + + sysinfo_cmr->num_cmrs =3D i; +} + +static int get_tdx_sys_info_cmr(struct tdx_sys_info_cmr *sysinfo_cmr) +{ + int ret =3D 0; + u16 i; + +#define READ_SYS_INFO(_field_id, _member) \ + ret =3D ret ?: read_sys_metadata_field(MD_FIELD_ID_##_field_id, \ + &sysinfo_cmr->_member) + + READ_SYS_INFO(NUM_CMRS, num_cmrs); + + if (ret) + return ret; + + for (i =3D 0; i < sysinfo_cmr->num_cmrs; i++) { + READ_SYS_INFO(CMR_BASE + i, cmr_base[i]); + READ_SYS_INFO(CMR_SIZE + i, cmr_size[i]); + } + + 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 =3D 0; @@ -358,6 +410,10 @@ static int get_tdx_sys_info(struct tdx_sys_info *sysin= fo) if (ret) return ret; =20 + ret =3D get_tdx_sys_info_cmr(&sysinfo->cmr); + if (ret) + return ret; + return get_tdx_sys_info_tdmr(&sysinfo->tdmr); } =20 @@ -378,9 +434,23 @@ static void print_sys_info_version(struct tdx_sys_info= _version *version) version->build_date); } =20 +static void print_sys_info_cmr(struct tdx_sys_info_cmr *sysinfo_cmr) +{ + int i; + + for (i =3D 0; i < sysinfo_cmr->num_cmrs; i++) { + u64 cmr_base =3D sysinfo_cmr->cmr_base[i]; + u64 cmr_size =3D 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); } =20 static int check_features(struct tdx_sys_info *sysinfo) @@ -816,29 +886,28 @@ static int tdmr_add_rsvd_area(struct tdmr_info *tdmr,= int *p_idx, u64 addr, } =20 /* - * 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; =20 /* * Start looking for reserved blocks at the * beginning of the TDMR. */ prev_end =3D tdmr->base; - list_for_each_entry(tmb, tmb_list, list) { + for (i =3D 0; i < sysinfo_cmr->num_cmrs; i++) { u64 start, end; =20 - start =3D PFN_PHYS(tmb->start_pfn); - end =3D PFN_PHYS(tmb->end_pfn); + start =3D sysinfo_cmr->cmr_base[i]; + end =3D start + sysinfo_cmr->cmr_size[i]; =20 /* Break if this region is after the TDMR */ if (start >=3D tdmr_end(tdmr)) @@ -939,16 +1008,16 @@ static int rsvd_area_cmp_func(const void *a, const v= oid *b) =20 /* * 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 =3D 0; =20 - ret =3D tdmr_populate_rsvd_holes(tmb_list, tdmr, &rsvd_idx, + ret =3D tdmr_populate_rsvd_holes(sysinfo_cmr, tdmr, &rsvd_idx, max_reserved_per_tdmr); if (ret) return ret; @@ -967,10 +1036,10 @@ static int tdmr_populate_rsvd_areas(struct tdmr_info= *tdmr, =20 /* * 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; @@ -979,7 +1048,7 @@ static int tdmrs_populate_rsvd_areas_all(struct tdmr_i= nfo_list *tdmr_list, int ret; =20 ret =3D 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; } @@ -994,7 +1063,8 @@ static int tdmrs_populate_rsvd_areas_all(struct tdmr_i= nfo_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; =20 @@ -1007,7 +1077,7 @@ static int construct_tdmrs(struct list_head *tmb_list, if (ret) return ret; =20 - ret =3D tdmrs_populate_rsvd_areas_all(tdmr_list, tmb_list, + ret =3D tdmrs_populate_rsvd_areas_all(tdmr_list, sysinfo_cmr, sysinfo_tdmr->max_reserved_per_tdmr); if (ret) tdmrs_free_pamt_all(tdmr_list); @@ -1203,7 +1273,8 @@ static int init_tdx_module(void) goto err_free_tdxmem; =20 /* Cover all TDX-usable memory regions in TDMRs */ - ret =3D construct_tdmrs(&tdx_memlist, &tdx_tdmr_list, &sysinfo.tdmr); + ret =3D construct_tdmrs(&tdx_memlist, &tdx_tdmr_list, &sysinfo.tdmr, + &sysinfo.cmr); if (ret) goto err_free_tdmrs; =20 diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h index 18c54e1e3a4a..eeb42bd75a75 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 =20 /* * Sub-field definition of metadata field ID. @@ -130,6 +133,14 @@ struct tdx_sys_info_version { u32 build_date; }; =20 +/* 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; @@ -140,6 +151,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; }; =20 --=20 2.46.2