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