Commit c5833c7a authored by Sean Christopherson's avatar Sean Christopherson Committed by Paolo Bonzini
Browse files

KVM: x86: Open code kvm_set_hflags



Prepare for clearing HF_SMM_MASK prior to loading state from the SMRAM
save state map, i.e. kvm_smm_changed() needs to be called after state
has been loaded and so cannot be done automatically when setting
hflags from RSM.

Signed-off-by: default avatarSean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent ed19321f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -228,6 +228,7 @@ struct x86_emulate_ops {
	void (*set_hflags)(struct x86_emulate_ctxt *ctxt, unsigned hflags);
	int (*pre_leave_smm)(struct x86_emulate_ctxt *ctxt,
			     const char *smstate);
	void (*post_leave_smm)(struct x86_emulate_ctxt *ctxt);

};

+3 −0
Original line number Diff line number Diff line
@@ -2629,6 +2629,9 @@ static int em_rsm(struct x86_emulate_ctxt *ctxt)

	ctxt->ops->set_hflags(ctxt, ctxt->ops->get_hflags(ctxt) &
		~(X86EMUL_SMM_INSIDE_NMI_MASK | X86EMUL_SMM_MASK));

	ctxt->ops->post_leave_smm(ctxt);

	return X86EMUL_CONTINUE;
}

+15 −18
Original line number Diff line number Diff line
@@ -3530,7 +3530,7 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu,
	memset(&events->reserved, 0, sizeof(events->reserved));
}

static void kvm_set_hflags(struct kvm_vcpu *vcpu, unsigned emul_flags);
static void kvm_smm_changed(struct kvm_vcpu *vcpu);

static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
					      struct kvm_vcpu_events *events)
@@ -3590,12 +3590,13 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
		vcpu->arch.apic->sipi_vector = events->sipi_vector;

	if (events->flags & KVM_VCPUEVENT_VALID_SMM) {
		u32 hflags = vcpu->arch.hflags;
		if (!!(vcpu->arch.hflags & HF_SMM_MASK) != events->smi.smm) {
			if (events->smi.smm)
			hflags |= HF_SMM_MASK;
				vcpu->arch.hflags |= HF_SMM_MASK;
			else
			hflags &= ~HF_SMM_MASK;
		kvm_set_hflags(vcpu, hflags);
				vcpu->arch.hflags &= ~HF_SMM_MASK;
			kvm_smm_changed(vcpu);
		}

		vcpu->arch.smi_pending = events->smi.pending;

@@ -5960,7 +5961,7 @@ static unsigned emulator_get_hflags(struct x86_emulate_ctxt *ctxt)

static void emulator_set_hflags(struct x86_emulate_ctxt *ctxt, unsigned emul_flags)
{
	kvm_set_hflags(emul_to_vcpu(ctxt), emul_flags);
	emul_to_vcpu(ctxt)->arch.hflags = emul_flags;
}

static int emulator_pre_leave_smm(struct x86_emulate_ctxt *ctxt,
@@ -5969,6 +5970,11 @@ static int emulator_pre_leave_smm(struct x86_emulate_ctxt *ctxt,
	return kvm_x86_ops->pre_leave_smm(emul_to_vcpu(ctxt), smstate);
}

static void emulator_post_leave_smm(struct x86_emulate_ctxt *ctxt)
{
	kvm_smm_changed(emul_to_vcpu(ctxt));
}

static const struct x86_emulate_ops emulate_ops = {
	.read_gpr            = emulator_read_gpr,
	.write_gpr           = emulator_write_gpr,
@@ -6009,6 +6015,7 @@ static const struct x86_emulate_ops emulate_ops = {
	.get_hflags          = emulator_get_hflags,
	.set_hflags          = emulator_set_hflags,
	.pre_leave_smm       = emulator_pre_leave_smm,
	.post_leave_smm      = emulator_post_leave_smm,
};

static void toggle_interruptibility(struct kvm_vcpu *vcpu, u32 mask)
@@ -6250,16 +6257,6 @@ static void kvm_smm_changed(struct kvm_vcpu *vcpu)
	kvm_mmu_reset_context(vcpu);
}

static void kvm_set_hflags(struct kvm_vcpu *vcpu, unsigned emul_flags)
{
	unsigned changed = vcpu->arch.hflags ^ emul_flags;

	vcpu->arch.hflags = emul_flags;

	if (changed & HF_SMM_MASK)
		kvm_smm_changed(vcpu);
}

static int kvm_vcpu_check_hw_bp(unsigned long addr, u32 type, u32 dr7,
				unsigned long *db)
{