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
12static struct dentry *vfio_debugfs_root;
13
14static 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
61void 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
78void vfio_device_debugfs_exit(struct vfio_device *vdev)
79{
80	debugfs_remove_recursive(vdev->debug_root);
81}
82
83void vfio_debugfs_create_root(void)
84{
85	vfio_debugfs_root = debugfs_create_dir("vfio", NULL);
86}
87
88void vfio_debugfs_remove_root(void)
89{
90	debugfs_remove_recursive(vfio_debugfs_root);
91	vfio_debugfs_root = NULL;
92}
93