public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
Cc: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
Subject: [PATCH 7/7] KVM: Ack interrupts only after they have successfully been injected
Date: Tue,  4 Dec 2007 11:44:14 +0200	[thread overview]
Message-ID: <1196761455542-git-send-email-avi@qumranet.com> (raw)
In-Reply-To: <11967614542283-git-send-email-avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>

Instead of acking an interrupt when we *think* the guest is ready for it,
and then juggling it around in subarch-specific registers if it isn't (e.g.
page fault while trying to inject the interrupt), separate the injection and
ack.

Subarh specific code now provides two hooks: ->queue_interrupt() will attempt
to inject the interrupt, and ->interrupt_injected() will check whether this
actually succeeded (upon which common code will ack the interrupt).  This
allows much simpler management of pending interrupts.

Signed-off-by: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
---
 drivers/kvm/svm.c |  113 ++++++++------------------------------------
 drivers/kvm/vmx.c |  137 +++++++++--------------------------------------------
 drivers/kvm/x86.c |   79 ++++++++++++++++++++++---------
 drivers/kvm/x86.h |   11 ++--
 4 files changed, 103 insertions(+), 237 deletions(-)

diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 10146a8..9fb9ee1 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -46,8 +46,6 @@ MODULE_LICENSE("GPL");
 #define SVM_FEATURE_LBRV (1 << 1)
 #define SVM_DEATURE_SVML (1 << 2)
 
-static void kvm_reput_irq(struct vcpu_svm *svm);
-
 static inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu)
 {
 	return container_of(vcpu, struct vcpu_svm, vcpu);
@@ -838,16 +836,6 @@ static int svm_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg)
 	return -EOPNOTSUPP;
 }
 
-static int svm_get_irq(struct kvm_vcpu *vcpu)
-{
-	struct vcpu_svm *svm = to_svm(vcpu);
-	u32 exit_int_info = svm->vmcb->control.exit_int_info;
-
-	if (is_external_interrupt(exit_int_info))
-		return exit_int_info & SVM_EVTINJ_VEC_MASK;
-	return -1;
-}
-
 static void load_host_msrs(struct kvm_vcpu *vcpu)
 {
 #ifdef CONFIG_X86_64
@@ -1245,8 +1233,6 @@ static int handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
 	struct vcpu_svm *svm = to_svm(vcpu);
 	u32 exit_code = svm->vmcb->control.exit_code;
 
-	kvm_reput_irq(svm);
-
 	if (svm->vmcb->control.exit_code == SVM_EXIT_ERR) {
 		kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
 		kvm_run->fail_entry.hardware_entry_failure_reason
@@ -1304,102 +1290,43 @@ static inline void svm_inject_irq(struct vcpu_svm *svm, int irq)
 		((/*control->int_vector >> 4*/ 0xf) << V_INTR_PRIO_SHIFT);
 }
 
-static void svm_set_irq(struct kvm_vcpu *vcpu, int irq)
+static void svm_set_tpr_threshold(struct kvm_vcpu *vcpu)
 {
-	struct vcpu_svm *svm = to_svm(vcpu);
-
-	svm_inject_irq(svm, irq);
 }
 
-static void svm_intr_assist(struct kvm_vcpu *vcpu)
+static bool svm_queue_interrupt(struct kvm_vcpu *vcpu, unsigned vector)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 	struct vmcb *vmcb = svm->vmcb;
-	int intr_vector = -1;
-	struct kvm_pending_irq irq;
-	unsigned tpr_threshold;
-
-	if ((vmcb->control.exit_int_info & SVM_EVTINJ_VALID) &&
-	    ((vmcb->control.exit_int_info & SVM_EVTINJ_TYPE_MASK) == 0)) {
-		intr_vector = vmcb->control.exit_int_info &
-			      SVM_EVTINJ_VEC_MASK;
-		vmcb->control.exit_int_info = 0;
-		svm_inject_irq(svm, intr_vector);
-		return;
-	}
 
 	if (vmcb->control.int_ctl & V_IRQ_MASK)
-		return;
-
-	if (!kvm_cpu_get_interrupt(vcpu, &irq, &tpr_threshold))
-		return;
+		return false;
 
 	if (!(vmcb->save.rflags & X86_EFLAGS_IF) ||
 	    (vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) ||
-	    (vmcb->control.event_inj & SVM_EVTINJ_VALID)) {
+	    vcpu->exception.pending) {
 		/* unable to deliver irq, set pending irq */
 		vmcb->control.intercept |= (1ULL << INTERCEPT_VINTR);
 		svm_inject_irq(svm, 0x0);
-		return;
-	}
-	/* Okay, we can deliver the interrupt: grab it and update PIC state. */
-	irq.ack(vcpu, irq.info);
-	intr_vector = irq.vector;
-	svm_inject_irq(svm, intr_vector);
-	kvm_timer_intr_post(vcpu, intr_vector);
-}
-
-static void kvm_reput_irq(struct vcpu_svm *svm)
-{
-	struct vmcb_control_area *control = &svm->vmcb->control;
-
-	if ((control->int_ctl & V_IRQ_MASK)
-	    && !irqchip_in_kernel(svm->vcpu.kvm)) {
-		control->int_ctl &= ~V_IRQ_MASK;
-		push_irq(&svm->vcpu, control->int_vector);
+		return false;
 	}
-
-	svm->vcpu.interrupt_window_open =
-		!(control->int_state & SVM_INTERRUPT_SHADOW_MASK);
-}
-
-static void svm_do_inject_vector(struct vcpu_svm *svm)
-{
-	struct kvm_vcpu *vcpu = &svm->vcpu;
-	int word_index = __ffs(vcpu->irq_summary);
-	int bit_index = __ffs(vcpu->irq_pending[word_index]);
-	int irq = word_index * BITS_PER_LONG + bit_index;
-
-	clear_bit(bit_index, &vcpu->irq_pending[word_index]);
-	if (!vcpu->irq_pending[word_index])
-		clear_bit(word_index, &vcpu->irq_summary);
-	svm_inject_irq(svm, irq);
+	svm_inject_irq(svm, vector);
+	return true;
 }
 
-static void do_interrupt_requests(struct kvm_vcpu *vcpu,
-				       struct kvm_run *kvm_run)
+static bool svm_interrupt_injected(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 	struct vmcb_control_area *control = &svm->vmcb->control;
+	bool injected;
 
-	svm->vcpu.interrupt_window_open =
-		(!(control->int_state & SVM_INTERRUPT_SHADOW_MASK) &&
-		 (svm->vmcb->save.rflags & X86_EFLAGS_IF));
-
-	if (svm->vcpu.interrupt_window_open && svm->vcpu.irq_summary)
-		/*
-		 * If interrupts enabled, and not blocked by sti or mov ss. Good.
-		 */
-		svm_do_inject_vector(svm);
+	injected = !(control->int_ctl & V_IRQ_MASK)
+		&& !(control->intercept & (1ULL << INTERCEPT_VINTR))
+		&& !(control->exit_int_info & SVM_EXITINTINFO_VALID);
 
-	/*
-	 * Interrupts blocked.  Wait for unblock.
-	 */
-	if (!svm->vcpu.interrupt_window_open &&
-	    (svm->vcpu.irq_summary || kvm_run->request_interrupt_window))
-		control->intercept |= 1ULL << INTERCEPT_VINTR;
-	 else
-		control->intercept &= ~(1ULL << INTERCEPT_VINTR);
+	if (!injected)
+		control->int_ctl &= ~V_IRQ_MASK;
+	return injected;
 }
 
 static int svm_set_tss_addr(struct kvm *kvm, unsigned int addr)
@@ -1586,6 +1513,8 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 	stgi();
 
 	svm->next_rip = 0;
+	svm->vcpu.interrupt_window_open =
+		!(svm->vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK);
 }
 
 static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned long root)
@@ -1676,13 +1605,11 @@ static struct kvm_x86_ops svm_x86_ops = {
 	.handle_exit = handle_exit,
 	.skip_emulated_instruction = skip_emulated_instruction,
 	.patch_hypercall = svm_patch_hypercall,
-	.get_irq = svm_get_irq,
-	.set_irq = svm_set_irq,
 	.queue_exception = svm_queue_exception,
 	.exception_injected = svm_exception_injected,
-	.inject_pending_irq = svm_intr_assist,
-	.inject_pending_vectors = do_interrupt_requests,
-
+	.queue_interrupt = svm_queue_interrupt,
+	.interrupt_injected = svm_interrupt_injected,
+	.set_tpr_threshold = svm_set_tpr_threshold,
 	.set_tss_addr = svm_set_tss_addr,
 };
 
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index b788c6b..c180c04 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -861,21 +861,6 @@ static int set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg)
 	return 0;
 }
 
-static int vmx_get_irq(struct kvm_vcpu *vcpu)
-{
-	struct vcpu_vmx *vmx = to_vmx(vcpu);
-	u32 idtv_info_field;
-
-	idtv_info_field = vmx->idt_vectoring_info;
-	if (idtv_info_field & INTR_INFO_VALID_MASK) {
-		if (is_external_interrupt(idtv_info_field))
-			return idtv_info_field & VECTORING_INFO_VECTOR_MASK;
-		else
-			printk(KERN_DEBUG "pending exception: not handled yet\n");
-	}
-	return -1;
-}
-
 static __init int cpu_has_kvm_support(void)
 {
 	unsigned long ecx = cpuid_ecx(1);
@@ -1732,48 +1717,6 @@ static void vmx_inject_irq(struct kvm_vcpu *vcpu, int irq)
 			irq | INTR_TYPE_EXT_INTR | INTR_INFO_VALID_MASK);
 }
 
-static void kvm_do_inject_irq(struct kvm_vcpu *vcpu)
-{
-	int word_index = __ffs(vcpu->irq_summary);
-	int bit_index = __ffs(vcpu->irq_pending[word_index]);
-	int irq = word_index * BITS_PER_LONG + bit_index;
-
-	clear_bit(bit_index, &vcpu->irq_pending[word_index]);
-	if (!vcpu->irq_pending[word_index])
-		clear_bit(word_index, &vcpu->irq_summary);
-	vmx_inject_irq(vcpu, irq);
-}
-
-
-static void do_interrupt_requests(struct kvm_vcpu *vcpu,
-				       struct kvm_run *kvm_run)
-{
-	u32 cpu_based_vm_exec_control;
-
-	vcpu->interrupt_window_open =
-		((vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_IF) &&
-		 (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0);
-
-	if (vcpu->interrupt_window_open &&
-	    vcpu->irq_summary &&
-	    !(vmcs_read32(VM_ENTRY_INTR_INFO_FIELD) & INTR_INFO_VALID_MASK))
-		/*
-		 * If interrupts enabled, and not blocked by sti or mov ss. Good.
-		 */
-		kvm_do_inject_irq(vcpu);
-
-	cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
-	if (!vcpu->interrupt_window_open &&
-	    (vcpu->irq_summary || kvm_run->request_interrupt_window))
-		/*
-		 * Interrupts blocked.  Wait for unblock.
-		 */
-		cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING;
-	else
-		cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
-	vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
-}
-
 static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr)
 {
 	int ret;
@@ -2218,12 +2161,12 @@ static void vmx_flush_tlb(struct kvm_vcpu *vcpu)
 {
 }
 
-static void update_tpr_threshold(struct kvm_vcpu *vcpu, unsigned tpr_threshold)
+static void update_tpr_threshold(struct kvm_vcpu *vcpu)
 {
 	if (!vm_need_tpr_shadow(vcpu->kvm))
 		return;
 
-	vmcs_write32(TPR_THRESHOLD, tpr_threshold >> 4);
+	vmcs_write32(TPR_THRESHOLD, vcpu->tpr_threshold >> 4);
 }
 
 static void enable_irq_window(struct kvm_vcpu *vcpu)
@@ -2235,65 +2178,30 @@ static void enable_irq_window(struct kvm_vcpu *vcpu)
 	vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
 }
 
-static void vmx_intr_assist(struct kvm_vcpu *vcpu)
+static bool vmx_queue_interrupt(struct kvm_vcpu *vcpu, unsigned vector)
 {
-	struct vcpu_vmx *vmx = to_vmx(vcpu);
-	u32 idtv_info_field, intr_info_field;
-	int has_ext_irq, interrupt_window_open;
-	struct kvm_pending_irq irq;
-	int vector;
-	unsigned tpr_threshold;
-
-	has_ext_irq = kvm_cpu_get_interrupt(vcpu, &irq, &tpr_threshold);
-
-	update_tpr_threshold(vcpu, tpr_threshold);
-
-	intr_info_field = vmcs_read32(VM_ENTRY_INTR_INFO_FIELD);
-	idtv_info_field = vmx->idt_vectoring_info;
-	if (intr_info_field & INTR_INFO_VALID_MASK) {
-		if (idtv_info_field & INTR_INFO_VALID_MASK) {
-			/* TODO: fault when IDT_Vectoring */
-			printk(KERN_ERR "Fault when IDT_Vectoring\n");
-		}
-		if (has_ext_irq)
-			enable_irq_window(vcpu);
-		return;
-	}
-	if (unlikely(idtv_info_field & INTR_INFO_VALID_MASK)) {
-		if ((idtv_info_field & VECTORING_INFO_TYPE_MASK)
-		    == INTR_TYPE_EXT_INTR
-		    && vcpu->rmode.active) {
-			u8 vect = idtv_info_field & VECTORING_INFO_VECTOR_MASK;
-
-			vmx_inject_irq(vcpu, vect);
-			if (unlikely(has_ext_irq))
-				enable_irq_window(vcpu);
-			return;
-		}
-
-		vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, idtv_info_field);
-		vmcs_write32(VM_ENTRY_INSTRUCTION_LEN,
-				vmcs_read32(VM_EXIT_INSTRUCTION_LEN));
+	int interrupt_window_open;
 
-		if (unlikely(idtv_info_field & INTR_INFO_DELIEVER_CODE_MASK))
-			vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE,
-				vmcs_read32(IDT_VECTORING_ERROR_CODE));
-		if (unlikely(has_ext_irq))
-			enable_irq_window(vcpu);
-		return;
-	}
-	if (!has_ext_irq)
-		return;
 	interrupt_window_open =
 		((vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_IF) &&
 		 (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0);
-	if (interrupt_window_open) {
-		irq.ack(vcpu, irq.info);
-		vector = irq.vector;
+
+	if (!vcpu->exception.pending && interrupt_window_open) {
 		vmx_inject_irq(vcpu, vector);
-		kvm_timer_intr_post(vcpu, vector);
-	} else
+		return true;
+	} else {
 		enable_irq_window(vcpu);
+		return false;
+	}
+}
+
+static bool vmx_interrupt_injected(struct kvm_vcpu *vcpu)
+{
+	struct vcpu_vmx *vmx = to_vmx(vcpu);
+	bool valid = vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK;
+	unsigned type = vmx->idt_vectoring_info & VECTORING_INFO_TYPE_MASK;
+
+	return !(valid && (type == INTR_TYPE_EXT_INTR));
 }
 
 /*
@@ -2597,12 +2505,11 @@ static struct kvm_x86_ops vmx_x86_ops = {
 	.handle_exit = kvm_handle_exit,
 	.skip_emulated_instruction = skip_emulated_instruction,
 	.patch_hypercall = vmx_patch_hypercall,
-	.get_irq = vmx_get_irq,
-	.set_irq = vmx_inject_irq,
 	.queue_exception = vmx_queue_exception,
 	.exception_injected = vmx_exception_injected,
-	.inject_pending_irq = vmx_intr_assist,
-	.inject_pending_vectors = do_interrupt_requests,
+	.queue_interrupt = vmx_queue_interrupt,
+	.interrupt_injected = vmx_interrupt_injected,
+	.set_tpr_threshold = update_tpr_threshold,
 
 	.set_tss_addr = vmx_set_tss_addr,
 };
diff --git a/drivers/kvm/x86.c b/drivers/kvm/x86.c
index 6deb052..a196d5d 100644
--- a/drivers/kvm/x86.c
+++ b/drivers/kvm/x86.c
@@ -2365,9 +2365,51 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu,
 					 vcpu->irq_summary == 0);
 }
 
+static void ack_vector(struct kvm_vcpu *vcpu, unsigned vector)
+{
+	unsigned word_index = vector / BITS_PER_LONG;
+	unsigned bit_index = vector % BITS_PER_LONG;
+
+	clear_bit(bit_index, &vcpu->irq_pending[word_index]);
+	if (!vcpu->irq_pending[word_index])
+		clear_bit(word_index, &vcpu->irq_summary);
+}
+
+static bool get_pending_irq(struct kvm_vcpu *vcpu, struct kvm_pending_irq *irq,
+			    unsigned *tpr_threshold)
+{
+	unsigned word_index, bit_index;
+
+	if (irqchip_in_kernel(vcpu->kvm))
+		return kvm_cpu_get_interrupt(vcpu, irq, tpr_threshold);
+
+	*tpr_threshold = 0;
+
+	if (!vcpu->irq_summary)
+		return false;
+
+	word_index = __ffs(vcpu->irq_summary);
+	bit_index = __ffs(vcpu->irq_pending[word_index]);
+	irq->vector = word_index * BITS_PER_LONG + bit_index;
+	irq->ack = ack_vector;
+	irq->info = irq->vector;
+	return true;
+}
+
+static void update_tpr_threshold(struct kvm_vcpu *vcpu, unsigned tpr_threshold)
+{
+	if (tpr_threshold != vcpu->tpr_threshold) {
+		vcpu->tpr_threshold = tpr_threshold;
+		kvm_x86_ops->set_tpr_threshold(vcpu);
+	}
+}
+
 static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
 	int r;
+	bool irq_pending;
+	struct kvm_pending_irq irq;
+	unsigned tpr_threshold;
 
 	if (unlikely(vcpu->mp_state == VCPU_MP_STATE_SIPI_RECEIVED)) {
 		pr_debug("vcpu %d received sipi with vector # %x\n",
@@ -2408,10 +2450,12 @@ again:
 
 	if (vcpu->exception.pending)
 		__queue_exception(vcpu);
-	else if (irqchip_in_kernel(vcpu->kvm))
-		kvm_x86_ops->inject_pending_irq(vcpu);
-	else
-		kvm_x86_ops->inject_pending_vectors(vcpu, kvm_run);
+
+	irq_pending = get_pending_irq(vcpu, &irq, &tpr_threshold);
+	if (irq_pending)
+		irq_pending = kvm_x86_ops->queue_interrupt(vcpu, irq.vector);
+
+	update_tpr_threshold(vcpu, tpr_threshold);
 
 	vcpu->guest_mode = 1;
 	kvm_guest_enter();
@@ -2450,6 +2494,11 @@ again:
 	if (vcpu->exception.pending && kvm_x86_ops->exception_injected(vcpu))
 		vcpu->exception.pending = false;
 
+	if (irq_pending && kvm_x86_ops->interrupt_injected(vcpu)) {
+		irq.ack(vcpu, irq.info);
+		kvm_timer_intr_post(vcpu, irq.vector);
+	}
+
 	r = kvm_x86_ops->handle_exit(kvm_run, vcpu);
 
 	if (r > 0) {
@@ -2623,7 +2672,6 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
 				  struct kvm_sregs *sregs)
 {
 	struct descriptor_table dt;
-	int pending_vec;
 
 	vcpu_load(vcpu);
 
@@ -2653,14 +2701,10 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
 	sregs->efer = vcpu->shadow_efer;
 	sregs->apic_base = kvm_get_apic_base(vcpu);
 
-	if (irqchip_in_kernel(vcpu->kvm)) {
+	if (irqchip_in_kernel(vcpu->kvm))
 		memset(sregs->interrupt_bitmap, 0,
 		       sizeof sregs->interrupt_bitmap);
-		pending_vec = kvm_x86_ops->get_irq(vcpu);
-		if (pending_vec >= 0)
-			set_bit(pending_vec,
-				(unsigned long *)sregs->interrupt_bitmap);
-	} else
+	else
 		memcpy(sregs->interrupt_bitmap, vcpu->irq_pending,
 		       sizeof sregs->interrupt_bitmap);
 
@@ -2679,7 +2723,7 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
 				  struct kvm_sregs *sregs)
 {
 	int mmu_reset_needed = 0;
-	int i, pending_vec, max_bits;
+	int i;
 	struct descriptor_table dt;
 
 	vcpu_load(vcpu);
@@ -2724,17 +2768,6 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
 		for (i = 0; i < ARRAY_SIZE(vcpu->irq_pending); ++i)
 			if (vcpu->irq_pending[i])
 				__set_bit(i, &vcpu->irq_summary);
-	} else {
-		max_bits = (sizeof sregs->interrupt_bitmap) << 3;
-		pending_vec = find_first_bit(
-			(const unsigned long *)sregs->interrupt_bitmap,
-			max_bits);
-		/* Only pending external irq is handled here */
-		if (pending_vec < max_bits) {
-			kvm_x86_ops->set_irq(vcpu, pending_vec);
-			pr_debug("Set back pending irq %d\n",
-				 pending_vec);
-		}
 	}
 
 	set_segment(vcpu, &sregs->cs, VCPU_SREG_CS);
diff --git a/drivers/kvm/x86.h b/drivers/kvm/x86.h
index fb48b2f..52f3199 100644
--- a/drivers/kvm/x86.h
+++ b/drivers/kvm/x86.h
@@ -136,6 +136,8 @@ struct kvm_vcpu {
 	struct kvm_pio_request pio;
 	void *pio_data;
 
+	unsigned tpr_threshold;
+
 	struct kvm_queued_exception {
 		bool pending;
 		bool has_error_code;
@@ -217,15 +219,12 @@ struct kvm_x86_ops {
 	void (*skip_emulated_instruction)(struct kvm_vcpu *vcpu);
 	void (*patch_hypercall)(struct kvm_vcpu *vcpu,
 				unsigned char *hypercall_addr);
-	int (*get_irq)(struct kvm_vcpu *vcpu);
-	void (*set_irq)(struct kvm_vcpu *vcpu, int vec);
 	void (*queue_exception)(struct kvm_vcpu *vcpu, unsigned nr,
 				bool has_error_code, u32 error_code);
 	bool (*exception_injected)(struct kvm_vcpu *vcpu);
-	void (*inject_pending_irq)(struct kvm_vcpu *vcpu);
-	void (*inject_pending_vectors)(struct kvm_vcpu *vcpu,
-				       struct kvm_run *run);
-
+	bool (*queue_interrupt)(struct kvm_vcpu *vcpu, unsigned vector);
+	bool (*interrupt_injected)(struct kvm_vcpu *vcpu);
+	void (*set_tpr_threshold)(struct kvm_vcpu *vcpu);
 	int (*set_tss_addr)(struct kvm *kvm, unsigned int addr);
 };
 
-- 
1.5.3


-------------------------------------------------------------------------
SF.Net email is sponsored by: The Future of Linux Business White Paper
from Novell.  From the desktop to the data center, Linux is going
mainstream.  Let it simplify your IT future.
http://altfarm.mediaplex.com/ad/ck/8857-50307-18918-4

  parent reply	other threads:[~2007-12-04  9:44 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-12-04  9:44 [PATCH 0/7] Rework irq injection infrastructure Avi Kivity
     [not found] ` <11967614542283-git-send-email-avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-12-04  9:44   ` [PATCH 1/7] KVM: Generalize exception injection mechanism Avi Kivity
2007-12-04  9:44   ` [PATCH 2/7] KVM: Replace page fault injection by the generalized exception queue Avi Kivity
2007-12-04  9:44   ` [PATCH 3/7] KVM: Replace #GP " Avi Kivity
2007-12-04  9:44   ` [PATCH 4/7] KVM: Use generalized exception queue for injecting #UD Avi Kivity
2007-12-04  9:44   ` [PATCH 5/7] KVM: Add explicit acks to interrupt controller model Avi Kivity
2007-12-04  9:44   ` [PATCH 6/7] KVM: Move tpr threshold calculation into common code Avi Kivity
2007-12-04  9:44   ` Avi Kivity [this message]
2007-12-04 16:51   ` [PATCH 0/7] Rework irq injection infrastructure Joerg Roedel
     [not found]     ` <20071204165101.GA23093-5C7GfCeVMHo@public.gmane.org>
2007-12-04 16:56       ` Avi Kivity
2007-12-06  7:50   ` Dong, Eddie
     [not found]     ` <10EA09EFD8728347A513008B6B0DA77A0279CC10-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-12-06  8:28       ` Avi Kivity
     [not found]         ` <4757B2C3.3000402-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-12-06  9:33           ` Dong, Eddie
     [not found]             ` <10EA09EFD8728347A513008B6B0DA77A0279CCE0-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-12-06 10:10               ` Avi Kivity
     [not found]                 ` <4757CA93.1090704-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-12-06 10:26                   ` Dong, Eddie
     [not found]                     ` <10EA09EFD8728347A513008B6B0DA77A0279CCF2-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-12-06 13:24                       ` Dong, Eddie
     [not found]                         ` <10EA09EFD8728347A513008B6B0DA77A0279CD1C-wq7ZOvIWXbNpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-12-06 14:19                           ` Avi Kivity

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1196761455542-git-send-email-avi@qumranet.com \
    --to=avi-atkuwr5tajbwk0htik3j/w@public.gmane.org \
    --cc=kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox