Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 95cb2295 authored by Gleb Natapov's avatar Gleb Natapov Committed by Avi Kivity
Browse files

KVM: x86 emulator: move interruptibility state tracking out of emulator



Emulator shouldn't access vcpu directly.

Signed-off-by: default avatarGleb Natapov <gleb@redhat.com>
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent 4d2179e1
Loading
Loading
Loading
Loading
+2 −17
Original line number Diff line number Diff line
@@ -1843,20 +1843,6 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt,
	return X86EMUL_CONTINUE;
}

static 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;
}

static inline void
setup_syscalls_segments(struct x86_emulate_ctxt *ctxt,
			struct x86_emulate_ops *ops, struct desc_struct *cs,
@@ -2516,7 +2502,6 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
	int rc = X86EMUL_CONTINUE;
	int saved_dst_type = c->dst.type;

	ctxt->interruptibility = 0;
	ctxt->decode.mem_read.pos = 0;

	if (ctxt->mode == X86EMUL_MODE_PROT64 && (c->d & No64)) {
@@ -2789,7 +2774,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
		}

		if (c->modrm_reg == VCPU_SREG_SS)
			toggle_interruptibility(ctxt, KVM_X86_SHADOW_INT_MOV_SS);
			ctxt->interruptibility = KVM_X86_SHADOW_INT_MOV_SS;

		rc = load_segment_descriptor(ctxt, ops, sel, c->modrm_reg);

@@ -2958,7 +2943,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
		if (emulator_bad_iopl(ctxt, ops))
			kvm_inject_gp(ctxt->vcpu, 0);
		else {
			toggle_interruptibility(ctxt, KVM_X86_SHADOW_INT_STI);
			ctxt->interruptibility = KVM_X86_SHADOW_INT_STI;
			ctxt->eflags |= X86_EFLAGS_IF;
			c->dst.type = OP_NONE;	/* Disable writeback. */
		}
+17 −3
Original line number Diff line number Diff line
@@ -3838,12 +3838,26 @@ static void cache_all_regs(struct kvm_vcpu *vcpu)
	vcpu->arch.regs_dirty = ~0;
}

static void toggle_interruptibility(struct kvm_vcpu *vcpu, u32 mask)
{
	u32 int_shadow = kvm_x86_ops->get_interrupt_shadow(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))
		kvm_x86_ops->set_interrupt_shadow(vcpu, mask);
}

int emulate_instruction(struct kvm_vcpu *vcpu,
			unsigned long cr2,
			u16 error_code,
			int emulation_type)
{
	int r, shadow_mask;
	int r;
	struct decode_cache *c = &vcpu->arch.emulate_ctxt.decode;

	kvm_clear_exception_queue(vcpu);
@@ -3871,6 +3885,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
			? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
		memset(c, 0, sizeof(struct decode_cache));
		memcpy(c->regs, vcpu->arch.regs, sizeof c->regs);
		vcpu->arch.emulate_ctxt.interruptibility = 0;

		r = x86_decode_insn(&vcpu->arch.emulate_ctxt, &emulate_ops);
		trace_kvm_emulate_insn_start(vcpu);
@@ -3938,8 +3953,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
		return EMULATE_FAIL;
	}

	shadow_mask = vcpu->arch.emulate_ctxt.interruptibility;
	kvm_x86_ops->set_interrupt_shadow(vcpu, shadow_mask);
	toggle_interruptibility(vcpu, vcpu->arch.emulate_ctxt.interruptibility);
	kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags);
	memcpy(vcpu->arch.regs, c->regs, sizeof c->regs);
	kvm_rip_write(vcpu, vcpu->arch.emulate_ctxt.eip);