Merge branch 'kvm-fixes' into 'next'
[platform/kernel/linux-rpi.git] / arch / x86 / kvm / vmx / vmx.h
index a0e4772..f6f66e5 100644 (file)
@@ -9,8 +9,9 @@
 
 #include "capabilities.h"
 #include "kvm_cache_regs.h"
-#include "ops.h"
+#include "posted_intr.h"
 #include "vmcs.h"
+#include "vmx_ops.h"
 #include "cpuid.h"
 
 extern const u32 vmx_msr_index[];
@@ -22,20 +23,20 @@ extern const u32 vmx_msr_index[];
 #define X2APIC_MSR(r) (APIC_BASE_MSR + ((r) >> 4))
 
 #ifdef CONFIG_X86_64
-#define NR_SHARED_MSRS 7
+#define MAX_NR_USER_RETURN_MSRS        7
 #else
-#define NR_SHARED_MSRS 4
+#define MAX_NR_USER_RETURN_MSRS        4
 #endif
 
-#define NR_LOADSTORE_MSRS 8
+#define MAX_NR_LOADSTORE_MSRS  8
 
 struct vmx_msrs {
        unsigned int            nr;
-       struct vmx_msr_entry    val[NR_LOADSTORE_MSRS];
+       struct vmx_msr_entry    val[MAX_NR_LOADSTORE_MSRS];
 };
 
-struct shared_msr_entry {
-       unsigned index;
+struct vmx_uret_msr {
+       unsigned int slot; /* The MSR's slot in kvm_user_return_msrs. */
        u64 data;
        u64 mask;
 };
@@ -49,29 +50,6 @@ enum segment_cache_field {
        SEG_FIELD_NR = 4
 };
 
-/* Posted-Interrupt Descriptor */
-struct pi_desc {
-       u32 pir[8];     /* Posted interrupt requested */
-       union {
-               struct {
-                               /* bit 256 - Outstanding Notification */
-                       u16     on      : 1,
-                               /* bit 257 - Suppress Notification */
-                               sn      : 1,
-                               /* bit 271:258 - Reserved */
-                               rsvd_1  : 14;
-                               /* bit 279:272 - Notification Vector */
-                       u8      nv;
-                               /* bit 287:280 - Reserved */
-                       u8      rsvd_2;
-                               /* bit 319:288 - Notification Destination */
-                       u32     ndst;
-               };
-               u64 control;
-       };
-       u32 rsvd[6];
-} __aligned(64);
-
 #define RTIT_ADDR_RANGE                4
 
 struct pt_ctx {
@@ -218,10 +196,10 @@ struct vcpu_vmx {
        u32                   idt_vectoring_info;
        ulong                 rflags;
 
-       struct shared_msr_entry guest_msrs[NR_SHARED_MSRS];
-       int                   nmsrs;
-       int                   save_nmsrs;
-       bool                  guest_msrs_ready;
+       struct vmx_uret_msr   guest_uret_msrs[MAX_NR_USER_RETURN_MSRS];
+       int                   nr_uret_msrs;
+       int                   nr_active_uret_msrs;
+       bool                  guest_uret_msrs_loaded;
 #ifdef CONFIG_X86_64
        u64                   msr_host_kernel_gs_base;
        u64                   msr_guest_kernel_gs_base;
@@ -301,6 +279,13 @@ struct vcpu_vmx {
        u64 ept_pointer;
 
        struct pt_desc pt_desc;
+
+       /* Save desired MSR intercept (read: pass-through) state */
+#define MAX_POSSIBLE_PASSTHROUGH_MSRS  13
+       struct {
+               DECLARE_BITMAP(read, MAX_POSSIBLE_PASSTHROUGH_MSRS);
+               DECLARE_BITMAP(write, MAX_POSSIBLE_PASSTHROUGH_MSRS);
+       } shadow_msr_intercept;
 };
 
 enum ept_pointers_status {
@@ -334,7 +319,7 @@ unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu);
 void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags);
 u32 vmx_get_interrupt_shadow(struct kvm_vcpu *vcpu);
 void vmx_set_interrupt_shadow(struct kvm_vcpu *vcpu, int mask);
-void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer);
+int vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer);
 void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0);
 int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4);
 void set_cr4_guest_host_mask(struct vcpu_vmx *vmx);
@@ -343,6 +328,7 @@ void vmx_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg);
 void vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg);
 u64 construct_eptp(struct kvm_vcpu *vcpu, unsigned long root_hpa,
                   int root_level);
+
 void update_exception_bitmap(struct kvm_vcpu *vcpu);
 void vmx_update_msr_bitmap(struct kvm_vcpu *vcpu);
 bool vmx_nmi_blocked(struct kvm_vcpu *vcpu);
@@ -350,75 +336,12 @@ bool vmx_interrupt_blocked(struct kvm_vcpu *vcpu);
 bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu);
 void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked);
 void vmx_set_virtual_apic_mode(struct kvm_vcpu *vcpu);
-struct shared_msr_entry *find_msr_entry(struct vcpu_vmx *vmx, u32 msr);
-void pt_update_intercept_for_msr(struct vcpu_vmx *vmx);
+struct vmx_uret_msr *vmx_find_uret_msr(struct vcpu_vmx *vmx, u32 msr);
+void pt_update_intercept_for_msr(struct kvm_vcpu *vcpu);
 void vmx_update_host_rsp(struct vcpu_vmx *vmx, unsigned long host_rsp);
-int vmx_find_msr_index(struct vmx_msrs *m, u32 msr);
-int vmx_handle_memory_failure(struct kvm_vcpu *vcpu, int r,
-                             struct x86_exception *e);
+int vmx_find_loadstore_msr_slot(struct vmx_msrs *m, u32 msr);
 void vmx_ept_load_pdptrs(struct kvm_vcpu *vcpu);
 
-#define POSTED_INTR_ON  0
-#define POSTED_INTR_SN  1
-
-static inline bool pi_test_and_set_on(struct pi_desc *pi_desc)
-{
-       return test_and_set_bit(POSTED_INTR_ON,
-                       (unsigned long *)&pi_desc->control);
-}
-
-static inline bool pi_test_and_clear_on(struct pi_desc *pi_desc)
-{
-       return test_and_clear_bit(POSTED_INTR_ON,
-                       (unsigned long *)&pi_desc->control);
-}
-
-static inline int pi_test_and_set_pir(int vector, struct pi_desc *pi_desc)
-{
-       return test_and_set_bit(vector, (unsigned long *)pi_desc->pir);
-}
-
-static inline bool pi_is_pir_empty(struct pi_desc *pi_desc)
-{
-       return bitmap_empty((unsigned long *)pi_desc->pir, NR_VECTORS);
-}
-
-static inline void pi_set_sn(struct pi_desc *pi_desc)
-{
-       set_bit(POSTED_INTR_SN,
-               (unsigned long *)&pi_desc->control);
-}
-
-static inline void pi_set_on(struct pi_desc *pi_desc)
-{
-       set_bit(POSTED_INTR_ON,
-               (unsigned long *)&pi_desc->control);
-}
-
-static inline void pi_clear_on(struct pi_desc *pi_desc)
-{
-       clear_bit(POSTED_INTR_ON,
-               (unsigned long *)&pi_desc->control);
-}
-
-static inline void pi_clear_sn(struct pi_desc *pi_desc)
-{
-       clear_bit(POSTED_INTR_SN,
-               (unsigned long *)&pi_desc->control);
-}
-
-static inline int pi_test_on(struct pi_desc *pi_desc)
-{
-       return test_bit(POSTED_INTR_ON,
-                       (unsigned long *)&pi_desc->control);
-}
-
-static inline int pi_test_sn(struct pi_desc *pi_desc)
-{
-       return test_bit(POSTED_INTR_SN,
-                       (unsigned long *)&pi_desc->control);
-}
-
 static inline u8 vmx_get_rvi(void)
 {
        return vmcs_read16(GUEST_INTR_STATUS) & 0xff;
@@ -499,11 +422,6 @@ static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu)
        return container_of(vcpu, struct vcpu_vmx, vcpu);
 }
 
-static inline struct pi_desc *vcpu_to_pi_desc(struct kvm_vcpu *vcpu)
-{
-       return &(to_vmx(vcpu)->pi_desc);
-}
-
 static inline unsigned long vmx_get_exit_qual(struct kvm_vcpu *vcpu)
 {
        struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -558,6 +476,19 @@ static inline bool vmx_need_pf_intercept(struct kvm_vcpu *vcpu)
        return allow_smaller_maxphyaddr && cpuid_maxphyaddr(vcpu) < boot_cpu_data.x86_phys_bits;
 }
 
+static inline bool is_unrestricted_guest(struct kvm_vcpu *vcpu)
+{
+       return enable_unrestricted_guest && (!is_guest_mode(vcpu) ||
+           (secondary_exec_controls_get(to_vmx(vcpu)) &
+           SECONDARY_EXEC_UNRESTRICTED_GUEST));
+}
+
+bool __vmx_guest_state_valid(struct kvm_vcpu *vcpu);
+static inline bool vmx_guest_state_valid(struct kvm_vcpu *vcpu)
+{
+       return is_unrestricted_guest(vcpu) || __vmx_guest_state_valid(vcpu);
+}
+
 void dump_vmcs(void);
 
 #endif /* __KVM_X86_VMX_H */