KVM: PPC: Merge powerpc's debugfs entry content into generic entry
authorAlexey Kardashevskiy <aik@ozlabs.ru>
Tue, 11 Jan 2022 00:54:04 +0000 (11:54 +1100)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 2 Feb 2022 09:30:26 +0000 (20:30 +1100)
At the moment KVM on PPC creates 4 types of entries under the kvm debugfs:
1) "%pid-%fd" per a KVM instance (for all platforms);
2) "vm%pid" (for PPC Book3s HV KVM);
3) "vm%u_vcpu%u_timing" (for PPC Book3e KVM);
4) "kvm-xive-%p" (for XIVE PPC Book3s KVM, the same for XICS);

The problem with this is that multiple VMs per process is not allowed for
2) and 3) which makes it possible for userspace to trigger errors when
creating duplicated debugfs entries.

This merges all these into 1).

This defines kvm_arch_create_kvm_debugfs() similar to
kvm_arch_create_vcpu_debugfs().

This defines 2 hooks in kvmppc_ops that allow specific KVM implementations
add necessary entries, this adds the _e500 suffix to
kvmppc_create_vcpu_debugfs_e500() to make it clear what platform it is for.

This makes use of already existing kvm_arch_create_vcpu_debugfs() on PPC.

This removes no more used debugfs_dir pointers from PPC kvm_arch structs.

This stops removing vcpu entries as once created vcpus stay around
for the entire life of a VM and removed when the KVM instance is closed,
see commit d56f5136b010 ("KVM: let kvm_destroy_vm_debugfs clean up vCPU
debugfs directories").

Suggested-by: Fabiano Rosas <farosas@linux.ibm.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20220111005404.162219-1-aik@ozlabs.ru
13 files changed:
arch/powerpc/include/asm/kvm_host.h
arch/powerpc/include/asm/kvm_ppc.h
arch/powerpc/kvm/book3s_64_mmu_hv.c
arch/powerpc/kvm/book3s_64_mmu_radix.c
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/kvm/book3s_xics.c
arch/powerpc/kvm/book3s_xive.c
arch/powerpc/kvm/book3s_xive_native.c
arch/powerpc/kvm/e500.c
arch/powerpc/kvm/e500mc.c
arch/powerpc/kvm/powerpc.c
arch/powerpc/kvm/timing.c
arch/powerpc/kvm/timing.h

index d9bf60bf081617c7c3a7f5fbaa1527cb3f6e70b8..faf301d0dec0164c7420644e9a64c916fa1442d0 100644 (file)
@@ -26,6 +26,8 @@
 #include <asm/hvcall.h>
 #include <asm/mce.h>
 
+#define __KVM_HAVE_ARCH_VCPU_DEBUGFS
+
 #define KVM_MAX_VCPUS          NR_CPUS
 #define KVM_MAX_VCORES         NR_CPUS
 
@@ -295,7 +297,6 @@ struct kvm_arch {
        bool dawr1_enabled;
        pgd_t *pgtable;
        u64 process_table;
-       struct dentry *debugfs_dir;
        struct kvm_resize_hpt *resize_hpt; /* protected by kvm->lock */
 #endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */
 #ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
@@ -673,7 +674,6 @@ struct kvm_vcpu_arch {
        u64 timing_min_duration[__NUMBER_OF_KVM_EXIT_TYPES];
        u64 timing_max_duration[__NUMBER_OF_KVM_EXIT_TYPES];
        u64 timing_last_exit;
-       struct dentry *debugfs_exit_timing;
 #endif
 
 #ifdef CONFIG_PPC_BOOK3S
@@ -831,8 +831,6 @@ struct kvm_vcpu_arch {
        struct kvmhv_tb_accumulator rm_exit;    /* real-mode exit code */
        struct kvmhv_tb_accumulator guest_time; /* guest execution */
        struct kvmhv_tb_accumulator cede_time;  /* time napping inside guest */
-
-       struct dentry *debugfs_dir;
 #endif /* CONFIG_KVM_BOOK3S_HV_EXIT_TIMING */
 };
 
index a14dbcd1b8ce00e5942235f39e17ae158b9fc1ed..c583d0c37f319247471811960d9b6e534ace6b23 100644 (file)
@@ -314,6 +314,8 @@ struct kvmppc_ops {
        int (*svm_off)(struct kvm *kvm);
        int (*enable_dawr1)(struct kvm *kvm);
        bool (*hash_v3_possible)(void);
+       int (*create_vm_debugfs)(struct kvm *kvm);
+       int (*create_vcpu_debugfs)(struct kvm_vcpu *vcpu, struct dentry *debugfs_dentry);
 };
 
 extern struct kvmppc_ops *kvmppc_hv_ops;
index 2132329143670ea3f6a3c4d7dd5d7ff6de9afa14..0aeb51738ca9b2d8e0966c291a3d6b19bf84d87a 100644 (file)
@@ -2112,7 +2112,7 @@ static const struct file_operations debugfs_htab_fops = {
 
 void kvmppc_mmu_debugfs_init(struct kvm *kvm)
 {
-       debugfs_create_file("htab", 0400, kvm->arch.debugfs_dir, kvm,
+       debugfs_create_file("htab", 0400, kvm->debugfs_dentry, kvm,
                            &debugfs_htab_fops);
 }
 
index 8cebe5542256072e6972c67ce2078ffc1a0d9463..e4ce2a35483f6fcb32f00b50c633c563375e1a1d 100644 (file)
@@ -1454,7 +1454,7 @@ static const struct file_operations debugfs_radix_fops = {
 
 void kvmhv_radix_debugfs_init(struct kvm *kvm)
 {
-       debugfs_create_file("radix", 0400, kvm->arch.debugfs_dir, kvm,
+       debugfs_create_file("radix", 0400, kvm->debugfs_dentry, kvm,
                            &debugfs_radix_fops);
 }
 
index 84c89f08ae9aa97eb04b8de6b91f491dedf0592a..c7e44d75f8aa85e72e4d9c8260386afc05f812f7 100644 (file)
@@ -2767,20 +2767,17 @@ static const struct file_operations debugfs_timings_ops = {
 };
 
 /* Create a debugfs directory for the vcpu */
-static void debugfs_vcpu_init(struct kvm_vcpu *vcpu, unsigned int id)
+static int kvmppc_arch_create_vcpu_debugfs_hv(struct kvm_vcpu *vcpu, struct dentry *debugfs_dentry)
 {
-       char buf[16];
-       struct kvm *kvm = vcpu->kvm;
-
-       snprintf(buf, sizeof(buf), "vcpu%u", id);
-       vcpu->arch.debugfs_dir = debugfs_create_dir(buf, kvm->arch.debugfs_dir);
-       debugfs_create_file("timings", 0444, vcpu->arch.debugfs_dir, vcpu,
+       debugfs_create_file("timings", 0444, debugfs_dentry, vcpu,
                            &debugfs_timings_ops);
+       return 0;
 }
 
 #else /* CONFIG_KVM_BOOK3S_HV_EXIT_TIMING */
-static void debugfs_vcpu_init(struct kvm_vcpu *vcpu, unsigned int id)
+static int kvmppc_arch_create_vcpu_debugfs_hv(struct kvm_vcpu *vcpu, struct dentry *debugfs_dentry)
 {
+       return 0;
 }
 #endif /* CONFIG_KVM_BOOK3S_HV_EXIT_TIMING */
 
@@ -2903,8 +2900,6 @@ static int kvmppc_core_vcpu_create_hv(struct kvm_vcpu *vcpu)
        vcpu->arch.cpu_type = KVM_CPU_3S_64;
        kvmppc_sanity_check(vcpu);
 
-       debugfs_vcpu_init(vcpu, id);
-
        return 0;
 }
 
@@ -5223,7 +5218,6 @@ void kvmppc_free_host_rm_ops(void)
 static int kvmppc_core_init_vm_hv(struct kvm *kvm)
 {
        unsigned long lpcr, lpid;
-       char buf[32];
        int ret;
 
        mutex_init(&kvm->arch.uvmem_lock);
@@ -5356,15 +5350,14 @@ static int kvmppc_core_init_vm_hv(struct kvm *kvm)
                kvm->arch.smt_mode = 1;
        kvm->arch.emul_smt_mode = 1;
 
-       /*
-        * Create a debugfs directory for the VM
-        */
-       snprintf(buf, sizeof(buf), "vm%d", current->pid);
-       kvm->arch.debugfs_dir = debugfs_create_dir(buf, kvm_debugfs_dir);
+       return 0;
+}
+
+static int kvmppc_arch_create_vm_debugfs_hv(struct kvm *kvm)
+{
        kvmppc_mmu_debugfs_init(kvm);
        if (radix_enabled())
                kvmhv_radix_debugfs_init(kvm);
-
        return 0;
 }
 
@@ -5379,8 +5372,6 @@ static void kvmppc_free_vcores(struct kvm *kvm)
 
 static void kvmppc_core_destroy_vm_hv(struct kvm *kvm)
 {
-       debugfs_remove_recursive(kvm->arch.debugfs_dir);
-
        if (!cpu_has_feature(CPU_FTR_ARCH_300))
                kvm_hv_vm_deactivated();
 
@@ -6042,6 +6033,8 @@ static struct kvmppc_ops kvm_ops_hv = {
        .svm_off = kvmhv_svm_off,
        .enable_dawr1 = kvmhv_enable_dawr1,
        .hash_v3_possible = kvmppc_hash_v3_possible,
+       .create_vcpu_debugfs = kvmppc_arch_create_vcpu_debugfs_hv,
+       .create_vm_debugfs = kvmppc_arch_create_vm_debugfs_hv,
 };
 
 static int kvm_init_subcore_bitmap(void)
index 9cc466006e8bb57331d3564c6c5043746ccd7591..306c85e70eeac1574e1c89ae67913b06ea7d75f2 100644 (file)
@@ -1016,19 +1016,10 @@ DEFINE_SHOW_ATTRIBUTE(xics_debug);
 
 static void xics_debugfs_init(struct kvmppc_xics *xics)
 {
-       char *name;
-
-       name = kasprintf(GFP_KERNEL, "kvm-xics-%p", xics);
-       if (!name) {
-               pr_err("%s: no memory for name\n", __func__);
-               return;
-       }
-
-       xics->dentry = debugfs_create_file(name, 0444, arch_debugfs_dir,
+       xics->dentry = debugfs_create_file("xics", 0444, xics->kvm->debugfs_dentry,
                                           xics, &xics_debug_fops);
 
-       pr_debug("%s: created %s\n", __func__, name);
-       kfree(name);
+       pr_debug("%s: created\n", __func__);
 }
 
 static struct kvmppc_ics *kvmppc_xics_create_ics(struct kvm *kvm,
index e216c068075d7d69ea1bd623c5532b80cdcc2c90..37a56cbb17014ba06a068f372e558dd286879680 100644 (file)
@@ -2354,19 +2354,10 @@ DEFINE_SHOW_ATTRIBUTE(xive_debug);
 
 static void xive_debugfs_init(struct kvmppc_xive *xive)
 {
-       char *name;
-
-       name = kasprintf(GFP_KERNEL, "kvm-xive-%p", xive);
-       if (!name) {
-               pr_err("%s: no memory for name\n", __func__);
-               return;
-       }
-
-       xive->dentry = debugfs_create_file(name, S_IRUGO, arch_debugfs_dir,
+       xive->dentry = debugfs_create_file("xive", S_IRUGO, xive->kvm->debugfs_dentry,
                                           xive, &xive_debug_fops);
 
-       pr_debug("%s: created %s\n", __func__, name);
-       kfree(name);
+       pr_debug("%s: created\n", __func__);
 }
 
 static void kvmppc_xive_init(struct kvm_device *dev)
index 561a5bfe0468f1c8ea52ee537e0dbf193df6062f..3c2b128e5f0fb4bd2d1fe2dcbcde80e620870321 100644 (file)
@@ -1259,19 +1259,10 @@ DEFINE_SHOW_ATTRIBUTE(xive_native_debug);
 
 static void xive_native_debugfs_init(struct kvmppc_xive *xive)
 {
-       char *name;
-
-       name = kasprintf(GFP_KERNEL, "kvm-xive-%p", xive);
-       if (!name) {
-               pr_err("%s: no memory for name\n", __func__);
-               return;
-       }
-
-       xive->dentry = debugfs_create_file(name, 0444, arch_debugfs_dir,
+       xive->dentry = debugfs_create_file("xive", 0444, xive->kvm->debugfs_dentry,
                                           xive, &xive_native_debug_fops);
 
-       pr_debug("%s: created %s\n", __func__, name);
-       kfree(name);
+       pr_debug("%s: created\n", __func__);
 }
 
 static void kvmppc_xive_native_init(struct kvm_device *dev)
index 7e8b69015d207a54e99f758e4fc5c4aa4851d1ac..c8b2b447854554ff338cbddb804bbbd8d987539a 100644 (file)
@@ -495,6 +495,7 @@ static struct kvmppc_ops kvm_ops_e500 = {
        .emulate_op = kvmppc_core_emulate_op_e500,
        .emulate_mtspr = kvmppc_core_emulate_mtspr_e500,
        .emulate_mfspr = kvmppc_core_emulate_mfspr_e500,
+       .create_vcpu_debugfs = kvmppc_create_vcpu_debugfs_e500,
 };
 
 static int __init kvmppc_e500_init(void)
index 1c189b5aadccc277ee4a0a66a843b25fdf87ae1c..fa0d8dbbe48411c28703e0577518ed984ad96d66 100644 (file)
@@ -381,6 +381,7 @@ static struct kvmppc_ops kvm_ops_e500mc = {
        .emulate_op = kvmppc_core_emulate_op_e500,
        .emulate_mtspr = kvmppc_core_emulate_mtspr_e500,
        .emulate_mfspr = kvmppc_core_emulate_mfspr_e500,
+       .create_vcpu_debugfs = kvmppc_create_vcpu_debugfs_e500,
 };
 
 static int __init kvmppc_e500mc_init(void)
index 82d889db2b6b80b8d98f50f662f5449916ab942e..1d06b68739b03247db47233ec8c0444a8c6c2cc7 100644 (file)
@@ -777,7 +777,6 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
 
        rcuwait_init(&vcpu->arch.wait);
        vcpu->arch.waitp = &vcpu->arch.wait;
-       kvmppc_create_vcpu_debugfs(vcpu, vcpu->vcpu_id);
        return 0;
 
 out_vcpu_uninit:
@@ -794,8 +793,6 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
        /* Make sure we're not using the vcpu anymore */
        hrtimer_cancel(&vcpu->arch.dec_timer);
 
-       kvmppc_remove_vcpu_debugfs(vcpu);
-
        switch (vcpu->arch.irq_type) {
        case KVMPPC_IRQ_MPIC:
                kvmppc_mpic_disconnect_vcpu(vcpu->arch.mpic, vcpu);
@@ -2521,3 +2518,16 @@ int kvm_arch_init(void *opaque)
 }
 
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_ppc_instr);
+
+void kvm_arch_create_vcpu_debugfs(struct kvm_vcpu *vcpu, struct dentry *debugfs_dentry)
+{
+       if (vcpu->kvm->arch.kvm_ops->create_vcpu_debugfs)
+               vcpu->kvm->arch.kvm_ops->create_vcpu_debugfs(vcpu, debugfs_dentry);
+}
+
+int kvm_arch_create_vm_debugfs(struct kvm *kvm)
+{
+       if (kvm->arch.kvm_ops->create_vm_debugfs)
+               kvm->arch.kvm_ops->create_vm_debugfs(kvm);
+       return 0;
+}
index ba56a5cbba97f367b9cfa11e5350b58e78d47672..25071331f8c1cd18094959d02f2d4a8e3db936fe 100644 (file)
@@ -204,21 +204,10 @@ static const struct file_operations kvmppc_exit_timing_fops = {
        .release = single_release,
 };
 
-void kvmppc_create_vcpu_debugfs(struct kvm_vcpu *vcpu, unsigned int id)
+int kvmppc_create_vcpu_debugfs_e500(struct kvm_vcpu *vcpu,
+                                   struct dentry *debugfs_dentry)
 {
-       static char dbg_fname[50];
-       struct dentry *debugfs_file;
-
-       snprintf(dbg_fname, sizeof(dbg_fname), "vm%u_vcpu%u_timing",
-                current->pid, id);
-       debugfs_file = debugfs_create_file(dbg_fname, 0666, kvm_debugfs_dir,
-                                               vcpu, &kvmppc_exit_timing_fops);
-
-       vcpu->arch.debugfs_exit_timing = debugfs_file;
-}
-
-void kvmppc_remove_vcpu_debugfs(struct kvm_vcpu *vcpu)
-{
-       debugfs_remove(vcpu->arch.debugfs_exit_timing);
-       vcpu->arch.debugfs_exit_timing = NULL;
+       debugfs_create_file("timing", 0666, debugfs_dentry,
+                           vcpu, &kvmppc_exit_timing_fops);
+       return 0;
 }
index feef7885ba8269f3e842584166fbdd558efe22cc..45817ab82bb43636f1ac63d56944df1d043430ef 100644 (file)
@@ -14,8 +14,8 @@
 #ifdef CONFIG_KVM_EXIT_TIMING
 void kvmppc_init_timing_stats(struct kvm_vcpu *vcpu);
 void kvmppc_update_timing_stats(struct kvm_vcpu *vcpu);
-void kvmppc_create_vcpu_debugfs(struct kvm_vcpu *vcpu, unsigned int id);
-void kvmppc_remove_vcpu_debugfs(struct kvm_vcpu *vcpu);
+int kvmppc_create_vcpu_debugfs_e500(struct kvm_vcpu *vcpu,
+                                   struct dentry *debugfs_dentry);
 
 static inline void kvmppc_set_exit_type(struct kvm_vcpu *vcpu, int type)
 {
@@ -26,9 +26,11 @@ static inline void kvmppc_set_exit_type(struct kvm_vcpu *vcpu, int type)
 /* if exit timing is not configured there is no need to build the c file */
 static inline void kvmppc_init_timing_stats(struct kvm_vcpu *vcpu) {}
 static inline void kvmppc_update_timing_stats(struct kvm_vcpu *vcpu) {}
-static inline void kvmppc_create_vcpu_debugfs(struct kvm_vcpu *vcpu,
-                                               unsigned int id) {}
-static inline void kvmppc_remove_vcpu_debugfs(struct kvm_vcpu *vcpu) {}
+static inline int kvmppc_create_vcpu_debugfs_e500(struct kvm_vcpu *vcpu,
+                                                 struct dentry *debugfs_dentry)
+{
+       return 0;
+}
 static inline void kvmppc_set_exit_type(struct kvm_vcpu *vcpu, int type) {}
 #endif /* CONFIG_KVM_EXIT_TIMING */