Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/x86/xen/debugfs.c
10817 views
1
#include <linux/init.h>
2
#include <linux/debugfs.h>
3
#include <linux/slab.h>
4
#include <linux/module.h>
5
6
#include "debugfs.h"
7
8
static struct dentry *d_xen_debug;
9
10
struct dentry * __init xen_init_debugfs(void)
11
{
12
if (!d_xen_debug) {
13
d_xen_debug = debugfs_create_dir("xen", NULL);
14
15
if (!d_xen_debug)
16
pr_warning("Could not create 'xen' debugfs directory\n");
17
}
18
19
return d_xen_debug;
20
}
21
22
struct array_data
23
{
24
void *array;
25
unsigned elements;
26
};
27
28
static int u32_array_open(struct inode *inode, struct file *file)
29
{
30
file->private_data = NULL;
31
return nonseekable_open(inode, file);
32
}
33
34
static size_t format_array(char *buf, size_t bufsize, const char *fmt,
35
u32 *array, unsigned array_size)
36
{
37
size_t ret = 0;
38
unsigned i;
39
40
for(i = 0; i < array_size; i++) {
41
size_t len;
42
43
len = snprintf(buf, bufsize, fmt, array[i]);
44
len++; /* ' ' or '\n' */
45
ret += len;
46
47
if (buf) {
48
buf += len;
49
bufsize -= len;
50
buf[-1] = (i == array_size-1) ? '\n' : ' ';
51
}
52
}
53
54
ret++; /* \0 */
55
if (buf)
56
*buf = '\0';
57
58
return ret;
59
}
60
61
static char *format_array_alloc(const char *fmt, u32 *array, unsigned array_size)
62
{
63
size_t len = format_array(NULL, 0, fmt, array, array_size);
64
char *ret;
65
66
ret = kmalloc(len, GFP_KERNEL);
67
if (ret == NULL)
68
return NULL;
69
70
format_array(ret, len, fmt, array, array_size);
71
return ret;
72
}
73
74
static ssize_t u32_array_read(struct file *file, char __user *buf, size_t len,
75
loff_t *ppos)
76
{
77
struct inode *inode = file->f_path.dentry->d_inode;
78
struct array_data *data = inode->i_private;
79
size_t size;
80
81
if (*ppos == 0) {
82
if (file->private_data) {
83
kfree(file->private_data);
84
file->private_data = NULL;
85
}
86
87
file->private_data = format_array_alloc("%u", data->array, data->elements);
88
}
89
90
size = 0;
91
if (file->private_data)
92
size = strlen(file->private_data);
93
94
return simple_read_from_buffer(buf, len, ppos, file->private_data, size);
95
}
96
97
static int xen_array_release(struct inode *inode, struct file *file)
98
{
99
kfree(file->private_data);
100
101
return 0;
102
}
103
104
static const struct file_operations u32_array_fops = {
105
.owner = THIS_MODULE,
106
.open = u32_array_open,
107
.release= xen_array_release,
108
.read = u32_array_read,
109
.llseek = no_llseek,
110
};
111
112
struct dentry *xen_debugfs_create_u32_array(const char *name, mode_t mode,
113
struct dentry *parent,
114
u32 *array, unsigned elements)
115
{
116
struct array_data *data = kmalloc(sizeof(*data), GFP_KERNEL);
117
118
if (data == NULL)
119
return NULL;
120
121
data->array = array;
122
data->elements = elements;
123
124
return debugfs_create_file(name, mode, parent, data, &u32_array_fops);
125
}
126
127