diff mbox series

[v4,2/5] KVM: x86: Move CPUID.(EAX=0x12,ECX=1) mangling to __kvm_update_cpuid_runtime()

Message ID 20220121132852.2482355-3-vkuznets@redhat.com (mailing list archive)
State New, archived
Headers show
Series KVM: x86: Partially allow KVM_SET_CPUID{,2} after KVM_RUN for CPU hotplug | expand

Commit Message

Vitaly Kuznetsov Jan. 21, 2022, 1:28 p.m. UTC
To support comparing CPUID data update with what's already set for a vCPU
all mangling needs to happen in __kvm_update_cpuid_runtime(), before
'vcpu->arch.cpuid_entries' is updated. CPUID.(EAX=0x12,ECX=1) is currently
being mangled in kvm_vcpu_after_set_cpuid(), move it to
__kvm_update_cpuid_runtime(). Split off cpuid_get_supported_xcr0() helper
as 'vcpu->arch.guest_supported_xcr0' update needs (logically) to stay in
kvm_vcpu_after_set_cpuid().

No functional change intended.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 arch/x86/kvm/cpuid.c | 54 +++++++++++++++++++++++++++-----------------
 1 file changed, 33 insertions(+), 21 deletions(-)

Comments

Paolo Bonzini Jan. 21, 2022, 6:13 p.m. UTC | #1
On 1/21/22 14:28, Vitaly Kuznetsov wrote:
> To support comparing CPUID data update with what's already set for a vCPU
> all mangling needs to happen in __kvm_update_cpuid_runtime(), before
> 'vcpu->arch.cpuid_entries' is updated. CPUID.(EAX=0x12,ECX=1) is currently
> being mangled in kvm_vcpu_after_set_cpuid(), move it to
> __kvm_update_cpuid_runtime(). Split off cpuid_get_supported_xcr0() helper
> as 'vcpu->arch.guest_supported_xcr0' update needs (logically) to stay in
> kvm_vcpu_after_set_cpuid().
> 
> No functional change intended.

Since v3 is already on its way to Linus, I'll merge this patch next week.

Paolo
Vitaly Kuznetsov Jan. 22, 2022, 8:17 a.m. UTC | #2
Paolo Bonzini <pbonzini@redhat.com> writes:

> On 1/21/22 14:28, Vitaly Kuznetsov wrote:
>> To support comparing CPUID data update with what's already set for a vCPU
>> all mangling needs to happen in __kvm_update_cpuid_runtime(), before
>> 'vcpu->arch.cpuid_entries' is updated. CPUID.(EAX=0x12,ECX=1) is currently
>> being mangled in kvm_vcpu_after_set_cpuid(), move it to
>> __kvm_update_cpuid_runtime(). Split off cpuid_get_supported_xcr0() helper
>> as 'vcpu->arch.guest_supported_xcr0' update needs (logically) to stay in
>> kvm_vcpu_after_set_cpuid().
>> 
>> No functional change intended.
>
> Since v3 is already on its way to Linus, I'll merge this patch next week.
>

Thanks,

there is also a change in "[PATCH v4 3/5] KVM: x86: Partially allow
KVM_SET_CPUID{,2} after KVM_RUN" where I switch to memcmp (as suggested
by Sean). I can send an incremental patch if needed.
Paolo Bonzini Jan. 24, 2022, 9:45 a.m. UTC | #3
On 1/22/22 09:17, Vitaly Kuznetsov wrote:
> Thanks,
> 
> there is also a change in "[PATCH v4 3/5] KVM: x86: Partially allow
> KVM_SET_CPUID{,2} after KVM_RUN" where I switch to memcmp (as suggested
> by Sean). I can send an incremental patch if needed.

Sure, thanks!

Paolo
diff mbox series

Patch

diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 812190a707f6..7c48daee6670 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -174,10 +174,26 @@  void kvm_update_pv_runtime(struct kvm_vcpu *vcpu)
 		vcpu->arch.pv_cpuid.features = best->eax;
 }
 
+/*
+ * Calculate guest's supported XCR0 taking into account guest CPUID data and
+ * supported_xcr0 (comprised of host configuration and KVM_SUPPORTED_XCR0).
+ */
+static u64 cpuid_get_supported_xcr0(struct kvm_cpuid_entry2 *entries, int nent)
+{
+	struct kvm_cpuid_entry2 *best;
+
+	best = cpuid_entry2_find(entries, nent, 0xd, 0);
+	if (!best)
+		return 0;
+
+	return (best->eax | ((u64)best->edx << 32)) & supported_xcr0;
+}
+
 static void __kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry2 *entries,
 				       int nent)
 {
 	struct kvm_cpuid_entry2 *best;
+	u64 guest_supported_xcr0 = cpuid_get_supported_xcr0(entries, nent);
 
 	best = cpuid_entry2_find(entries, nent, 1, 0);
 	if (best) {
@@ -216,6 +232,21 @@  static void __kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu, struct kvm_cpuid_e
 					   vcpu->arch.ia32_misc_enable_msr &
 					   MSR_IA32_MISC_ENABLE_MWAIT);
 	}
+
+	/*
+	 * Bits 127:0 of the allowed SECS.ATTRIBUTES (CPUID.0x12.0x1) enumerate
+	 * the supported XSAVE Feature Request Mask (XFRM), i.e. the enclave's
+	 * requested XCR0 value.  The enclave's XFRM must be a subset of XCRO
+	 * at the time of EENTER, thus adjust the allowed XFRM by the guest's
+	 * supported XCR0.  Similar to XCR0 handling, FP and SSE are forced to
+	 * '1' even on CPUs that don't support XSAVE.
+	 */
+	best = cpuid_entry2_find(entries, nent, 0x12, 0x1);
+	if (best) {
+		best->ecx &= guest_supported_xcr0 & 0xffffffff;
+		best->edx &= guest_supported_xcr0 >> 32;
+		best->ecx |= XFEATURE_MASK_FPSSE;
+	}
 }
 
 void kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu)
@@ -239,27 +270,8 @@  static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
 		kvm_apic_set_version(vcpu);
 	}
 
-	best = kvm_find_cpuid_entry(vcpu, 0xD, 0);
-	if (!best)
-		vcpu->arch.guest_supported_xcr0 = 0;
-	else
-		vcpu->arch.guest_supported_xcr0 =
-			(best->eax | ((u64)best->edx << 32)) & supported_xcr0;
-
-	/*
-	 * Bits 127:0 of the allowed SECS.ATTRIBUTES (CPUID.0x12.0x1) enumerate
-	 * the supported XSAVE Feature Request Mask (XFRM), i.e. the enclave's
-	 * requested XCR0 value.  The enclave's XFRM must be a subset of XCRO
-	 * at the time of EENTER, thus adjust the allowed XFRM by the guest's
-	 * supported XCR0.  Similar to XCR0 handling, FP and SSE are forced to
-	 * '1' even on CPUs that don't support XSAVE.
-	 */
-	best = kvm_find_cpuid_entry(vcpu, 0x12, 0x1);
-	if (best) {
-		best->ecx &= vcpu->arch.guest_supported_xcr0 & 0xffffffff;
-		best->edx &= vcpu->arch.guest_supported_xcr0 >> 32;
-		best->ecx |= XFEATURE_MASK_FPSSE;
-	}
+	vcpu->arch.guest_supported_xcr0 =
+		cpuid_get_supported_xcr0(vcpu->arch.cpuid_entries, vcpu->arch.cpuid_nent);
 
 	kvm_update_pv_runtime(vcpu);