summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--virt/kvm/kvm_main.c78
1 files changed, 72 insertions, 6 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index d92c3d5b0fbe..b44edd85011a 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -595,7 +595,7 @@ static int kvm_create_vm_debugfs(struct kvm *kvm, int fd)
595 stat_data->kvm = kvm; 595 stat_data->kvm = kvm;
596 stat_data->offset = p->offset; 596 stat_data->offset = p->offset;
597 kvm->debugfs_stat_data[p - debugfs_entries] = stat_data; 597 kvm->debugfs_stat_data[p - debugfs_entries] = stat_data;
598 if (!debugfs_create_file(p->name, 0444, 598 if (!debugfs_create_file(p->name, 0644,
599 kvm->debugfs_dentry, 599 kvm->debugfs_dentry,
600 stat_data, 600 stat_data,
601 stat_fops_per_vm[p->kind])) 601 stat_fops_per_vm[p->kind]))
@@ -3663,11 +3663,23 @@ static int vm_stat_get_per_vm(void *data, u64 *val)
3663 return 0; 3663 return 0;
3664} 3664}
3665 3665
3666static int vm_stat_clear_per_vm(void *data, u64 val)
3667{
3668 struct kvm_stat_data *stat_data = (struct kvm_stat_data *)data;
3669
3670 if (val)
3671 return -EINVAL;
3672
3673 *(ulong *)((void *)stat_data->kvm + stat_data->offset) = 0;
3674
3675 return 0;
3676}
3677
3666static int vm_stat_get_per_vm_open(struct inode *inode, struct file *file) 3678static int vm_stat_get_per_vm_open(struct inode *inode, struct file *file)
3667{ 3679{
3668 __simple_attr_check_format("%llu\n", 0ull); 3680 __simple_attr_check_format("%llu\n", 0ull);
3669 return kvm_debugfs_open(inode, file, vm_stat_get_per_vm, 3681 return kvm_debugfs_open(inode, file, vm_stat_get_per_vm,
3670 NULL, "%llu\n"); 3682 vm_stat_clear_per_vm, "%llu\n");
3671} 3683}
3672 3684
3673static const struct file_operations vm_stat_get_per_vm_fops = { 3685static const struct file_operations vm_stat_get_per_vm_fops = {
@@ -3693,11 +3705,26 @@ static int vcpu_stat_get_per_vm(void *data, u64 *val)
3693 return 0; 3705 return 0;
3694} 3706}
3695 3707
3708static int vcpu_stat_clear_per_vm(void *data, u64 val)
3709{
3710 int i;
3711 struct kvm_stat_data *stat_data = (struct kvm_stat_data *)data;
3712 struct kvm_vcpu *vcpu;
3713
3714 if (val)
3715 return -EINVAL;
3716
3717 kvm_for_each_vcpu(i, vcpu, stat_data->kvm)
3718 *(u64 *)((void *)vcpu + stat_data->offset) = 0;
3719
3720 return 0;
3721}
3722
3696static int vcpu_stat_get_per_vm_open(struct inode *inode, struct file *file) 3723static int vcpu_stat_get_per_vm_open(struct inode *inode, struct file *file)
3697{ 3724{
3698 __simple_attr_check_format("%llu\n", 0ull); 3725 __simple_attr_check_format("%llu\n", 0ull);
3699 return kvm_debugfs_open(inode, file, vcpu_stat_get_per_vm, 3726 return kvm_debugfs_open(inode, file, vcpu_stat_get_per_vm,
3700 NULL, "%llu\n"); 3727 vcpu_stat_clear_per_vm, "%llu\n");
3701} 3728}
3702 3729
3703static const struct file_operations vcpu_stat_get_per_vm_fops = { 3730static const struct file_operations vcpu_stat_get_per_vm_fops = {
@@ -3732,7 +3759,26 @@ static int vm_stat_get(void *_offset, u64 *val)
3732 return 0; 3759 return 0;
3733} 3760}
3734 3761
3735DEFINE_SIMPLE_ATTRIBUTE(vm_stat_fops, vm_stat_get, NULL, "%llu\n"); 3762static int vm_stat_clear(void *_offset, u64 val)
3763{
3764 unsigned offset = (long)_offset;
3765 struct kvm *kvm;
3766 struct kvm_stat_data stat_tmp = {.offset = offset};
3767
3768 if (val)
3769 return -EINVAL;
3770
3771 spin_lock(&kvm_lock);
3772 list_for_each_entry(kvm, &vm_list, vm_list) {
3773 stat_tmp.kvm = kvm;
3774 vm_stat_clear_per_vm((void *)&stat_tmp, 0);
3775 }
3776 spin_unlock(&kvm_lock);
3777
3778 return 0;
3779}
3780
3781DEFINE_SIMPLE_ATTRIBUTE(vm_stat_fops, vm_stat_get, vm_stat_clear, "%llu\n");
3736 3782
3737static int vcpu_stat_get(void *_offset, u64 *val) 3783static int vcpu_stat_get(void *_offset, u64 *val)
3738{ 3784{
@@ -3752,7 +3798,27 @@ static int vcpu_stat_get(void *_offset, u64 *val)
3752 return 0; 3798 return 0;
3753} 3799}
3754 3800
3755DEFINE_SIMPLE_ATTRIBUTE(vcpu_stat_fops, vcpu_stat_get, NULL, "%llu\n"); 3801static int vcpu_stat_clear(void *_offset, u64 val)
3802{
3803 unsigned offset = (long)_offset;
3804 struct kvm *kvm;
3805 struct kvm_stat_data stat_tmp = {.offset = offset};
3806
3807 if (val)
3808 return -EINVAL;
3809
3810 spin_lock(&kvm_lock);
3811 list_for_each_entry(kvm, &vm_list, vm_list) {
3812 stat_tmp.kvm = kvm;
3813 vcpu_stat_clear_per_vm((void *)&stat_tmp, 0);
3814 }
3815 spin_unlock(&kvm_lock);
3816
3817 return 0;
3818}
3819
3820DEFINE_SIMPLE_ATTRIBUTE(vcpu_stat_fops, vcpu_stat_get, vcpu_stat_clear,
3821 "%llu\n");
3756 3822
3757static const struct file_operations *stat_fops[] = { 3823static const struct file_operations *stat_fops[] = {
3758 [KVM_STAT_VCPU] = &vcpu_stat_fops, 3824 [KVM_STAT_VCPU] = &vcpu_stat_fops,
@@ -3770,7 +3836,7 @@ static int kvm_init_debug(void)
3770 3836
3771 kvm_debugfs_num_entries = 0; 3837 kvm_debugfs_num_entries = 0;
3772 for (p = debugfs_entries; p->name; ++p, kvm_debugfs_num_entries++) { 3838 for (p = debugfs_entries; p->name; ++p, kvm_debugfs_num_entries++) {
3773 if (!debugfs_create_file(p->name, 0444, kvm_debugfs_dir, 3839 if (!debugfs_create_file(p->name, 0644, kvm_debugfs_dir,
3774 (void *)(long)p->offset, 3840 (void *)(long)p->offset,
3775 stat_fops[p->kind])) 3841 stat_fops[p->kind]))
3776 goto out_dir; 3842 goto out_dir;