KVM: x86: Use emulator callbacks instead of duplicating "host flags"
authorMaxim Levitsky <mlevitsk@redhat.com>
Tue, 29 Nov 2022 19:37:11 +0000 (21:37 +0200)
committerSean Christopherson <seanjc@google.com>
Wed, 1 Feb 2023 01:29:09 +0000 (17:29 -0800)
Instead of re-defining the "host flags" bits, just expose dedicated
helpers for each of the two remaining flags that are consumed by the
emulator.  The emulator never consumes both "is guest" and "is SMM" in
close proximity, so there is no motivation to avoid additional indirect
branches.

Also while at it, garbage collect the recently removed host flags.

No functional change is intended.

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
Tested-by: Santosh Shukla <Santosh.Shukla@amd.com>
Link: https://lore.kernel.org/r/20221129193717.513824-6-mlevitsk@redhat.com
[sean: fix CONFIG_KVM_SMM=n builds, tweak names of wrappers]
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/include/asm/kvm_host.h
arch/x86/kvm/emulate.c
arch/x86/kvm/kvm_emulate.h
arch/x86/kvm/smm.c
arch/x86/kvm/x86.c

index e653b0b7ff775564e598a8c6e62ab2758b93b8d0..3b0436b1f93cef58fa3d5a47b0d896d527086457 100644 (file)
@@ -2074,11 +2074,11 @@ enum {
        TASK_SWITCH_GATE = 3,
 };
 
-#define HF_GUEST_MASK          (1 << 5) /* VCPU is in guest-mode */
+#define HF_GUEST_MASK          (1 << 0) /* VCPU is in guest-mode */
 
 #ifdef CONFIG_KVM_SMM
-#define HF_SMM_MASK            (1 << 6)
-#define HF_SMM_INSIDE_NMI_MASK (1 << 7)
+#define HF_SMM_MASK            (1 << 1)
+#define HF_SMM_INSIDE_NMI_MASK (1 << 2)
 
 # define __KVM_VCPU_MULTIPLE_ADDRESS_SPACE
 # define KVM_ADDRESS_SPACE_NUM 2
index c3443045cd930992d821411e00038de8a16bb18d..5f7d9082c835ab03cbe0de17ffd6bb7984325bed 100644 (file)
@@ -2310,7 +2310,7 @@ static int em_lseg(struct x86_emulate_ctxt *ctxt)
 
 static int em_rsm(struct x86_emulate_ctxt *ctxt)
 {
-       if ((ctxt->ops->get_hflags(ctxt) & X86EMUL_SMM_MASK) == 0)
+       if (!ctxt->ops->is_smm(ctxt))
                return emulate_ud(ctxt);
 
        if (ctxt->ops->leave_smm(ctxt))
@@ -5133,7 +5133,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
        const struct x86_emulate_ops *ops = ctxt->ops;
        int rc = X86EMUL_CONTINUE;
        int saved_dst_type = ctxt->dst.type;
-       unsigned emul_flags;
+       bool is_guest_mode = ctxt->ops->is_guest_mode(ctxt);
 
        ctxt->mem_read.pos = 0;
 
@@ -5148,7 +5148,6 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
                goto done;
        }
 
-       emul_flags = ctxt->ops->get_hflags(ctxt);
        if (unlikely(ctxt->d &
                     (No64|Undefined|Sse|Mmx|Intercept|CheckPerm|Priv|Prot|String))) {
                if ((ctxt->mode == X86EMUL_MODE_PROT64 && (ctxt->d & No64)) ||
@@ -5182,7 +5181,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
                                fetch_possible_mmx_operand(&ctxt->dst);
                }
 
-               if (unlikely(emul_flags & X86EMUL_GUEST_MASK) && ctxt->intercept) {
+               if (unlikely(is_guest_mode) && ctxt->intercept) {
                        rc = emulator_check_intercept(ctxt, ctxt->intercept,
                                                      X86_ICPT_PRE_EXCEPT);
                        if (rc != X86EMUL_CONTINUE)
@@ -5211,7 +5210,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
                                goto done;
                }
 
-               if (unlikely(emul_flags & X86EMUL_GUEST_MASK) && (ctxt->d & Intercept)) {
+               if (unlikely(is_guest_mode) && (ctxt->d & Intercept)) {
                        rc = emulator_check_intercept(ctxt, ctxt->intercept,
                                                      X86_ICPT_POST_EXCEPT);
                        if (rc != X86EMUL_CONTINUE)
@@ -5265,7 +5264,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
 
 special_insn:
 
-       if (unlikely(emul_flags & X86EMUL_GUEST_MASK) && (ctxt->d & Intercept)) {
+       if (unlikely(is_guest_mode) && (ctxt->d & Intercept)) {
                rc = emulator_check_intercept(ctxt, ctxt->intercept,
                                              X86_ICPT_POST_MEMACCESS);
                if (rc != X86EMUL_CONTINUE)
index 2d9662be8333781c8851cd779869b680bd39b1b1..ab65f3a47dfde5bbdde5dd0b3ed25c3a08006ab0 100644 (file)
@@ -220,7 +220,8 @@ struct x86_emulate_ops {
 
        void (*set_nmi_mask)(struct x86_emulate_ctxt *ctxt, bool masked);
 
-       unsigned (*get_hflags)(struct x86_emulate_ctxt *ctxt);
+       bool (*is_smm)(struct x86_emulate_ctxt *ctxt);
+       bool (*is_guest_mode)(struct x86_emulate_ctxt *ctxt);
        int (*leave_smm)(struct x86_emulate_ctxt *ctxt);
        void (*triple_fault)(struct x86_emulate_ctxt *ctxt);
        int (*set_xcr)(struct x86_emulate_ctxt *ctxt, u32 index, u64 xcr);
@@ -275,10 +276,6 @@ enum x86emul_mode {
        X86EMUL_MODE_PROT64,    /* 64-bit (long) mode.    */
 };
 
-/* These match some of the HF_* flags defined in kvm_host.h  */
-#define X86EMUL_GUEST_MASK           (1 << 5) /* VCPU is in guest-mode */
-#define X86EMUL_SMM_MASK             (1 << 6)
-
 /*
  * fastop functions are declared as taking a never-defined fastop parameter,
  * so they can't be called from C directly.
index cc43638d48a3aff9e578b46c7c547dd9cb172ce9..b42111a24cc28de2b680b9b495d6f3cb256541ef 100644 (file)
@@ -111,8 +111,6 @@ static void check_smram_offsets(void)
 
 void kvm_smm_changed(struct kvm_vcpu *vcpu, bool entering_smm)
 {
-       BUILD_BUG_ON(HF_SMM_MASK != X86EMUL_SMM_MASK);
-
        trace_kvm_smm_transition(vcpu->vcpu_id, vcpu->arch.smbase, entering_smm);
 
        if (entering_smm) {
index 508074e47bc0ebd4535de4bc548f57abdffe863d..cf9e3d213c837c53e05344613eb21383143db17d 100644 (file)
@@ -8150,9 +8150,14 @@ static void emulator_set_nmi_mask(struct x86_emulate_ctxt *ctxt, bool masked)
        static_call(kvm_x86_set_nmi_mask)(emul_to_vcpu(ctxt), masked);
 }
 
-static unsigned emulator_get_hflags(struct x86_emulate_ctxt *ctxt)
+static bool emulator_is_smm(struct x86_emulate_ctxt *ctxt)
 {
-       return emul_to_vcpu(ctxt)->arch.hflags;
+       return is_smm(emul_to_vcpu(ctxt));
+}
+
+static bool emulator_is_guest_mode(struct x86_emulate_ctxt *ctxt)
+{
+       return is_guest_mode(emul_to_vcpu(ctxt));
 }
 
 #ifndef CONFIG_KVM_SMM
@@ -8221,7 +8226,8 @@ static const struct x86_emulate_ops emulate_ops = {
        .guest_has_fxsr      = emulator_guest_has_fxsr,
        .guest_has_rdpid     = emulator_guest_has_rdpid,
        .set_nmi_mask        = emulator_set_nmi_mask,
-       .get_hflags          = emulator_get_hflags,
+       .is_smm              = emulator_is_smm,
+       .is_guest_mode       = emulator_is_guest_mode,
        .leave_smm           = emulator_leave_smm,
        .triple_fault        = emulator_triple_fault,
        .set_xcr             = emulator_set_xcr,
@@ -8293,8 +8299,6 @@ static void init_emulate_ctxt(struct kvm_vcpu *vcpu)
                     (cs_l && is_long_mode(vcpu))       ? X86EMUL_MODE_PROT64 :
                     cs_db                              ? X86EMUL_MODE_PROT32 :
                                                          X86EMUL_MODE_PROT16;
-       BUILD_BUG_ON(HF_GUEST_MASK != X86EMUL_GUEST_MASK);
-
        ctxt->interruptibility = 0;
        ctxt->have_exception = false;
        ctxt->exception.vector = -1;