Commit a584539b authored by Paolo Bonzini's avatar Paolo Bonzini

KVM: x86: pass the whole hflags field to emulator and back

The hflags field will contain information about system management mode
and will be useful for the emulator.  Pass the entire field rather than
just the guest-mode information.
Reviewed-by: default avatarRadim Krčmář <rkrcmar@redhat.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 609e36d3
...@@ -262,6 +262,9 @@ enum x86emul_mode { ...@@ -262,6 +262,9 @@ enum x86emul_mode {
X86EMUL_MODE_PROT64, /* 64-bit (long) 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 */
struct x86_emulate_ctxt { struct x86_emulate_ctxt {
const struct x86_emulate_ops *ops; const struct x86_emulate_ops *ops;
...@@ -273,8 +276,8 @@ struct x86_emulate_ctxt { ...@@ -273,8 +276,8 @@ struct x86_emulate_ctxt {
/* interruptibility state, as a result of execution of STI or MOV SS */ /* interruptibility state, as a result of execution of STI or MOV SS */
int interruptibility; int interruptibility;
int emul_flags;
bool guest_mode; /* guest running a nested guest */
bool perm_ok; /* do not check permissions if true */ bool perm_ok; /* do not check permissions if true */
bool ud; /* inject an #UD if host doesn't support insn */ bool ud; /* inject an #UD if host doesn't support insn */
......
...@@ -4895,7 +4895,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) ...@@ -4895,7 +4895,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
fetch_possible_mmx_operand(ctxt, &ctxt->dst); fetch_possible_mmx_operand(ctxt, &ctxt->dst);
} }
if (unlikely(ctxt->guest_mode) && (ctxt->d & Intercept)) { if (unlikely(ctxt->emul_flags & X86EMUL_GUEST_MASK) && ctxt->intercept) {
rc = emulator_check_intercept(ctxt, ctxt->intercept, rc = emulator_check_intercept(ctxt, ctxt->intercept,
X86_ICPT_PRE_EXCEPT); X86_ICPT_PRE_EXCEPT);
if (rc != X86EMUL_CONTINUE) if (rc != X86EMUL_CONTINUE)
...@@ -4924,7 +4924,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) ...@@ -4924,7 +4924,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
goto done; goto done;
} }
if (unlikely(ctxt->guest_mode) && (ctxt->d & Intercept)) { if (unlikely(ctxt->emul_flags & X86EMUL_GUEST_MASK) && (ctxt->d & Intercept)) {
rc = emulator_check_intercept(ctxt, ctxt->intercept, rc = emulator_check_intercept(ctxt, ctxt->intercept,
X86_ICPT_POST_EXCEPT); X86_ICPT_POST_EXCEPT);
if (rc != X86EMUL_CONTINUE) if (rc != X86EMUL_CONTINUE)
...@@ -4978,7 +4978,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) ...@@ -4978,7 +4978,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
special_insn: special_insn:
if (unlikely(ctxt->guest_mode) && (ctxt->d & Intercept)) { if (unlikely(ctxt->emul_flags & X86EMUL_GUEST_MASK) && (ctxt->d & Intercept)) {
rc = emulator_check_intercept(ctxt, ctxt->intercept, rc = emulator_check_intercept(ctxt, ctxt->intercept,
X86_ICPT_POST_MEMACCESS); X86_ICPT_POST_MEMACCESS);
if (rc != X86EMUL_CONTINUE) if (rc != X86EMUL_CONTINUE)
......
...@@ -5240,7 +5240,8 @@ static void init_emulate_ctxt(struct kvm_vcpu *vcpu) ...@@ -5240,7 +5240,8 @@ static void init_emulate_ctxt(struct kvm_vcpu *vcpu)
(cs_l && is_long_mode(vcpu)) ? X86EMUL_MODE_PROT64 : (cs_l && is_long_mode(vcpu)) ? X86EMUL_MODE_PROT64 :
cs_db ? X86EMUL_MODE_PROT32 : cs_db ? X86EMUL_MODE_PROT32 :
X86EMUL_MODE_PROT16; X86EMUL_MODE_PROT16;
ctxt->guest_mode = is_guest_mode(vcpu); BUILD_BUG_ON(HF_GUEST_MASK != X86EMUL_GUEST_MASK);
ctxt->emul_flags = vcpu->arch.hflags;
init_decode_cache(ctxt); init_decode_cache(ctxt);
vcpu->arch.emulate_regs_need_sync_from_vcpu = false; vcpu->arch.emulate_regs_need_sync_from_vcpu = false;
...@@ -5409,6 +5410,11 @@ static bool retry_instruction(struct x86_emulate_ctxt *ctxt, ...@@ -5409,6 +5410,11 @@ static bool retry_instruction(struct x86_emulate_ctxt *ctxt,
static int complete_emulated_mmio(struct kvm_vcpu *vcpu); static int complete_emulated_mmio(struct kvm_vcpu *vcpu);
static int complete_emulated_pio(struct kvm_vcpu *vcpu); static int complete_emulated_pio(struct kvm_vcpu *vcpu);
void kvm_set_hflags(struct kvm_vcpu *vcpu, unsigned emul_flags)
{
vcpu->arch.hflags = emul_flags;
}
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)
{ {
...@@ -5608,6 +5614,8 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, ...@@ -5608,6 +5614,8 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu,
unsigned long rflags = kvm_x86_ops->get_rflags(vcpu); unsigned long rflags = kvm_x86_ops->get_rflags(vcpu);
toggle_interruptibility(vcpu, ctxt->interruptibility); toggle_interruptibility(vcpu, ctxt->interruptibility);
vcpu->arch.emulate_regs_need_sync_to_vcpu = false; vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
if (vcpu->arch.hflags != ctxt->emul_flags)
kvm_set_hflags(vcpu, ctxt->emul_flags);
kvm_rip_write(vcpu, ctxt->eip); kvm_rip_write(vcpu, ctxt->eip);
if (r == EMULATE_DONE) if (r == EMULATE_DONE)
kvm_vcpu_check_singlestep(vcpu, rflags, &r); kvm_vcpu_check_singlestep(vcpu, rflags, &r);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment