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: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Sean Christopherson 2019-04-02 08:03:10 -07:00 committed by Paolo Bonzini
parent ed19321fb6
commit c5833c7a43
3 changed files with 19 additions and 18 deletions

View File

@ -228,6 +228,7 @@ struct x86_emulate_ops {
void (*set_hflags)(struct x86_emulate_ctxt *ctxt, unsigned hflags); void (*set_hflags)(struct x86_emulate_ctxt *ctxt, unsigned hflags);
int (*pre_leave_smm)(struct x86_emulate_ctxt *ctxt, int (*pre_leave_smm)(struct x86_emulate_ctxt *ctxt,
const char *smstate); const char *smstate);
void (*post_leave_smm)(struct x86_emulate_ctxt *ctxt);
}; };

View File

@ -2629,6 +2629,9 @@ static int em_rsm(struct x86_emulate_ctxt *ctxt)
ctxt->ops->set_hflags(ctxt, ctxt->ops->get_hflags(ctxt) & ctxt->ops->set_hflags(ctxt, ctxt->ops->get_hflags(ctxt) &
~(X86EMUL_SMM_INSIDE_NMI_MASK | X86EMUL_SMM_MASK)); ~(X86EMUL_SMM_INSIDE_NMI_MASK | X86EMUL_SMM_MASK));
ctxt->ops->post_leave_smm(ctxt);
return X86EMUL_CONTINUE; return X86EMUL_CONTINUE;
} }

View File

@ -3530,7 +3530,7 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu,
memset(&events->reserved, 0, sizeof(events->reserved)); 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, static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
struct kvm_vcpu_events *events) 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; vcpu->arch.apic->sipi_vector = events->sipi_vector;
if (events->flags & KVM_VCPUEVENT_VALID_SMM) { 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) if (events->smi.smm)
hflags |= HF_SMM_MASK; vcpu->arch.hflags |= HF_SMM_MASK;
else else
hflags &= ~HF_SMM_MASK; vcpu->arch.hflags &= ~HF_SMM_MASK;
kvm_set_hflags(vcpu, hflags); kvm_smm_changed(vcpu);
}
vcpu->arch.smi_pending = events->smi.pending; 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) 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, 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); 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 = { static const struct x86_emulate_ops emulate_ops = {
.read_gpr = emulator_read_gpr, .read_gpr = emulator_read_gpr,
.write_gpr = emulator_write_gpr, .write_gpr = emulator_write_gpr,
@ -6009,6 +6015,7 @@ static const struct x86_emulate_ops emulate_ops = {
.get_hflags = emulator_get_hflags, .get_hflags = emulator_get_hflags,
.set_hflags = emulator_set_hflags, .set_hflags = emulator_set_hflags,
.pre_leave_smm = emulator_pre_leave_smm, .pre_leave_smm = emulator_pre_leave_smm,
.post_leave_smm = emulator_post_leave_smm,
}; };
static void toggle_interruptibility(struct kvm_vcpu *vcpu, u32 mask) 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); 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, static int kvm_vcpu_check_hw_bp(unsigned long addr, u32 type, u32 dr7,
unsigned long *db) unsigned long *db)
{ {