On Sun, Mar 13, 2022 at 11:49:57PM +1300, Kai Huang <kai.huang@xxxxxxxxx> wrote: > diff --git a/arch/x86/virt/vmx/tdx.c b/arch/x86/virt/vmx/tdx.c > index e03dc3e420db..39b1b7d0417d 100644 > --- a/arch/x86/virt/vmx/tdx.c > +++ b/arch/x86/virt/vmx/tdx.c > @@ -23,6 +23,7 @@ > #include <asm/virtext.h> > #include <asm/e820/api.h> > #include <asm/pgtable.h> > +#include <asm/smp.h> > #include <asm/tdx.h> > #include "tdx.h" > > @@ -398,6 +399,47 @@ static int seamcall_on_each_cpu(struct seamcall_ctx *sc) > return atomic_read(&sc->err); > } > > +/* > + * Call the SEAMCALL on one (any) cpu for each physical package in > + * serialized way. Note for serialized calls 'seamcall_ctx::err' > + * doesn't have to be atomic, but for simplicity just reuse it > + * instead of adding a new one. > + * > + * Return -ENXIO if IPI SEAMCALL wasn't run on any cpu, or -EFAULT > + * when SEAMCALL fails, or -EPERM when the cpu where SEAMCALL runs > + * on is not in VMX operation. In case of -EFAULT, the error code > + * of SEAMCALL is in 'struct seamcall_ctx::seamcall_ret'. > + */ > +static int seamcall_on_each_package_serialized(struct seamcall_ctx *sc) > +{ > + cpumask_var_t packages; > + int cpu, ret; > + > + if (!zalloc_cpumask_var(&packages, GFP_KERNEL)) > + return -ENOMEM; Memory leak. This should be freed before returning. > + for_each_online_cpu(cpu) { > + if (cpumask_test_and_set_cpu(topology_physical_package_id(cpu), > + packages)) > + continue; > + > + ret = smp_call_function_single(cpu, seamcall_smp_call_function, > + sc, true); > + if (ret) > + return ret; > + > + /* > + * Doesn't have to use atomic_read(), but it doesn't > + * hurt either. > + */ > + ret = atomic_read(&sc->err); > + if (ret) > + return ret; > + } > + > + return 0; > +} > + > static inline bool p_seamldr_ready(void) > { > return !!p_seamldr_info.p_seamldr_ready; > @@ -1316,6 +1358,18 @@ static int config_tdx_module(struct tdmr_info **tdmr_array, int tdmr_num, > return ret; > } > > +static int config_global_keyid(u64 global_keyid) global_keyid argument isn't used. Is global variable tdx_global_keyid used? > +{ > + struct seamcall_ctx sc = { .fn = TDH_SYS_KEY_CONFIG }; > + > + /* > + * TDH.SYS.KEY.CONFIG may fail with entropy error (which is > + * a recoverable error). Assume this is exceedingly rare and > + * just return error if encountered instead of retrying. > + */ > + return seamcall_on_each_package_serialized(&sc); > +} > + -- Isaku Yamahata <isaku.yamahata@xxxxxxxxx>