KVM: x86/xen: Add event channel interrupt vector upcall
[linux-2.6-microblaze.git] / arch / x86 / include / asm / kvm_host.h
index 3d6616f..b37afd8 100644 (file)
@@ -52,6 +52,9 @@
 #define KVM_DIRTY_LOG_MANUAL_CAPS   (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \
                                        KVM_DIRTY_LOG_INITIALLY_SET)
 
+#define KVM_BUS_LOCK_DETECTION_VALID_MODE      (KVM_BUS_LOCK_DETECTION_OFF | \
+                                                KVM_BUS_LOCK_DETECTION_EXIT)
+
 /* x86-specific vcpu->requests bit members */
 #define KVM_REQ_MIGRATE_TIMER          KVM_ARCH_REQ(0)
 #define KVM_REQ_REPORT_TPR_ACCESS      KVM_ARCH_REQ(1)
@@ -200,9 +203,17 @@ enum x86_intercept_stage;
 #define DR6_BS         (1 << 14)
 #define DR6_BT         (1 << 15)
 #define DR6_RTM                (1 << 16)
-#define DR6_FIXED_1    0xfffe0ff0
-#define DR6_INIT       0xffff0ff0
+/*
+ * DR6_ACTIVE_LOW combines fixed-1 and active-low bits.
+ * We can regard all the bits in DR6_FIXED_1 as active_low bits;
+ * they will never be 0 for now, but when they are defined
+ * in the future it will require no code change.
+ *
+ * DR6_ACTIVE_LOW is also used as the init/reset value for DR6.
+ */
+#define DR6_ACTIVE_LOW 0xffff0ff0
 #define DR6_VOLATILE   0x0001e00f
+#define DR6_FIXED_1    (DR6_ACTIVE_LOW & ~DR6_VOLATILE)
 
 #define DR7_BP_EN_MASK 0x000000ff
 #define DR7_GE         (1 << 9)
@@ -337,6 +348,8 @@ struct kvm_mmu_root_info {
 
 #define KVM_MMU_NUM_PREV_ROOTS 3
 
+#define KVM_HAVE_MMU_RWLOCK
+
 struct kvm_mmu_page;
 
 /*
@@ -358,8 +371,6 @@ struct kvm_mmu {
        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);
-       void (*update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
-                          u64 *spte, const void *pte);
        hpa_t root_hpa;
        gpa_t root_pgd;
        union kvm_mmu_role mmu_role;
@@ -520,6 +531,15 @@ struct kvm_vcpu_hv {
        cpumask_t tlb_flush;
 };
 
+/* Xen HVM per vcpu emulation context */
+struct kvm_vcpu_xen {
+       u64 hypercall_rip;
+       bool vcpu_info_set;
+       bool vcpu_time_info_set;
+       struct gfn_to_hva_cache vcpu_info_cache;
+       struct gfn_to_hva_cache vcpu_time_info_cache;
+};
+
 struct kvm_vcpu_arch {
        /*
         * rip and regs accesses must go through
@@ -718,6 +738,7 @@ struct kvm_vcpu_arch {
        unsigned long singlestep_rip;
 
        struct kvm_vcpu_hv hyperv;
+       struct kvm_vcpu_xen xen;
 
        cpumask_var_t wbinvd_dirty_mask;
 
@@ -888,6 +909,14 @@ struct msr_bitmap_range {
        unsigned long *bitmap;
 };
 
+/* Xen emulation context */
+struct kvm_xen {
+       bool long_mode;
+       bool shinfo_set;
+       u8 upcall_vector;
+       struct gfn_to_hva_cache shinfo_cache;
+};
+
 enum kvm_irqchip_mode {
        KVM_IRQCHIP_NONE,
        KVM_IRQCHIP_KERNEL,       /* created with KVM_CREATE_IRQCHIP */
@@ -967,6 +996,7 @@ struct kvm_arch {
        struct hlist_head mask_notifier_list;
 
        struct kvm_hv hyperv;
+       struct kvm_xen xen;
 
        #ifdef CONFIG_KVM_MMU_AUDIT
        int audit_point;
@@ -998,6 +1028,8 @@ struct kvm_arch {
                struct msr_bitmap_range ranges[16];
        } msr_filter;
 
+       bool bus_lock_detection_enabled;
+
        struct kvm_pmu_event_filter *pmu_event_filter;
        struct task_struct *nx_lpage_recovery_thread;
 
@@ -1026,12 +1058,24 @@ struct kvm_arch {
         * tdp_mmu_page set and a root_count of 0.
         */
        struct list_head tdp_mmu_pages;
+
+       /*
+        * Protects accesses to the following fields when the MMU lock
+        * is held in read mode:
+        *  - tdp_mmu_pages (above)
+        *  - the link field of struct kvm_mmu_pages used by the TDP MMU
+        *  - lpage_disallowed_mmu_pages
+        *  - the lpage_disallowed_link field of struct kvm_mmu_pages used
+        *    by the TDP MMU
+        * It is acceptable, but not necessary, to acquire this lock when
+        * the thread holds the MMU lock in write mode.
+        */
+       spinlock_t tdp_mmu_pages_lock;
 };
 
 struct kvm_vm_stat {
        ulong mmu_shadow_zapped;
        ulong mmu_pte_write;
-       ulong mmu_pte_updated;
        ulong mmu_pde_zapped;
        ulong mmu_flooded;
        ulong mmu_recycled;
@@ -1340,6 +1384,19 @@ extern u64 __read_mostly host_efer;
 extern bool __read_mostly allow_smaller_maxphyaddr;
 extern struct kvm_x86_ops kvm_x86_ops;
 
+#define KVM_X86_OP(func) \
+       DECLARE_STATIC_CALL(kvm_x86_##func, *(((struct kvm_x86_ops *)0)->func));
+#define KVM_X86_OP_NULL KVM_X86_OP
+#include <asm/kvm-x86-ops.h>
+
+static inline void kvm_ops_static_call_update(void)
+{
+#define KVM_X86_OP(func) \
+       static_call_update(kvm_x86_##func, kvm_x86_ops.func);
+#define KVM_X86_OP_NULL KVM_X86_OP
+#include <asm/kvm-x86-ops.h>
+}
+
 #define __KVM_HAVE_ARCH_VM_ALLOC
 static inline struct kvm *kvm_arch_alloc_vm(void)
 {
@@ -1351,7 +1408,7 @@ void kvm_arch_free_vm(struct kvm *kvm);
 static inline int kvm_arch_flush_remote_tlb(struct kvm *kvm)
 {
        if (kvm_x86_ops.tlb_remote_flush &&
-           !kvm_x86_ops.tlb_remote_flush(kvm))
+           !static_call(kvm_x86_tlb_remote_flush)(kvm))
                return 0;
        else
                return -ENOTSUPP;
@@ -1421,6 +1478,8 @@ extern u8   kvm_tsc_scaling_ratio_frac_bits;
 extern u64  kvm_max_tsc_scaling_ratio;
 /* 1ull << kvm_tsc_scaling_ratio_frac_bits */
 extern u64  kvm_default_tsc_scaling_ratio;
+/* bus lock detection supported? */
+extern bool kvm_has_bus_lock_exit;
 
 extern u64 kvm_mce_cap_supported;
 
@@ -1742,14 +1801,12 @@ static inline bool kvm_irq_is_postable(struct kvm_lapic_irq *irq)
 
 static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu)
 {
-       if (kvm_x86_ops.vcpu_blocking)
-               kvm_x86_ops.vcpu_blocking(vcpu);
+       static_call_cond(kvm_x86_vcpu_blocking)(vcpu);
 }
 
 static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu)
 {
-       if (kvm_x86_ops.vcpu_unblocking)
-               kvm_x86_ops.vcpu_unblocking(vcpu);
+       static_call_cond(kvm_x86_vcpu_unblocking)(vcpu);
 }
 
 static inline void kvm_arch_vcpu_block_finish(struct kvm_vcpu *vcpu) {}