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>
18 #include <xen/xenbus.h>
19 #include <xen/interface/xen.h>
20 #include <xen/interface/version.h>
22 #define HYPERVISOR_ATTR_RO(_name) \
23 static struct hyp_sysfs_attr _name##_attr = __ATTR_RO(_name)
25 #define HYPERVISOR_ATTR_RW(_name) \
26 static struct hyp_sysfs_attr _name##_attr = \
27 __ATTR(_name, 0644, _name##_show, _name##_store)
29 struct hyp_sysfs_attr
{
30 struct attribute attr
;
31 ssize_t (*show
)(struct hyp_sysfs_attr
*, char *);
32 ssize_t (*store
)(struct hyp_sysfs_attr
*, const char *, size_t);
36 static ssize_t
type_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
38 return sprintf(buffer
, "xen\n");
41 HYPERVISOR_ATTR_RO(type
);
43 static int __init
xen_sysfs_type_init(void)
45 return sysfs_create_file(hypervisor_kobj
, &type_attr
.attr
);
48 static void xen_sysfs_type_destroy(void)
50 sysfs_remove_file(hypervisor_kobj
, &type_attr
.attr
);
53 /* xen version attributes */
54 static ssize_t
major_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
56 int version
= HYPERVISOR_xen_version(XENVER_version
, NULL
);
58 return sprintf(buffer
, "%d\n", version
>> 16);
62 HYPERVISOR_ATTR_RO(major
);
64 static ssize_t
minor_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
66 int version
= HYPERVISOR_xen_version(XENVER_version
, NULL
);
68 return sprintf(buffer
, "%d\n", version
& 0xff);
72 HYPERVISOR_ATTR_RO(minor
);
74 static ssize_t
extra_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
79 extra
= kmalloc(XEN_EXTRAVERSION_LEN
, GFP_KERNEL
);
81 ret
= HYPERVISOR_xen_version(XENVER_extraversion
, extra
);
83 ret
= sprintf(buffer
, "%s\n", extra
);
90 HYPERVISOR_ATTR_RO(extra
);
92 static struct attribute
*version_attrs
[] = {
99 static struct attribute_group version_group
= {
101 .attrs
= version_attrs
,
104 static int __init
xen_sysfs_version_init(void)
106 return sysfs_create_group(hypervisor_kobj
, &version_group
);
109 static void xen_sysfs_version_destroy(void)
111 sysfs_remove_group(hypervisor_kobj
, &version_group
);
116 static ssize_t
uuid_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
120 extern int xenstored_ready
;
122 if (!xenstored_ready
)
125 vm
= xenbus_read(XBT_NIL
, "vm", "", NULL
);
128 val
= xenbus_read(XBT_NIL
, vm
, "uuid", NULL
);
132 ret
= sprintf(buffer
, "%s\n", val
);
137 HYPERVISOR_ATTR_RO(uuid
);
139 static int __init
xen_sysfs_uuid_init(void)
141 return sysfs_create_file(hypervisor_kobj
, &uuid_attr
.attr
);
144 static void xen_sysfs_uuid_destroy(void)
146 sysfs_remove_file(hypervisor_kobj
, &uuid_attr
.attr
);
149 /* xen compilation attributes */
151 static ssize_t
compiler_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
154 struct xen_compile_info
*info
;
156 info
= kmalloc(sizeof(struct xen_compile_info
), GFP_KERNEL
);
158 ret
= HYPERVISOR_xen_version(XENVER_compile_info
, info
);
160 ret
= sprintf(buffer
, "%s\n", info
->compiler
);
167 HYPERVISOR_ATTR_RO(compiler
);
169 static ssize_t
compiled_by_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
172 struct xen_compile_info
*info
;
174 info
= kmalloc(sizeof(struct xen_compile_info
), GFP_KERNEL
);
176 ret
= HYPERVISOR_xen_version(XENVER_compile_info
, info
);
178 ret
= sprintf(buffer
, "%s\n", info
->compile_by
);
185 HYPERVISOR_ATTR_RO(compiled_by
);
187 static ssize_t
compile_date_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
190 struct xen_compile_info
*info
;
192 info
= kmalloc(sizeof(struct xen_compile_info
), GFP_KERNEL
);
194 ret
= HYPERVISOR_xen_version(XENVER_compile_info
, info
);
196 ret
= sprintf(buffer
, "%s\n", info
->compile_date
);
203 HYPERVISOR_ATTR_RO(compile_date
);
205 static struct attribute
*xen_compile_attrs
[] = {
207 &compiled_by_attr
.attr
,
208 &compile_date_attr
.attr
,
212 static struct attribute_group xen_compilation_group
= {
213 .name
= "compilation",
214 .attrs
= xen_compile_attrs
,
217 int __init
static xen_compilation_init(void)
219 return sysfs_create_group(hypervisor_kobj
, &xen_compilation_group
);
222 static void xen_compilation_destroy(void)
224 sysfs_remove_group(hypervisor_kobj
, &xen_compilation_group
);
227 /* xen properties info */
229 static ssize_t
capabilities_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
234 caps
= kmalloc(XEN_CAPABILITIES_INFO_LEN
, GFP_KERNEL
);
236 ret
= HYPERVISOR_xen_version(XENVER_capabilities
, caps
);
238 ret
= sprintf(buffer
, "%s\n", caps
);
245 HYPERVISOR_ATTR_RO(capabilities
);
247 static ssize_t
changeset_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
252 cset
= kmalloc(XEN_CHANGESET_INFO_LEN
, GFP_KERNEL
);
254 ret
= HYPERVISOR_xen_version(XENVER_changeset
, cset
);
256 ret
= sprintf(buffer
, "%s\n", cset
);
263 HYPERVISOR_ATTR_RO(changeset
);
265 static ssize_t
virtual_start_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
268 struct xen_platform_parameters
*parms
;
270 parms
= kmalloc(sizeof(struct xen_platform_parameters
), GFP_KERNEL
);
272 ret
= HYPERVISOR_xen_version(XENVER_platform_parameters
,
275 ret
= sprintf(buffer
, "%lx\n", parms
->virt_start
);
282 HYPERVISOR_ATTR_RO(virtual_start
);
284 static ssize_t
pagesize_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
288 ret
= HYPERVISOR_xen_version(XENVER_pagesize
, NULL
);
290 ret
= sprintf(buffer
, "%x\n", ret
);
295 HYPERVISOR_ATTR_RO(pagesize
);
297 static ssize_t
xen_feature_show(int index
, char *buffer
)
300 struct xen_feature_info info
;
302 info
.submap_idx
= index
;
303 ret
= HYPERVISOR_xen_version(XENVER_get_features
, &info
);
305 ret
= sprintf(buffer
, "%08x", info
.submap
);
310 static ssize_t
features_show(struct hyp_sysfs_attr
*attr
, char *buffer
)
316 for (i
= XENFEAT_NR_SUBMAPS
-1; i
>= 0; i
--) {
317 int ret
= xen_feature_show(i
, buffer
+ len
);
326 buffer
[len
++] = '\n';
331 HYPERVISOR_ATTR_RO(features
);
333 static struct attribute
*xen_properties_attrs
[] = {
334 &capabilities_attr
.attr
,
335 &changeset_attr
.attr
,
336 &virtual_start_attr
.attr
,
342 static struct attribute_group xen_properties_group
= {
343 .name
= "properties",
344 .attrs
= xen_properties_attrs
,
347 static int __init
xen_properties_init(void)
349 return sysfs_create_group(hypervisor_kobj
, &xen_properties_group
);
352 static void xen_properties_destroy(void)
354 sysfs_remove_group(hypervisor_kobj
, &xen_properties_group
);
357 static int __init
hyper_sysfs_init(void)
364 ret
= xen_sysfs_type_init();
367 ret
= xen_sysfs_version_init();
370 ret
= xen_compilation_init();
373 ret
= xen_sysfs_uuid_init();
376 ret
= xen_properties_init();
383 xen_sysfs_uuid_destroy();
385 xen_compilation_destroy();
387 xen_sysfs_version_destroy();
389 xen_sysfs_type_destroy();
394 static void __exit
hyper_sysfs_exit(void)
396 xen_properties_destroy();
397 xen_compilation_destroy();
398 xen_sysfs_uuid_destroy();
399 xen_sysfs_version_destroy();
400 xen_sysfs_type_destroy();
403 module_init(hyper_sysfs_init
);
404 module_exit(hyper_sysfs_exit
);
406 static ssize_t
hyp_sysfs_show(struct kobject
*kobj
,
407 struct attribute
*attr
,
410 struct hyp_sysfs_attr
*hyp_attr
;
411 hyp_attr
= container_of(attr
, struct hyp_sysfs_attr
, attr
);
413 return hyp_attr
->show(hyp_attr
, buffer
);
417 static ssize_t
hyp_sysfs_store(struct kobject
*kobj
,
418 struct attribute
*attr
,
422 struct hyp_sysfs_attr
*hyp_attr
;
423 hyp_attr
= container_of(attr
, struct hyp_sysfs_attr
, attr
);
425 return hyp_attr
->store(hyp_attr
, buffer
, len
);
429 static struct sysfs_ops hyp_sysfs_ops
= {
430 .show
= hyp_sysfs_show
,
431 .store
= hyp_sysfs_store
,
434 static struct kobj_type hyp_sysfs_kobj_type
= {
435 .sysfs_ops
= &hyp_sysfs_ops
,
438 static int __init
hypervisor_subsys_init(void)
443 hypervisor_kobj
->ktype
= &hyp_sysfs_kobj_type
;
446 device_initcall(hypervisor_subsys_init
);