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 <[EMAIL PROTECTED]>
---
 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
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to