On Mon, Jan 22, 2024 at 03:52:56PM -0800, isaku.yamahata@xxxxxxxxx wrote: > From: Isaku Yamahata <isaku.yamahata@xxxxxxxxx> > > TDX KVM needs system-wide information about the TDX module, store it in > struct tdx_info. > > TODO: Once TDX host patch series introduces a framework to read TDX meta > data, convert the code to it. > > Signed-off-by: Isaku Yamahata <isaku.yamahata@xxxxxxxxx> > --- > Change v18: > - Newly Added > --- > arch/x86/include/uapi/asm/kvm.h | 11 +++++ > arch/x86/kvm/vmx/main.c | 9 +++- > arch/x86/kvm/vmx/tdx.c | 79 ++++++++++++++++++++++++++++++++- > arch/x86/kvm/vmx/x86_ops.h | 2 + > 4 files changed, 99 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h > index aa7a56a47564..45b2c2304491 100644 > --- a/arch/x86/include/uapi/asm/kvm.h > +++ b/arch/x86/include/uapi/asm/kvm.h > @@ -567,4 +567,15 @@ struct kvm_pmu_event_filter { > #define KVM_X86_TDX_VM 2 > #define KVM_X86_SNP_VM 3 > > +#define KVM_TDX_CPUID_NO_SUBLEAF ((__u32)-1) > + > +struct kvm_tdx_cpuid_config { > + __u32 leaf; > + __u32 sub_leaf; > + __u32 eax; > + __u32 ebx; > + __u32 ecx; > + __u32 edx; > +}; > + > #endif /* _ASM_X86_KVM_H */ > diff --git a/arch/x86/kvm/vmx/main.c b/arch/x86/kvm/vmx/main.c > index 62236bde3779..f181620b2922 100644 > --- a/arch/x86/kvm/vmx/main.c > +++ b/arch/x86/kvm/vmx/main.c > @@ -47,6 +47,13 @@ static __init int vt_hardware_setup(void) > return 0; > } > > +static void vt_hardware_unsetup(void) > +{ > + if (enable_tdx) > + tdx_hardware_unsetup(); > + vmx_hardware_unsetup(); > +} > + > static int vt_vm_init(struct kvm *kvm) > { > if (is_td(kvm)) > @@ -69,7 +76,7 @@ struct kvm_x86_ops vt_x86_ops __initdata = { > > .check_processor_compatibility = vmx_check_processor_compat, > > - .hardware_unsetup = vmx_hardware_unsetup, > + .hardware_unsetup = vt_hardware_unsetup, > > .hardware_enable = vt_hardware_enable, > .hardware_disable = vmx_hardware_disable, > diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c > index 1608bdf2381d..55399136b680 100644 > --- a/arch/x86/kvm/vmx/tdx.c > +++ b/arch/x86/kvm/vmx/tdx.c > @@ -67,7 +67,7 @@ static size_t tdx_md_element_size(u64 fid) > } > } > > -int tdx_md_read(struct tdx_md_map *maps, int nr_maps) > +static int tdx_md_read(struct tdx_md_map *maps, int nr_maps) > { > struct tdx_md_map *m; > int ret, i; > @@ -85,9 +85,39 @@ int tdx_md_read(struct tdx_md_map *maps, int nr_maps) > return 0; > } > > +struct tdx_info { > + u64 attributes_fixed0; > + u64 attributes_fixed1; > + u64 xfam_fixed0; > + u64 xfam_fixed1; > + > + u16 num_cpuid_config; > + /* This must the last member. */ > + DECLARE_FLEX_ARRAY(struct kvm_tdx_cpuid_config, cpuid_configs); > +}; > + > +/* Info about the TDX module. */ > +static struct tdx_info *tdx_info; > + > static int __init tdx_module_setup(void) > { > + u16 num_cpuid_config; > int ret; > + u32 i; > + > + struct tdx_md_map mds[] = { > + TDX_MD_MAP(NUM_CPUID_CONFIG, &num_cpuid_config), > + }; > + > +#define TDX_INFO_MAP(_field_id, _member) \ > + TD_SYSINFO_MAP(_field_id, struct tdx_info, _member) > + > + struct tdx_metadata_field_mapping tdx_info_md[] = { > + TDX_INFO_MAP(ATTRS_FIXED0, attributes_fixed0), > + TDX_INFO_MAP(ATTRS_FIXED1, attributes_fixed1), > + TDX_INFO_MAP(XFAM_FIXED0, xfam_fixed0), > + TDX_INFO_MAP(XFAM_FIXED1, xfam_fixed1), > + }; > > ret = tdx_enable(); > if (ret) { > @@ -95,7 +125,49 @@ static int __init tdx_module_setup(void) > return ret; > } > > + ret = tdx_md_read(mds, ARRAY_SIZE(mds)); > + if (ret) > + return ret; > + > + tdx_info = kzalloc(sizeof(*tdx_info) + > + sizeof(*tdx_info->cpuid_configs) * num_cpuid_config, > + GFP_KERNEL); > + if (!tdx_info) > + return -ENOMEM; > + tdx_info->num_cpuid_config = num_cpuid_config; > + > + ret = tdx_sys_metadata_read(tdx_info_md, ARRAY_SIZE(tdx_info_md), tdx_info); > + if (ret) > + return ret; "goto error_sys_rd" as below to free the tdx_info ? > + > + for (i = 0; i < num_cpuid_config; i++) { > + struct kvm_tdx_cpuid_config *c = &tdx_info->cpuid_configs[i]; > + u64 leaf, eax_ebx, ecx_edx; > + struct tdx_md_map cpuids[] = { > + TDX_MD_MAP(CPUID_CONFIG_LEAVES + i, &leaf), > + TDX_MD_MAP(CPUID_CONFIG_VALUES + i * 2, &eax_ebx), > + TDX_MD_MAP(CPUID_CONFIG_VALUES + i * 2 + 1, &ecx_edx), > + }; > + > + ret = tdx_md_read(cpuids, ARRAY_SIZE(cpuids)); > + if (ret) > + goto error_sys_rd; > + > + c->leaf = (u32)leaf; > + c->sub_leaf = leaf >> 32; > + c->eax = (u32)eax_ebx; > + c->ebx = eax_ebx >> 32; > + c->ecx = (u32)ecx_edx; > + c->edx = ecx_edx >> 32; > + } > + > return 0; > + > +error_sys_rd: > + ret = -EIO; > + /* kfree() accepts NULL. */ > + kfree(tdx_info); > + return ret; > } > > bool tdx_is_vm_type_supported(unsigned long type) > @@ -163,3 +235,8 @@ int __init tdx_hardware_setup(struct kvm_x86_ops *x86_ops) > out: > return r; > } > + > +void tdx_hardware_unsetup(void) > +{ > + kfree(tdx_info); > +} > diff --git a/arch/x86/kvm/vmx/x86_ops.h b/arch/x86/kvm/vmx/x86_ops.h > index 5da7a5fd91cb..9523087ae355 100644 > --- a/arch/x86/kvm/vmx/x86_ops.h > +++ b/arch/x86/kvm/vmx/x86_ops.h > @@ -136,9 +136,11 @@ void vmx_setup_mce(struct kvm_vcpu *vcpu); > > #ifdef CONFIG_INTEL_TDX_HOST > int __init tdx_hardware_setup(struct kvm_x86_ops *x86_ops); > +void tdx_hardware_unsetup(void); > bool tdx_is_vm_type_supported(unsigned long type); > #else > static inline int tdx_hardware_setup(struct kvm_x86_ops *x86_ops) { return -EOPNOTSUPP; } > +static inline void tdx_hardware_unsetup(void) {} > static inline bool tdx_is_vm_type_supported(unsigned long type) { return false; } > #endif > > -- > 2.25.1 > >