public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: "Huang, Kai" <kai.huang@intel.com>
To: "Hansen, Dave" <dave.hansen@intel.com>,
	"seanjc@google.com" <seanjc@google.com>,
	"bp@alien8.de" <bp@alien8.de>,
	"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>,
	"pbonzini@redhat.com" <pbonzini@redhat.com>,
	"Williams, Dan J" <dan.j.williams@intel.com>
Cc: "Edgecombe, Rick P" <rick.p.edgecombe@intel.com>,
	"kvm@vger.kernel.org" <kvm@vger.kernel.org>,
	"nik.borisov@suse.com" <nik.borisov@suse.com>,
	"Hunter, Adrian" <adrian.hunter@intel.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"Yamahata, Isaku" <isaku.yamahata@intel.com>,
	"x86@kernel.org" <x86@kernel.org>
Subject: Re: [PATCH v7 00/10] TDX host: metadata reading tweaks, bug fix and info dump
Date: Wed, 13 Nov 2024 11:26:32 +0000	[thread overview]
Message-ID: <d5aed06ae4b46df5db97fdbac9c01843920a2f96.camel@intel.com> (raw)
In-Reply-To: <1bd6a48d06e9bbf05ce5d6b138955b4306e2e383.camel@intel.com>

[-- Attachment #1: Type: text/plain, Size: 2510 bytes --]

On Mon, 2024-11-11 at 21:28 +0000, Huang, Kai wrote:
> On Mon, 2024-11-11 at 13:00 -0800, Hansen, Dave wrote:
> > On 11/11/24 12:49, Huang, Kai wrote:
> > > It also has a patch to fail module initialization when NO_MOD_BBP feature is not
> > > support.
> > > 
> > > Just want to confirm, do you want to remove the code to:
> > > 
> > >  - print CMRs;
> > >  - print TDX module versoin;
> > 
> > What is your goal?  What is the bare minimum amount of code to get there?
> 
> The goal is to get everything that KVM TDX needs merged, plus the bug fix.
> 
> KVM TDX needs the new metadata infrastructure and the NO_MOD_BRP patch, so yeah
> only printing CMRs and TDX module version are not needed.
> 
> I'll remove them in the next version.

I removed the "version" part in the 'tdx_global_metadata.py' script in order to
remove the code which reads TDX module version from the auto-generated code. 
For the sake of having a lore link of the script that I used in the new version,
I attached the updated script here.  It just got "version" part removed thus is
not interesting to read.

And Sorry I didn't provide enough info about the "goal" in my previous reply:

The goal of this series is to provide a new TDX global metadata infrastructure
to:

1) address two issues in the current TDX module initialization code, and
2) have an extendable infrastructure which is super easy to read more metadata
and share with KVM for KVM TDX support (and other kernel components for TDX
Connect in the future).

And the reason that we need a new global metadata infrastructure is the current
one can only read TDMR related metadata fields and it is not extendable to read
more metadata fields, which is required to address both 1) and 2) above.

Specifically, below two issues in the current module initialization code need to
be addressed:

1) Module initialization may fail on some large systems (e.g., with 4 or more
sockets).
2) Some old modules can clobber host's RBP when existing from the TDX guest, and
currently they can be initialized successfully.  We don't want to use such
modules thus we should just fail to initialize them to avoid memory/cpu cycle
cost of initializing TDX module.

The minimal code to achieve this goal is to remove the code which prints TDX
module version and CMR info in this series.  After removing them, the fist 6
patches in this series introduce the new metadata infrastructure, and the rest
patches address the two above issues.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: tdx_global_metadata.py --]
[-- Type: text/x-python3; name="tdx_global_metadata.py", Size: 6151 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 = {
    "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"
    ],
}

STRUCT_PREFIX = "tdx_sys_info"
FUNC_PREFIX = "get_tdx_sys_info"
STRVAR_PREFIX = "sysinfo"

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 = "%s_%s" % (STRUCT_PREFIX, 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 = "%s_%s" % (FUNC_PREFIX, class_name)
    struct_name = "%s_%s" % (STRUCT_PREFIX, class_name)
    struct_var = "%s_%s" % (STRVAR_PREFIX, 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 = "%s_%s->num_cmrs" %(STRVAR_PREFIX, "cmr")
            elif fname == "CPUID_CONFIG_LEAVES" or fname == "CPUID_CONFIG_VALUES":
                limit = "%s_%s->num_cpuid_config" %(STRVAR_PREFIX, "td_conf")
            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 = "%s_%s" % (STRUCT_PREFIX, 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 = "%s_%s" % (FUNC_PREFIX, 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)

      reply	other threads:[~2024-11-13 11:26 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-11-11 10:39 [PATCH v7 00/10] TDX host: metadata reading tweaks, bug fix and info dump Kai Huang
2024-11-11 10:39 ` [PATCH v7 01/10] x86/virt/tdx: Rename 'struct tdx_tdmr_sysinfo' to reflect the spec better Kai Huang
2024-11-11 10:39 ` [PATCH v7 02/10] x86/virt/tdx: Start to track all global metadata in one structure Kai Huang
2024-11-11 10:39 ` [PATCH v7 03/10] x86/virt/tdx: Use auto-generated code to read global metadata Kai Huang
2024-11-11 10:39 ` [PATCH v7 04/10] x86/virt/tdx: Use dedicated struct members for PAMT entry sizes Kai Huang
2024-11-11 10:39 ` [PATCH v7 05/10] x86/virt/tdx: Add missing header file inclusion to local tdx.h Kai Huang
2024-11-11 10:39 ` [PATCH v7 06/10] x86/virt/tdx: Switch to use auto-generated global metadata reading code Kai Huang
2024-11-11 10:39 ` [PATCH v7 07/10] x86/virt/tdx: Trim away tail null CMRs Kai Huang
2024-11-11 16:32   ` Nikolay Borisov
2024-11-11 19:30     ` Huang, Kai
2024-11-11 19:41   ` Dave Hansen
2024-11-11 20:22     ` Huang, Kai
2024-11-11 10:39 ` [PATCH v7 08/10] x86/virt/tdx: Reduce TDMR's reserved areas by using CMRs to find memory holes Kai Huang
2024-11-11 10:39 ` [PATCH v7 09/10] x86/virt/tdx: Require the module to assert it has the NO_RBP_MOD mitigation Kai Huang
2024-11-11 10:39 ` [PATCH v7 10/10] x86/virt/tdx: Print TDX module version Kai Huang
2024-11-11 20:33 ` [PATCH v7 00/10] TDX host: metadata reading tweaks, bug fix and info dump Dave Hansen
2024-11-11 20:49   ` Huang, Kai
2024-11-11 21:00     ` Dave Hansen
2024-11-11 21:28       ` Huang, Kai
2024-11-13 11:26         ` 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=d5aed06ae4b46df5db97fdbac9c01843920a2f96.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