linux/drivers/xen/xenbus/xenbus_probe.c
<<
>>
Prefs
   1/******************************************************************************
   2 * Talks to Xen Store to figure out what devices we have.
   3 *
   4 * Copyright (C) 2005 Rusty Russell, IBM Corporation
   5 * Copyright (C) 2005 Mike Wray, Hewlett-Packard
   6 * Copyright (C) 2005, 2006 XenSource Ltd
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License version 2
  10 * as published by the Free Software Foundation; or, when distributed
  11 * separately from the Linux kernel or incorporated into other
  12 * software packages, subject to the following license:
  13 *
  14 * Permission is hereby granted, free of charge, to any person obtaining a copy
  15 * of this source file (the "Software"), to deal in the Software without
  16 * restriction, including without limitation the rights to use, copy, modify,
  17 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
  18 * and to permit persons to whom the Software is furnished to do so, subject to
  19 * the following conditions:
  20 *
  21 * The above copyright notice and this permission notice shall be included in
  22 * all copies or substantial portions of the Software.
  23 *
  24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  27 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  28 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  29 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  30 * IN THE SOFTWARE.
  31 */
  32
  33#define DPRINTK(fmt, args...)                           \
  34        pr_debug("xenbus_probe (%s:%d) " fmt ".\n",     \
  35                 __func__, __LINE__, ##args)
  36
  37#include <linux/kernel.h>
  38#include <linux/err.h>
  39#include <linux/string.h>
  40#include <linux/ctype.h>
  41#include <linux/fcntl.h>
  42#include <linux/mm.h>
  43#include <linux/proc_fs.h>
  44#include <linux/notifier.h>
  45#include <linux/kthread.h>
  46#include <linux/mutex.h>
  47#include <linux/io.h>
  48#include <linux/slab.h>
  49
  50#include <asm/page.h>
  51#include <asm/pgtable.h>
  52#include <asm/xen/hypervisor.h>
  53
  54#include <xen/xen.h>
  55#include <xen/xenbus.h>
  56#include <xen/events.h>
  57#include <xen/page.h>
  58
  59#include <xen/hvm.h>
  60
  61#include "xenbus_comms.h"
  62#include "xenbus_probe.h"
  63
  64
  65int xen_store_evtchn;
  66EXPORT_SYMBOL_GPL(xen_store_evtchn);
  67
  68struct xenstore_domain_interface *xen_store_interface;
  69EXPORT_SYMBOL_GPL(xen_store_interface);
  70
  71static unsigned long xen_store_mfn;
  72
  73static BLOCKING_NOTIFIER_HEAD(xenstore_chain);
  74
  75/* If something in array of ids matches this device, return it. */
  76static const struct xenbus_device_id *
  77match_device(const struct xenbus_device_id *arr, struct xenbus_device *dev)
  78{
  79        for (; *arr->devicetype != '\0'; arr++) {
  80                if (!strcmp(arr->devicetype, dev->devicetype))
  81                        return arr;
  82        }
  83        return NULL;
  84}
  85
  86int xenbus_match(struct device *_dev, struct device_driver *_drv)
  87{
  88        struct xenbus_driver *drv = to_xenbus_driver(_drv);
  89
  90        if (!drv->ids)
  91                return 0;
  92
  93        return match_device(drv->ids, to_xenbus_device(_dev)) != NULL;
  94}
  95EXPORT_SYMBOL_GPL(xenbus_match);
  96
  97
  98static void free_otherend_details(struct xenbus_device *dev)
  99{
 100        kfree(dev->otherend);
 101        dev->otherend = NULL;
 102}
 103
 104
 105static void free_otherend_watch(struct xenbus_device *dev)
 106{
 107        if (dev->otherend_watch.node) {
 108                unregister_xenbus_watch(&dev->otherend_watch);
 109                kfree(dev->otherend_watch.node);
 110                dev->otherend_watch.node = NULL;
 111        }
 112}
 113
 114
 115static int talk_to_otherend(struct xenbus_device *dev)
 116{
 117        struct xenbus_driver *drv = to_xenbus_driver(dev->dev.driver);
 118
 119        free_otherend_watch(dev);
 120        free_otherend_details(dev);
 121
 122        return drv->read_otherend_details(dev);
 123}
 124
 125
 126
 127static int watch_otherend(struct xenbus_device *dev)
 128{
 129        struct xen_bus_type *bus =
 130                container_of(dev->dev.bus, struct xen_bus_type, bus);
 131
 132        return xenbus_watch_pathfmt(dev, &dev->otherend_watch,
 133                                    bus->otherend_changed,
 134                                    "%s/%s", dev->otherend, "state");
 135}
 136
 137
 138int xenbus_read_otherend_details(struct xenbus_device *xendev,
 139                                 char *id_node, char *path_node)
 140{
 141        int err = xenbus_gather(XBT_NIL, xendev->nodename,
 142                                id_node, "%i", &xendev->otherend_id,
 143                                path_node, NULL, &xendev->otherend,
 144                                NULL);
 145        if (err) {
 146                xenbus_dev_fatal(xendev, err,
 147                                 "reading other end details from %s",
 148                                 xendev->nodename);
 149                return err;
 150        }
 151        if (strlen(xendev->otherend) == 0 ||
 152            !xenbus_exists(XBT_NIL, xendev->otherend, "")) {
 153                xenbus_dev_fatal(xendev, -ENOENT,
 154                                 "unable to read other end from %s.  "
 155                                 "missing or inaccessible.",
 156                                 xendev->nodename);
 157                free_otherend_details(xendev);
 158                return -ENOENT;
 159        }
 160
 161        return 0;
 162}
 163EXPORT_SYMBOL_GPL(xenbus_read_otherend_details);
 164
 165void xenbus_otherend_changed(struct xenbus_watch *watch,
 166                             const char **vec, unsigned int len,
 167                             int ignore_on_shutdown)
 168{
 169        struct xenbus_device *dev =
 170                container_of(watch, struct xenbus_device, otherend_watch);
 171        struct xenbus_driver *drv = to_xenbus_driver(dev->dev.driver);
 172        enum xenbus_state state;
 173
 174        /* Protect us against watches firing on old details when the otherend
 175           details change, say immediately after a resume. */
 176        if (!dev->otherend ||
 177            strncmp(dev->otherend, vec[XS_WATCH_PATH],
 178                    strlen(dev->otherend))) {
 179                dev_dbg(&dev->dev, "Ignoring watch at %s\n",
 180                        vec[XS_WATCH_PATH]);
 181                return;
 182        }
 183
 184        state = xenbus_read_driver_state(dev->otherend);
 185
 186        dev_dbg(&dev->dev, "state is %d, (%s), %s, %s\n",
 187                state, xenbus_strstate(state), dev->otherend_watch.node,
 188                vec[XS_WATCH_PATH]);
 189
 190        /*
 191         * Ignore xenbus transitions during shutdown. This prevents us doing
 192         * work that can fail e.g., when the rootfs is gone.
 193         */
 194        if (system_state > SYSTEM_RUNNING) {
 195                if (ignore_on_shutdown && (state == XenbusStateClosing))
 196                        xenbus_frontend_closed(dev);
 197                return;
 198        }
 199
 200        if (drv->otherend_changed)
 201                drv->otherend_changed(dev, state);
 202}
 203EXPORT_SYMBOL_GPL(xenbus_otherend_changed);
 204
 205int xenbus_dev_probe(struct device *_dev)
 206{
 207        struct xenbus_device *dev = to_xenbus_device(_dev);
 208        struct xenbus_driver *drv = to_xenbus_driver(_dev->driver);
 209        const struct xenbus_device_id *id;
 210        int err;
 211
 212        DPRINTK("%s", dev->nodename);
 213
 214        if (!drv->probe) {
 215                err = -ENODEV;
 216                goto fail;
 217        }
 218
 219        id = match_device(drv->ids, dev);
 220        if (!id) {
 221                err = -ENODEV;
 222                goto fail;
 223        }
 224
 225        err = talk_to_otherend(dev);
 226        if (err) {
 227                dev_warn(&dev->dev, "talk_to_otherend on %s failed.\n",
 228                         dev->nodename);
 229                return err;
 230        }
 231
 232        err = drv->probe(dev, id);
 233        if (err)
 234                goto fail;
 235
 236        err = watch_otherend(dev);
 237        if (err) {
 238                dev_warn(&dev->dev, "watch_otherend on %s failed.\n",
 239                       dev->nodename);
 240                return err;
 241        }
 242
 243        return 0;
 244fail:
 245        xenbus_dev_error(dev, err, "xenbus_dev_probe on %s", dev->nodename);
 246        xenbus_switch_state(dev, XenbusStateClosed);
 247        return err;
 248}
 249EXPORT_SYMBOL_GPL(xenbus_dev_probe);
 250
 251int xenbus_dev_remove(struct device *_dev)
 252{
 253        struct xenbus_device *dev = to_xenbus_device(_dev);
 254        struct xenbus_driver *drv = to_xenbus_driver(_dev->driver);
 255
 256        DPRINTK("%s", dev->nodename);
 257
 258        free_otherend_watch(dev);
 259        free_otherend_details(dev);
 260
 261        if (drv->remove)
 262                drv->remove(dev);
 263
 264        xenbus_switch_state(dev, XenbusStateClosed);
 265        return 0;
 266}
 267EXPORT_SYMBOL_GPL(xenbus_dev_remove);
 268
 269void xenbus_dev_shutdown(struct device *_dev)
 270{
 271        struct xenbus_device *dev = to_xenbus_device(_dev);
 272        unsigned long timeout = 5*HZ;
 273
 274        DPRINTK("%s", dev->nodename);
 275
 276        get_device(&dev->dev);
 277        if (dev->state != XenbusStateConnected) {
 278                printk(KERN_INFO "%s: %s: %s != Connected, skipping\n", __func__,
 279                       dev->nodename, xenbus_strstate(dev->state));
 280                goto out;
 281        }
 282        xenbus_switch_state(dev, XenbusStateClosing);
 283        timeout = wait_for_completion_timeout(&dev->down, timeout);
 284        if (!timeout)
 285                printk(KERN_INFO "%s: %s timeout closing device\n",
 286                       __func__, dev->nodename);
 287 out:
 288        put_device(&dev->dev);
 289}
 290EXPORT_SYMBOL_GPL(xenbus_dev_shutdown);
 291
 292int xenbus_register_driver_common(struct xenbus_driver *drv,
 293                                  struct xen_bus_type *bus,
 294                                  struct module *owner,
 295                                  const char *mod_name)
 296{
 297        drv->driver.name = drv->name;
 298        drv->driver.bus = &bus->bus;
 299        drv->driver.owner = owner;
 300        drv->driver.mod_name = mod_name;
 301
 302        return driver_register(&drv->driver);
 303}
 304EXPORT_SYMBOL_GPL(xenbus_register_driver_common);
 305
 306void xenbus_unregister_driver(struct xenbus_driver *drv)
 307{
 308        driver_unregister(&drv->driver);
 309}
 310EXPORT_SYMBOL_GPL(xenbus_unregister_driver);
 311
 312struct xb_find_info
 313{
 314        struct xenbus_device *dev;
 315        const char *nodename;
 316};
 317
 318static int cmp_dev(struct device *dev, void *data)
 319{
 320        struct xenbus_device *xendev = to_xenbus_device(dev);
 321        struct xb_find_info *info = data;
 322
 323        if (!strcmp(xendev->nodename, info->nodename)) {
 324                info->dev = xendev;
 325                get_device(dev);
 326                return 1;
 327        }
 328        return 0;
 329}
 330
 331struct xenbus_device *xenbus_device_find(const char *nodename,
 332                                         struct bus_type *bus)
 333{
 334        struct xb_find_info info = { .dev = NULL, .nodename = nodename };
 335
 336        bus_for_each_dev(bus, NULL, &info, cmp_dev);
 337        return info.dev;
 338}
 339
 340static int cleanup_dev(struct device *dev, void *data)
 341{
 342        struct xenbus_device *xendev = to_xenbus_device(dev);
 343        struct xb_find_info *info = data;
 344        int len = strlen(info->nodename);
 345
 346        DPRINTK("%s", info->nodename);
 347
 348        /* Match the info->nodename path, or any subdirectory of that path. */
 349        if (strncmp(xendev->nodename, info->nodename, len))
 350                return 0;
 351
 352        /* If the node name is longer, ensure it really is a subdirectory. */
 353        if ((strlen(xendev->nodename) > len) && (xendev->nodename[len] != '/'))
 354                return 0;
 355
 356        info->dev = xendev;
 357        get_device(dev);
 358        return 1;
 359}
 360
 361static void xenbus_cleanup_devices(const char *path, struct bus_type *bus)
 362{
 363        struct xb_find_info info = { .nodename = path };
 364
 365        do {
 366                info.dev = NULL;
 367                bus_for_each_dev(bus, NULL, &info, cleanup_dev);
 368                if (info.dev) {
 369                        device_unregister(&info.dev->dev);
 370                        put_device(&info.dev->dev);
 371                }
 372        } while (info.dev);
 373}
 374
 375static void xenbus_dev_release(struct device *dev)
 376{
 377        if (dev)
 378                kfree(to_xenbus_device(dev));
 379}
 380
 381static ssize_t xendev_show_nodename(struct device *dev,
 382                                    struct device_attribute *attr, char *buf)
 383{
 384        return sprintf(buf, "%s\n", to_xenbus_device(dev)->nodename);
 385}
 386static DEVICE_ATTR(nodename, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_nodename, NULL);
 387
 388static ssize_t xendev_show_devtype(struct device *dev,
 389                                   struct device_attribute *attr, char *buf)
 390{
 391        return sprintf(buf, "%s\n", to_xenbus_device(dev)->devicetype);
 392}
 393static DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_devtype, NULL);
 394
 395static ssize_t xendev_show_modalias(struct device *dev,
 396                                    struct device_attribute *attr, char *buf)
 397{
 398        return sprintf(buf, "xen:%s\n", to_xenbus_device(dev)->devicetype);
 399}
 400static DEVICE_ATTR(modalias, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_modalias, NULL);
 401
 402int xenbus_probe_node(struct xen_bus_type *bus,
 403                      const char *type,
 404                      const char *nodename)
 405{
 406        char devname[XEN_BUS_ID_SIZE];
 407        int err;
 408        struct xenbus_device *xendev;
 409        size_t stringlen;
 410        char *tmpstring;
 411
 412        enum xenbus_state state = xenbus_read_driver_state(nodename);
 413
 414        if (state != XenbusStateInitialising) {
 415                /* Device is not new, so ignore it.  This can happen if a
 416                   device is going away after switching to Closed.  */
 417                return 0;
 418        }
 419
 420        stringlen = strlen(nodename) + 1 + strlen(type) + 1;
 421        xendev = kzalloc(sizeof(*xendev) + stringlen, GFP_KERNEL);
 422        if (!xendev)
 423                return -ENOMEM;
 424
 425        xendev->state = XenbusStateInitialising;
 426
 427        /* Copy the strings into the extra space. */
 428
 429        tmpstring = (char *)(xendev + 1);
 430        strcpy(tmpstring, nodename);
 431        xendev->nodename = tmpstring;
 432
 433        tmpstring += strlen(tmpstring) + 1;
 434        strcpy(tmpstring, type);
 435        xendev->devicetype = tmpstring;
 436        init_completion(&xendev->down);
 437
 438        xendev->dev.bus = &bus->bus;
 439        xendev->dev.release = xenbus_dev_release;
 440
 441        err = bus->get_bus_id(devname, xendev->nodename);
 442        if (err)
 443                goto fail;
 444
 445        dev_set_name(&xendev->dev, devname);
 446
 447        /* Register with generic device framework. */
 448        err = device_register(&xendev->dev);
 449        if (err)
 450                goto fail;
 451
 452        err = device_create_file(&xendev->dev, &dev_attr_nodename);
 453        if (err)
 454                goto fail_unregister;
 455
 456        err = device_create_file(&xendev->dev, &dev_attr_devtype);
 457        if (err)
 458                goto fail_remove_nodename;
 459
 460        err = device_create_file(&xendev->dev, &dev_attr_modalias);
 461        if (err)
 462                goto fail_remove_devtype;
 463
 464        return 0;
 465fail_remove_devtype:
 466        device_remove_file(&xendev->dev, &dev_attr_devtype);
 467fail_remove_nodename:
 468        device_remove_file(&xendev->dev, &dev_attr_nodename);
 469fail_unregister:
 470        device_unregister(&xendev->dev);
 471fail:
 472        kfree(xendev);
 473        return err;
 474}
 475EXPORT_SYMBOL_GPL(xenbus_probe_node);
 476
 477static int xenbus_probe_device_type(struct xen_bus_type *bus, const char *type)
 478{
 479        int err = 0;
 480        char **dir;
 481        unsigned int dir_n = 0;
 482        int i;
 483
 484        dir = xenbus_directory(XBT_NIL, bus->root, type, &dir_n);
 485        if (IS_ERR(dir))
 486                return PTR_ERR(dir);
 487
 488        for (i = 0; i < dir_n; i++) {
 489                err = bus->probe(bus, type, dir[i]);
 490                if (err)
 491                        break;
 492        }
 493
 494        kfree(dir);
 495        return err;
 496}
 497
 498int xenbus_probe_devices(struct xen_bus_type *bus)
 499{
 500        int err = 0;
 501        char **dir;
 502        unsigned int i, dir_n;
 503
 504        dir = xenbus_directory(XBT_NIL, bus->root, "", &dir_n);
 505        if (IS_ERR(dir))
 506                return PTR_ERR(dir);
 507
 508        for (i = 0; i < dir_n; i++) {
 509                err = xenbus_probe_device_type(bus, dir[i]);
 510                if (err)
 511                        break;
 512        }
 513
 514        kfree(dir);
 515        return err;
 516}
 517EXPORT_SYMBOL_GPL(xenbus_probe_devices);
 518
 519static unsigned int char_count(const char *str, char c)
 520{
 521        unsigned int i, ret = 0;
 522
 523        for (i = 0; str[i]; i++)
 524                if (str[i] == c)
 525                        ret++;
 526        return ret;
 527}
 528
 529static int strsep_len(const char *str, char c, unsigned int len)
 530{
 531        unsigned int i;
 532
 533        for (i = 0; str[i]; i++)
 534                if (str[i] == c) {
 535                        if (len == 0)
 536                                return i;
 537                        len--;
 538                }
 539        return (len == 0) ? i : -ERANGE;
 540}
 541
 542void xenbus_dev_changed(const char *node, struct xen_bus_type *bus)
 543{
 544        int exists, rootlen;
 545        struct xenbus_device *dev;
 546        char type[XEN_BUS_ID_SIZE];
 547        const char *p, *root;
 548
 549        if (char_count(node, '/') < 2)
 550                return;
 551
 552        exists = xenbus_exists(XBT_NIL, node, "");
 553        if (!exists) {
 554                xenbus_cleanup_devices(node, &bus->bus);
 555                return;
 556        }
 557
 558        /* backend/<type>/... or device/<type>/... */
 559        p = strchr(node, '/') + 1;
 560        snprintf(type, XEN_BUS_ID_SIZE, "%.*s", (int)strcspn(p, "/"), p);
 561        type[XEN_BUS_ID_SIZE-1] = '\0';
 562
 563        rootlen = strsep_len(node, '/', bus->levels);
 564        if (rootlen < 0)
 565                return;
 566        root = kasprintf(GFP_KERNEL, "%.*s", rootlen, node);
 567        if (!root)
 568                return;
 569
 570        dev = xenbus_device_find(root, &bus->bus);
 571        if (!dev)
 572                xenbus_probe_node(bus, type, root);
 573        else
 574                put_device(&dev->dev);
 575
 576        kfree(root);
 577}
 578EXPORT_SYMBOL_GPL(xenbus_dev_changed);
 579
 580int xenbus_dev_suspend(struct device *dev, pm_message_t state)
 581{
 582        int err = 0;
 583        struct xenbus_driver *drv;
 584        struct xenbus_device *xdev
 585                = container_of(dev, struct xenbus_device, dev);
 586
 587        DPRINTK("%s", xdev->nodename);
 588
 589        if (dev->driver == NULL)
 590                return 0;
 591        drv = to_xenbus_driver(dev->driver);
 592        if (drv->suspend)
 593                err = drv->suspend(xdev, state);
 594        if (err)
 595                printk(KERN_WARNING
 596                       "xenbus: suspend %s failed: %i\n", dev_name(dev), err);
 597        return 0;
 598}
 599EXPORT_SYMBOL_GPL(xenbus_dev_suspend);
 600
 601int xenbus_dev_resume(struct device *dev)
 602{
 603        int err;
 604        struct xenbus_driver *drv;
 605        struct xenbus_device *xdev
 606                = container_of(dev, struct xenbus_device, dev);
 607
 608        DPRINTK("%s", xdev->nodename);
 609
 610        if (dev->driver == NULL)
 611                return 0;
 612        drv = to_xenbus_driver(dev->driver);
 613        err = talk_to_otherend(xdev);
 614        if (err) {
 615                printk(KERN_WARNING
 616                       "xenbus: resume (talk_to_otherend) %s failed: %i\n",
 617                       dev_name(dev), err);
 618                return err;
 619        }
 620
 621        xdev->state = XenbusStateInitialising;
 622
 623        if (drv->resume) {
 624                err = drv->resume(xdev);
 625                if (err) {
 626                        printk(KERN_WARNING
 627                               "xenbus: resume %s failed: %i\n",
 628                               dev_name(dev), err);
 629                        return err;
 630                }
 631        }
 632
 633        err = watch_otherend(xdev);
 634        if (err) {
 635                printk(KERN_WARNING
 636                       "xenbus_probe: resume (watch_otherend) %s failed: "
 637                       "%d.\n", dev_name(dev), err);
 638                return err;
 639        }
 640
 641        return 0;
 642}
 643EXPORT_SYMBOL_GPL(xenbus_dev_resume);
 644
 645/* A flag to determine if xenstored is 'ready' (i.e. has started) */
 646int xenstored_ready = 0;
 647
 648
 649int register_xenstore_notifier(struct notifier_block *nb)
 650{
 651        int ret = 0;
 652
 653        if (xenstored_ready > 0)
 654                ret = nb->notifier_call(nb, 0, NULL);
 655        else
 656                blocking_notifier_chain_register(&xenstore_chain, nb);
 657
 658        return ret;
 659}
 660EXPORT_SYMBOL_GPL(register_xenstore_notifier);
 661
 662void unregister_xenstore_notifier(struct notifier_block *nb)
 663{
 664        blocking_notifier_chain_unregister(&xenstore_chain, nb);
 665}
 666EXPORT_SYMBOL_GPL(unregister_xenstore_notifier);
 667
 668void xenbus_probe(struct work_struct *unused)
 669{
 670        xenstored_ready = 1;
 671
 672        /* Notify others that xenstore is up */
 673        blocking_notifier_call_chain(&xenstore_chain, 0, NULL);
 674}
 675EXPORT_SYMBOL_GPL(xenbus_probe);
 676
 677static int __init xenbus_probe_initcall(void)
 678{
 679        if (!xen_domain())
 680                return -ENODEV;
 681
 682        if (xen_initial_domain() || xen_hvm_domain())
 683                return 0;
 684
 685        xenbus_probe(NULL);
 686        return 0;
 687}
 688
 689device_initcall(xenbus_probe_initcall);
 690
 691static int __init xenbus_init(void)
 692{
 693        int err = 0;
 694        unsigned long page = 0;
 695
 696        DPRINTK("");
 697
 698        err = -ENODEV;
 699        if (!xen_domain())
 700                return err;
 701
 702        /*
 703         * Domain0 doesn't have a store_evtchn or store_mfn yet.
 704         */
 705        if (xen_initial_domain()) {
 706                struct evtchn_alloc_unbound alloc_unbound;
 707
 708                /* Allocate Xenstore page */
 709                page = get_zeroed_page(GFP_KERNEL);
 710                if (!page)
 711                        goto out_error;
 712
 713                xen_store_mfn = xen_start_info->store_mfn =
 714                        pfn_to_mfn(virt_to_phys((void *)page) >>
 715                                   PAGE_SHIFT);
 716
 717                /* Next allocate a local port which xenstored can bind to */
 718                alloc_unbound.dom        = DOMID_SELF;
 719                alloc_unbound.remote_dom = 0;
 720
 721                err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
 722                                                  &alloc_unbound);
 723                if (err == -ENOSYS)
 724                        goto out_error;
 725
 726                BUG_ON(err);
 727                xen_store_evtchn = xen_start_info->store_evtchn =
 728                        alloc_unbound.port;
 729
 730                xen_store_interface = mfn_to_virt(xen_store_mfn);
 731        } else {
 732                if (xen_hvm_domain()) {
 733                        uint64_t v = 0;
 734                        err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v);
 735                        if (err)
 736                                goto out_error;
 737                        xen_store_evtchn = (int)v;
 738                        err = hvm_get_parameter(HVM_PARAM_STORE_PFN, &v);
 739                        if (err)
 740                                goto out_error;
 741                        xen_store_mfn = (unsigned long)v;
 742                        xen_store_interface = ioremap(xen_store_mfn << PAGE_SHIFT, PAGE_SIZE);
 743                } else {
 744                        xen_store_evtchn = xen_start_info->store_evtchn;
 745                        xen_store_mfn = xen_start_info->store_mfn;
 746                        xen_store_interface = mfn_to_virt(xen_store_mfn);
 747                        xenstored_ready = 1;
 748                }
 749        }
 750
 751        /* Initialize the interface to xenstore. */
 752        err = xs_init();
 753        if (err) {
 754                printk(KERN_WARNING
 755                       "XENBUS: Error initializing xenstore comms: %i\n", err);
 756                goto out_error;
 757        }
 758
 759#ifdef CONFIG_XEN_COMPAT_XENFS
 760        /*
 761         * Create xenfs mountpoint in /proc for compatibility with
 762         * utilities that expect to find "xenbus" under "/proc/xen".
 763         */
 764        proc_mkdir("xen", NULL);
 765#endif
 766
 767        return 0;
 768
 769  out_error:
 770        if (page != 0)
 771                free_page(page);
 772
 773        return err;
 774}
 775
 776postcore_initcall(xenbus_init);
 777
 778MODULE_LICENSE("GPL");
 779