Skip to content

Commit

Permalink
KVM: x86: pass the whole hflags field to emulator and back
Browse files Browse the repository at this point in the history
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: Radim Krčmář <rkrcmar@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
Paolo Bonzini committed Jun 4, 2015
1 parent 609e36d commit a584539
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 5 deletions.
5 changes: 4 additions & 1 deletion arch/x86/include/asm/kvm_emulate.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,9 @@ 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 */

struct x86_emulate_ctxt {
const struct x86_emulate_ops *ops;

Expand All @@ -273,8 +276,8 @@ struct x86_emulate_ctxt {

/* interruptibility state, as a result of execution of STI or MOV SS */
int interruptibility;
int emul_flags;

bool guest_mode; /* guest running a nested guest */
bool perm_ok; /* do not check permissions if true */
bool ud; /* inject an #UD if host doesn't support insn */

Expand Down
6 changes: 3 additions & 3 deletions arch/x86/kvm/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -4895,7 +4895,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
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,
X86_ICPT_PRE_EXCEPT);
if (rc != X86EMUL_CONTINUE)
Expand Down Expand Up @@ -4924,7 +4924,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
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,
X86_ICPT_POST_EXCEPT);
if (rc != X86EMUL_CONTINUE)
Expand Down Expand Up @@ -4978,7 +4978,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)

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,
X86_ICPT_POST_MEMACCESS);
if (rc != X86EMUL_CONTINUE)
Expand Down
10 changes: 9 additions & 1 deletion arch/x86/kvm/x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -5240,7 +5240,8 @@ 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;
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);
vcpu->arch.emulate_regs_need_sync_from_vcpu = false;
Expand Down Expand Up @@ -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_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,
unsigned long *db)
{
Expand Down Expand Up @@ -5608,6 +5614,8 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu,
unsigned long rflags = kvm_x86_ops->get_rflags(vcpu);
toggle_interruptibility(vcpu, ctxt->interruptibility);
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);
if (r == EMULATE_DONE)
kvm_vcpu_check_singlestep(vcpu, rflags, &r);
Expand Down

0 comments on commit a584539

Please sign in to comment.