From nobody Wed Dec 17 15:50:43 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.11]) (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 63A4A18AE2 for ; Sat, 14 Dec 2024 15:16:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734189379; cv=none; b=Hiimqv1sRWUhzlSYxtR8L6+/9R3+5e76kRGAppMy59pjC1jbRgPQfkx188Js21MVYZNsDQxlxqT1aZ6GMHcR1vpAVikVqjB9cTvGZnVU0XJw1ciDYi0nzZVjhCVma/A4QmJHfewVcc3wUVFLeoqQssMnFTRcIj9XtgCKAz+qvQQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734189379; c=relaxed/simple; bh=owQmkqaLRIE9GeiR0sm2qoSY/RWQT987XFzzAtkcayY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=K2YNF/TMeOdM42wwlemfuI8zZS8iA7BHEyAa26m89ZdXGUQhXcqoobgyxBAQOnC1xdUUjqc5idgpXqX/I/AyLXAh3AQmgMlwGi/ywjt6pEnidrO/7asMi4l7PruzsKedx/hSjTTiuh0Y9lHWLxXC64F6KjOD4qZqzWM5e/QanN0= 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=fqd1S7z2; arc=none smtp.client-ip=198.175.65.11 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="fqd1S7z2" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1734189378; x=1765725378; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=owQmkqaLRIE9GeiR0sm2qoSY/RWQT987XFzzAtkcayY=; b=fqd1S7z2FVKauwVujV4cJICSpMzT4roAHyqkGzWThPBJKbofwxtA97Yz ryMIgud5OSaVCeT4ZgABmI4SWmHjYu3LtuveMVRgeourClu96XImmQycm EoGYkkRgpIM5vwee2VgOWUUCvVUUG6U7ApkitdOJkHslBIP+Of5uqG07+ UTKG0ye8pGsNtoxzCsWJeDCpIKdnX6kB+4LK6XVuC2mzSepxHp950E8Ql BSJXckAAnl8yNL9Mk1SsEok7FZue9rMXbkKGambvQ8NndPvrc1wDEF0KA ufmcVCi9Q9SVkc4+sTTzlA34YpqbCDH9otIZgve3QqMN5fZzsRgOC0lQn g==; X-CSE-ConnectionGUID: OViyRm4wRUKLmpKgRLxSzQ== X-CSE-MsgGUID: /Pylb+RmQ9yfeVcRFeIKfg== X-IronPort-AV: E=McAfee;i="6700,10204,11282"; a="45109877" X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="45109877" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by orvoesa103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Dec 2024 07:16:17 -0800 X-CSE-ConnectionGUID: KxRuVakLSOqJJh9GWhditw== X-CSE-MsgGUID: AxjnC7kATRG3GzjHWeAx6Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="120050132" Received: from bjrankin-mobl3.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.223.200]) by fmviesa002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Dec 2024 07:16:10 -0800 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, rick.p.edgecombe@intel.com, isaku.yamahata@intel.com, adrian.hunter@intel.com, nik.borisov@suse.com, kai.huang@intel.com Subject: [PATCH v9 1/6] x86/virt/tdx: Rename 'struct tdx_tdmr_sysinfo' to reflect the spec better Date: Sun, 15 Dec 2024 04:15:42 +1300 Message-ID: X-Mailer: git-send-email 2.47.1 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". Today the kernel reads some of the global metadata to initialize the TDX module. KVM will need to read additional metadata fields to run TDX guests. Move towards having the TDX host core-kernel provide a centralized, canonical, and immutable structure for the global metadata that comes out from the TDX module for all kernel components to use. More specifically, prepare the code to end up with an organization 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'. Prepare for the above by renaming 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 --- v8 -> v9: - Minor changelog improvement suggested by Rick and Reniette. --- 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.47.1 From nobody Wed Dec 17 15:50:43 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.11]) (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 0E1F1195FE3 for ; Sat, 14 Dec 2024 15:16:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734189386; cv=none; b=gvRMGwfjcZmXaUiHGL4zDj0I4BeUMQ7xOuhlrRVjNl+IBpP1hltnbjcVvHNyXDi2gWvlRslA+TKt0etmeAS3GuxP47lc1P8yzHrijh4a3cJoN53t7ZPx7yEuHepGP2PZS9IxEquQ0sXxhSX+e4clr2jwdPM14Wg8yyiy1OOsxyQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734189386; c=relaxed/simple; bh=qUFQTlxQxW1bCwelnRCVS/v3khy7lbqTGgx60XC0Bo8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=eJfvAiQy7F546HPZD25ySEZaWFJerTjg5Ix4xv1fHR5DBMTRLIYODKMnC5JhAf2RmGXu7nmYqezKh6a2YThSZIQ+T5SASePFpvzIGqSzkuXUQJZd1CqztdYufZQuPcWCKnkn6ikIEno8o1qD30/IRxy7T0gberQS5SKpHdNbOYU= 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=ANxmIyVp; arc=none smtp.client-ip=198.175.65.11 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="ANxmIyVp" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1734189385; x=1765725385; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=qUFQTlxQxW1bCwelnRCVS/v3khy7lbqTGgx60XC0Bo8=; b=ANxmIyVpvzCeoXdtaU5lHOs7To0Jm2I1aohzZwAJ1Ik6ynIJFVC0fBcn HqV8o2BPmKZXx/gebhhe/RN9bQppMS4SnhQoK/vdWc8cI8qoFYv04DgvJ /td8ihxQnlGdJrRb23RA+Fm+7A1h1j+AnQ+RbvSj0gP/e3+CXPrHdRxga xHQ+6669HLykqgo0kGuonkT54Z9YOcr7+TATabEYlFsUSTcGbF7YA+EpG MFCaAZnbGXEmn0/jMmKrNxxFoDtqOuyVfL3xg7EcJwLCmfojySyM3MHyH rb2kig0tmcT5F7WyVTXGW3pRfna2wpd5TUgQc6rBfpPRZbErAQI+Xg/FZ Q==; X-CSE-ConnectionGUID: Kwx/m2VARKGDfaIhI3oRMg== X-CSE-MsgGUID: D1JtAsVoQDapbMbRuKgAnw== X-IronPort-AV: E=McAfee;i="6700,10204,11282"; a="45109888" X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="45109888" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by orvoesa103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Dec 2024 07:16:25 -0800 X-CSE-ConnectionGUID: a5INe2RuTKO+oI9RinO4Vg== X-CSE-MsgGUID: Zr9TDpOvQyOQuCN1a1uXNQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="120050151" Received: from bjrankin-mobl3.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.223.200]) by fmviesa002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Dec 2024 07:16:17 -0800 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, rick.p.edgecombe@intel.com, isaku.yamahata@intel.com, adrian.hunter@intel.com, nik.borisov@suse.com, kai.huang@intel.com Subject: [PATCH v9 2/6] x86/virt/tdx: Start to track all global metadata in one structure Date: Sun, 15 Dec 2024 04:15:43 +1300 Message-ID: X-Mailer: git-send-email 2.47.1 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. Today the kernel only reads "TD Memory Region" (TDMR) related fields for module initialization. KVM will need to read additional metadata fields to run TDX guests. Move towards having the TDX host core-kernel provide a centralized, canonical, and immutable 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 categorizes 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 clearer. E.g., construct_tdmrs() can just take the structure which contains "TDMR Info" metadata fields. Add get_tdx_sys_info() as the placeholder to read all metadata fields. Have it only call get_tdx_sys_info_tdmr() to read TDMR related fields for now. Place get_tdx_sys_info() as the first step of init_tdx_module() to enable early prerequisite checks on the metadata to support early module initialization abort. This results in moving get_tdx_sys_info_tdmr() to be before build_tdx_memlist(), but this is fine because there are no dependencies between these two functions. Signed-off-by: Kai Huang Reviewed-by: Adrian Hunter Reviewed-by: Dan Williams --- v8 -> v9: - Minor changelog improvement suggested by Rick and Reniette. --- arch/x86/virt/vmx/tdx/tdx.c | 19 ++++++++++++------- arch/x86/virt/vmx/tdx/tdx.h | 19 ++++++++++++------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index e979bf442929..7a2f979092e7 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -326,6 +326,11 @@ static int get_tdx_sys_info_tdmr(struct tdx_sys_info_t= dmr *sysinfo_tdmr) return 0; } =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) { @@ -1098,9 +1103,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 @@ -1117,17 +1126,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 148f9b4d1140..2600ec3752f5 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -80,6 +80,18 @@ struct tdmr_info { DECLARE_FLEX_ARRAY(struct tdmr_reserved_area, reserved_areas); } __packed __aligned(TDMR_INFO_ALIGNMENT); =20 +/* Class "TDMR info" */ +struct tdx_sys_info_tdmr { + u16 max_tdmrs; + u16 max_reserved_per_tdmr; + u16 pamt_entry_size[TDX_PS_NR]; +}; + +/* Kernel used global metadata fields */ +struct tdx_sys_info { + struct tdx_sys_info_tdmr tdmr; +}; + /* * Do not put any hardware-defined TDX structure representations below * this comment! @@ -99,13 +111,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.47.1 From nobody Wed Dec 17 15:50:43 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.11]) (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 B77B0199FA4 for ; Sat, 14 Dec 2024 15:16:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734189399; cv=none; b=u87KwcT8mShbEgHGRUozyTxKPwyj5mlnRTBk9HYRPS2qXAQtgeadGrBu5eyljp816Evdxt06eruWaGBMU882rQAmKgzGxHG01zKSUE06v01ECMeyvkl+IDALc4pQe7/uLpf15OfD1u5X3CY2tuGVMd6Y/xBLoqGeh7vAvUlm5JY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734189399; c=relaxed/simple; bh=/2pVLCoro9y1+4wg4uZt9uImZoxVNxSa4uu1CRnd658=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KkZJwU5d3Xphux/wWaaeifOQKWcnJjrqU9Bzyq/ORhvFl9i4XvXhsNxZ0zRT+tOZQyJ2/YI0l+vEQWU+/tuqf4MJqumHUCXvuojy8TbzOdTvQPP3olP287nvmQf1f+5bijCxjjNaCa9MCfnHTgavggjGwyYkvArESgxdJupUWRc= 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=G9psPDzN; arc=none smtp.client-ip=198.175.65.11 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="G9psPDzN" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1734189398; x=1765725398; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=/2pVLCoro9y1+4wg4uZt9uImZoxVNxSa4uu1CRnd658=; b=G9psPDzNt5l26Y/pF3S66Uc7QbeaOSvFz7ryLYHCR5HZPrny+ZiLzQaV 3CMJeDjqXtTj1XWeMBJ/e8hS5RkuEKgl5uO8J7F8McAONa4AmlUuGyDmJ Sxta62cJXsWzAe1b7t1Hz+BBsE1/wG4w7ob/Nz+i+werqyH6ahH27d3Md m6Fz2H8vS7Kwdr30D0GEkizthlDdHQAZ0UdO7EzimJX64EYyy5//4YBRa nSayMldaqY18UzaB+WeTvAMjyRrssh1bPrcUCTYAToI9iH0d581xqnMd/ HP0VOW88/um1C++vdyZVYmDm9BGauzVosroN/plJaF16qGEUdsdGlpkUy w==; X-CSE-ConnectionGUID: oKeddqmmSnSAVhhFL2JAHQ== X-CSE-MsgGUID: FLTNZU7GSC2W50qo7ESngw== X-IronPort-AV: E=McAfee;i="6700,10204,11282"; a="45109898" X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="45109898" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by orvoesa103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Dec 2024 07:16:37 -0800 X-CSE-ConnectionGUID: qbyUObKITUu8u2/Wmua4JA== X-CSE-MsgGUID: DoSNNkVkScaJc8lfVdKrJg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="120050172" Received: from bjrankin-mobl3.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.223.200]) by fmviesa002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Dec 2024 07:16:25 -0800 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, rick.p.edgecombe@intel.com, isaku.yamahata@intel.com, adrian.hunter@intel.com, nik.borisov@suse.com, kai.huang@intel.com Subject: [PATCH v9 3/6] x86/virt/tdx: Use auto-generated code to read global metadata Date: Sun, 15 Dec 2024 04:15:44 +1300 Message-ID: X-Mailer: git-send-email 2.47.1 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" From: Paolo Bonzini 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 needs to read more global metadata fields for future use: - Supported features ("TDX_FEATURES0") to fail module initialization when the module doesn't support "not clobbering host RBP when exiting from TDX guest" feature [1]. - KVM TDX baseline support and other features like TDX Connect will need to read more. The current global metadata reading code has limitations (e.g., it only has a primitive helper to read metadata field with 16-bit element size, while TDX supports 8/16/32/64 bits metadata element sizes). It needs tweaks in order to read more metadata fields. But even with the tweaks, when new code is added to read a new field, the reviewers will still need to review against the spec to make sure the new code doesn't screw up things like using the wrong metadata field ID (each metadata field is associated with a unique field ID, which is a TDX-defined u64 constant) etc. TDX documents all global metadata fields in a 'global_metadata.json' file as part of TDX spec [2]. JSON format is machine readable. Instead of tweaking the metadata reading code, use a script to generate the code so that: 1) Using the generated C is simple. 2) Adding a field is simple, e.g., the script just pulls the field ID out of the JSON for a given field thus no manual review is needed. Specifically, to match the layout of the 'struct tdx_sys_info' and its sub-structures, the script uses a table with each entry containing the the name of the sub-structures (which reflects the "Class") and the "Field Name" of all its fields, and auto-generate: 1) The 'struct tdx_sys_info' and all 'struct tdx_sys_info_xx' sub-structures in 'tdx_global_metadata.h'. 2) The main function 'get_tdx_sys_info()' which reads all metadata to 'struct tdx_sys_info' and the 'get_tdx_sys_info_xx()' functions which read 'struct tdx_sys_info_xx()' in 'tdx_global_metadata.c'. Using the generated C is simple: 1) include "tdx_global_metadata.h" to the local "tdx.h"; 2) explicitly include "tdx_global_metadata.c" to the local "tdx.c" after the read_sys_metadata_field() primitive (which is a wrapper of TDH.SYS.RD SEAMCALL to read global metadata). Adding a field is also simple: 1) just add the new field to an existing structure, or add it with a new structure; 2) re-run the script to generate the new code; 3) update the existing tdx_global_metadata.{hc} with the new ones. For now, use the auto-generated code to read the TDMR related fields and the aforesaid metadata field "TDX_FEATURES0". The tdx_global_metadata.{hc} can be generated by running below: #python tdx_global_metadata.py global_metadata.json \ tdx_global_metadata.h tdx_global_metadata.c .. where the 'global_metadata.json' can be fetched from [2] and the 'tdx_global_metadata.py' can be found from [3]. Link: https://lore.kernel.org/fc0e8ab7-86d4-4428-be31-82e1ece6dd21@intel.co= m/ [1] Link: https://cdrdv2.intel.com/v1/dl/getContent/795381 [2] Link: https://lore.kernel.org/762a50133300710771337398284567b299a86f67.came= l@intel.com/ [3] Signed-off-by: Paolo Bonzini Co-developed-by: Kai Huang Signed-off-by: Kai Huang Reviewed-by: Dan Williams --- v8 -> v9: - Remove CMR reading code and update changelog accordingly. --- arch/x86/virt/vmx/tdx/tdx_global_metadata.c | 48 +++++++++++++++++++++ arch/x86/virt/vmx/tdx/tdx_global_metadata.h | 25 +++++++++++ 2 files changed, 73 insertions(+) create mode 100644 arch/x86/virt/vmx/tdx/tdx_global_metadata.c create mode 100644 arch/x86/virt/vmx/tdx/tdx_global_metadata.h diff --git a/arch/x86/virt/vmx/tdx/tdx_global_metadata.c b/arch/x86/virt/vm= x/tdx/tdx_global_metadata.c new file mode 100644 index 000000000000..8027a24d1c6e --- /dev/null +++ b/arch/x86/virt/vmx/tdx/tdx_global_metadata.c @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Automatically generated functions to read TDX global metadata. + * + * This file doesn't compile on its own as it lacks of inclusion + * of SEAMCALL wrapper primitive which reads global metadata. + * Include this file to other C file instead. + */ + +static int get_tdx_sys_info_features(struct tdx_sys_info_features *sysinfo= _features) +{ + int ret =3D 0; + u64 val; + + if (!ret && !(ret =3D read_sys_metadata_field(0x0A00000300000008, &val))) + sysinfo_features->tdx_features0 =3D val; + + return ret; +} + +static int get_tdx_sys_info_tdmr(struct tdx_sys_info_tdmr *sysinfo_tdmr) +{ + int ret =3D 0; + u64 val; + + if (!ret && !(ret =3D read_sys_metadata_field(0x9100000100000008, &val))) + sysinfo_tdmr->max_tdmrs =3D val; + if (!ret && !(ret =3D read_sys_metadata_field(0x9100000100000009, &val))) + sysinfo_tdmr->max_reserved_per_tdmr =3D val; + if (!ret && !(ret =3D read_sys_metadata_field(0x9100000100000010, &val))) + sysinfo_tdmr->pamt_4k_entry_size =3D val; + if (!ret && !(ret =3D read_sys_metadata_field(0x9100000100000011, &val))) + sysinfo_tdmr->pamt_2m_entry_size =3D val; + if (!ret && !(ret =3D read_sys_metadata_field(0x9100000100000012, &val))) + sysinfo_tdmr->pamt_1g_entry_size =3D val; + + return ret; +} + +static int get_tdx_sys_info(struct tdx_sys_info *sysinfo) +{ + int ret =3D 0; + + ret =3D ret ?: get_tdx_sys_info_features(&sysinfo->features); + ret =3D ret ?: get_tdx_sys_info_tdmr(&sysinfo->tdmr); + + return ret; +} diff --git a/arch/x86/virt/vmx/tdx/tdx_global_metadata.h b/arch/x86/virt/vm= x/tdx/tdx_global_metadata.h new file mode 100644 index 000000000000..6dd3c9695f59 --- /dev/null +++ b/arch/x86/virt/vmx/tdx/tdx_global_metadata.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Automatically generated TDX global metadata structures. */ +#ifndef _X86_VIRT_TDX_AUTO_GENERATED_TDX_GLOBAL_METADATA_H +#define _X86_VIRT_TDX_AUTO_GENERATED_TDX_GLOBAL_METADATA_H + +#include + +struct tdx_sys_info_features { + u64 tdx_features0; +}; + +struct tdx_sys_info_tdmr { + u16 max_tdmrs; + u16 max_reserved_per_tdmr; + u16 pamt_4k_entry_size; + u16 pamt_2m_entry_size; + u16 pamt_1g_entry_size; +}; + +struct tdx_sys_info { + struct tdx_sys_info_features features; + struct tdx_sys_info_tdmr tdmr; +}; + +#endif --=20 2.47.1 From nobody Wed Dec 17 15:50:43 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.11]) (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 DDA87195FE5 for ; Sat, 14 Dec 2024 15:16:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734189408; cv=none; b=lTD5cvXz8GQVfaDHjVKh2ZGgz/LADZXEQ8ucNu8SsHz3UgU2tVjEpWE0dbFdZ0iX3ynLY9wmz6uH95rX6UPNc10gfXhpLMyINyLGPNx9ImqtO+sFr6Nk0id/e/E/DA9+kUejmK+8vAmBtlsT11Do78Bb4ONhk/JppjH5zjVxF/E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734189408; c=relaxed/simple; bh=KK8X38CNscfJpPfeQuOnllEfBhSvoC4tkCFHMTuag6M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rVNDIYBqqEfZjiYUKqIGP3XTV8klUQziZkapFiZBYsTPlXD/8v0oikMXzyLITi1SiSVQC62B7j3Lr55qDHiLHz1sxJ1LDAZEIds6vRzP1Cju4MBo/Qer72H1cvoxgrBsGV/NWt5a6clgGCCkul0EA+FCBfw6DBQIUWiHt6wu4DU= 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=P6NEnUA1; arc=none smtp.client-ip=198.175.65.11 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="P6NEnUA1" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1734189407; x=1765725407; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=KK8X38CNscfJpPfeQuOnllEfBhSvoC4tkCFHMTuag6M=; b=P6NEnUA1iING8TbCIVpy6tfybffJa24sTjmT0Y7vlxp+Je7aE6w7/AAr +R18SVX9HqFRPiawmRus6eIohZk6ufI1BcRJCwO2tAt3qYvluRMU4lcqc zjyYnfKAR1I/7Jt/czxFj3p+/ykB4idjfLkKrh9vMY0VHguySEQ2Rfnn+ rAU0Zz3e27NI5XhQho8Klf7lA6LyYXpDgE6ExpJhr3jJmBZcB90V2vd4e b2/cTRe5xeirqdNu9LlIfMvGfprhKcJ5V9P1qD1Iw60aIUY6oSXf+nRwd k6CdzV3SaZ3Vhs52iB17G6HA+kPjMs4nHDbGFWe+p2FQmwNm24ZCfhniJ w==; X-CSE-ConnectionGUID: tm/pSrQITXmh672N2Fj2aw== X-CSE-MsgGUID: yyzvEdROQ3qoXO1zHKVpRg== X-IronPort-AV: E=McAfee;i="6700,10204,11282"; a="45109916" X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="45109916" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by orvoesa103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Dec 2024 07:16:47 -0800 X-CSE-ConnectionGUID: CV8pDeISQMKTqfA+NlvmmQ== X-CSE-MsgGUID: +pQR5jDsRVuZvxyEvPcIZA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="120050184" Received: from bjrankin-mobl3.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.223.200]) by fmviesa002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Dec 2024 07:16:37 -0800 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, rick.p.edgecombe@intel.com, isaku.yamahata@intel.com, adrian.hunter@intel.com, nik.borisov@suse.com, kai.huang@intel.com Subject: [PATCH v9 4/6] x86/virt/tdx: Use dedicated struct members for PAMT entry sizes Date: Sun, 15 Dec 2024 04:15:45 +1300 Message-ID: X-Mailer: git-send-email 2.47.1 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 'struct tdmr_sys_info_tdmr' which includes TDMR related fields defines the PAMT entry sizes for TDX supported page sizes (4KB, 2MB and 1GB) as an array: struct tdx_sys_info_tdmr { ... u16 pamt_entry_sizes[TDX_PS_NR]; }; PAMT entry sizes are needed when allocating PAMTs for each TDMR. Using the array to contain PAMT entry sizes reduces the number of arguments that need to be passed when calling tdmr_set_up_pamt(). It also makes the code pattern like below clearer: for (pgsz =3D TDX_PS_4K; pgsz < TDX_PS_NR; pgsz++) { pamt_size[pgsz] =3D tdmr_get_pamt_sz(tdmr, pgsz, pamt_entry_size[pgsz]); tdmr_pamt_size +=3D pamt_size[pgsz]; } However, the auto-generated metadata reading code generates a structure member for each field. The 'global_metadata.json' has a dedicated field for each PAMT entry size, and the new 'struct tdx_sys_info_tdmr' looks like: struct tdx_sys_info_tdmr { ... u16 pamt_4k_entry_size; u16 pamt_2m_entry_size; u16 pamt_1g_entry_size; }; Prepare to use the autogenerated code by making the existing 'struct tdx_sys_info_tdmr' look like the generated one. When passing to tdmrs_set_up_pamt_all(), build a local array of PAMT entry sizes from the structure so the code to allocate PAMTs can stay the same. Signed-off-by: Kai Huang Reviewed-by: Nikolay Borisov Reviewed-by: Dan Williams --- arch/x86/virt/vmx/tdx/tdx.c | 14 +++++++++----- arch/x86/virt/vmx/tdx/tdx.h | 4 +++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 7a2f979092e7..28537a6c47fc 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -304,9 +304,9 @@ struct field_mapping { 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]), + TD_SYSINFO_MAP(PAMT_4K_ENTRY_SIZE, pamt_4k_entry_size), + TD_SYSINFO_MAP(PAMT_2M_ENTRY_SIZE, pamt_2m_entry_size), + TD_SYSINFO_MAP(PAMT_1G_ENTRY_SIZE, pamt_1g_entry_size), }; =20 static int get_tdx_sys_info_tdmr(struct tdx_sys_info_tdmr *sysinfo_tdmr) @@ -932,14 +932,18 @@ static int construct_tdmrs(struct list_head *tmb_list, struct tdmr_info_list *tdmr_list, struct tdx_sys_info_tdmr *sysinfo_tdmr) { + u16 pamt_entry_size[TDX_PS_NR] =3D { + sysinfo_tdmr->pamt_4k_entry_size, + sysinfo_tdmr->pamt_2m_entry_size, + sysinfo_tdmr->pamt_1g_entry_size, + }; int ret; =20 ret =3D fill_out_tdmrs(tmb_list, tdmr_list); if (ret) return ret; =20 - ret =3D tdmrs_set_up_pamt_all(tdmr_list, tmb_list, - sysinfo_tdmr->pamt_entry_size); + ret =3D tdmrs_set_up_pamt_all(tdmr_list, tmb_list, pamt_entry_size); if (ret) return ret; =20 diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h index 2600ec3752f5..ec879d54eb5c 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -84,7 +84,9 @@ struct tdmr_info { struct tdx_sys_info_tdmr { u16 max_tdmrs; u16 max_reserved_per_tdmr; - u16 pamt_entry_size[TDX_PS_NR]; + u16 pamt_4k_entry_size; + u16 pamt_2m_entry_size; + u16 pamt_1g_entry_size; }; =20 /* Kernel used global metadata fields */ --=20 2.47.1 From nobody Wed Dec 17 15:50:43 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.11]) (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 A803D1A3034 for ; Sat, 14 Dec 2024 15:16:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734189416; cv=none; b=OxI2qzbyt+Q0V9NdE7e/5VM4zQ1siYeOSOwE8IaJfYgGRx+IBRY7pQoxZj5xrqc0sWo1L/PIvB0AJSljYzPLsfUuh0ItP0/F26IlUrTJtSnu9r770W44omVireuSLVfYv1bqRFxKt/EkBQSVimHodKqN6xsBDBwLN05MOgWpQ80= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734189416; c=relaxed/simple; bh=WeF04S8Gk0z2Y2rgXyEQT2J2OCs20Gh9h2IGzFi0np0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=r/0mlDesfTjqneAzx/1qvUYCZjcE8GzuyWXSxkl9F4jXC3MuCLcSd+l8/+FWGwZj5vuGlSE6gJapKIjupBdYJMBYUu9/wXVeAOcRpOupJ6zvMnY4TYRu+ud4ylnu8y9p507NRqGTaGCpE8bjOEwKADT/MXQZvZzGEI5Ds4Nn52Y= 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=Boewuzqc; arc=none smtp.client-ip=198.175.65.11 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="Boewuzqc" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1734189415; x=1765725415; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=WeF04S8Gk0z2Y2rgXyEQT2J2OCs20Gh9h2IGzFi0np0=; b=BoewuzqcBG2BikTYVmXuUGYebNcpXC6fGHg/lLuIp0llz0Em4EIAfP+B DinixHHWxJYKgIZgXDHoYPbkgWJOZVa/YlBEAoOSHQKvwx1VlwQGfiLhi rCiaHeHkbkHl2o/Qj5lvQogETAEGzt1ghTN3IQLpFVvPQRx88cvXhYeSo c9EBm5dZeYtRlCbx5YFN52t+oJ+T6gMOb+el+keZrzsqVP5d8pi+gm9er D/zmAxukdeziyyP6YSicZ9YU1acRdbQ7POADlqUOB1sAle7j3Xbw9/hmU lTnBhbBjiSJwvVJOsp+/CLhotJPgqrrgk9z7+PBDR9g0ZvEpy8oSBfLQ4 w==; X-CSE-ConnectionGUID: Kk/P9r/aR/Cw8S/L3Ukdnw== X-CSE-MsgGUID: p2kjaVtQTq2hVVq94KzcXQ== X-IronPort-AV: E=McAfee;i="6700,10204,11282"; a="45109925" X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="45109925" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by orvoesa103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Dec 2024 07:16:54 -0800 X-CSE-ConnectionGUID: h1Wlp24NSsmw4ibPfUWdBA== X-CSE-MsgGUID: lTHkvCq6QvGkdi7XbPPp8Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="120050203" Received: from bjrankin-mobl3.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.223.200]) by fmviesa002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Dec 2024 07:16:46 -0800 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, rick.p.edgecombe@intel.com, isaku.yamahata@intel.com, adrian.hunter@intel.com, nik.borisov@suse.com, kai.huang@intel.com Subject: [PATCH v9 5/6] x86/virt/tdx: Switch to use auto-generated global metadata reading code Date: Sun, 15 Dec 2024 04:15:46 +1300 Message-ID: X-Mailer: git-send-email 2.47.1 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" Continue the process to have a centralized solution for TDX global metadata reading. Now that the new autogenerated solution is ready for use, switch to it and remove the old one. Signed-off-by: Kai Huang Reviewed-by: Nikolay Borisov Reviewed-by: Dan Williams --- v8 -> v9: - Improve changelog suggested by Rick. --- arch/x86/virt/vmx/tdx/tdx.c | 61 +------------------------------------ arch/x86/virt/vmx/tdx/tdx.h | 45 +-------------------------- 2 files changed, 2 insertions(+), 104 deletions(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 28537a6c47fc..43ec56db5084 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -270,66 +270,7 @@ 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) -{ - u16 *ts_member =3D ((void *)ts) + offset; - u64 tmp; - int ret; - - 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; - - *ts_member =3D tmp; - - return 0; -} - -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_4k_entry_size), - TD_SYSINFO_MAP(PAMT_2M_ENTRY_SIZE, pamt_2m_entry_size), - TD_SYSINFO_MAP(PAMT_1G_ENTRY_SIZE, pamt_1g_entry_size), -}; - -static int get_tdx_sys_info_tdmr(struct tdx_sys_info_tdmr *sysinfo_tdmr) -{ - int ret; - int i; - - /* 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; - } - - return 0; -} - -static int get_tdx_sys_info(struct tdx_sys_info *sysinfo) -{ - return get_tdx_sys_info_tdmr(&sysinfo->tdmr); -} +#include "tdx_global_metadata.c" =20 /* Calculate the actual TDMR size */ static int tdmr_size_single(u16 max_reserved_per_tdmr) diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h index ec879d54eb5c..641beec86e73 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -2,7 +2,7 @@ #ifndef _X86_VIRT_TDX_H #define _X86_VIRT_TDX_H =20 -#include +#include "tdx_global_metadata.h" =20 /* * This file contains both macros and data structures defined by the TDX @@ -26,35 +26,6 @@ #define PT_NDA 0x0 #define PT_RSVD 0x1 =20 -/* - * Global scope metadata field ID. - * - * See Table "Global Scope Metadata", TDX module 1.5 ABI spec. - */ -#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 -#define MD_FIELD_ID_PAMT_2M_ENTRY_SIZE 0x9100000100000011ULL -#define MD_FIELD_ID_PAMT_1G_ENTRY_SIZE 0x9100000100000012ULL - -/* - * Sub-field definition of metadata field ID. - * - * See Table "MD_FIELD_ID (Metadata Field Identifier / Sequence Header) - * Definition", TDX module 1.5 ABI spec. - * - * - Bit 33:32: ELEMENT_SIZE_CODE -- size of a single element of metadata - * - * 0: 8 bits - * 1: 16 bits - * 2: 32 bits - * 3: 64 bits - */ -#define MD_FIELD_ID_ELE_SIZE_CODE(_field_id) \ - (((_field_id) & GENMASK_ULL(33, 32)) >> 32) - -#define MD_FIELD_ID_ELE_SIZE_16BIT 1 - struct tdmr_reserved_area { u64 offset; u64 size; @@ -80,20 +51,6 @@ struct tdmr_info { DECLARE_FLEX_ARRAY(struct tdmr_reserved_area, reserved_areas); } __packed __aligned(TDMR_INFO_ALIGNMENT); =20 -/* Class "TDMR info" */ -struct tdx_sys_info_tdmr { - u16 max_tdmrs; - u16 max_reserved_per_tdmr; - u16 pamt_4k_entry_size; - u16 pamt_2m_entry_size; - u16 pamt_1g_entry_size; -}; - -/* Kernel used global metadata fields */ -struct tdx_sys_info { - struct tdx_sys_info_tdmr tdmr; -}; - /* * Do not put any hardware-defined TDX structure representations below * this comment! --=20 2.47.1 From nobody Wed Dec 17 15:50:43 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.11]) (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 C40C51A8F75 for ; Sat, 14 Dec 2024 15:17:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734189424; cv=none; b=hl17+Yv4aw6iQOOnTmBSbPASHIJ/SdahDflJpKT+UWhSqRcQdb7tFviH+0rjvDzSPqd2lrYoMWY2r3iQIsWTmGDLpGIajEzbgPGhwyq49OIEoZ6ydenRGpnMWbjKaIq+GS/gfHXlPgD1klKCob0k27gcfvtDZ/FPml6SCktiK5I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734189424; c=relaxed/simple; bh=JxMZELjVGKGPt6XOV2bTuB1nEjDz6560szhLElfrufc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=noRAQ41PRETKAhDzF9Q3QeJ/vbKhBT1cR0IDZbmYF+BFKmmvy/2o0b/zccG0nJKbdWnWM2xA9KkDZrsidel8/s5DiJ0i3/GIjxprCEwj0ZHAy8Xn85YFd0PAcbWR8b4uZ90yLndFPmWvDzURcFfPQczqbvjvVI1jjfO44JJyU3g= 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=GY/CHKNd; arc=none smtp.client-ip=198.175.65.11 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="GY/CHKNd" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1734189423; x=1765725423; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=JxMZELjVGKGPt6XOV2bTuB1nEjDz6560szhLElfrufc=; b=GY/CHKNdoFlsG+zs+QPXFhqyC66zSBRPU+ovIPFuWy0QUMB8cGZHVxpK XUFhcRMUUcXZbPBiHgMCiNS5ywUKsHXHsvvF+Zc8DTqp8wRvk1XlmT2VH BU8xs+XmOOm2TBOb2kaqTovumuhGpJCfStSaKpwdqkFljO5zpOh0ii3/+ uHC6hj7jOPOgNd5eMj+yRJWWW70N0K3psWPDV0uKGPPkIhb8Ao4UqpgPQ 6OdWUJFFeapuEguHXXVGUlrbWHMH+yWW6vdAp1YtJkXpnWs5OhhkoNf78 Z1i7Y67j56EpmruBSEPMVST8pRXwJsji/+jA/WwQvcgJBuZBDNbiNthdD A==; X-CSE-ConnectionGUID: JWzYpJ2VS2CZ1Cpdr9b6eA== X-CSE-MsgGUID: 2dIlWEGhTQyjtxGAa0wavg== X-IronPort-AV: E=McAfee;i="6700,10204,11282"; a="45109944" X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="45109944" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by orvoesa103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Dec 2024 07:17:02 -0800 X-CSE-ConnectionGUID: OpPYWUKgQKCntZovrZyk7g== X-CSE-MsgGUID: DO6Oq3FaTbq2UxiApXR2Cw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="120050216" Received: from bjrankin-mobl3.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.223.200]) by fmviesa002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Dec 2024 07:16:54 -0800 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, rick.p.edgecombe@intel.com, isaku.yamahata@intel.com, adrian.hunter@intel.com, nik.borisov@suse.com, kai.huang@intel.com Subject: [PATCH v9 6/6] x86/virt/tdx: Require the module to assert it has the NO_RBP_MOD mitigation Date: Sun, 15 Dec 2024 04:15:47 +1300 Message-ID: <76ae5025502c84d799e3a56a6fc4f69a82da8f93.1734188033.git.kai.huang@intel.com> X-Mailer: git-send-email 2.47.1 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. KVM will need to use the TDH.VP.ENTER SEAMCALL to run TDX guests. It won't be safe to run TDX guests w/o this feature. To prevent it, just don't initialize the TDX module if this feature is not supported [1]. Note the bit definitions of TDX_FEATURES0 are not auto-generated in tdx_global_metadata.h. Manually define a macro for it in "tdx.h". Link: https://lore.kernel.org/fc0e8ab7-86d4-4428-be31-82e1ece6dd21@intel.co= m/ [1] Signed-off-by: Kai Huang Reviewed-by: Nikolay Borisov Reviewed-by: Adrian Hunter Reviewed-by: Dan Williams --- v8 -> v9: - Minor changelog improvement suggested by Rick and Reniette. - Rebase due to the removal of CMR reading code. Note: This doesn't need to be included to stable kernels because TDH.VP.ENTER won't be used until KVM is able to support TDX. --- arch/x86/virt/vmx/tdx/tdx.c | 17 +++++++++++++++++ arch/x86/virt/vmx/tdx/tdx.h | 4 ++++ 2 files changed, 21 insertions(+) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 43ec56db5084..7fdb37387886 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -272,6 +272,18 @@ static int read_sys_metadata_field(u64 field_id, u64 *= data) =20 #include "tdx_global_metadata.c" =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) { @@ -1055,6 +1067,11 @@ static int init_tdx_module(void) if (ret) return ret; =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 641beec86e73..4e3d533cdd61 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -2,6 +2,7 @@ #ifndef _X86_VIRT_TDX_H #define _X86_VIRT_TDX_H =20 +#include #include "tdx_global_metadata.h" =20 /* @@ -51,6 +52,9 @@ struct tdmr_info { DECLARE_FLEX_ARRAY(struct tdmr_reserved_area, reserved_areas); } __packed __aligned(TDMR_INFO_ALIGNMENT); =20 +/* Bit definitions of TDX_FEATURES0 metadata field */ +#define TDX_FEATURES0_NO_RBP_MOD BIT(18) + /* * Do not put any hardware-defined TDX structure representations below * this comment! --=20 2.47.1