GNU Linux-libre 6.9.1-gnu
[releases.git] / drivers / vfio / debugfs.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2023, HiSilicon Ltd.
4  */
5
6 #include <linux/device.h>
7 #include <linux/debugfs.h>
8 #include <linux/seq_file.h>
9 #include <linux/vfio.h>
10 #include "vfio.h"
11
12 static struct dentry *vfio_debugfs_root;
13
14 static int vfio_device_state_read(struct seq_file *seq, void *data)
15 {
16         struct device *vf_dev = seq->private;
17         struct vfio_device *vdev = container_of(vf_dev,
18                                                 struct vfio_device, device);
19         enum vfio_device_mig_state state;
20         int ret;
21
22         BUILD_BUG_ON(VFIO_DEVICE_STATE_NR !=
23                      VFIO_DEVICE_STATE_PRE_COPY_P2P + 1);
24
25         ret = vdev->mig_ops->migration_get_state(vdev, &state);
26         if (ret)
27                 return -EINVAL;
28
29         switch (state) {
30         case VFIO_DEVICE_STATE_ERROR:
31                 seq_puts(seq, "ERROR\n");
32                 break;
33         case VFIO_DEVICE_STATE_STOP:
34                 seq_puts(seq, "STOP\n");
35                 break;
36         case VFIO_DEVICE_STATE_RUNNING:
37                 seq_puts(seq, "RUNNING\n");
38                 break;
39         case VFIO_DEVICE_STATE_STOP_COPY:
40                 seq_puts(seq, "STOP_COPY\n");
41                 break;
42         case VFIO_DEVICE_STATE_RESUMING:
43                 seq_puts(seq, "RESUMING\n");
44                 break;
45         case VFIO_DEVICE_STATE_RUNNING_P2P:
46                 seq_puts(seq, "RUNNING_P2P\n");
47                 break;
48         case VFIO_DEVICE_STATE_PRE_COPY:
49                 seq_puts(seq, "PRE_COPY\n");
50                 break;
51         case VFIO_DEVICE_STATE_PRE_COPY_P2P:
52                 seq_puts(seq, "PRE_COPY_P2P\n");
53                 break;
54         default:
55                 seq_puts(seq, "Invalid\n");
56         }
57
58         return 0;
59 }
60
61 void vfio_device_debugfs_init(struct vfio_device *vdev)
62 {
63         struct device *dev = &vdev->device;
64
65         vdev->debug_root = debugfs_create_dir(dev_name(vdev->dev),
66                                               vfio_debugfs_root);
67
68         if (vdev->mig_ops) {
69                 struct dentry *vfio_dev_migration = NULL;
70
71                 vfio_dev_migration = debugfs_create_dir("migration",
72                                                         vdev->debug_root);
73                 debugfs_create_devm_seqfile(dev, "state", vfio_dev_migration,
74                                             vfio_device_state_read);
75         }
76 }
77
78 void vfio_device_debugfs_exit(struct vfio_device *vdev)
79 {
80         debugfs_remove_recursive(vdev->debug_root);
81 }
82
83 void vfio_debugfs_create_root(void)
84 {
85         vfio_debugfs_root = debugfs_create_dir("vfio", NULL);
86 }
87
88 void vfio_debugfs_remove_root(void)
89 {
90         debugfs_remove_recursive(vfio_debugfs_root);
91         vfio_debugfs_root = NULL;
92 }