Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 146584
b: refs/heads/master
c: 310b5d3
h: refs/heads/master
v: v3
  • Loading branch information
Glauber Costa authored and Avi Kivity committed Jun 10, 2009
1 parent 6c14cca commit be2e5e6
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2809f5d2c4cfad171167b131bb2a21ab65eba40f
refs/heads/master: 310b5d306c1aee7ebe32f702c0e33e7988d50646
3 changes: 3 additions & 0 deletions trunk/arch/x86/include/asm/kvm_x86_emulate.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,9 @@ struct x86_emulate_ctxt {
int mode;
u32 cs_base;

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

/* decode cache */
struct decode_cache decode;
};
Expand Down
6 changes: 5 additions & 1 deletion trunk/arch/x86/kvm/x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -2379,7 +2379,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
u16 error_code,
int emulation_type)
{
int r;
int r, shadow_mask;
struct decode_cache *c;

kvm_clear_exception_queue(vcpu);
Expand Down Expand Up @@ -2433,6 +2433,10 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
}

r = x86_emulate_insn(&vcpu->arch.emulate_ctxt, &emulate_ops);
shadow_mask = vcpu->arch.emulate_ctxt.interruptibility;

if (r == 0)
kvm_x86_ops->set_interrupt_shadow(vcpu, shadow_mask);

if (vcpu->arch.pio.string)
return EMULATE_DO_MMIO;
Expand Down
20 changes: 20 additions & 0 deletions trunk/arch/x86/kvm/x86_emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -1361,6 +1361,20 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt,
return 0;
}

void toggle_interruptibility(struct x86_emulate_ctxt *ctxt, u32 mask)
{
u32 int_shadow = kvm_x86_ops->get_interrupt_shadow(ctxt->vcpu, mask);
/*
* an sti; sti; sequence only disable interrupts for the first
* instruction. So, if the last instruction, be it emulated or
* not, left the system with the INT_STI flag enabled, it
* means that the last instruction is an sti. We should not
* leave the flag on in this case. The same goes for mov ss
*/
if (!(int_shadow & mask))
ctxt->interruptibility = mask;
}

int
x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
{
Expand All @@ -1372,6 +1386,8 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
int io_dir_in;
int rc = 0;

ctxt->interruptibility = 0;

/* Shadow copy of register state. Committed on successful emulation.
* NOTE: we can copy them from vcpu as x86_decode_insn() doesn't
* modify them.
Expand Down Expand Up @@ -1618,6 +1634,9 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
int err;

sel = c->src.val;
if (c->modrm_reg == VCPU_SREG_SS)
toggle_interruptibility(ctxt, X86_SHADOW_INT_MOV_SS);

if (c->modrm_reg <= 5) {
type_bits = (c->modrm_reg == 1) ? 9 : 1;
err = kvm_load_segment_descriptor(ctxt->vcpu, sel,
Expand Down Expand Up @@ -1847,6 +1866,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
c->dst.type = OP_NONE; /* Disable writeback. */
break;
case 0xfb: /* sti */
toggle_interruptibility(ctxt, X86_SHADOW_INT_STI);
ctxt->eflags |= X86_EFLAGS_IF;
c->dst.type = OP_NONE; /* Disable writeback. */
break;
Expand Down

0 comments on commit be2e5e6

Please sign in to comment.