This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / drivers / xen / core / xen_sysfs.c
1 /*
2  *  copyright (c) 2006 IBM Corporation
3  *  Authored by: Mike D. Day <ncmike@us.ibm.com>
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License version 2 as
7  *  published by the Free Software Foundation.
8  */
9
10 #include <linux/config.h>
11 #include <linux/err.h>
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <asm/hypervisor.h>
16 #include <xen/features.h>
17 #include <xen/hypervisor_sysfs.h>
18 #include <xen/xenbus.h>
19
20 MODULE_LICENSE("GPL");
21 MODULE_AUTHOR("Mike D. Day <ncmike@us.ibm.com>");
22
23 static ssize_t type_show(struct hyp_sysfs_attr *attr, char *buffer)
24 {
25         return sprintf(buffer, "xen\n");
26 }
27
28 HYPERVISOR_ATTR_RO(type);
29
30 static int __init xen_sysfs_type_init(void)
31 {
32         return sysfs_create_file(&hypervisor_subsys.kset.kobj, &type_attr.attr);
33 }
34
35 static void xen_sysfs_type_destroy(void)
36 {
37         sysfs_remove_file(&hypervisor_subsys.kset.kobj, &type_attr.attr);
38 }
39
40 /* xen version attributes */
41 static ssize_t major_show(struct hyp_sysfs_attr *attr, char *buffer)
42 {
43         int version = HYPERVISOR_xen_version(XENVER_version, NULL);
44         if (version)
45                 return sprintf(buffer, "%d\n", version >> 16);
46         return -ENODEV;
47 }
48
49 HYPERVISOR_ATTR_RO(major);
50
51 static ssize_t minor_show(struct hyp_sysfs_attr *attr, char *buffer)
52 {
53         int version = HYPERVISOR_xen_version(XENVER_version, NULL);
54         if (version)
55                 return sprintf(buffer, "%d\n", version & 0xff);
56         return -ENODEV;
57 }
58
59 HYPERVISOR_ATTR_RO(minor);
60
61 static ssize_t extra_show(struct hyp_sysfs_attr *attr, char *buffer)
62 {
63         int ret = -ENOMEM;
64         char *extra;
65
66         extra = kmalloc(XEN_EXTRAVERSION_LEN, GFP_KERNEL);
67         if (extra) {
68                 ret = HYPERVISOR_xen_version(XENVER_extraversion, extra);
69                 if (!ret)
70                         ret = sprintf(buffer, "%s\n", extra);
71                 kfree(extra);
72         }
73
74         return ret;
75 }
76
77 HYPERVISOR_ATTR_RO(extra);
78
79 static struct attribute *version_attrs[] = {
80         &major_attr.attr,
81         &minor_attr.attr,
82         &extra_attr.attr,
83         NULL
84 };
85
86 static struct attribute_group version_group = {
87         .name = "version",
88         .attrs = version_attrs,
89 };
90
91 static int __init xen_sysfs_version_init(void)
92 {
93         return sysfs_create_group(&hypervisor_subsys.kset.kobj,
94                                   &version_group);
95 }
96
97 static void xen_sysfs_version_destroy(void)
98 {
99         sysfs_remove_group(&hypervisor_subsys.kset.kobj, &version_group);
100 }
101
102 /* UUID */
103
104 static ssize_t uuid_show(struct hyp_sysfs_attr *attr, char *buffer)
105 {
106         char *vm, *val;
107         int ret;
108
109         vm = xenbus_read(XBT_NIL, "vm", "", NULL);
110         if (IS_ERR(vm))
111                 return PTR_ERR(vm);
112         val = xenbus_read(XBT_NIL, vm, "uuid", NULL);
113         kfree(vm);
114         if (IS_ERR(val))
115                 return PTR_ERR(val);
116         ret = sprintf(buffer, "%s\n", val);
117         kfree(val);
118         return ret;
119 }
120
121 HYPERVISOR_ATTR_RO(uuid);
122
123 static int __init xen_sysfs_uuid_init(void)
124 {
125         return sysfs_create_file(&hypervisor_subsys.kset.kobj, &uuid_attr.attr);
126 }
127
128 static void xen_sysfs_uuid_destroy(void)
129 {
130         sysfs_remove_file(&hypervisor_subsys.kset.kobj, &uuid_attr.attr);
131 }
132
133 /* xen compilation attributes */
134
135 static ssize_t compiler_show(struct hyp_sysfs_attr *attr, char *buffer)
136 {
137         int ret = -ENOMEM;
138         struct xen_compile_info *info;
139
140         info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL);
141         if (info) {
142                 ret = HYPERVISOR_xen_version(XENVER_compile_info, info);
143                 if (!ret)
144                         ret = sprintf(buffer, "%s\n", info->compiler);
145                 kfree(info);
146         }
147
148         return ret;
149 }
150
151 HYPERVISOR_ATTR_RO(compiler);
152
153 static ssize_t compiled_by_show(struct hyp_sysfs_attr *attr, char *buffer)
154 {
155         int ret = -ENOMEM;
156         struct xen_compile_info *info;
157
158         info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL);
159         if (info) {
160                 ret = HYPERVISOR_xen_version(XENVER_compile_info, info);
161                 if (!ret)
162                         ret = sprintf(buffer, "%s\n", info->compile_by);
163                 kfree(info);
164         }
165
166         return ret;
167 }
168
169 HYPERVISOR_ATTR_RO(compiled_by);
170
171 static ssize_t compile_date_show(struct hyp_sysfs_attr *attr, char *buffer)
172 {
173         int ret = -ENOMEM;
174         struct xen_compile_info *info;
175
176         info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL);
177         if (info) {
178                 ret = HYPERVISOR_xen_version(XENVER_compile_info, info);
179                 if (!ret)
180                         ret = sprintf(buffer, "%s\n", info->compile_date);
181                 kfree(info);
182         }
183
184         return ret;
185 }
186
187 HYPERVISOR_ATTR_RO(compile_date);
188
189 static struct attribute *xen_compile_attrs[] = {
190         &compiler_attr.attr,
191         &compiled_by_attr.attr,
192         &compile_date_attr.attr,
193         NULL
194 };
195
196 static struct attribute_group xen_compilation_group = {
197         .name = "compilation",
198         .attrs = xen_compile_attrs,
199 };
200
201 int __init static xen_compilation_init(void)
202 {
203         return sysfs_create_group(&hypervisor_subsys.kset.kobj,
204                                   &xen_compilation_group);
205 }
206
207 static void xen_compilation_destroy(void)
208 {
209         sysfs_remove_group(&hypervisor_subsys.kset.kobj,
210                            &xen_compilation_group);
211 }
212
213 /* xen properties info */
214
215 static ssize_t capabilities_show(struct hyp_sysfs_attr *attr, char *buffer)
216 {
217         int ret = -ENOMEM;
218         char *caps;
219
220         caps = kmalloc(XEN_CAPABILITIES_INFO_LEN, GFP_KERNEL);
221         if (caps) {
222                 ret = HYPERVISOR_xen_version(XENVER_capabilities, caps);
223                 if (!ret)
224                         ret = sprintf(buffer, "%s\n", caps);
225                 kfree(caps);
226         }
227
228         return ret;
229 }
230
231 HYPERVISOR_ATTR_RO(capabilities);
232
233 static ssize_t changeset_show(struct hyp_sysfs_attr *attr, char *buffer)
234 {
235         int ret = -ENOMEM;
236         char *cset;
237
238         cset = kmalloc(XEN_CHANGESET_INFO_LEN, GFP_KERNEL);
239         if (cset) {
240                 ret = HYPERVISOR_xen_version(XENVER_changeset, cset);
241                 if (!ret)
242                         ret = sprintf(buffer, "%s\n", cset);
243                 kfree(cset);
244         }
245
246         return ret;
247 }
248
249 HYPERVISOR_ATTR_RO(changeset);
250
251 static ssize_t virtual_start_show(struct hyp_sysfs_attr *attr, char *buffer)
252 {
253         int ret = -ENOMEM;
254         struct xen_platform_parameters *parms;
255
256         parms = kmalloc(sizeof(struct xen_platform_parameters), GFP_KERNEL);
257         if (parms) {
258                 ret = HYPERVISOR_xen_version(XENVER_platform_parameters,
259                                              parms);
260                 if (!ret)
261                         ret = sprintf(buffer, "%lx\n", parms->virt_start);
262                 kfree(parms);
263         }
264
265         return ret;
266 }
267
268 HYPERVISOR_ATTR_RO(virtual_start);
269
270 static ssize_t pagesize_show(struct hyp_sysfs_attr *attr, char *buffer)
271 {
272         int ret;
273
274         ret = HYPERVISOR_xen_version(XENVER_pagesize, NULL);
275         if (ret > 0)
276                 ret = sprintf(buffer, "%x\n", ret);
277
278         return ret;
279 }
280
281 HYPERVISOR_ATTR_RO(pagesize);
282
283 /* eventually there will be several more features to export */
284 static ssize_t xen_feature_show(int index, char *buffer)
285 {
286         int ret = -ENOMEM;
287         struct xen_feature_info *info;
288
289         info = kmalloc(sizeof(struct xen_feature_info), GFP_KERNEL);
290         if (info) {
291                 info->submap_idx = index;
292                 ret = HYPERVISOR_xen_version(XENVER_get_features, info);
293                 if (!ret)
294                         ret = sprintf(buffer, "%d\n", info->submap);
295                 kfree(info);
296         }
297
298         return ret;
299 }
300
301 static ssize_t writable_pt_show(struct hyp_sysfs_attr *attr, char *buffer)
302 {
303         return xen_feature_show(XENFEAT_writable_page_tables, buffer);
304 }
305
306 HYPERVISOR_ATTR_RO(writable_pt);
307
308 static struct attribute *xen_properties_attrs[] = {
309         &capabilities_attr.attr,
310         &changeset_attr.attr,
311         &virtual_start_attr.attr,
312         &pagesize_attr.attr,
313         &writable_pt_attr.attr,
314         NULL
315 };
316
317 static struct attribute_group xen_properties_group = {
318         .name = "properties",
319         .attrs = xen_properties_attrs,
320 };
321
322 static int __init xen_properties_init(void)
323 {
324         return sysfs_create_group(&hypervisor_subsys.kset.kobj,
325                                   &xen_properties_group);
326 }
327
328 static void xen_properties_destroy(void)
329 {
330         sysfs_remove_group(&hypervisor_subsys.kset.kobj,
331                            &xen_properties_group);
332 }
333
334 static int __init hyper_sysfs_init(void)
335 {
336         int ret;
337
338         if (!is_running_on_xen())
339                 return -ENODEV;
340
341         ret = xen_sysfs_type_init();
342         if (ret)
343                 goto out;
344         ret = xen_sysfs_version_init();
345         if (ret)
346                 goto version_out;
347         ret = xen_compilation_init();
348         if (ret)
349                 goto comp_out;
350         ret = xen_sysfs_uuid_init();
351         if (ret)
352                 goto uuid_out;
353         ret = xen_properties_init();
354         if (!ret)
355                 goto out;
356
357         xen_sysfs_uuid_destroy();
358 uuid_out:
359         xen_compilation_destroy();
360 comp_out:
361         xen_sysfs_version_destroy();
362 version_out:
363         xen_sysfs_type_destroy();
364 out:
365         return ret;
366 }
367
368 static void hyper_sysfs_exit(void)
369 {
370         xen_properties_destroy();
371         xen_compilation_destroy();
372         xen_sysfs_uuid_destroy();
373         xen_sysfs_version_destroy();
374         xen_sysfs_type_destroy();
375
376 }
377
378 module_init(hyper_sysfs_init);
379 module_exit(hyper_sysfs_exit);