1cff7e81bSJeremy Fitzhardinge /* 2cff7e81bSJeremy Fitzhardinge * copyright (c) 2006 IBM Corporation 3cff7e81bSJeremy Fitzhardinge * Authored by: Mike D. Day <ncmike@us.ibm.com> 4cff7e81bSJeremy Fitzhardinge * 5cff7e81bSJeremy Fitzhardinge * This program is free software; you can redistribute it and/or modify 6cff7e81bSJeremy Fitzhardinge * it under the terms of the GNU General Public License version 2 as 7cff7e81bSJeremy Fitzhardinge * published by the Free Software Foundation. 8cff7e81bSJeremy Fitzhardinge */ 9cff7e81bSJeremy Fitzhardinge 10cff7e81bSJeremy Fitzhardinge #include <linux/kernel.h> 11cff7e81bSJeremy Fitzhardinge #include <linux/module.h> 12cff7e81bSJeremy Fitzhardinge #include <linux/kobject.h> 13cff7e81bSJeremy Fitzhardinge 14cff7e81bSJeremy Fitzhardinge #include <asm/xen/hypervisor.h> 15cff7e81bSJeremy Fitzhardinge #include <asm/xen/hypercall.h> 16cff7e81bSJeremy Fitzhardinge 17cff7e81bSJeremy Fitzhardinge #include <xen/xenbus.h> 18cff7e81bSJeremy Fitzhardinge #include <xen/interface/xen.h> 19cff7e81bSJeremy Fitzhardinge #include <xen/interface/version.h> 20cff7e81bSJeremy Fitzhardinge 21cff7e81bSJeremy Fitzhardinge #define HYPERVISOR_ATTR_RO(_name) \ 22cff7e81bSJeremy Fitzhardinge static struct hyp_sysfs_attr _name##_attr = __ATTR_RO(_name) 23cff7e81bSJeremy Fitzhardinge 24cff7e81bSJeremy Fitzhardinge #define HYPERVISOR_ATTR_RW(_name) \ 25cff7e81bSJeremy Fitzhardinge static struct hyp_sysfs_attr _name##_attr = \ 26cff7e81bSJeremy Fitzhardinge __ATTR(_name, 0644, _name##_show, _name##_store) 27cff7e81bSJeremy Fitzhardinge 28cff7e81bSJeremy Fitzhardinge struct hyp_sysfs_attr { 29cff7e81bSJeremy Fitzhardinge struct attribute attr; 30cff7e81bSJeremy Fitzhardinge ssize_t (*show)(struct hyp_sysfs_attr *, char *); 31cff7e81bSJeremy Fitzhardinge ssize_t (*store)(struct hyp_sysfs_attr *, const char *, size_t); 32cff7e81bSJeremy Fitzhardinge void *hyp_attr_data; 33cff7e81bSJeremy Fitzhardinge }; 34cff7e81bSJeremy Fitzhardinge 35cff7e81bSJeremy Fitzhardinge static ssize_t type_show(struct hyp_sysfs_attr *attr, char *buffer) 36cff7e81bSJeremy Fitzhardinge { 37cff7e81bSJeremy Fitzhardinge return sprintf(buffer, "xen\n"); 38cff7e81bSJeremy Fitzhardinge } 39cff7e81bSJeremy Fitzhardinge 40cff7e81bSJeremy Fitzhardinge HYPERVISOR_ATTR_RO(type); 41cff7e81bSJeremy Fitzhardinge 42cff7e81bSJeremy Fitzhardinge static int __init xen_sysfs_type_init(void) 43cff7e81bSJeremy Fitzhardinge { 44cff7e81bSJeremy Fitzhardinge return sysfs_create_file(hypervisor_kobj, &type_attr.attr); 45cff7e81bSJeremy Fitzhardinge } 46cff7e81bSJeremy Fitzhardinge 47cff7e81bSJeremy Fitzhardinge static void xen_sysfs_type_destroy(void) 48cff7e81bSJeremy Fitzhardinge { 49cff7e81bSJeremy Fitzhardinge sysfs_remove_file(hypervisor_kobj, &type_attr.attr); 50cff7e81bSJeremy Fitzhardinge } 51cff7e81bSJeremy Fitzhardinge 52cff7e81bSJeremy Fitzhardinge /* xen version attributes */ 53cff7e81bSJeremy Fitzhardinge static ssize_t major_show(struct hyp_sysfs_attr *attr, char *buffer) 54cff7e81bSJeremy Fitzhardinge { 55cff7e81bSJeremy Fitzhardinge int version = HYPERVISOR_xen_version(XENVER_version, NULL); 56cff7e81bSJeremy Fitzhardinge if (version) 57cff7e81bSJeremy Fitzhardinge return sprintf(buffer, "%d\n", version >> 16); 58cff7e81bSJeremy Fitzhardinge return -ENODEV; 59cff7e81bSJeremy Fitzhardinge } 60cff7e81bSJeremy Fitzhardinge 61cff7e81bSJeremy Fitzhardinge HYPERVISOR_ATTR_RO(major); 62cff7e81bSJeremy Fitzhardinge 63cff7e81bSJeremy Fitzhardinge static ssize_t minor_show(struct hyp_sysfs_attr *attr, char *buffer) 64cff7e81bSJeremy Fitzhardinge { 65cff7e81bSJeremy Fitzhardinge int version = HYPERVISOR_xen_version(XENVER_version, NULL); 66cff7e81bSJeremy Fitzhardinge if (version) 67cff7e81bSJeremy Fitzhardinge return sprintf(buffer, "%d\n", version & 0xff); 68cff7e81bSJeremy Fitzhardinge return -ENODEV; 69cff7e81bSJeremy Fitzhardinge } 70cff7e81bSJeremy Fitzhardinge 71cff7e81bSJeremy Fitzhardinge HYPERVISOR_ATTR_RO(minor); 72cff7e81bSJeremy Fitzhardinge 73cff7e81bSJeremy Fitzhardinge static ssize_t extra_show(struct hyp_sysfs_attr *attr, char *buffer) 74cff7e81bSJeremy Fitzhardinge { 75cff7e81bSJeremy Fitzhardinge int ret = -ENOMEM; 76cff7e81bSJeremy Fitzhardinge char *extra; 77cff7e81bSJeremy Fitzhardinge 78cff7e81bSJeremy Fitzhardinge extra = kmalloc(XEN_EXTRAVERSION_LEN, GFP_KERNEL); 79cff7e81bSJeremy Fitzhardinge if (extra) { 80cff7e81bSJeremy Fitzhardinge ret = HYPERVISOR_xen_version(XENVER_extraversion, extra); 81cff7e81bSJeremy Fitzhardinge if (!ret) 82cff7e81bSJeremy Fitzhardinge ret = sprintf(buffer, "%s\n", extra); 83cff7e81bSJeremy Fitzhardinge kfree(extra); 84cff7e81bSJeremy Fitzhardinge } 85cff7e81bSJeremy Fitzhardinge 86cff7e81bSJeremy Fitzhardinge return ret; 87cff7e81bSJeremy Fitzhardinge } 88cff7e81bSJeremy Fitzhardinge 89cff7e81bSJeremy Fitzhardinge HYPERVISOR_ATTR_RO(extra); 90cff7e81bSJeremy Fitzhardinge 91cff7e81bSJeremy Fitzhardinge static struct attribute *version_attrs[] = { 92cff7e81bSJeremy Fitzhardinge &major_attr.attr, 93cff7e81bSJeremy Fitzhardinge &minor_attr.attr, 94cff7e81bSJeremy Fitzhardinge &extra_attr.attr, 95cff7e81bSJeremy Fitzhardinge NULL 96cff7e81bSJeremy Fitzhardinge }; 97cff7e81bSJeremy Fitzhardinge 98cff7e81bSJeremy Fitzhardinge static struct attribute_group version_group = { 99cff7e81bSJeremy Fitzhardinge .name = "version", 100cff7e81bSJeremy Fitzhardinge .attrs = version_attrs, 101cff7e81bSJeremy Fitzhardinge }; 102cff7e81bSJeremy Fitzhardinge 103cff7e81bSJeremy Fitzhardinge static int __init xen_sysfs_version_init(void) 104cff7e81bSJeremy Fitzhardinge { 105cff7e81bSJeremy Fitzhardinge return sysfs_create_group(hypervisor_kobj, &version_group); 106cff7e81bSJeremy Fitzhardinge } 107cff7e81bSJeremy Fitzhardinge 108cff7e81bSJeremy Fitzhardinge static void xen_sysfs_version_destroy(void) 109cff7e81bSJeremy Fitzhardinge { 110cff7e81bSJeremy Fitzhardinge sysfs_remove_group(hypervisor_kobj, &version_group); 111cff7e81bSJeremy Fitzhardinge } 112cff7e81bSJeremy Fitzhardinge 113cff7e81bSJeremy Fitzhardinge /* UUID */ 114cff7e81bSJeremy Fitzhardinge 115cff7e81bSJeremy Fitzhardinge static ssize_t uuid_show(struct hyp_sysfs_attr *attr, char *buffer) 116cff7e81bSJeremy Fitzhardinge { 117cff7e81bSJeremy Fitzhardinge char *vm, *val; 118cff7e81bSJeremy Fitzhardinge int ret; 119cff7e81bSJeremy Fitzhardinge extern int xenstored_ready; 120cff7e81bSJeremy Fitzhardinge 121cff7e81bSJeremy Fitzhardinge if (!xenstored_ready) 122cff7e81bSJeremy Fitzhardinge return -EBUSY; 123cff7e81bSJeremy Fitzhardinge 124cff7e81bSJeremy Fitzhardinge vm = xenbus_read(XBT_NIL, "vm", "", NULL); 125cff7e81bSJeremy Fitzhardinge if (IS_ERR(vm)) 126cff7e81bSJeremy Fitzhardinge return PTR_ERR(vm); 127cff7e81bSJeremy Fitzhardinge val = xenbus_read(XBT_NIL, vm, "uuid", NULL); 128cff7e81bSJeremy Fitzhardinge kfree(vm); 129cff7e81bSJeremy Fitzhardinge if (IS_ERR(val)) 130cff7e81bSJeremy Fitzhardinge return PTR_ERR(val); 131cff7e81bSJeremy Fitzhardinge ret = sprintf(buffer, "%s\n", val); 132cff7e81bSJeremy Fitzhardinge kfree(val); 133cff7e81bSJeremy Fitzhardinge return ret; 134cff7e81bSJeremy Fitzhardinge } 135cff7e81bSJeremy Fitzhardinge 136cff7e81bSJeremy Fitzhardinge HYPERVISOR_ATTR_RO(uuid); 137cff7e81bSJeremy Fitzhardinge 138cff7e81bSJeremy Fitzhardinge static int __init xen_sysfs_uuid_init(void) 139cff7e81bSJeremy Fitzhardinge { 140cff7e81bSJeremy Fitzhardinge return sysfs_create_file(hypervisor_kobj, &uuid_attr.attr); 141cff7e81bSJeremy Fitzhardinge } 142cff7e81bSJeremy Fitzhardinge 143cff7e81bSJeremy Fitzhardinge static void xen_sysfs_uuid_destroy(void) 144cff7e81bSJeremy Fitzhardinge { 145cff7e81bSJeremy Fitzhardinge sysfs_remove_file(hypervisor_kobj, &uuid_attr.attr); 146cff7e81bSJeremy Fitzhardinge } 147cff7e81bSJeremy Fitzhardinge 148cff7e81bSJeremy Fitzhardinge /* xen compilation attributes */ 149cff7e81bSJeremy Fitzhardinge 150cff7e81bSJeremy Fitzhardinge static ssize_t compiler_show(struct hyp_sysfs_attr *attr, char *buffer) 151cff7e81bSJeremy Fitzhardinge { 152cff7e81bSJeremy Fitzhardinge int ret = -ENOMEM; 153cff7e81bSJeremy Fitzhardinge struct xen_compile_info *info; 154cff7e81bSJeremy Fitzhardinge 155cff7e81bSJeremy Fitzhardinge info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL); 156cff7e81bSJeremy Fitzhardinge if (info) { 157cff7e81bSJeremy Fitzhardinge ret = HYPERVISOR_xen_version(XENVER_compile_info, info); 158cff7e81bSJeremy Fitzhardinge if (!ret) 159cff7e81bSJeremy Fitzhardinge ret = sprintf(buffer, "%s\n", info->compiler); 160cff7e81bSJeremy Fitzhardinge kfree(info); 161cff7e81bSJeremy Fitzhardinge } 162cff7e81bSJeremy Fitzhardinge 163cff7e81bSJeremy Fitzhardinge return ret; 164cff7e81bSJeremy Fitzhardinge } 165cff7e81bSJeremy Fitzhardinge 166cff7e81bSJeremy Fitzhardinge HYPERVISOR_ATTR_RO(compiler); 167cff7e81bSJeremy Fitzhardinge 168cff7e81bSJeremy Fitzhardinge static ssize_t compiled_by_show(struct hyp_sysfs_attr *attr, char *buffer) 169cff7e81bSJeremy Fitzhardinge { 170cff7e81bSJeremy Fitzhardinge int ret = -ENOMEM; 171cff7e81bSJeremy Fitzhardinge struct xen_compile_info *info; 172cff7e81bSJeremy Fitzhardinge 173cff7e81bSJeremy Fitzhardinge info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL); 174cff7e81bSJeremy Fitzhardinge if (info) { 175cff7e81bSJeremy Fitzhardinge ret = HYPERVISOR_xen_version(XENVER_compile_info, info); 176cff7e81bSJeremy Fitzhardinge if (!ret) 177cff7e81bSJeremy Fitzhardinge ret = sprintf(buffer, "%s\n", info->compile_by); 178cff7e81bSJeremy Fitzhardinge kfree(info); 179cff7e81bSJeremy Fitzhardinge } 180cff7e81bSJeremy Fitzhardinge 181cff7e81bSJeremy Fitzhardinge return ret; 182cff7e81bSJeremy Fitzhardinge } 183cff7e81bSJeremy Fitzhardinge 184cff7e81bSJeremy Fitzhardinge HYPERVISOR_ATTR_RO(compiled_by); 185cff7e81bSJeremy Fitzhardinge 186cff7e81bSJeremy Fitzhardinge static ssize_t compile_date_show(struct hyp_sysfs_attr *attr, char *buffer) 187cff7e81bSJeremy Fitzhardinge { 188cff7e81bSJeremy Fitzhardinge int ret = -ENOMEM; 189cff7e81bSJeremy Fitzhardinge struct xen_compile_info *info; 190cff7e81bSJeremy Fitzhardinge 191cff7e81bSJeremy Fitzhardinge info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL); 192cff7e81bSJeremy Fitzhardinge if (info) { 193cff7e81bSJeremy Fitzhardinge ret = HYPERVISOR_xen_version(XENVER_compile_info, info); 194cff7e81bSJeremy Fitzhardinge if (!ret) 195cff7e81bSJeremy Fitzhardinge ret = sprintf(buffer, "%s\n", info->compile_date); 196cff7e81bSJeremy Fitzhardinge kfree(info); 197cff7e81bSJeremy Fitzhardinge } 198cff7e81bSJeremy Fitzhardinge 199cff7e81bSJeremy Fitzhardinge return ret; 200cff7e81bSJeremy Fitzhardinge } 201cff7e81bSJeremy Fitzhardinge 202cff7e81bSJeremy Fitzhardinge HYPERVISOR_ATTR_RO(compile_date); 203cff7e81bSJeremy Fitzhardinge 204cff7e81bSJeremy Fitzhardinge static struct attribute *xen_compile_attrs[] = { 205cff7e81bSJeremy Fitzhardinge &compiler_attr.attr, 206cff7e81bSJeremy Fitzhardinge &compiled_by_attr.attr, 207cff7e81bSJeremy Fitzhardinge &compile_date_attr.attr, 208cff7e81bSJeremy Fitzhardinge NULL 209cff7e81bSJeremy Fitzhardinge }; 210cff7e81bSJeremy Fitzhardinge 211cff7e81bSJeremy Fitzhardinge static struct attribute_group xen_compilation_group = { 212cff7e81bSJeremy Fitzhardinge .name = "compilation", 213cff7e81bSJeremy Fitzhardinge .attrs = xen_compile_attrs, 214cff7e81bSJeremy Fitzhardinge }; 215cff7e81bSJeremy Fitzhardinge 216cff7e81bSJeremy Fitzhardinge int __init static xen_compilation_init(void) 217cff7e81bSJeremy Fitzhardinge { 218cff7e81bSJeremy Fitzhardinge return sysfs_create_group(hypervisor_kobj, &xen_compilation_group); 219cff7e81bSJeremy Fitzhardinge } 220cff7e81bSJeremy Fitzhardinge 221cff7e81bSJeremy Fitzhardinge static void xen_compilation_destroy(void) 222cff7e81bSJeremy Fitzhardinge { 223cff7e81bSJeremy Fitzhardinge sysfs_remove_group(hypervisor_kobj, &xen_compilation_group); 224cff7e81bSJeremy Fitzhardinge } 225cff7e81bSJeremy Fitzhardinge 226cff7e81bSJeremy Fitzhardinge /* xen properties info */ 227cff7e81bSJeremy Fitzhardinge 228cff7e81bSJeremy Fitzhardinge static ssize_t capabilities_show(struct hyp_sysfs_attr *attr, char *buffer) 229cff7e81bSJeremy Fitzhardinge { 230cff7e81bSJeremy Fitzhardinge int ret = -ENOMEM; 231cff7e81bSJeremy Fitzhardinge char *caps; 232cff7e81bSJeremy Fitzhardinge 233cff7e81bSJeremy Fitzhardinge caps = kmalloc(XEN_CAPABILITIES_INFO_LEN, GFP_KERNEL); 234cff7e81bSJeremy Fitzhardinge if (caps) { 235cff7e81bSJeremy Fitzhardinge ret = HYPERVISOR_xen_version(XENVER_capabilities, caps); 236cff7e81bSJeremy Fitzhardinge if (!ret) 237cff7e81bSJeremy Fitzhardinge ret = sprintf(buffer, "%s\n", caps); 238cff7e81bSJeremy Fitzhardinge kfree(caps); 239cff7e81bSJeremy Fitzhardinge } 240cff7e81bSJeremy Fitzhardinge 241cff7e81bSJeremy Fitzhardinge return ret; 242cff7e81bSJeremy Fitzhardinge } 243cff7e81bSJeremy Fitzhardinge 244cff7e81bSJeremy Fitzhardinge HYPERVISOR_ATTR_RO(capabilities); 245cff7e81bSJeremy Fitzhardinge 246cff7e81bSJeremy Fitzhardinge static ssize_t changeset_show(struct hyp_sysfs_attr *attr, char *buffer) 247cff7e81bSJeremy Fitzhardinge { 248cff7e81bSJeremy Fitzhardinge int ret = -ENOMEM; 249cff7e81bSJeremy Fitzhardinge char *cset; 250cff7e81bSJeremy Fitzhardinge 251cff7e81bSJeremy Fitzhardinge cset = kmalloc(XEN_CHANGESET_INFO_LEN, GFP_KERNEL); 252cff7e81bSJeremy Fitzhardinge if (cset) { 253cff7e81bSJeremy Fitzhardinge ret = HYPERVISOR_xen_version(XENVER_changeset, cset); 254cff7e81bSJeremy Fitzhardinge if (!ret) 255cff7e81bSJeremy Fitzhardinge ret = sprintf(buffer, "%s\n", cset); 256cff7e81bSJeremy Fitzhardinge kfree(cset); 257cff7e81bSJeremy Fitzhardinge } 258cff7e81bSJeremy Fitzhardinge 259cff7e81bSJeremy Fitzhardinge return ret; 260cff7e81bSJeremy Fitzhardinge } 261cff7e81bSJeremy Fitzhardinge 262cff7e81bSJeremy Fitzhardinge HYPERVISOR_ATTR_RO(changeset); 263cff7e81bSJeremy Fitzhardinge 264cff7e81bSJeremy Fitzhardinge static ssize_t virtual_start_show(struct hyp_sysfs_attr *attr, char *buffer) 265cff7e81bSJeremy Fitzhardinge { 266cff7e81bSJeremy Fitzhardinge int ret = -ENOMEM; 267cff7e81bSJeremy Fitzhardinge struct xen_platform_parameters *parms; 268cff7e81bSJeremy Fitzhardinge 269cff7e81bSJeremy Fitzhardinge parms = kmalloc(sizeof(struct xen_platform_parameters), GFP_KERNEL); 270cff7e81bSJeremy Fitzhardinge if (parms) { 271cff7e81bSJeremy Fitzhardinge ret = HYPERVISOR_xen_version(XENVER_platform_parameters, 272cff7e81bSJeremy Fitzhardinge parms); 273cff7e81bSJeremy Fitzhardinge if (!ret) 274cff7e81bSJeremy Fitzhardinge ret = sprintf(buffer, "%lx\n", parms->virt_start); 275cff7e81bSJeremy Fitzhardinge kfree(parms); 276cff7e81bSJeremy Fitzhardinge } 277cff7e81bSJeremy Fitzhardinge 278cff7e81bSJeremy Fitzhardinge return ret; 279cff7e81bSJeremy Fitzhardinge } 280cff7e81bSJeremy Fitzhardinge 281cff7e81bSJeremy Fitzhardinge HYPERVISOR_ATTR_RO(virtual_start); 282cff7e81bSJeremy Fitzhardinge 283cff7e81bSJeremy Fitzhardinge static ssize_t pagesize_show(struct hyp_sysfs_attr *attr, char *buffer) 284cff7e81bSJeremy Fitzhardinge { 285cff7e81bSJeremy Fitzhardinge int ret; 286cff7e81bSJeremy Fitzhardinge 287cff7e81bSJeremy Fitzhardinge ret = HYPERVISOR_xen_version(XENVER_pagesize, NULL); 288cff7e81bSJeremy Fitzhardinge if (ret > 0) 289cff7e81bSJeremy Fitzhardinge ret = sprintf(buffer, "%x\n", ret); 290cff7e81bSJeremy Fitzhardinge 291cff7e81bSJeremy Fitzhardinge return ret; 292cff7e81bSJeremy Fitzhardinge } 293cff7e81bSJeremy Fitzhardinge 294cff7e81bSJeremy Fitzhardinge HYPERVISOR_ATTR_RO(pagesize); 295cff7e81bSJeremy Fitzhardinge 296cff7e81bSJeremy Fitzhardinge static ssize_t xen_feature_show(int index, char *buffer) 297cff7e81bSJeremy Fitzhardinge { 298*a649b720SJeremy Fitzhardinge ssize_t ret; 299*a649b720SJeremy Fitzhardinge struct xen_feature_info info; 300cff7e81bSJeremy Fitzhardinge 301*a649b720SJeremy Fitzhardinge info.submap_idx = index; 302*a649b720SJeremy Fitzhardinge ret = HYPERVISOR_xen_version(XENVER_get_features, &info); 303cff7e81bSJeremy Fitzhardinge if (!ret) 304*a649b720SJeremy Fitzhardinge ret = sprintf(buffer, "%08x", info.submap); 305cff7e81bSJeremy Fitzhardinge 306cff7e81bSJeremy Fitzhardinge return ret; 307cff7e81bSJeremy Fitzhardinge } 308cff7e81bSJeremy Fitzhardinge 309*a649b720SJeremy Fitzhardinge static ssize_t features_show(struct hyp_sysfs_attr *attr, char *buffer) 310cff7e81bSJeremy Fitzhardinge { 311*a649b720SJeremy Fitzhardinge ssize_t len; 312*a649b720SJeremy Fitzhardinge int i; 313*a649b720SJeremy Fitzhardinge 314*a649b720SJeremy Fitzhardinge len = 0; 315*a649b720SJeremy Fitzhardinge for (i = XENFEAT_NR_SUBMAPS-1; i >= 0; i--) { 316*a649b720SJeremy Fitzhardinge int ret = xen_feature_show(i, buffer + len); 317*a649b720SJeremy Fitzhardinge if (ret < 0) { 318*a649b720SJeremy Fitzhardinge if (len == 0) 319*a649b720SJeremy Fitzhardinge len = ret; 320*a649b720SJeremy Fitzhardinge break; 321*a649b720SJeremy Fitzhardinge } 322*a649b720SJeremy Fitzhardinge len += ret; 323*a649b720SJeremy Fitzhardinge } 324*a649b720SJeremy Fitzhardinge if (len > 0) 325*a649b720SJeremy Fitzhardinge buffer[len++] = '\n'; 326*a649b720SJeremy Fitzhardinge 327*a649b720SJeremy Fitzhardinge return len; 328cff7e81bSJeremy Fitzhardinge } 329cff7e81bSJeremy Fitzhardinge 330*a649b720SJeremy Fitzhardinge HYPERVISOR_ATTR_RO(features); 331cff7e81bSJeremy Fitzhardinge 332cff7e81bSJeremy Fitzhardinge static struct attribute *xen_properties_attrs[] = { 333cff7e81bSJeremy Fitzhardinge &capabilities_attr.attr, 334cff7e81bSJeremy Fitzhardinge &changeset_attr.attr, 335cff7e81bSJeremy Fitzhardinge &virtual_start_attr.attr, 336cff7e81bSJeremy Fitzhardinge &pagesize_attr.attr, 337*a649b720SJeremy Fitzhardinge &features_attr.attr, 338cff7e81bSJeremy Fitzhardinge NULL 339cff7e81bSJeremy Fitzhardinge }; 340cff7e81bSJeremy Fitzhardinge 341cff7e81bSJeremy Fitzhardinge static struct attribute_group xen_properties_group = { 342cff7e81bSJeremy Fitzhardinge .name = "properties", 343cff7e81bSJeremy Fitzhardinge .attrs = xen_properties_attrs, 344cff7e81bSJeremy Fitzhardinge }; 345cff7e81bSJeremy Fitzhardinge 346cff7e81bSJeremy Fitzhardinge static int __init xen_properties_init(void) 347cff7e81bSJeremy Fitzhardinge { 348cff7e81bSJeremy Fitzhardinge return sysfs_create_group(hypervisor_kobj, &xen_properties_group); 349cff7e81bSJeremy Fitzhardinge } 350cff7e81bSJeremy Fitzhardinge 351cff7e81bSJeremy Fitzhardinge static void xen_properties_destroy(void) 352cff7e81bSJeremy Fitzhardinge { 353cff7e81bSJeremy Fitzhardinge sysfs_remove_group(hypervisor_kobj, &xen_properties_group); 354cff7e81bSJeremy Fitzhardinge } 355cff7e81bSJeremy Fitzhardinge 356cff7e81bSJeremy Fitzhardinge #ifdef CONFIG_KEXEC 357cff7e81bSJeremy Fitzhardinge 358cff7e81bSJeremy Fitzhardinge extern size_t vmcoreinfo_size_xen; 359cff7e81bSJeremy Fitzhardinge extern unsigned long paddr_vmcoreinfo_xen; 360cff7e81bSJeremy Fitzhardinge 361cff7e81bSJeremy Fitzhardinge static ssize_t vmcoreinfo_show(struct hyp_sysfs_attr *attr, char *page) 362cff7e81bSJeremy Fitzhardinge { 363cff7e81bSJeremy Fitzhardinge return sprintf(page, "%lx %zx\n", 364cff7e81bSJeremy Fitzhardinge paddr_vmcoreinfo_xen, vmcoreinfo_size_xen); 365cff7e81bSJeremy Fitzhardinge } 366cff7e81bSJeremy Fitzhardinge 367cff7e81bSJeremy Fitzhardinge HYPERVISOR_ATTR_RO(vmcoreinfo); 368cff7e81bSJeremy Fitzhardinge 369cff7e81bSJeremy Fitzhardinge static int __init xen_sysfs_vmcoreinfo_init(void) 370cff7e81bSJeremy Fitzhardinge { 371cff7e81bSJeremy Fitzhardinge return sysfs_create_file(hypervisor_kobj, 372cff7e81bSJeremy Fitzhardinge &vmcoreinfo_attr.attr); 373cff7e81bSJeremy Fitzhardinge } 374cff7e81bSJeremy Fitzhardinge 375cff7e81bSJeremy Fitzhardinge static void xen_sysfs_vmcoreinfo_destroy(void) 376cff7e81bSJeremy Fitzhardinge { 377cff7e81bSJeremy Fitzhardinge sysfs_remove_file(hypervisor_kobj, &vmcoreinfo_attr.attr); 378cff7e81bSJeremy Fitzhardinge } 379cff7e81bSJeremy Fitzhardinge 380cff7e81bSJeremy Fitzhardinge #endif 381cff7e81bSJeremy Fitzhardinge 382cff7e81bSJeremy Fitzhardinge static int __init hyper_sysfs_init(void) 383cff7e81bSJeremy Fitzhardinge { 384cff7e81bSJeremy Fitzhardinge int ret; 385cff7e81bSJeremy Fitzhardinge 386cff7e81bSJeremy Fitzhardinge if (!xen_domain()) 387cff7e81bSJeremy Fitzhardinge return -ENODEV; 388cff7e81bSJeremy Fitzhardinge 389cff7e81bSJeremy Fitzhardinge ret = xen_sysfs_type_init(); 390cff7e81bSJeremy Fitzhardinge if (ret) 391cff7e81bSJeremy Fitzhardinge goto out; 392cff7e81bSJeremy Fitzhardinge ret = xen_sysfs_version_init(); 393cff7e81bSJeremy Fitzhardinge if (ret) 394cff7e81bSJeremy Fitzhardinge goto version_out; 395cff7e81bSJeremy Fitzhardinge ret = xen_compilation_init(); 396cff7e81bSJeremy Fitzhardinge if (ret) 397cff7e81bSJeremy Fitzhardinge goto comp_out; 398cff7e81bSJeremy Fitzhardinge ret = xen_sysfs_uuid_init(); 399cff7e81bSJeremy Fitzhardinge if (ret) 400cff7e81bSJeremy Fitzhardinge goto uuid_out; 401cff7e81bSJeremy Fitzhardinge ret = xen_properties_init(); 402cff7e81bSJeremy Fitzhardinge if (ret) 403cff7e81bSJeremy Fitzhardinge goto prop_out; 404cff7e81bSJeremy Fitzhardinge #ifdef CONFIG_KEXEC 405cff7e81bSJeremy Fitzhardinge if (vmcoreinfo_size_xen != 0) { 406cff7e81bSJeremy Fitzhardinge ret = xen_sysfs_vmcoreinfo_init(); 407cff7e81bSJeremy Fitzhardinge if (ret) 408cff7e81bSJeremy Fitzhardinge goto vmcoreinfo_out; 409cff7e81bSJeremy Fitzhardinge } 410cff7e81bSJeremy Fitzhardinge #endif 411cff7e81bSJeremy Fitzhardinge 412cff7e81bSJeremy Fitzhardinge goto out; 413cff7e81bSJeremy Fitzhardinge 414cff7e81bSJeremy Fitzhardinge #ifdef CONFIG_KEXEC 415cff7e81bSJeremy Fitzhardinge vmcoreinfo_out: 416cff7e81bSJeremy Fitzhardinge #endif 417cff7e81bSJeremy Fitzhardinge xen_properties_destroy(); 418cff7e81bSJeremy Fitzhardinge prop_out: 419cff7e81bSJeremy Fitzhardinge xen_sysfs_uuid_destroy(); 420cff7e81bSJeremy Fitzhardinge uuid_out: 421cff7e81bSJeremy Fitzhardinge xen_compilation_destroy(); 422cff7e81bSJeremy Fitzhardinge comp_out: 423cff7e81bSJeremy Fitzhardinge xen_sysfs_version_destroy(); 424cff7e81bSJeremy Fitzhardinge version_out: 425cff7e81bSJeremy Fitzhardinge xen_sysfs_type_destroy(); 426cff7e81bSJeremy Fitzhardinge out: 427cff7e81bSJeremy Fitzhardinge return ret; 428cff7e81bSJeremy Fitzhardinge } 429cff7e81bSJeremy Fitzhardinge 430cff7e81bSJeremy Fitzhardinge static void __exit hyper_sysfs_exit(void) 431cff7e81bSJeremy Fitzhardinge { 432cff7e81bSJeremy Fitzhardinge #ifdef CONFIG_KEXEC 433cff7e81bSJeremy Fitzhardinge if (vmcoreinfo_size_xen != 0) 434cff7e81bSJeremy Fitzhardinge xen_sysfs_vmcoreinfo_destroy(); 435cff7e81bSJeremy Fitzhardinge #endif 436cff7e81bSJeremy Fitzhardinge xen_properties_destroy(); 437cff7e81bSJeremy Fitzhardinge xen_compilation_destroy(); 438cff7e81bSJeremy Fitzhardinge xen_sysfs_uuid_destroy(); 439cff7e81bSJeremy Fitzhardinge xen_sysfs_version_destroy(); 440cff7e81bSJeremy Fitzhardinge xen_sysfs_type_destroy(); 441cff7e81bSJeremy Fitzhardinge 442cff7e81bSJeremy Fitzhardinge } 443cff7e81bSJeremy Fitzhardinge module_init(hyper_sysfs_init); 444cff7e81bSJeremy Fitzhardinge module_exit(hyper_sysfs_exit); 445cff7e81bSJeremy Fitzhardinge 446cff7e81bSJeremy Fitzhardinge static ssize_t hyp_sysfs_show(struct kobject *kobj, 447cff7e81bSJeremy Fitzhardinge struct attribute *attr, 448cff7e81bSJeremy Fitzhardinge char *buffer) 449cff7e81bSJeremy Fitzhardinge { 450cff7e81bSJeremy Fitzhardinge struct hyp_sysfs_attr *hyp_attr; 451cff7e81bSJeremy Fitzhardinge hyp_attr = container_of(attr, struct hyp_sysfs_attr, attr); 452cff7e81bSJeremy Fitzhardinge if (hyp_attr->show) 453cff7e81bSJeremy Fitzhardinge return hyp_attr->show(hyp_attr, buffer); 454cff7e81bSJeremy Fitzhardinge return 0; 455cff7e81bSJeremy Fitzhardinge } 456cff7e81bSJeremy Fitzhardinge 457cff7e81bSJeremy Fitzhardinge static ssize_t hyp_sysfs_store(struct kobject *kobj, 458cff7e81bSJeremy Fitzhardinge struct attribute *attr, 459cff7e81bSJeremy Fitzhardinge const char *buffer, 460cff7e81bSJeremy Fitzhardinge size_t len) 461cff7e81bSJeremy Fitzhardinge { 462cff7e81bSJeremy Fitzhardinge struct hyp_sysfs_attr *hyp_attr; 463cff7e81bSJeremy Fitzhardinge hyp_attr = container_of(attr, struct hyp_sysfs_attr, attr); 464cff7e81bSJeremy Fitzhardinge if (hyp_attr->store) 465cff7e81bSJeremy Fitzhardinge return hyp_attr->store(hyp_attr, buffer, len); 466cff7e81bSJeremy Fitzhardinge return 0; 467cff7e81bSJeremy Fitzhardinge } 468cff7e81bSJeremy Fitzhardinge 469cff7e81bSJeremy Fitzhardinge static struct sysfs_ops hyp_sysfs_ops = { 470cff7e81bSJeremy Fitzhardinge .show = hyp_sysfs_show, 471cff7e81bSJeremy Fitzhardinge .store = hyp_sysfs_store, 472cff7e81bSJeremy Fitzhardinge }; 473cff7e81bSJeremy Fitzhardinge 474cff7e81bSJeremy Fitzhardinge static struct kobj_type hyp_sysfs_kobj_type = { 475cff7e81bSJeremy Fitzhardinge .sysfs_ops = &hyp_sysfs_ops, 476cff7e81bSJeremy Fitzhardinge }; 477cff7e81bSJeremy Fitzhardinge 478cff7e81bSJeremy Fitzhardinge static int __init hypervisor_subsys_init(void) 479cff7e81bSJeremy Fitzhardinge { 480cff7e81bSJeremy Fitzhardinge if (!xen_domain()) 481cff7e81bSJeremy Fitzhardinge return -ENODEV; 482cff7e81bSJeremy Fitzhardinge 483cff7e81bSJeremy Fitzhardinge hypervisor_kobj->ktype = &hyp_sysfs_kobj_type; 484cff7e81bSJeremy Fitzhardinge return 0; 485cff7e81bSJeremy Fitzhardinge } 486cff7e81bSJeremy Fitzhardinge device_initcall(hypervisor_subsys_init); 487