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

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

KVM: Fix interrupt unhalting a vcpu when it shouldn't



kvm_vcpu_block() unhalts vpu on an interrupt/timer without checking
if interrupt window is actually opened.

Signed-off-by: default avatarGleb Natapov <gleb@redhat.com>
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent 09cec754
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -1963,6 +1963,12 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu)
	return 0;
}

int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu)
{
	/* do real check here */
	return 1;
}

int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
{
	return vcpu->arch.timer_fired;
+6 −0
Original line number Diff line number Diff line
@@ -41,6 +41,12 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
	return !!(v->arch.pending_exceptions);
}

int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu)
{
	/* do real check here */
	return 1;
}

int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
{
	return !(v->arch.msr & MSR_WE);
+6 −0
Original line number Diff line number Diff line
@@ -318,6 +318,12 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu)
	return rc;
}

int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu)
{
	/* do real check here */
	return 1;
}

int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
{
	return 0;
+1 −1
Original line number Diff line number Diff line
@@ -521,7 +521,7 @@ struct kvm_x86_ops {
	void (*inject_pending_irq)(struct kvm_vcpu *vcpu);
	void (*inject_pending_vectors)(struct kvm_vcpu *vcpu,
				       struct kvm_run *run);

	int (*interrupt_allowed)(struct kvm_vcpu *vcpu);
	int (*set_tss_addr)(struct kvm *kvm, unsigned int addr);
	int (*get_tdp_level)(void);
	int (*get_mt_mask_shift)(void);
+10 −0
Original line number Diff line number Diff line
@@ -2270,6 +2270,15 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu)
		vmcb->control.intercept_cr_write |= INTERCEPT_CR8_MASK;
}

static int svm_interrupt_allowed(struct kvm_vcpu *vcpu)
{
	struct vcpu_svm *svm = to_svm(vcpu);
	struct vmcb *vmcb = svm->vmcb;
	return (vmcb->save.rflags & X86_EFLAGS_IF) &&
		!(vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) &&
		(svm->vcpu.arch.hflags & HF_GIF_MASK);
}

static void svm_intr_assist(struct kvm_vcpu *vcpu)
{
	struct vcpu_svm *svm = to_svm(vcpu);
@@ -2649,6 +2658,7 @@ static struct kvm_x86_ops svm_x86_ops = {
	.exception_injected = svm_exception_injected,
	.inject_pending_irq = svm_intr_assist,
	.inject_pending_vectors = do_interrupt_requests,
	.interrupt_allowed = svm_interrupt_allowed,

	.set_tss_addr = svm_set_tss_addr,
	.get_tdp_level = get_npt_level,
Loading