Commit 32e69f23 authored by Maxim Levitsky's avatar Maxim Levitsky Committed by Sean Christopherson
Browse files

KVM: x86: Use emulator callbacks instead of duplicating "host flags"



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: default avatarMaxim Levitsky <mlevitsk@redhat.com>
Tested-by: default avatarSantosh 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: default avatarSean Christopherson <seanjc@google.com>
parent 916b54a7
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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
+5 −6
Original line number Diff line number Diff line
@@ -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)
+2 −5
Original line number Diff line number Diff line
@@ -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.
+0 −2
Original line number Diff line number Diff line
@@ -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) {
+9 −5
Original line number Diff line number Diff line
@@ -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;