Merge tag 'Smack-for-5.14' of git://github.com/cschaufler/smack-next
[linux-2.6-microblaze.git] / include / linux / kvm_host.h
index 8583ed3..ae7735b 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/rcuwait.h>
 #include <linux/refcount.h>
 #include <linux/nospec.h>
+#include <linux/notifier.h>
 #include <asm/signal.h>
 
 #include <linux/kvm.h>
@@ -304,7 +305,6 @@ struct kvm_vcpu {
        struct pid __rcu *pid;
        int sigset_active;
        sigset_t sigset;
-       struct kvm_vcpu_stat stat;
        unsigned int halt_poll_ns;
        bool valid_wakeup;
 
@@ -341,6 +341,8 @@ struct kvm_vcpu {
        bool preempted;
        bool ready;
        struct kvm_vcpu_arch arch;
+       struct kvm_vcpu_stat stat;
+       char stats_id[KVM_STATS_NAME_SIZE];
        struct kvm_dirty_ring dirty_ring;
 };
 
@@ -523,6 +525,15 @@ struct kvm {
 #endif /* KVM_HAVE_MMU_RWLOCK */
 
        struct mutex slots_lock;
+
+       /*
+        * Protects the arch-specific fields of struct kvm_memory_slots in
+        * use by the VM. To be used under the slots_lock (above) or in a
+        * kvm->srcu critical section where acquiring the slots_lock would
+        * lead to deadlock with the synchronize_srcu in
+        * install_new_memslots.
+        */
+       struct mutex slots_arch_lock;
        struct mm_struct *mm; /* userspace tied to this vm */
        struct kvm_memslots __rcu *memslots[KVM_ADDRESS_SPACE_NUM];
        struct kvm_vcpu *vcpus[KVM_MAX_VCPUS];
@@ -585,6 +596,11 @@ struct kvm {
        pid_t userspace_pid;
        unsigned int max_halt_poll_ns;
        u32 dirty_ring_size;
+
+#ifdef CONFIG_HAVE_KVM_PM_NOTIFIER
+       struct notifier_block pm_notifier;
+#endif
+       char stats_id[KVM_STATS_NAME_SIZE];
 };
 
 #define kvm_err(fmt, ...) \
@@ -998,6 +1014,10 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu);
 void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu);
 void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu);
 
+#ifdef CONFIG_HAVE_KVM_PM_NOTIFIER
+int kvm_arch_pm_notifier(struct kvm *kvm, unsigned long state);
+#endif
+
 #ifdef __KVM_HAVE_ARCH_VCPU_DEBUGFS
 void kvm_arch_create_vcpu_debugfs(struct kvm_vcpu *vcpu, struct dentry *debugfs_dentry);
 #endif
@@ -1244,26 +1264,104 @@ enum kvm_stat_kind {
 
 struct kvm_stat_data {
        struct kvm *kvm;
-       struct kvm_stats_debugfs_item *dbgfs_item;
-};
-
-struct kvm_stats_debugfs_item {
-       const char *name;
-       int offset;
+       const struct _kvm_stats_desc *desc;
        enum kvm_stat_kind kind;
-       int mode;
 };
 
-#define KVM_DBGFS_GET_MODE(dbgfs_item)                                         \
-       ((dbgfs_item)->mode ? (dbgfs_item)->mode : 0644)
+struct _kvm_stats_desc {
+       struct kvm_stats_desc desc;
+       char name[KVM_STATS_NAME_SIZE];
+};
 
-#define VM_STAT(n, x, ...)                                                     \
-       { n, offsetof(struct kvm, stat.x), KVM_STAT_VM, ## __VA_ARGS__ }
-#define VCPU_STAT(n, x, ...)                                                   \
-       { n, offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU, ## __VA_ARGS__ }
+#define STATS_DESC_COMMON(type, unit, base, exp)                              \
+       .flags = type | unit | base |                                          \
+                BUILD_BUG_ON_ZERO(type & ~KVM_STATS_TYPE_MASK) |              \
+                BUILD_BUG_ON_ZERO(unit & ~KVM_STATS_UNIT_MASK) |              \
+                BUILD_BUG_ON_ZERO(base & ~KVM_STATS_BASE_MASK),               \
+       .exponent = exp,                                                       \
+       .size = 1
+
+#define VM_GENERIC_STATS_DESC(stat, type, unit, base, exp)                    \
+       {                                                                      \
+               {                                                              \
+                       STATS_DESC_COMMON(type, unit, base, exp),              \
+                       .offset = offsetof(struct kvm_vm_stat, generic.stat)   \
+               },                                                             \
+               .name = #stat,                                                 \
+       }
+#define VCPU_GENERIC_STATS_DESC(stat, type, unit, base, exp)                  \
+       {                                                                      \
+               {                                                              \
+                       STATS_DESC_COMMON(type, unit, base, exp),              \
+                       .offset = offsetof(struct kvm_vcpu_stat, generic.stat) \
+               },                                                             \
+               .name = #stat,                                                 \
+       }
+#define VM_STATS_DESC(stat, type, unit, base, exp)                            \
+       {                                                                      \
+               {                                                              \
+                       STATS_DESC_COMMON(type, unit, base, exp),              \
+                       .offset = offsetof(struct kvm_vm_stat, stat)           \
+               },                                                             \
+               .name = #stat,                                                 \
+       }
+#define VCPU_STATS_DESC(stat, type, unit, base, exp)                          \
+       {                                                                      \
+               {                                                              \
+                       STATS_DESC_COMMON(type, unit, base, exp),              \
+                       .offset = offsetof(struct kvm_vcpu_stat, stat)         \
+               },                                                             \
+               .name = #stat,                                                 \
+       }
+/* SCOPE: VM, VM_GENERIC, VCPU, VCPU_GENERIC */
+#define STATS_DESC(SCOPE, stat, type, unit, base, exp)                        \
+       SCOPE##_STATS_DESC(stat, type, unit, base, exp)
+
+#define STATS_DESC_CUMULATIVE(SCOPE, name, unit, base, exponent)              \
+       STATS_DESC(SCOPE, name, KVM_STATS_TYPE_CUMULATIVE, unit, base, exponent)
+#define STATS_DESC_INSTANT(SCOPE, name, unit, base, exponent)                 \
+       STATS_DESC(SCOPE, name, KVM_STATS_TYPE_INSTANT, unit, base, exponent)
+#define STATS_DESC_PEAK(SCOPE, name, unit, base, exponent)                    \
+       STATS_DESC(SCOPE, name, KVM_STATS_TYPE_PEAK, unit, base, exponent)
+
+/* Cumulative counter, read/write */
+#define STATS_DESC_COUNTER(SCOPE, name)                                               \
+       STATS_DESC_CUMULATIVE(SCOPE, name, KVM_STATS_UNIT_NONE,                \
+               KVM_STATS_BASE_POW10, 0)
+/* Instantaneous counter, read only */
+#define STATS_DESC_ICOUNTER(SCOPE, name)                                      \
+       STATS_DESC_INSTANT(SCOPE, name, KVM_STATS_UNIT_NONE,                   \
+               KVM_STATS_BASE_POW10, 0)
+/* Peak counter, read/write */
+#define STATS_DESC_PCOUNTER(SCOPE, name)                                      \
+       STATS_DESC_PEAK(SCOPE, name, KVM_STATS_UNIT_NONE,                      \
+               KVM_STATS_BASE_POW10, 0)
+
+/* Cumulative time in nanosecond */
+#define STATS_DESC_TIME_NSEC(SCOPE, name)                                     \
+       STATS_DESC_CUMULATIVE(SCOPE, name, KVM_STATS_UNIT_SECONDS,             \
+               KVM_STATS_BASE_POW10, -9)
+
+#define KVM_GENERIC_VM_STATS()                                                \
+       STATS_DESC_COUNTER(VM_GENERIC, remote_tlb_flush)
+
+#define KVM_GENERIC_VCPU_STATS()                                              \
+       STATS_DESC_COUNTER(VCPU_GENERIC, halt_successful_poll),                \
+       STATS_DESC_COUNTER(VCPU_GENERIC, halt_attempted_poll),                 \
+       STATS_DESC_COUNTER(VCPU_GENERIC, halt_poll_invalid),                   \
+       STATS_DESC_COUNTER(VCPU_GENERIC, halt_wakeup),                         \
+       STATS_DESC_TIME_NSEC(VCPU_GENERIC, halt_poll_success_ns),              \
+       STATS_DESC_TIME_NSEC(VCPU_GENERIC, halt_poll_fail_ns)
 
-extern struct kvm_stats_debugfs_item debugfs_entries[];
 extern struct dentry *kvm_debugfs_dir;
+ssize_t kvm_stats_read(char *id, const struct kvm_stats_header *header,
+                      const struct _kvm_stats_desc *desc,
+                      void *stats, size_t size_stats,
+                      char __user *user_buffer, size_t size, loff_t *offset);
+extern const struct kvm_stats_header kvm_vm_stats_header;
+extern const struct _kvm_stats_desc kvm_vm_stats_desc[];
+extern const struct kvm_stats_header kvm_vcpu_stats_header;
+extern const struct _kvm_stats_desc kvm_vcpu_stats_desc[];
 
 #if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
 static inline int mmu_notifier_retry(struct kvm *kvm, unsigned long mmu_seq)