KVM: x86: Add dedicated emulator helpers for querying CPUID features
authorSean Christopherson <sean.j.christopherson@intel.com>
Tue, 17 Dec 2019 21:32:38 +0000 (13:32 -0800)
committerPaolo Bonzini <pbonzini@redhat.com>
Tue, 21 Jan 2020 12:58:22 +0000 (13:58 +0100)
Add feature-specific helpers for querying guest CPUID support from the
emulator instead of having the emulator do a full CPUID and perform its
own bit tests.  The primary motivation is to eliminate the emulator's
usage of bit() so that future patches can add more extensive build-time
assertions on the usage of bit() without having to expose yet more code
to the emulator.

Note, providing a generic guest_cpuid_has() to the emulator doesn't work
due to the existing built-time assertions in guest_cpuid_has(), which
require the feature being checked to be a compile-time constant.

No functional change intended.

Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/include/asm/kvm_emulate.h
arch/x86/kvm/emulate.c
arch/x86/kvm/x86.c

index 77cf6c11f66bd86341ef58f5503d68b24e3b6833..03946eb3e2b9e5162c6f20fff85bf1747ad8431a 100644 (file)
@@ -222,6 +222,10 @@ struct x86_emulate_ops {
 
        bool (*get_cpuid)(struct x86_emulate_ctxt *ctxt, u32 *eax, u32 *ebx,
                          u32 *ecx, u32 *edx, bool check_limit);
+       bool (*guest_has_long_mode)(struct x86_emulate_ctxt *ctxt);
+       bool (*guest_has_movbe)(struct x86_emulate_ctxt *ctxt);
+       bool (*guest_has_fxsr)(struct x86_emulate_ctxt *ctxt);
+
        void (*set_nmi_mask)(struct x86_emulate_ctxt *ctxt, bool masked);
 
        unsigned (*get_hflags)(struct x86_emulate_ctxt *ctxt);
index 952d1a4f4d7ef731174b26b8fc268f848956b129..e9833e345a5c5ab5474e728a1dcb0f52f7e0e659 100644 (file)
@@ -2348,12 +2348,7 @@ static int em_lseg(struct x86_emulate_ctxt *ctxt)
 static int emulator_has_longmode(struct x86_emulate_ctxt *ctxt)
 {
 #ifdef CONFIG_X86_64
-       u32 eax, ebx, ecx, edx;
-
-       eax = 0x80000001;
-       ecx = 0;
-       ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, false);
-       return edx & bit(X86_FEATURE_LM);
+       return ctxt->ops->guest_has_long_mode(ctxt);
 #else
        return false;
 #endif
@@ -3618,18 +3613,11 @@ static int em_mov(struct x86_emulate_ctxt *ctxt)
        return X86EMUL_CONTINUE;
 }
 
-#define FFL(x) bit(X86_FEATURE_##x)
-
 static int em_movbe(struct x86_emulate_ctxt *ctxt)
 {
-       u32 ebx, ecx, edx, eax = 1;
        u16 tmp;
 
-       /*
-        * Check MOVBE is set in the guest-visible CPUID leaf.
-        */
-       ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, false);
-       if (!(ecx & FFL(MOVBE)))
+       if (!ctxt->ops->guest_has_movbe(ctxt))
                return emulate_ud(ctxt);
 
        switch (ctxt->op_bytes) {
@@ -4027,10 +4015,7 @@ static int em_movsxd(struct x86_emulate_ctxt *ctxt)
 
 static int check_fxsr(struct x86_emulate_ctxt *ctxt)
 {
-       u32 eax = 1, ebx, ecx = 0, edx;
-
-       ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, false);
-       if (!(edx & FFL(FXSR)))
+       if (!ctxt->ops->guest_has_fxsr(ctxt))
                return emulate_ud(ctxt);
 
        if (ctxt->ops->get_cr(ctxt, 0) & (X86_CR0_TS | X86_CR0_EM))
index 456fc131c95efc3b28d92e9f8a32e38f004e9921..60b0d69af0f17430fdf193b9035037b6f90fe605 100644 (file)
@@ -6245,6 +6245,21 @@ static bool emulator_get_cpuid(struct x86_emulate_ctxt *ctxt,
        return kvm_cpuid(emul_to_vcpu(ctxt), eax, ebx, ecx, edx, check_limit);
 }
 
+static bool emulator_guest_has_long_mode(struct x86_emulate_ctxt *ctxt)
+{
+       return guest_cpuid_has(emul_to_vcpu(ctxt), X86_FEATURE_LM);
+}
+
+static bool emulator_guest_has_movbe(struct x86_emulate_ctxt *ctxt)
+{
+       return guest_cpuid_has(emul_to_vcpu(ctxt), X86_FEATURE_MOVBE);
+}
+
+static bool emulator_guest_has_fxsr(struct x86_emulate_ctxt *ctxt)
+{
+       return guest_cpuid_has(emul_to_vcpu(ctxt), X86_FEATURE_FXSR);
+}
+
 static ulong emulator_read_gpr(struct x86_emulate_ctxt *ctxt, unsigned reg)
 {
        return kvm_register_read(emul_to_vcpu(ctxt), reg);
@@ -6322,6 +6337,9 @@ static const struct x86_emulate_ops emulate_ops = {
        .fix_hypercall       = emulator_fix_hypercall,
        .intercept           = emulator_intercept,
        .get_cpuid           = emulator_get_cpuid,
+       .guest_has_long_mode = emulator_guest_has_long_mode,
+       .guest_has_movbe     = emulator_guest_has_movbe,
+       .guest_has_fxsr      = emulator_guest_has_fxsr,
        .set_nmi_mask        = emulator_set_nmi_mask,
        .get_hflags          = emulator_get_hflags,
        .set_hflags          = emulator_set_hflags,