Message ID | 20240812224820.34826-23-rick.p.edgecombe@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | TDX vCPU/VM creation | expand |
On 8/13/24 00:48, Rick Edgecombe wrote: > @@ -576,6 +575,9 @@ static int setup_tdparams_cpuids(struct kvm_cpuid2 *cpuid, > value->ebx = entry->ebx; > value->ecx = entry->ecx; > value->edx = entry->edx; > + > + if (c->leaf == 0x80000008) > + value->eax &= 0xff00ffff; > } > > return 0; Ah, this answers my question in 21/25. It definitely needs a comment though! Also to explain what will future support in the TDX module look like (a new feature bit I guess). Paolo
On 8/13/2024 6:48 AM, Rick Edgecombe wrote: > From: Xiaoyao Li <xiaoyao.li@intel.com> > > KVM reports guest physical address in CPUID.0x800000008.EAX[23:16], > which is similar to TDX's GPAW. Use this field as the interface for > userspace to configure the GPAW and EPT level for TDs. > > Note, > > 1. only value 48 and 52 are supported. 52 means GPAW-52 and EPT level > 5, and 48 means GPAW-48 and EPT level 4. > 2. value 48, i.e., GPAW-48 is always supported. value 52 is only > supported when the platform supports 5 level EPT. > > Current TDX module doesn't support max_gpa configuration. However > current implementation relies on max_gpa to configure EPT level and > GPAW. Hack KVM to make it work. This patch needs to be squashed into patch 14. > Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com> > Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com> > --- > uAPI breakout v1: > - New patch > --- > arch/x86/kvm/vmx/tdx.c | 32 +++++++++++++++++++------------- > 1 file changed, 19 insertions(+), 13 deletions(-) > > diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c > index fe2bbc2ced41..c6bfeb0b3cc9 100644 > --- a/arch/x86/kvm/vmx/tdx.c > +++ b/arch/x86/kvm/vmx/tdx.c > @@ -514,23 +514,22 @@ static int setup_tdparams_eptp_controls(struct kvm_cpuid2 *cpuid, > struct td_params *td_params) > { > const struct kvm_cpuid_entry2 *entry; > - int max_pa = 36; > + int guest_pa; > > entry = kvm_find_cpuid_entry2(cpuid->entries, cpuid->nent, 0x80000008, 0); > - if (entry) > - max_pa = entry->eax & 0xff; > + if (!entry) > + return -EINVAL; > + > + guest_pa = (entry->eax >> 16) & 0xff; > + > + if (guest_pa != 48 && guest_pa != 52) > + return -EINVAL; > + > + if (guest_pa == 52 && !cpu_has_vmx_ept_5levels()) > + return -EINVAL; > > td_params->eptp_controls = VMX_EPTP_MT_WB; > - /* > - * No CPU supports 4-level && max_pa > 48. > - * "5-level paging and 5-level EPT" section 4.1 4-level EPT > - * "4-level EPT is limited to translating 48-bit guest-physical > - * addresses." > - * cpu_has_vmx_ept_5levels() check is just in case. > - */ > - if (!cpu_has_vmx_ept_5levels() && max_pa > 48) > - return -EINVAL; > - if (cpu_has_vmx_ept_5levels() && max_pa > 48) { > + if (guest_pa == 52) { > td_params->eptp_controls |= VMX_EPTP_PWL_5; > td_params->exec_controls |= TDX_EXEC_CONTROL_MAX_GPAW; > } else { > @@ -576,6 +575,9 @@ static int setup_tdparams_cpuids(struct kvm_cpuid2 *cpuid, > value->ebx = entry->ebx; > value->ecx = entry->ecx; > value->edx = entry->edx; > + > + if (c->leaf == 0x80000008) > + value->eax &= 0xff00ffff; > } > > return 0; > @@ -1277,6 +1279,10 @@ static int __init setup_kvm_tdx_caps(void) > memcpy(dest, &source, sizeof(struct kvm_tdx_cpuid_config)); > if (dest->sub_leaf == KVM_TDX_CPUID_NO_SUBLEAF) > dest->sub_leaf = 0; > + > + /* Work around missing support on old TDX modules */ > + if (dest->leaf == 0x80000008) > + dest->eax |= 0x00ff0000; > } > > return 0;
On Thu, Oct 10, 2024 at 05:13:43PM +0800, Xiaoyao Li wrote: > On 8/13/2024 6:48 AM, Rick Edgecombe wrote: > > From: Xiaoyao Li <xiaoyao.li@intel.com> > > > > KVM reports guest physical address in CPUID.0x800000008.EAX[23:16], > > which is similar to TDX's GPAW. Use this field as the interface for > > userspace to configure the GPAW and EPT level for TDs. > > > > Note, > > > > 1. only value 48 and 52 are supported. 52 means GPAW-52 and EPT level > > 5, and 48 means GPAW-48 and EPT level 4. > > 2. value 48, i.e., GPAW-48 is always supported. value 52 is only > > supported when the platform supports 5 level EPT. > > > > Current TDX module doesn't support max_gpa configuration. However > > current implementation relies on max_gpa to configure EPT level and > > GPAW. Hack KVM to make it work. > > This patch needs to be squashed into patch 14. Yes agreed that makes sense. Regards, Tony
diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c index fe2bbc2ced41..c6bfeb0b3cc9 100644 --- a/arch/x86/kvm/vmx/tdx.c +++ b/arch/x86/kvm/vmx/tdx.c @@ -514,23 +514,22 @@ static int setup_tdparams_eptp_controls(struct kvm_cpuid2 *cpuid, struct td_params *td_params) { const struct kvm_cpuid_entry2 *entry; - int max_pa = 36; + int guest_pa; entry = kvm_find_cpuid_entry2(cpuid->entries, cpuid->nent, 0x80000008, 0); - if (entry) - max_pa = entry->eax & 0xff; + if (!entry) + return -EINVAL; + + guest_pa = (entry->eax >> 16) & 0xff; + + if (guest_pa != 48 && guest_pa != 52) + return -EINVAL; + + if (guest_pa == 52 && !cpu_has_vmx_ept_5levels()) + return -EINVAL; td_params->eptp_controls = VMX_EPTP_MT_WB; - /* - * No CPU supports 4-level && max_pa > 48. - * "5-level paging and 5-level EPT" section 4.1 4-level EPT - * "4-level EPT is limited to translating 48-bit guest-physical - * addresses." - * cpu_has_vmx_ept_5levels() check is just in case. - */ - if (!cpu_has_vmx_ept_5levels() && max_pa > 48) - return -EINVAL; - if (cpu_has_vmx_ept_5levels() && max_pa > 48) { + if (guest_pa == 52) { td_params->eptp_controls |= VMX_EPTP_PWL_5; td_params->exec_controls |= TDX_EXEC_CONTROL_MAX_GPAW; } else { @@ -576,6 +575,9 @@ static int setup_tdparams_cpuids(struct kvm_cpuid2 *cpuid, value->ebx = entry->ebx; value->ecx = entry->ecx; value->edx = entry->edx; + + if (c->leaf == 0x80000008) + value->eax &= 0xff00ffff; } return 0; @@ -1277,6 +1279,10 @@ static int __init setup_kvm_tdx_caps(void) memcpy(dest, &source, sizeof(struct kvm_tdx_cpuid_config)); if (dest->sub_leaf == KVM_TDX_CPUID_NO_SUBLEAF) dest->sub_leaf = 0; + + /* Work around missing support on old TDX modules */ + if (dest->leaf == 0x80000008) + dest->eax |= 0x00ff0000; } return 0;