Message ID | b96a789edc879dc2a902c9c31a675e08f1796a00.1659854790.git.isaku.yamahata@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | KVM TDX basic feature support | expand |
On Sun, Aug 07, 2022 at 03:01:04PM -0700, isaku.yamahata@intel.com wrote: > From: Isaku Yamahata <isaku.yamahata@intel.com> > > TDX private host key id is assigned to guest TD. The memory controller > encrypts guest TD memory with the assigned TDX private host key id (HIKD). > Add helper functions to allocate/free TDX private host key id so that TDX > KVM manage it. > > Also export the global TDX private host key id that is used to encrypt TDX > module, its memory and some dynamic data (TDR). When VMM releasing > encrypted page to reuse it, the page needs to be flushed with the used host > key id. VMM needs the global TDX private host key id to flush such pages > TDX module accesses with the global TDX private host key id. > > Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com> > --- > arch/x86/include/asm/tdx.h | 12 ++++++++++++ > arch/x86/virt/vmx/tdx/tdx.c | 28 +++++++++++++++++++++++++++- > 2 files changed, 39 insertions(+), 1 deletion(-) > > diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h > index c887618e3cec..a32e8881e758 100644 > --- a/arch/x86/include/asm/tdx.h > +++ b/arch/x86/include/asm/tdx.h > @@ -144,6 +144,16 @@ struct tdsysinfo_struct { > bool platform_tdx_enabled(void); > int tdx_init(void); > const struct tdsysinfo_struct *tdx_get_sysinfo(void); > +/* > + * Key id globally used by TDX module: TDX module maps TDR with this TDX global > + * key id. TDR includes key id assigned to the TD. Then TDX module maps other > + * TD-related pages with the assigned key id. TDR requires this TDX global key > + * id for cache flush unlike other TD-related pages. > + */ > +extern u32 tdx_global_keyid __read_mostly; > +int tdx_keyid_alloc(void); > +void tdx_keyid_free(int keyid); > + > u64 __seamcall(u64 op, u64 rcx, u64 rdx, u64 r8, u64 r9, > struct tdx_module_output *out); > #else /* !CONFIG_INTEL_TDX_HOST */ > @@ -151,6 +161,8 @@ static inline bool platform_tdx_enabled(void) { return false; } > static inline int tdx_init(void) { return -ENODEV; } > struct tdsysinfo_struct; > static inline const struct tdsysinfo_struct *tdx_get_sysinfo(void) { return NULL; } > +static inline int tdx_keyid_alloc(void) { return -EOPNOTSUPP; } > +static inline void tdx_keyid_free(int keyid) { } > #endif /* CONFIG_INTEL_TDX_HOST */ > > #endif /* !__ASSEMBLY__ */ > diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c > index 918e79159bbf..2168e6133d45 100644 > --- a/arch/x86/virt/vmx/tdx/tdx.c > +++ b/arch/x86/virt/vmx/tdx/tdx.c > @@ -56,7 +56,8 @@ static struct cmr_info tdx_cmr_array[MAX_CMRS] __aligned(CMR_INFO_ARRAY_ALIGNMEN > static int tdx_cmr_num; > > /* TDX module global KeyID. Used in TDH.SYS.CONFIG ABI. */ > -static u32 tdx_global_keyid; > +u32 tdx_global_keyid __read_mostly; > +EXPORT_SYMBOL_GPL(tdx_global_keyid); > > /* Detect whether CPU supports SEAM */ > static int detect_seam(void) > @@ -80,6 +81,31 @@ static int detect_seam(void) > return 0; > } > > +/* TDX KeyID pool */ > +static DEFINE_IDA(tdx_keyid_pool); > + > +int tdx_keyid_alloc(void) > +{ > + if (WARN_ON_ONCE(!tdx_keyid_start || !tdx_keyid_num)) > + return -EINVAL; > + > + /* The first keyID is reserved for the global key. */ > + return ida_alloc_range(&tdx_keyid_pool, tdx_keyid_start + 1, > + tdx_keyid_start + tdx_keyid_num - 1, > + GFP_KERNEL); > +} > +EXPORT_SYMBOL_GPL(tdx_keyid_alloc); > + > +void tdx_keyid_free(int keyid) > +{ > + /* keyid = 0 is reserved. */ > + if (!keyid || keyid <= 0) keyid <=0 covers !keyid. > + return; > + > + ida_free(&tdx_keyid_pool, keyid); > +} > +EXPORT_SYMBOL_GPL(tdx_keyid_free); > + > static int detect_tdx_keyids(void) > { > u64 keyid_part; > -- > 2.25.1 >
diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h index c887618e3cec..a32e8881e758 100644 --- a/arch/x86/include/asm/tdx.h +++ b/arch/x86/include/asm/tdx.h @@ -144,6 +144,16 @@ struct tdsysinfo_struct { bool platform_tdx_enabled(void); int tdx_init(void); const struct tdsysinfo_struct *tdx_get_sysinfo(void); +/* + * Key id globally used by TDX module: TDX module maps TDR with this TDX global + * key id. TDR includes key id assigned to the TD. Then TDX module maps other + * TD-related pages with the assigned key id. TDR requires this TDX global key + * id for cache flush unlike other TD-related pages. + */ +extern u32 tdx_global_keyid __read_mostly; +int tdx_keyid_alloc(void); +void tdx_keyid_free(int keyid); + u64 __seamcall(u64 op, u64 rcx, u64 rdx, u64 r8, u64 r9, struct tdx_module_output *out); #else /* !CONFIG_INTEL_TDX_HOST */ @@ -151,6 +161,8 @@ static inline bool platform_tdx_enabled(void) { return false; } static inline int tdx_init(void) { return -ENODEV; } struct tdsysinfo_struct; static inline const struct tdsysinfo_struct *tdx_get_sysinfo(void) { return NULL; } +static inline int tdx_keyid_alloc(void) { return -EOPNOTSUPP; } +static inline void tdx_keyid_free(int keyid) { } #endif /* CONFIG_INTEL_TDX_HOST */ #endif /* !__ASSEMBLY__ */ diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 918e79159bbf..2168e6133d45 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -56,7 +56,8 @@ static struct cmr_info tdx_cmr_array[MAX_CMRS] __aligned(CMR_INFO_ARRAY_ALIGNMEN static int tdx_cmr_num; /* TDX module global KeyID. Used in TDH.SYS.CONFIG ABI. */ -static u32 tdx_global_keyid; +u32 tdx_global_keyid __read_mostly; +EXPORT_SYMBOL_GPL(tdx_global_keyid); /* Detect whether CPU supports SEAM */ static int detect_seam(void) @@ -80,6 +81,31 @@ static int detect_seam(void) return 0; } +/* TDX KeyID pool */ +static DEFINE_IDA(tdx_keyid_pool); + +int tdx_keyid_alloc(void) +{ + if (WARN_ON_ONCE(!tdx_keyid_start || !tdx_keyid_num)) + return -EINVAL; + + /* The first keyID is reserved for the global key. */ + return ida_alloc_range(&tdx_keyid_pool, tdx_keyid_start + 1, + tdx_keyid_start + tdx_keyid_num - 1, + GFP_KERNEL); +} +EXPORT_SYMBOL_GPL(tdx_keyid_alloc); + +void tdx_keyid_free(int keyid) +{ + /* keyid = 0 is reserved. */ + if (!keyid || keyid <= 0) + return; + + ida_free(&tdx_keyid_pool, keyid); +} +EXPORT_SYMBOL_GPL(tdx_keyid_free); + static int detect_tdx_keyids(void) { u64 keyid_part;