KVM: Non-atomic interrupt injection
[firefly-linux-kernel-4.4.55.git] / arch / x86 / include / asm / kvm_host.h
index 009a4a1b370e1ed8c944258d89ae05c02106c074..80224bf5d4f8b3c6c662bc57a3b9048962ac5ea0 100644 (file)
@@ -239,12 +239,11 @@ struct kvm_mmu {
        void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long root);
        unsigned long (*get_cr3)(struct kvm_vcpu *vcpu);
        int (*page_fault)(struct kvm_vcpu *vcpu, gva_t gva, u32 err);
-       void (*inject_page_fault)(struct kvm_vcpu *vcpu,
-                                 unsigned long addr,
-                                 u32 error_code);
+       void (*inject_page_fault)(struct kvm_vcpu *vcpu);
        void (*free)(struct kvm_vcpu *vcpu);
        gpa_t (*gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t gva, u32 access,
                            u32 *error);
+       gpa_t (*translate_gpa)(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access);
        void (*prefetch_page)(struct kvm_vcpu *vcpu,
                              struct kvm_mmu_page *page);
        int (*sync_page)(struct kvm_vcpu *vcpu,
@@ -257,7 +256,12 @@ struct kvm_mmu {
        bool direct_map;
 
        u64 *pae_root;
+       u64 *lm_root;
        u64 rsvd_bits_mask[2][4];
+
+       bool nx;
+
+       u64 pdptrs[4]; /* pae */
 };
 
 struct kvm_vcpu_arch {
@@ -277,7 +281,6 @@ struct kvm_vcpu_arch {
        unsigned long cr4_guest_owned_bits;
        unsigned long cr8;
        u32 hflags;
-       u64 pdptrs[4]; /* pae */
        u64 efer;
        u64 apic_base;
        struct kvm_lapic *apic;    /* kernel irqchip context */
@@ -287,7 +290,40 @@ struct kvm_vcpu_arch {
        u64 ia32_misc_enable_msr;
        bool tpr_access_reporting;
 
+       /*
+        * Paging state of the vcpu
+        *
+        * If the vcpu runs in guest mode with two level paging this still saves
+        * the paging mode of the l1 guest. This context is always used to
+        * handle faults.
+        */
        struct kvm_mmu mmu;
+
+       /*
+        * Paging state of an L2 guest (used for nested npt)
+        *
+        * This context will save all necessary information to walk page tables
+        * of the an L2 guest. This context is only initialized for page table
+        * walking and not for faulting since we never handle l2 page faults on
+        * the host.
+        */
+       struct kvm_mmu nested_mmu;
+
+       /*
+        * Pointer to the mmu context currently used for
+        * gva_to_gpa translations.
+        */
+       struct kvm_mmu *walk_mmu;
+
+       /*
+        * This struct is filled with the necessary information to propagate a
+        * page fault into the guest
+        */
+       struct {
+               u64      address;
+               unsigned error_code;
+       } fault;
+
        /* 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;
@@ -516,6 +552,7 @@ struct kvm_x86_ops {
        void (*queue_exception)(struct kvm_vcpu *vcpu, unsigned nr,
                                bool has_error_code, u32 error_code,
                                bool reinject);
+       void (*cancel_injection)(struct kvm_vcpu *vcpu);
        int (*interrupt_allowed)(struct kvm_vcpu *vcpu);
        int (*nmi_allowed)(struct kvm_vcpu *vcpu);
        bool (*get_nmi_mask)(struct kvm_vcpu *vcpu);
@@ -560,7 +597,7 @@ void kvm_mmu_zap_all(struct kvm *kvm);
 unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm);
 void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages);
 
-int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3);
+int load_pdptrs(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, unsigned long cr3);
 
 int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
                          const void *val, int bytes);
@@ -624,8 +661,11 @@ void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr);
 void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code);
 void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned nr);
 void kvm_requeue_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_inject_page_fault(struct kvm_vcpu *vcpu);
+int kvm_read_guest_page_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
+                           gfn_t gfn, void *data, int offset, int len,
+                           u32 access);
+void kvm_propagate_fault(struct kvm_vcpu *vcpu);
 bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl);
 
 int kvm_pic_set_irq(void *opaque, int irq, int level);