2 * copyright (c) 2006 IBM Corporation
3 * Authored by: Mike D. Day <ncmike@us.ibm.com>
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.
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/kobject.h>
14 #include <asm/xen/hypervisor.h>
15 #include <asm/xen/hypercall.h>
17 #include <xen/xenbus.h>
18 #include <xen/interface/xen.h>
19 #include <xen/interface/version.h>
21 #define HYPERVISOR_ATTR_RO(_name) \
22 static struct hyp_sysfs_attr _name##_attr = __ATTR_RO(_name)
24 #define HYPERVISOR_ATTR_RW(_name) \
25 static struct hyp_sysfs_attr _name##_attr = \
26 __ATTR(_name, 0644, _name##_show, _name##_store)
28 struct hyp_sysfs_attr
{
29 struct attribute attr
;
30 ssize_t (*show
)(struct hyp_sysfs_attr
*, char *);
31 ssize_t (*store
)(struct hyp_sysfs_attr
*, const char *, size_t);
35 static ssize_t
type_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
37 return sprintf(buffer
, "xen\n");
40 HYPERVISOR_ATTR_RO(type
);
42 static int __init
xen_sysfs_type_init(void)
44 return sysfs_create_file(hypervisor_kobj
, &type_attr
.attr
);
47 static void xen_sysfs_type_destroy(void)
49 sysfs_remove_file(hypervisor_kobj
, &type_attr
.attr
);
52 /* xen version attributes */
53 static ssize_t
major_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
55 int version
= HYPERVISOR_xen_version(XENVER_version
, NULL
);
57 return sprintf(buffer
, "%d\n", version
>> 16);
61 HYPERVISOR_ATTR_RO(major
);
63 static ssize_t
minor_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
65 int version
= HYPERVISOR_xen_version(XENVER_version
, NULL
);
67 return sprintf(buffer
, "%d\n", version
& 0xff);
71 HYPERVISOR_ATTR_RO(minor
);
73 static ssize_t
extra_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
78 extra
= kmalloc(XEN_EXTRAVERSION_LEN
, GFP_KERNEL
);
80 ret
= HYPERVISOR_xen_version(XENVER_extraversion
, extra
);
82 ret
= sprintf(buffer
, "%s\n", extra
);
89 HYPERVISOR_ATTR_RO(extra
);
91 static struct attribute
*version_attrs
[] = {
98 static struct attribute_group version_group
= {
100 .attrs
= version_attrs
,
103 static int __init
xen_sysfs_version_init(void)
105 return sysfs_create_group(hypervisor_kobj
, &version_group
);
108 static void xen_sysfs_version_destroy(void)
110 sysfs_remove_group(hypervisor_kobj
, &version_group
);
115 static ssize_t
uuid_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
119 extern int xenstored_ready
;
121 if (!xenstored_ready
)
124 vm
= xenbus_read(XBT_NIL
, "vm", "", NULL
);
127 val
= xenbus_read(XBT_NIL
, vm
, "uuid", NULL
);
131 ret
= sprintf(buffer
, "%s\n", val
);
136 HYPERVISOR_ATTR_RO(uuid
);
138 static int __init
xen_sysfs_uuid_init(void)
140 return sysfs_create_file(hypervisor_kobj
, &uuid_attr
.attr
);
143 static void xen_sysfs_uuid_destroy(void)
145 sysfs_remove_file(hypervisor_kobj
, &uuid_attr
.attr
);
148 /* xen compilation attributes */
150 static ssize_t
compiler_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
153 struct xen_compile_info
*info
;
155 info
= kmalloc(sizeof(struct xen_compile_info
), GFP_KERNEL
);
157 ret
= HYPERVISOR_xen_version(XENVER_compile_info
, info
);
159 ret
= sprintf(buffer
, "%s\n", info
->compiler
);
166 HYPERVISOR_ATTR_RO(compiler
);
168 static ssize_t
compiled_by_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
171 struct xen_compile_info
*info
;
173 info
= kmalloc(sizeof(struct xen_compile_info
), GFP_KERNEL
);
175 ret
= HYPERVISOR_xen_version(XENVER_compile_info
, info
);
177 ret
= sprintf(buffer
, "%s\n", info
->compile_by
);
184 HYPERVISOR_ATTR_RO(compiled_by
);
186 static ssize_t
compile_date_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
189 struct xen_compile_info
*info
;
191 info
= kmalloc(sizeof(struct xen_compile_info
), GFP_KERNEL
);
193 ret
= HYPERVISOR_xen_version(XENVER_compile_info
, info
);
195 ret
= sprintf(buffer
, "%s\n", info
->compile_date
);
202 HYPERVISOR_ATTR_RO(compile_date
);
204 static struct attribute
*xen_compile_attrs
[] = {
206 &compiled_by_attr
.attr
,
207 &compile_date_attr
.attr
,
211 static struct attribute_group xen_compilation_group
= {
212 .name
= "compilation",
213 .attrs
= xen_compile_attrs
,
216 int __init
static xen_compilation_init(void)
218 return sysfs_create_group(hypervisor_kobj
, &xen_compilation_group
);
221 static void xen_compilation_destroy(void)
223 sysfs_remove_group(hypervisor_kobj
, &xen_compilation_group
);
226 /* xen properties info */
228 static ssize_t
capabilities_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
233 caps
= kmalloc(XEN_CAPABILITIES_INFO_LEN
, GFP_KERNEL
);
235 ret
= HYPERVISOR_xen_version(XENVER_capabilities
, caps
);
237 ret
= sprintf(buffer
, "%s\n", caps
);
244 HYPERVISOR_ATTR_RO(capabilities
);
246 static ssize_t
changeset_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
251 cset
= kmalloc(XEN_CHANGESET_INFO_LEN
, GFP_KERNEL
);
253 ret
= HYPERVISOR_xen_version(XENVER_changeset
, cset
);
255 ret
= sprintf(buffer
, "%s\n", cset
);
262 HYPERVISOR_ATTR_RO(changeset
);
264 static ssize_t
virtual_start_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
267 struct xen_platform_parameters
*parms
;
269 parms
= kmalloc(sizeof(struct xen_platform_parameters
), GFP_KERNEL
);
271 ret
= HYPERVISOR_xen_version(XENVER_platform_parameters
,
274 ret
= sprintf(buffer
, "%lx\n", parms
->virt_start
);
281 HYPERVISOR_ATTR_RO(virtual_start
);
283 static ssize_t
pagesize_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
287 ret
= HYPERVISOR_xen_version(XENVER_pagesize
, NULL
);
289 ret
= sprintf(buffer
, "%x\n", ret
);
294 HYPERVISOR_ATTR_RO(pagesize
);
296 static ssize_t
xen_feature_show(int index
, char *buffer
)
299 struct xen_feature_info info
;
301 info
.submap_idx
= index
;
302 ret
= HYPERVISOR_xen_version(XENVER_get_features
, &info
);
304 ret
= sprintf(buffer
, "%08x", info
.submap
);
309 static ssize_t
features_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
315 for (i
= XENFEAT_NR_SUBMAPS
-1; i
>= 0; i
--) {
316 int ret
= xen_feature_show(i
, buffer
+ len
);
325 buffer
[len
++] = '\n';
330 HYPERVISOR_ATTR_RO(features
);
332 static struct attribute
*xen_properties_attrs
[] = {
333 &capabilities_attr
.attr
,
334 &changeset_attr
.attr
,
335 &virtual_start_attr
.attr
,
341 static struct attribute_group xen_properties_group
= {
342 .name
= "properties",
343 .attrs
= xen_properties_attrs
,
346 static int __init
xen_properties_init(void)
348 return sysfs_create_group(hypervisor_kobj
, &xen_properties_group
);
351 static void xen_properties_destroy(void)
353 sysfs_remove_group(hypervisor_kobj
, &xen_properties_group
);
356 static int __init
hyper_sysfs_init(void)
363 ret
= xen_sysfs_type_init();
366 ret
= xen_sysfs_version_init();
369 ret
= xen_compilation_init();
372 ret
= xen_sysfs_uuid_init();
375 ret
= xen_properties_init();
382 xen_sysfs_uuid_destroy();
384 xen_compilation_destroy();
386 xen_sysfs_version_destroy();
388 xen_sysfs_type_destroy();
393 static void __exit
hyper_sysfs_exit(void)
395 xen_properties_destroy();
396 xen_compilation_destroy();
397 xen_sysfs_uuid_destroy();
398 xen_sysfs_version_destroy();
399 xen_sysfs_type_destroy();
402 module_init(hyper_sysfs_init
);
403 module_exit(hyper_sysfs_exit
);
405 static ssize_t
hyp_sysfs_show(struct kobject
*kobj
,
406 struct attribute
*attr
,
409 struct hyp_sysfs_attr
*hyp_attr
;
410 hyp_attr
= container_of(attr
, struct hyp_sysfs_attr
, attr
);
412 return hyp_attr
->show(hyp_attr
, buffer
);
416 static ssize_t
hyp_sysfs_store(struct kobject
*kobj
,
417 struct attribute
*attr
,
421 struct hyp_sysfs_attr
*hyp_attr
;
422 hyp_attr
= container_of(attr
, struct hyp_sysfs_attr
, attr
);
424 return hyp_attr
->store(hyp_attr
, buffer
, len
);
428 static struct sysfs_ops hyp_sysfs_ops
= {
429 .show
= hyp_sysfs_show
,
430 .store
= hyp_sysfs_store
,
433 static struct kobj_type hyp_sysfs_kobj_type
= {
434 .sysfs_ops
= &hyp_sysfs_ops
,
437 static int __init
hypervisor_subsys_init(void)
442 hypervisor_kobj
->ktype
= &hyp_sysfs_kobj_type
;
445 device_initcall(hypervisor_subsys_init
);