mirror of https://gitee.com/openkylin/linux.git
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:
parent
ed19321fb6
commit
c5833c7a43
|
@ -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);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue