diff options
Diffstat (limited to 'drivers/kvm/kvm_main.c')
-rw-r--r-- | drivers/kvm/kvm_main.c | 61 |
1 files changed, 43 insertions, 18 deletions
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index f5356358acff..911c8175cc08 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c | |||
@@ -51,27 +51,27 @@ static DEFINE_SPINLOCK(kvm_lock); | |||
51 | static LIST_HEAD(vm_list); | 51 | static LIST_HEAD(vm_list); |
52 | 52 | ||
53 | struct kvm_arch_ops *kvm_arch_ops; | 53 | struct kvm_arch_ops *kvm_arch_ops; |
54 | struct kvm_stat kvm_stat; | 54 | |
55 | EXPORT_SYMBOL_GPL(kvm_stat); | 55 | #define STAT_OFFSET(x) offsetof(struct kvm_vcpu, stat.x) |
56 | 56 | ||
57 | static struct kvm_stats_debugfs_item { | 57 | static struct kvm_stats_debugfs_item { |
58 | const char *name; | 58 | const char *name; |
59 | u32 *data; | 59 | int offset; |
60 | struct dentry *dentry; | 60 | struct dentry *dentry; |
61 | } debugfs_entries[] = { | 61 | } debugfs_entries[] = { |
62 | { "pf_fixed", &kvm_stat.pf_fixed }, | 62 | { "pf_fixed", STAT_OFFSET(pf_fixed) }, |
63 | { "pf_guest", &kvm_stat.pf_guest }, | 63 | { "pf_guest", STAT_OFFSET(pf_guest) }, |
64 | { "tlb_flush", &kvm_stat.tlb_flush }, | 64 | { "tlb_flush", STAT_OFFSET(tlb_flush) }, |
65 | { "invlpg", &kvm_stat.invlpg }, | 65 | { "invlpg", STAT_OFFSET(invlpg) }, |
66 | { "exits", &kvm_stat.exits }, | 66 | { "exits", STAT_OFFSET(exits) }, |
67 | { "io_exits", &kvm_stat.io_exits }, | 67 | { "io_exits", STAT_OFFSET(io_exits) }, |
68 | { "mmio_exits", &kvm_stat.mmio_exits }, | 68 | { "mmio_exits", STAT_OFFSET(mmio_exits) }, |
69 | { "signal_exits", &kvm_stat.signal_exits }, | 69 | { "signal_exits", STAT_OFFSET(signal_exits) }, |
70 | { "irq_window", &kvm_stat.irq_window_exits }, | 70 | { "irq_window", STAT_OFFSET(irq_window_exits) }, |
71 | { "halt_exits", &kvm_stat.halt_exits }, | 71 | { "halt_exits", STAT_OFFSET(halt_exits) }, |
72 | { "request_irq", &kvm_stat.request_irq_exits }, | 72 | { "request_irq", STAT_OFFSET(request_irq_exits) }, |
73 | { "irq_exits", &kvm_stat.irq_exits }, | 73 | { "irq_exits", STAT_OFFSET(irq_exits) }, |
74 | { NULL, NULL } | 74 | { NULL } |
75 | }; | 75 | }; |
76 | 76 | ||
77 | static struct dentry *debugfs_dir; | 77 | static struct dentry *debugfs_dir; |
@@ -2930,14 +2930,39 @@ static struct notifier_block kvm_cpu_notifier = { | |||
2930 | .priority = 20, /* must be > scheduler priority */ | 2930 | .priority = 20, /* must be > scheduler priority */ |
2931 | }; | 2931 | }; |
2932 | 2932 | ||
2933 | static u64 stat_get(void *_offset) | ||
2934 | { | ||
2935 | unsigned offset = (long)_offset; | ||
2936 | u64 total = 0; | ||
2937 | struct kvm *kvm; | ||
2938 | struct kvm_vcpu *vcpu; | ||
2939 | int i; | ||
2940 | |||
2941 | spin_lock(&kvm_lock); | ||
2942 | list_for_each_entry(kvm, &vm_list, vm_list) | ||
2943 | for (i = 0; i < KVM_MAX_VCPUS; ++i) { | ||
2944 | vcpu = &kvm->vcpus[i]; | ||
2945 | total += *(u32 *)((void *)vcpu + offset); | ||
2946 | } | ||
2947 | spin_unlock(&kvm_lock); | ||
2948 | return total; | ||
2949 | } | ||
2950 | |||
2951 | static void stat_set(void *offset, u64 val) | ||
2952 | { | ||
2953 | } | ||
2954 | |||
2955 | DEFINE_SIMPLE_ATTRIBUTE(stat_fops, stat_get, stat_set, "%llu\n"); | ||
2956 | |||
2933 | static __init void kvm_init_debug(void) | 2957 | static __init void kvm_init_debug(void) |
2934 | { | 2958 | { |
2935 | struct kvm_stats_debugfs_item *p; | 2959 | struct kvm_stats_debugfs_item *p; |
2936 | 2960 | ||
2937 | debugfs_dir = debugfs_create_dir("kvm", NULL); | 2961 | debugfs_dir = debugfs_create_dir("kvm", NULL); |
2938 | for (p = debugfs_entries; p->name; ++p) | 2962 | for (p = debugfs_entries; p->name; ++p) |
2939 | p->dentry = debugfs_create_u32(p->name, 0444, debugfs_dir, | 2963 | p->dentry = debugfs_create_file(p->name, 0444, debugfs_dir, |
2940 | p->data); | 2964 | (void *)(long)p->offset, |
2965 | &stat_fops); | ||
2941 | } | 2966 | } |
2942 | 2967 | ||
2943 | static void kvm_exit_debug(void) | 2968 | static void kvm_exit_debug(void) |