KVM: Separate irq ack notification out of arch/x86/kvm/irq.c
[safe/jmp/linux-2.6] / include / asm-x86 / kvm_host.h
index c2e34c2..411fb8c 100644 (file)
@@ -1,4 +1,4 @@
-#/*
+/*
  * Kernel-based Virtual Machine driver for Linux
  *
  * This header defines architecture specific interfaces, x86 version
@@ -8,8 +8,8 @@
  *
  */
 
-#ifndef ASM_KVM_HOST_H
-#define ASM_KVM_HOST_H
+#ifndef ASM_X86__KVM_HOST_H
+#define ASM_X86__KVM_HOST_H
 
 #include <linux/types.h>
 #include <linux/mm.h>
 #define KVM_PAGES_PER_HPAGE (KVM_HPAGE_SIZE / PAGE_SIZE)
 
 #define DE_VECTOR 0
+#define DB_VECTOR 1
+#define BP_VECTOR 3
+#define OF_VECTOR 4
+#define BR_VECTOR 5
 #define UD_VECTOR 6
 #define NM_VECTOR 7
 #define DF_VECTOR 8
@@ -65,6 +69,7 @@
 #define SS_VECTOR 12
 #define GP_VECTOR 13
 #define PF_VECTOR 14
+#define MF_VECTOR 16
 #define MC_VECTOR 18
 
 #define SELECTOR_TI_MASK (1 << 2)
@@ -89,7 +94,7 @@ extern struct list_head vm_list;
 struct kvm_vcpu;
 struct kvm;
 
-enum {
+enum kvm_reg {
        VCPU_REGS_RAX = 0,
        VCPU_REGS_RCX = 1,
        VCPU_REGS_RDX = 2,
@@ -108,6 +113,7 @@ enum {
        VCPU_REGS_R14 = 14,
        VCPU_REGS_R15 = 15,
 #endif
+       VCPU_REGS_RIP,
        NR_VCPU_REGS
 };
 
@@ -189,10 +195,20 @@ struct kvm_mmu_page {
                                    */
        int multimapped;         /* More than one parent_pte? */
        int root_count;          /* Currently serving as active root */
+       bool unsync;
+       bool unsync_children;
        union {
                u64 *parent_pte;               /* !multimapped */
                struct hlist_head parent_ptes; /* multimapped, kvm_pte_chain */
        };
+       DECLARE_BITMAP(unsync_child_bitmap, 512);
+};
+
+struct kvm_pv_mmu_op_buffer {
+       void *ptr;
+       unsigned len;
+       unsigned processed;
+       char buf[512] __aligned(sizeof(long));
 };
 
 /*
@@ -207,6 +223,9 @@ struct kvm_mmu {
        gpa_t (*gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t gva);
        void (*prefetch_page)(struct kvm_vcpu *vcpu,
                              struct kvm_mmu_page *page);
+       int (*sync_page)(struct kvm_vcpu *vcpu,
+                        struct kvm_mmu_page *sp);
+       void (*invlpg)(struct kvm_vcpu *vcpu, gva_t gva);
        hpa_t root_hpa;
        int root_level;
        int shadow_root_level;
@@ -219,8 +238,13 @@ struct kvm_vcpu_arch {
        int interrupt_window_open;
        unsigned long irq_summary; /* bit vector: 1 per word in irq_pending */
        DECLARE_BITMAP(irq_pending, KVM_NR_INTERRUPTS);
-       unsigned long regs[NR_VCPU_REGS]; /* for rsp: vcpu_load_rsp_rip() */
-       unsigned long rip;      /* needs vcpu_load_rsp_rip() */
+       /*
+        * rip and regs accesses must go through
+        * kvm_{register,rip}_{read,write} functions.
+        */
+       unsigned long regs[NR_VCPU_REGS];
+       u32 regs_avail;
+       u32 regs_dirty;
 
        unsigned long cr0;
        unsigned long cr2;
@@ -237,6 +261,9 @@ struct kvm_vcpu_arch {
        bool tpr_access_reporting;
 
        struct kvm_mmu mmu;
+       /* only needed in kvm_pv_mmu_op() path, but it's hot so
+        * put it here to avoid allocation */
+       struct kvm_pv_mmu_op_buffer mmu_op_buffer;
 
        struct kvm_mmu_memory_cache mmu_pte_chain_cache;
        struct kvm_mmu_memory_cache mmu_rmap_desc_cache;
@@ -269,6 +296,11 @@ struct kvm_vcpu_arch {
                u32 error_code;
        } exception;
 
+       struct kvm_queued_interrupt {
+               bool pending;
+               u8 nr;
+       } interrupt;
+
        struct {
                int active;
                u8 save_iopl;
@@ -294,6 +326,7 @@ struct kvm_vcpu_arch {
        struct page *time_page;
 
        bool nmi_pending;
+       bool nmi_injected;
 
        u64 mtrr[0x100];
 };
@@ -316,9 +349,12 @@ struct kvm_arch{
         * Hash table of struct kvm_mmu_page.
         */
        struct list_head active_mmu_pages;
+       struct list_head assigned_dev_head;
+       struct dmar_domain *intel_iommu_domain;
        struct kvm_pic *vpic;
        struct kvm_ioapic *vioapic;
        struct kvm_pit *vpit;
+       struct hlist_head irq_ack_notifier_list;
 
        int round_robin_prev_vcpu;
        unsigned int tss_addr;
@@ -338,6 +374,7 @@ struct kvm_vm_stat {
        u32 mmu_flooded;
        u32 mmu_recycled;
        u32 mmu_cache_miss;
+       u32 mmu_unsync;
        u32 remote_tlb_flush;
        u32 lpages;
 };
@@ -364,6 +401,7 @@ struct kvm_vcpu_stat {
        u32 insn_emulation;
        u32 insn_emulation_fail;
        u32 hypercalls;
+       u32 irq_injections;
 };
 
 struct descriptor_table {
@@ -414,8 +452,7 @@ struct kvm_x86_ops {
        unsigned long (*get_dr)(struct kvm_vcpu *vcpu, int dr);
        void (*set_dr)(struct kvm_vcpu *vcpu, int dr, unsigned long value,
                       int *exception);
-       void (*cache_regs)(struct kvm_vcpu *vcpu);
-       void (*decache_regs)(struct kvm_vcpu *vcpu);
+       void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg);
        unsigned long (*get_rflags)(struct kvm_vcpu *vcpu);
        void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags);
 
@@ -528,6 +565,8 @@ void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code);
 void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long cr2,
                           u32 error_code);
 
+void kvm_pic_set_irq(void *opaque, int irq, int level);
+
 void kvm_inject_nmi(struct kvm_vcpu *vcpu);
 
 void fx_init(struct kvm_vcpu *vcpu);
@@ -550,12 +589,14 @@ int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva);
 void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu);
 int kvm_mmu_load(struct kvm_vcpu *vcpu);
 void kvm_mmu_unload(struct kvm_vcpu *vcpu);
+void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu);
 
 int kvm_emulate_hypercall(struct kvm_vcpu *vcpu);
 
 int kvm_fix_hypercall(struct kvm_vcpu *vcpu);
 
 int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, u32 error_code);
+void kvm_mmu_invlpg(struct kvm_vcpu *vcpu, gva_t gva);
 
 void kvm_enable_tdp(void);
 void kvm_disable_tdp(void);
@@ -686,33 +727,6 @@ enum {
        TASK_SWITCH_GATE = 3,
 };
 
-#define KVMTRACE_5D(evt, vcpu, d1, d2, d3, d4, d5, name) \
-       trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \
-                                               vcpu, 5, d1, d2, d3, d4, d5)
-#define KVMTRACE_4D(evt, vcpu, d1, d2, d3, d4, name) \
-       trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \
-                                               vcpu, 4, d1, d2, d3, d4, 0)
-#define KVMTRACE_3D(evt, vcpu, d1, d2, d3, name) \
-       trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \
-                                               vcpu, 3, d1, d2, d3, 0, 0)
-#define KVMTRACE_2D(evt, vcpu, d1, d2, name) \
-       trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \
-                                               vcpu, 2, d1, d2, 0, 0, 0)
-#define KVMTRACE_1D(evt, vcpu, d1, name) \
-       trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \
-                                               vcpu, 1, d1, 0, 0, 0, 0)
-#define KVMTRACE_0D(evt, vcpu, name) \
-       trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \
-                                               vcpu, 0, 0, 0, 0, 0, 0)
-
-#ifdef CONFIG_64BIT
-# define KVM_EX_ENTRY ".quad"
-# define KVM_EX_PUSH "pushq"
-#else
-# define KVM_EX_ENTRY ".long"
-# define KVM_EX_PUSH "pushl"
-#endif
-
 /*
  * Hardware virtualization extension instructions may fault if a
  * reboot turns off virtualization while processes are running.
@@ -724,15 +738,15 @@ asmlinkage void kvm_handle_fault_on_reboot(void);
        "666: " insn "\n\t" \
        ".pushsection .fixup, \"ax\" \n" \
        "667: \n\t" \
-       KVM_EX_PUSH " $666b \n\t" \
+       __ASM_SIZE(push) " $666b \n\t"        \
        "jmp kvm_handle_fault_on_reboot \n\t" \
        ".popsection \n\t" \
        ".pushsection __ex_table, \"a\" \n\t" \
-       KVM_EX_ENTRY " 666b, 667b \n\t" \
+       _ASM_PTR " 666b, 667b \n\t" \
        ".popsection"
 
 #define KVM_ARCH_WANT_MMU_NOTIFIER
 int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);
 int kvm_age_hva(struct kvm *kvm, unsigned long hva);
 
-#endif
+#endif /* ASM_X86__KVM_HOST_H */