From: "Huang, Kai" <kai.huang@intel.com>
To: "pbonzini@redhat.com" <pbonzini@redhat.com>,
"Hansen, Dave" <dave.hansen@intel.com>
Cc: "Edgecombe, Rick P" <rick.p.edgecombe@intel.com>,
"seanjc@google.com" <seanjc@google.com>,
"bp@alien8.de" <bp@alien8.de>, "x86@kernel.org" <x86@kernel.org>,
"peterz@infradead.org" <peterz@infradead.org>,
"hpa@zytor.com" <hpa@zytor.com>,
"mingo@redhat.com" <mingo@redhat.com>,
"kirill.shutemov@linux.intel.com"
<kirill.shutemov@linux.intel.com>,
"tglx@linutronix.de" <tglx@linutronix.de>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"Williams, Dan J" <dan.j.williams@intel.com>,
"Yamahata, Isaku" <isaku.yamahata@intel.com>,
"kvm@vger.kernel.org" <kvm@vger.kernel.org>,
"Hunter, Adrian" <adrian.hunter@intel.com>,
"nik.borisov@suse.com" <nik.borisov@suse.com>
Subject: Re: [PATCH v5 0/8] TDX host: metadata reading tweaks, bug fix and info dump
Date: Mon, 28 Oct 2024 12:07:11 +0000 [thread overview]
Message-ID: <0853b155ec9aac09c594caa60914ed6ea4dc0a71.camel@intel.com> (raw)
In-Reply-To: <CABgObfYXUxqQV_FoxKjC8U3t5DnyM45nz5DpTxYZv2x_uFK_Kw@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 10709 bytes --]
On Tue, 2024-10-15 at 18:29 +0200, Paolo Bonzini wrote:
> On Tue, Oct 15, 2024 at 5:30 PM Dave Hansen <dave.hansen@intel.com> wrote:
> >
> > I'm having one of those "I hate this all" moments. Look at what we say
> > in the code:
> >
> > > * See the "global_metadata.json" in the "TDX 1.5 ABI definitions".
> >
> > Basically step one in verifying that this is all right is: Hey, humans,
> > please go parse a machine-readable format. That's insanity. If Intel
> > wants to publish JSON as the canonical source of truth, that's fine.
> > It's great, actually. But let's stop playing human JSON parser and make
> > the computers do it for us, OK?
> >
> > Let's just generate the code. Basically, as long as the generated C is
> > marginally readable, I'm OK with it. The most important things are:
> >
> > 1. Adding a field is dirt simple
> > 2. Using the generated C is simple
> >
> > In 99% of the cases, nobody ends up having to ever look at the generated
> > code.
> >
> > Take a look at the attached python program and generated C file. I
> > think they qualify. We can check the script into tools/scripts/ and it
> > can get re-run when new json comes out or when a new field is needed.
> > You'd could call the generated code like this:
>
> Ok, so let's move this thing forward. Here is a more polished script
> and the output. Untested beyond compilation.
>
> Kai, feel free to include it in v6 with my
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.om>
Hi Dave, Paolo,
I updated the script mainly for two purposes:
1) Add auto-generation of main structure 'struct tdx_sys_info' and the main
function 'get_tdx_sys_info()' which reads metadata to the main structure.
Without it, adding a new field of a new "Class" won't be that simple. Paolo's
script only generates 'struct tdx_sys_info_xx' sub-structures and
'get_tdx_sys_info_xx()' sub-functions. We will need to manually add the new
sub-structure to 'struct tdx_sys_info' and add code to call the new function to
read it.
2) Add support of reading large metadata field which has multiple 64-bit
elements.
Yes a metadata field can consist multiple 64-bit elements. The example is
CPUID_CONFIG_VALUE, which is an array, with each field consisting 2 64-bit
elements to represent 128-bit CPUID value EAX/EBX/ECX/EDX.
KVM will need to use this CPUID_CONFIG_VALUE to create TD.
The way to read such fields (see TDX 1.5 Base spec, 18.6.3. Arrays of Metadata
Fields, Figure 18.3: Example of an Array of Four 48 Byte TDCS.RTMR Fields, Each
Composed of 6 Elements):
Base field ID: X
---------------------------------
| elem 0 (X) | elem 1 (X+1) | Field 0
---------------------------------
| elem 0 (X+2) | elem 1 (X+3) | Field 1
---------------------------------
....
To make generation simple, I updated the script to generate such case as two-
dimensional array. E.g.,
Field Name: "XXX"
Num Field: M
Num Elements: N
->
u64 xxx[M][N];
And the code to read:
for (i = 0; i < M; i++)
for (j = 0; j < N; J++)
read...(BASE_ID + i * N + j, &val);
There are also some other minor updates. E.g., after asking TDX module guys,
they said we should use value reported via "NUM_CMRS" to loop when reading CMRs,
so I adjusted the script to use 'sysinfo_cmr->num_cmrs' to loop.
I pasted the script below, so that I can have a premalink of this script to use
in the next version of this series (for the sake to make the auto-generated code
reproducible). I also attached the updated script and auto-generated files.
Btw, the checkpatch.pl has below complain about the generated code:
ERROR: do not use assignment in if condition
#112: FILE: arch/x86/virt/vmx/tdx/tdx_global_metadata.c:15:
+ if (!ret && !(ret = read_sys_metadata_field(0x8800000200000001, &val)))
I didn't address this because this seems fine to me.
--- the updated script ---
#! /usr/bin/env python3
import json
import sys
# Note: this script does not run as part of the build process.
# It is used to generate structs from the TDX global_metadata.json
# file, and functions to fill in said structs. Rerun it if
# you need more fields.
TDX_STRUCTS = {
"version": [
"BUILD_DATE",
"BUILD_NUM",
"MINOR_VERSION",
"MAJOR_VERSION",
"UPDATE_VERSION",
"INTERNAL_VERSION",
],
"features": [
"TDX_FEATURES0"
],
"tdmr": [
"MAX_TDMRS",
"MAX_RESERVED_PER_TDMR",
"PAMT_4K_ENTRY_SIZE",
"PAMT_2M_ENTRY_SIZE",
"PAMT_1G_ENTRY_SIZE",
],
"cmr": [
"NUM_CMRS", "CMR_BASE", "CMR_SIZE"
],
# "td_ctrl": [
# "TDR_BASE_SIZE",
# "TDCS_BASE_SIZE",
# "TDVPS_BASE_SIZE",
# ],
# "td_conf": [
# "ATTRIBUTES_FIXED0",
# "ATTRIBUTES_FIXED1",
# "XFAM_FIXED0",
# "XFAM_FIXED1",
# "NUM_CPUID_CONFIG",
# "MAX_VCPUS_PER_TD",
# "CPUID_CONFIG_LEAVES",
# "CPUID_CONFIG_VALUES",
# ],
}
def print_class_struct_field(field_name, element_bytes, num_fields,
num_elements, file):
element_type = "u%s" % (element_bytes * 8)
element_array = ""
if num_fields > 1:
element_array += "[%d]" % (num_fields)
if num_elements > 1:
element_array += "[%d]" % (num_elements)
print("\t%s %s%s;" % (element_type, field_name, element_array), file=file)
def print_class_struct(class_name, fields, file):
struct_name = "tdx_sys_info_%s" % (class_name)
print("struct %s {" % (struct_name), file=file)
for f in fields:
print_class_struct_field(
f["Field Name"].lower(),
int(f["Element Size (Bytes)"]),
int(f["Num Fields"]),
int(f["Num Elements"]),
file=file)
print("};", file=file)
def print_read_field(field_id, struct_var, struct_member, indent, file):
print(
"%sif (!ret && !(ret = read_sys_metadata_field(%s, &val)))\n%s\t%s->%s =
val;"
% (indent, field_id, indent, struct_var, struct_member),
file=file,
)
def print_class_function(class_name, fields, file):
func_name = "get_tdx_sys_info_%s" % (class_name)
struct_name = "tdx_sys_info_%s" % (class_name)
struct_var = "sysinfo_%s" % (class_name)
print("static int %s(struct %s *%s)" % (func_name, struct_name, struct_var),
file=file)
print("{", file=file)
print("\tint ret = 0;", file=file)
print("\tu64 val;", file=file)
has_i = 0
has_j = 0
for f in fields:
num_fields = int(f["Num Fields"])
num_elements = int(f["Num Elements"])
if num_fields > 1:
has_i = 1
if num_elements > 1:
has_j = 1
if has_i == 1 and has_j == 1:
print("\tint i, j;", file=file)
elif has_i == 1:
print("\tint i;", file=file)
print(file=file)
for f in fields:
fname = f["Field Name"]
field_id = f["Base FIELD_ID (Hex)"]
num_fields = int(f["Num Fields"])
num_elements = int(f["Num Elements"])
struct_member = fname.lower()
indent = "\t"
if num_fields > 1:
if fname == "CMR_BASE" or fname == "CMR_SIZE":
limit = "sysinfo_cmr->num_cmrs"
elif fname == "CPUID_CONFIG_LEAVES" or fname ==
"CPUID_CONFIG_VALUES":
limit = "sysinfo_td_conf->num_cpuid_config"
else:
limit = "%d" %(num_fields)
print("%sfor (i = 0; i < %s; i++)" % (indent, limit), file=file)
indent += "\t"
field_id += " + i"
struct_member += "[i]"
if num_elements > 1:
print("%sfor (j = 0; j < %d; j++)" % (indent, num_elements),
file=file)
indent += "\t"
field_id += " * 2 + j"
struct_member += "[j]"
print_read_field(
field_id,
struct_var,
struct_member,
indent,
file=file,
)
print(file=file)
print("\treturn ret;", file=file)
print("}", file=file)
def print_main_struct(file):
print("struct tdx_sys_info {", file=file)
for class_name, field_names in TDX_STRUCTS.items():
struct_name = "tdx_sys_info_%s" % (class_name)
struct_var = class_name
print("\tstruct %s %s;" % (struct_name, struct_var), file=file)
print("};", file=file)
def print_main_function(file):
print("static int get_tdx_sys_info(struct tdx_sys_info *sysinfo)",
file=file)
print("{", file=file)
print("\tint ret = 0;", file=file)
print(file=file)
for class_name, field_names in TDX_STRUCTS.items():
func_name = "get_tdx_sys_info_" + class_name
struct_var = class_name
print("\tret = ret ?: %s(&sysinfo->%s);" % (func_name, struct_var),
file=file)
print(file=file)
print("\treturn ret;", file=file)
print("}", file=file)
jsonfile = sys.argv[1]
hfile = sys.argv[2]
cfile = sys.argv[3]
hfileifdef = hfile.replace(".", "_")
with open(jsonfile, "r") as f:
json_in = json.load(f)
fields = {x["Field Name"]: x for x in json_in["Fields"]}
with open(hfile, "w") as f:
print("/* SPDX-License-Identifier: GPL-2.0 */", file=f)
print("/* Automatically generated TDX global metadata structures. */",
file=f)
print("#ifndef _X86_VIRT_TDX_AUTO_GENERATED_" + hfileifdef.upper(), file=f)
print("#define _X86_VIRT_TDX_AUTO_GENERATED_" + hfileifdef.upper(), file=f)
print(file=f)
print("#include <linux/types.h>", file=f)
print(file=f)
for class_name, field_names in TDX_STRUCTS.items():
print_class_struct(class_name, [fields[x] for x in field_names], file=f)
print(file=f)
print_main_struct(file=f)
print(file=f)
print("#endif", file=f)
with open(cfile, "w") as f:
print("// SPDX-License-Identifier: GPL-2.0", file=f)
print("/*", file=f)
print(" * Automatically generated functions to read TDX global metadata.",
file=f)
print(" *", file=f)
print(" * This file doesn't compile on its own as it lacks of inclusion",
file=f)
print(" * of SEAMCALL wrapper primitive which reads global metadata.",
file=f)
print(" * Include this file to other C file instead.", file=f)
print(" */", file=f)
for class_name, field_names in TDX_STRUCTS.items():
print(file=f)
print_class_function(class_name, [fields[x] for x in field_names],
file=f)
print(file=f)
print_main_function(file=f)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: tdx.py --]
[-- Type: text/x-python3; name="tdx.py", Size: 6530 bytes --]
#! /usr/bin/env python3
import json
import sys
# Note: this script does not run as part of the build process.
# It is used to generate structs from the TDX global_metadata.json
# file, and functions to fill in said structs. Rerun it if
# you need more fields.
TDX_STRUCTS = {
"version": [
"BUILD_DATE",
"BUILD_NUM",
"MINOR_VERSION",
"MAJOR_VERSION",
"UPDATE_VERSION",
"INTERNAL_VERSION",
],
"features": [
"TDX_FEATURES0"
],
"tdmr": [
"MAX_TDMRS",
"MAX_RESERVED_PER_TDMR",
"PAMT_4K_ENTRY_SIZE",
"PAMT_2M_ENTRY_SIZE",
"PAMT_1G_ENTRY_SIZE",
],
"cmr": [
"NUM_CMRS", "CMR_BASE", "CMR_SIZE"
],
# "td_ctrl": [
# "TDR_BASE_SIZE",
# "TDCS_BASE_SIZE",
# "TDVPS_BASE_SIZE",
# ],
# "td_conf": [
# "ATTRIBUTES_FIXED0",
# "ATTRIBUTES_FIXED1",
# "XFAM_FIXED0",
# "XFAM_FIXED1",
# "NUM_CPUID_CONFIG",
# "MAX_VCPUS_PER_TD",
# "CPUID_CONFIG_LEAVES",
# "CPUID_CONFIG_VALUES",
# ],
}
def print_class_struct_field(field_name, element_bytes, num_fields, num_elements, file):
element_type = "u%s" % (element_bytes * 8)
element_array = ""
if num_fields > 1:
element_array += "[%d]" % (num_fields)
if num_elements > 1:
element_array += "[%d]" % (num_elements)
print("\t%s %s%s;" % (element_type, field_name, element_array), file=file)
def print_class_struct(class_name, fields, file):
struct_name = "tdx_sys_info_%s" % (class_name)
print("struct %s {" % (struct_name), file=file)
for f in fields:
print_class_struct_field(
f["Field Name"].lower(),
int(f["Element Size (Bytes)"]),
int(f["Num Fields"]),
int(f["Num Elements"]),
file=file)
print("};", file=file)
def print_read_field(field_id, struct_var, struct_member, indent, file):
print(
"%sif (!ret && !(ret = read_sys_metadata_field(%s, &val)))\n%s\t%s->%s = val;"
% (indent, field_id, indent, struct_var, struct_member),
file=file,
)
def print_class_function(class_name, fields, file):
func_name = "get_tdx_sys_info_%s" % (class_name)
struct_name = "tdx_sys_info_%s" % (class_name)
struct_var = "sysinfo_%s" % (class_name)
print("static int %s(struct %s *%s)" % (func_name, struct_name, struct_var), file=file)
print("{", file=file)
print("\tint ret = 0;", file=file)
print("\tu64 val;", file=file)
has_i = 0
has_j = 0
for f in fields:
num_fields = int(f["Num Fields"])
num_elements = int(f["Num Elements"])
if num_fields > 1:
has_i = 1
if num_elements > 1:
has_j = 1
if has_i == 1 and has_j == 1:
print("\tint i, j;", file=file)
elif has_i == 1:
print("\tint i;", file=file)
print(file=file)
for f in fields:
fname = f["Field Name"]
field_id = f["Base FIELD_ID (Hex)"]
num_fields = int(f["Num Fields"])
num_elements = int(f["Num Elements"])
struct_member = fname.lower()
indent = "\t"
if num_fields > 1:
if fname == "CMR_BASE" or fname == "CMR_SIZE":
limit = "sysinfo_cmr->num_cmrs"
elif fname == "CPUID_CONFIG_LEAVES" or fname == "CPUID_CONFIG_VALUES":
limit = "sysinfo_td_conf->num_cpuid_config"
else:
limit = "%d" %(num_fields)
print("%sfor (i = 0; i < %s; i++)" % (indent, limit), file=file)
indent += "\t"
field_id += " + i"
struct_member += "[i]"
if num_elements > 1:
print("%sfor (j = 0; j < %d; j++)" % (indent, num_elements), file=file)
indent += "\t"
field_id += " * 2 + j"
struct_member += "[j]"
print_read_field(
field_id,
struct_var,
struct_member,
indent,
file=file,
)
print(file=file)
print("\treturn ret;", file=file)
print("}", file=file)
def print_main_struct(file):
print("struct tdx_sys_info {", file=file)
for class_name, field_names in TDX_STRUCTS.items():
struct_name = "tdx_sys_info_%s" % (class_name)
struct_var = class_name
print("\tstruct %s %s;" % (struct_name, struct_var), file=file)
print("};", file=file)
def print_main_function(file):
print("static int get_tdx_sys_info(struct tdx_sys_info *sysinfo)", file=file)
print("{", file=file)
print("\tint ret = 0;", file=file)
print(file=file)
for class_name, field_names in TDX_STRUCTS.items():
func_name = "get_tdx_sys_info_" + class_name
struct_var = class_name
print("\tret = ret ?: %s(&sysinfo->%s);" % (func_name, struct_var), file=file)
print(file=file)
print("\treturn ret;", file=file)
print("}", file=file)
jsonfile = sys.argv[1]
hfile = sys.argv[2]
cfile = sys.argv[3]
hfileifdef = hfile.replace(".", "_")
with open(jsonfile, "r") as f:
json_in = json.load(f)
fields = {x["Field Name"]: x for x in json_in["Fields"]}
with open(hfile, "w") as f:
print("/* SPDX-License-Identifier: GPL-2.0 */", file=f)
print("/* Automatically generated TDX global metadata structures. */", file=f)
print("#ifndef _X86_VIRT_TDX_AUTO_GENERATED_" + hfileifdef.upper(), file=f)
print("#define _X86_VIRT_TDX_AUTO_GENERATED_" + hfileifdef.upper(), file=f)
print(file=f)
print("#include <linux/types.h>", file=f)
print(file=f)
for class_name, field_names in TDX_STRUCTS.items():
print_class_struct(class_name, [fields[x] for x in field_names], file=f)
print(file=f)
print_main_struct(file=f)
print(file=f)
print("#endif", file=f)
with open(cfile, "w") as f:
print("// SPDX-License-Identifier: GPL-2.0", file=f)
print("/*", file=f)
print(" * Automatically generated functions to read TDX global metadata.", file=f)
print(" *", file=f)
print(" * This file doesn't compile on its own as it lacks of inclusion", file=f)
print(" * of SEAMCALL wrapper primitive which reads global metadata.", file=f)
print(" * Include this file to other C file instead.", file=f)
print(" */", file=f)
for class_name, field_names in TDX_STRUCTS.items():
print(file=f)
print_class_function(class_name, [fields[x] for x in field_names], file=f)
print(file=f)
print_main_function(file=f)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: tdx_global_metadata.c --]
[-- Type: text/x-csrc; name="tdx_global_metadata.c", Size: 2873 bytes --]
// 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_version(struct tdx_sys_info_version *sysinfo_version)
{
int ret = 0;
u64 val;
if (!ret && !(ret = read_sys_metadata_field(0x8800000200000001, &val)))
sysinfo_version->build_date = val;
if (!ret && !(ret = read_sys_metadata_field(0x8800000100000002, &val)))
sysinfo_version->build_num = val;
if (!ret && !(ret = read_sys_metadata_field(0x0800000100000003, &val)))
sysinfo_version->minor_version = val;
if (!ret && !(ret = read_sys_metadata_field(0x0800000100000004, &val)))
sysinfo_version->major_version = val;
if (!ret && !(ret = read_sys_metadata_field(0x0800000100000005, &val)))
sysinfo_version->update_version = val;
if (!ret && !(ret = read_sys_metadata_field(0x0800000100000006, &val)))
sysinfo_version->internal_version = val;
return ret;
}
static int get_tdx_sys_info_features(struct tdx_sys_info_features *sysinfo_features)
{
int ret = 0;
u64 val;
if (!ret && !(ret = read_sys_metadata_field(0x0A00000300000008, &val)))
sysinfo_features->tdx_features0 = val;
return ret;
}
static int get_tdx_sys_info_tdmr(struct tdx_sys_info_tdmr *sysinfo_tdmr)
{
int ret = 0;
u64 val;
if (!ret && !(ret = read_sys_metadata_field(0x9100000100000008, &val)))
sysinfo_tdmr->max_tdmrs = val;
if (!ret && !(ret = read_sys_metadata_field(0x9100000100000009, &val)))
sysinfo_tdmr->max_reserved_per_tdmr = val;
if (!ret && !(ret = read_sys_metadata_field(0x9100000100000010, &val)))
sysinfo_tdmr->pamt_4k_entry_size = val;
if (!ret && !(ret = read_sys_metadata_field(0x9100000100000011, &val)))
sysinfo_tdmr->pamt_2m_entry_size = val;
if (!ret && !(ret = read_sys_metadata_field(0x9100000100000012, &val)))
sysinfo_tdmr->pamt_1g_entry_size = val;
return ret;
}
static int get_tdx_sys_info_cmr(struct tdx_sys_info_cmr *sysinfo_cmr)
{
int ret = 0;
u64 val;
int i;
if (!ret && !(ret = read_sys_metadata_field(0x9000000100000000, &val)))
sysinfo_cmr->num_cmrs = val;
for (i = 0; i < sysinfo_cmr->num_cmrs; i++)
if (!ret && !(ret = read_sys_metadata_field(0x9000000300000080 + i, &val)))
sysinfo_cmr->cmr_base[i] = val;
for (i = 0; i < sysinfo_cmr->num_cmrs; i++)
if (!ret && !(ret = read_sys_metadata_field(0x9000000300000100 + i, &val)))
sysinfo_cmr->cmr_size[i] = val;
return ret;
}
static int get_tdx_sys_info(struct tdx_sys_info *sysinfo)
{
int ret = 0;
ret = ret ?: get_tdx_sys_info_version(&sysinfo->version);
ret = ret ?: get_tdx_sys_info_features(&sysinfo->features);
ret = ret ?: get_tdx_sys_info_tdmr(&sysinfo->tdmr);
ret = ret ?: get_tdx_sys_info_cmr(&sysinfo->cmr);
return ret;
}
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: tdx_global_metadata.h --]
[-- Type: text/x-chdr; name="tdx_global_metadata.h", Size: 858 bytes --]
/* 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 <linux/types.h>
struct tdx_sys_info_version {
u32 build_date;
u16 build_num;
u16 minor_version;
u16 major_version;
u16 update_version;
u16 internal_version;
};
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_cmr {
u16 num_cmrs;
u64 cmr_base[32];
u64 cmr_size[32];
};
struct tdx_sys_info {
struct tdx_sys_info_version version;
struct tdx_sys_info_features features;
struct tdx_sys_info_tdmr tdmr;
struct tdx_sys_info_cmr cmr;
};
#endif
prev parent reply other threads:[~2024-10-28 12:07 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-14 11:31 Kai Huang
2024-10-14 11:31 ` [PATCH v5 1/8] x86/virt/tdx: Rename 'struct tdx_tdmr_sysinfo' to reflect the spec better Kai Huang
2024-10-14 11:31 ` [PATCH v5 2/8] x86/virt/tdx: Rework TD_SYSINFO_MAP to support build-time verification Kai Huang
2024-10-14 15:56 ` Dave Hansen
2024-10-14 19:13 ` Dan Williams
2024-10-15 11:34 ` Huang, Kai
2024-10-14 11:31 ` [PATCH v5 3/8] x86/virt/tdx: Prepare to support reading other global metadata fields Kai Huang
2024-10-14 11:31 ` [PATCH v5 4/8] x86/virt/tdx: Refine a comment to reflect the latest TDX spec Kai Huang
2024-10-14 11:31 ` [PATCH v5 5/8] x86/virt/tdx: Start to track all global metadata in one structure Kai Huang
2024-10-14 11:31 ` [PATCH v5 6/8] x86/virt/tdx: Print TDX module version Kai Huang
2024-10-14 11:31 ` [PATCH v5 7/8] x86/virt/tdx: Require the module to assert it has the NO_RBP_MOD mitigation Kai Huang
2024-10-14 11:31 ` [PATCH v5 8/8] x86/virt/tdx: Reduce TDMR's reserved areas by using CMRs to find memory holes Kai Huang
2024-10-15 15:30 ` [PATCH v5 0/8] TDX host: metadata reading tweaks, bug fix and info dump Dave Hansen
2024-10-15 16:29 ` Paolo Bonzini
2024-10-15 19:04 ` Dan Williams
2024-10-15 21:11 ` Huang, Kai
2024-10-28 12:07 ` Huang, Kai [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=0853b155ec9aac09c594caa60914ed6ea4dc0a71.camel@intel.com \
--to=kai.huang@intel.com \
--cc=adrian.hunter@intel.com \
--cc=bp@alien8.de \
--cc=dan.j.williams@intel.com \
--cc=dave.hansen@intel.com \
--cc=hpa@zytor.com \
--cc=isaku.yamahata@intel.com \
--cc=kirill.shutemov@linux.intel.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=nik.borisov@suse.com \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=rick.p.edgecombe@intel.com \
--cc=seanjc@google.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®