linux/drivers/xen/xenbus/xenbus_client.c
<<
>>
Prefs
   1/******************************************************************************
   2 * Client-facing interface for the Xenbus driver.  In other words, the
   3 * interface between the Xenbus and the device-specific code, be it the
   4 * frontend or the backend of that driver.
   5 *
   6 * Copyright (C) 2005 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#include <linux/types.h>
  34#include <linux/vmalloc.h>
  35#include <asm/xen/hypervisor.h>
  36#include <xen/interface/xen.h>
  37#include <xen/interface/event_channel.h>
  38#include <xen/events.h>
  39#include <xen/grant_table.h>
  40#include <xen/xenbus.h>
  41
  42const char *xenbus_strstate(enum xenbus_state state)
  43{
  44        static const char *const name[] = {
  45                [ XenbusStateUnknown      ] = "Unknown",
  46                [ XenbusStateInitialising ] = "Initialising",
  47                [ XenbusStateInitWait     ] = "InitWait",
  48                [ XenbusStateInitialised  ] = "Initialised",
  49                [ XenbusStateConnected    ] = "Connected",
  50                [ XenbusStateClosing      ] = "Closing",
  51                [ XenbusStateClosed       ] = "Closed",
  52        };
  53        return (state < ARRAY_SIZE(name)) ? name[state] : "INVALID";
  54}
  55EXPORT_SYMBOL_GPL(xenbus_strstate);
  56
  57/**
  58 * xenbus_watch_path - register a watch
  59 * @dev: xenbus device
  60 * @path: path to watch
  61 * @watch: watch to register
  62 * @callback: callback to register
  63 *
  64 * Register a @watch on the given path, using the given xenbus_watch structure
  65 * for storage, and the given @callback function as the callback.  Return 0 on
  66 * success, or -errno on error.  On success, the given @path will be saved as
  67 * @watch->node, and remains the caller's to free.  On error, @watch->node will
  68 * be NULL, the device will switch to %XenbusStateClosing, and the error will
  69 * be saved in the store.
  70 */
  71int xenbus_watch_path(struct xenbus_device *dev, const char *path,
  72                      struct xenbus_watch *watch,
  73                      void (*callback)(struct xenbus_watch *,
  74                                       const char **, unsigned int))
  75{
  76        int err;
  77
  78        watch->node = path;
  79        watch->callback = callback;
  80
  81        err = register_xenbus_watch(watch);
  82
  83        if (err) {
  84                watch->node = NULL;
  85                watch->callback = NULL;
  86                xenbus_dev_fatal(dev, err, "adding watch on %s", path);
  87        }
  88
  89        return err;
  90}
  91EXPORT_SYMBOL_GPL(xenbus_watch_path);
  92
  93
  94/**
  95 * xenbus_watch_pathfmt - register a watch on a sprintf-formatted path
  96 * @dev: xenbus device
  97 * @watch: watch to register
  98 * @callback: callback to register
  99 * @pathfmt: format of path to watch
 100 *
 101 * Register a watch on the given @path, using the given xenbus_watch
 102 * structure for storage, and the given @callback function as the callback.
 103 * Return 0 on success, or -errno on error.  On success, the watched path
 104 * (@path/@path2) will be saved as @watch->node, and becomes the caller's to
 105 * kfree().  On error, watch->node will be NULL, so the caller has nothing to
 106 * free, the device will switch to %XenbusStateClosing, and the error will be
 107 * saved in the store.
 108 */
 109int xenbus_watch_pathfmt(struct xenbus_device *dev,
 110                         struct xenbus_watch *watch,
 111                         void (*callback)(struct xenbus_watch *,
 112                                        const char **, unsigned int),
 113                         const char *pathfmt, ...)
 114{
 115        int err;
 116        va_list ap;
 117        char *path;
 118
 119        va_start(ap, pathfmt);
 120        path = kvasprintf(GFP_NOIO | __GFP_HIGH, pathfmt, ap);
 121        va_end(ap);
 122
 123        if (!path) {
 124                xenbus_dev_fatal(dev, -ENOMEM, "allocating path for watch");
 125                return -ENOMEM;
 126        }
 127        err = xenbus_watch_path(dev, path, watch, callback);
 128
 129        if (err)
 130                kfree(path);
 131        return err;
 132}
 133EXPORT_SYMBOL_GPL(xenbus_watch_pathfmt);
 134
 135
 136/**
 137 * xenbus_switch_state
 138 * @dev: xenbus device
 139 * @xbt: transaction handle
 140 * @state: new state
 141 *
 142 * Advertise in the store a change of the given driver to the given new_state.
 143 * Return 0 on success, or -errno on error.  On error, the device will switch
 144 * to XenbusStateClosing, and the error will be saved in the store.
 145 */
 146int xenbus_switch_state(struct xenbus_device *dev, enum xenbus_state state)
 147{
 148        /* We check whether the state is currently set to the given value, and
 149           if not, then the state is set.  We don't want to unconditionally
 150           write the given state, because we don't want to fire watches
 151           unnecessarily.  Furthermore, if the node has gone, we don't write
 152           to it, as the device will be tearing down, and we don't want to
 153           resurrect that directory.
 154
 155           Note that, because of this cached value of our state, this function
 156           will not work inside a Xenstore transaction (something it was
 157           trying to in the past) because dev->state would not get reset if
 158           the transaction was aborted.
 159
 160         */
 161
 162        int current_state;
 163        int err;
 164
 165        if (state == dev->state)
 166                return 0;
 167
 168        err = xenbus_scanf(XBT_NIL, dev->nodename, "state", "%d",
 169                           &current_state);
 170        if (err != 1)
 171                return 0;
 172
 173        err = xenbus_printf(XBT_NIL, dev->nodename, "state", "%d", state);
 174        if (err) {
 175                if (state != XenbusStateClosing) /* Avoid looping */
 176                        xenbus_dev_fatal(dev, err, "writing new state");
 177                return err;
 178        }
 179
 180        dev->state = state;
 181
 182        return 0;
 183}
 184EXPORT_SYMBOL_GPL(xenbus_switch_state);
 185
 186int xenbus_frontend_closed(struct xenbus_device *dev)
 187{
 188        xenbus_switch_state(dev, XenbusStateClosed);
 189        complete(&dev->down);
 190        return 0;
 191}
 192EXPORT_SYMBOL_GPL(xenbus_frontend_closed);
 193
 194/**
 195 * Return the path to the error node for the given device, or NULL on failure.
 196 * If the value returned is non-NULL, then it is the caller's to kfree.
 197 */
 198static char *error_path(struct xenbus_device *dev)
 199{
 200        return kasprintf(GFP_KERNEL, "error/%s", dev->nodename);
 201}
 202
 203
 204static void xenbus_va_dev_error(struct xenbus_device *dev, int err,
 205                                const char *fmt, va_list ap)
 206{
 207        int ret;
 208        unsigned int len;
 209        char *printf_buffer = NULL;
 210        char *path_buffer = NULL;
 211
 212#define PRINTF_BUFFER_SIZE 4096
 213        printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL);
 214        if (printf_buffer == NULL)
 215                goto fail;
 216
 217        len = sprintf(printf_buffer, "%i ", -err);
 218        ret = vsnprintf(printf_buffer+len, PRINTF_BUFFER_SIZE-len, fmt, ap);
 219
 220        BUG_ON(len + ret > PRINTF_BUFFER_SIZE-1);
 221
 222        dev_err(&dev->dev, "%s\n", printf_buffer);
 223
 224        path_buffer = error_path(dev);
 225
 226        if (path_buffer == NULL) {
 227                dev_err(&dev->dev, "failed to write error node for %s (%s)\n",
 228                       dev->nodename, printf_buffer);
 229                goto fail;
 230        }
 231
 232        if (xenbus_write(XBT_NIL, path_buffer, "error", printf_buffer) != 0) {
 233                dev_err(&dev->dev, "failed to write error node for %s (%s)\n",
 234                       dev->nodename, printf_buffer);
 235                goto fail;
 236        }
 237
 238fail:
 239        kfree(printf_buffer);
 240        kfree(path_buffer);
 241}
 242
 243
 244/**
 245 * xenbus_dev_error
 246 * @dev: xenbus device
 247 * @err: error to report
 248 * @fmt: error message format
 249 *
 250 * Report the given negative errno into the store, along with the given
 251 * formatted message.
 252 */
 253void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt, ...)
 254{
 255        va_list ap;
 256
 257        va_start(ap, fmt);
 258        xenbus_va_dev_error(dev, err, fmt, ap);
 259        va_end(ap);
 260}
 261EXPORT_SYMBOL_GPL(xenbus_dev_error);
 262
 263/**
 264 * xenbus_dev_fatal
 265 * @dev: xenbus device
 266 * @err: error to report
 267 * @fmt: error message format
 268 *
 269 * Equivalent to xenbus_dev_error(dev, err, fmt, args), followed by
 270 * xenbus_switch_state(dev, NULL, XenbusStateClosing) to schedule an orderly
 271 * closedown of this driver and its peer.
 272 */
 273
 274void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt, ...)
 275{
 276        va_list ap;
 277
 278        va_start(ap, fmt);
 279        xenbus_va_dev_error(dev, err, fmt, ap);
 280        va_end(ap);
 281
 282        xenbus_switch_state(dev, XenbusStateClosing);
 283}
 284EXPORT_SYMBOL_GPL(xenbus_dev_fatal);
 285
 286/**
 287 * xenbus_grant_ring
 288 * @dev: xenbus device
 289 * @ring_mfn: mfn of ring to grant
 290
 291 * Grant access to the given @ring_mfn to the peer of the given device.  Return
 292 * 0 on success, or -errno on error.  On error, the device will switch to
 293 * XenbusStateClosing, and the error will be saved in the store.
 294 */
 295int xenbus_grant_ring(struct xenbus_device *dev, unsigned long ring_mfn)
 296{
 297        int err = gnttab_grant_foreign_access(dev->otherend_id, ring_mfn, 0);
 298        if (err < 0)
 299                xenbus_dev_fatal(dev, err, "granting access to ring page");
 300        return err;
 301}
 302EXPORT_SYMBOL_GPL(xenbus_grant_ring);
 303
 304
 305/**
 306 * Allocate an event channel for the given xenbus_device, assigning the newly
 307 * created local port to *port.  Return 0 on success, or -errno on error.  On
 308 * error, the device will switch to XenbusStateClosing, and the error will be
 309 * saved in the store.
 310 */
 311int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port)
 312{
 313        struct evtchn_alloc_unbound alloc_unbound;
 314        int err;
 315
 316        alloc_unbound.dom = DOMID_SELF;
 317        alloc_unbound.remote_dom = dev->otherend_id;
 318
 319        err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
 320                                          &alloc_unbound);
 321        if (err)
 322                xenbus_dev_fatal(dev, err, "allocating event channel");
 323        else
 324                *port = alloc_unbound.port;
 325
 326        return err;
 327}
 328EXPORT_SYMBOL_GPL(xenbus_alloc_evtchn);
 329
 330
 331/**
 332 * Bind to an existing interdomain event channel in another domain. Returns 0
 333 * on success and stores the local port in *port. On error, returns -errno,
 334 * switches the device to XenbusStateClosing, and saves the error in XenStore.
 335 */
 336int xenbus_bind_evtchn(struct xenbus_device *dev, int remote_port, int *port)
 337{
 338        struct evtchn_bind_interdomain bind_interdomain;
 339        int err;
 340
 341        bind_interdomain.remote_dom = dev->otherend_id;
 342        bind_interdomain.remote_port = remote_port;
 343
 344        err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
 345                                          &bind_interdomain);
 346        if (err)
 347                xenbus_dev_fatal(dev, err,
 348                                 "binding to event channel %d from domain %d",
 349                                 remote_port, dev->otherend_id);
 350        else
 351                *port = bind_interdomain.local_port;
 352
 353        return err;
 354}
 355EXPORT_SYMBOL_GPL(xenbus_bind_evtchn);
 356
 357
 358/**
 359 * Free an existing event channel. Returns 0 on success or -errno on error.
 360 */
 361int xenbus_free_evtchn(struct xenbus_device *dev, int port)
 362{
 363        struct evtchn_close close;
 364        int err;
 365
 366        close.port = port;
 367
 368        err = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
 369        if (err)
 370                xenbus_dev_error(dev, err, "freeing event channel %d", port);
 371
 372        return err;
 373}
 374EXPORT_SYMBOL_GPL(xenbus_free_evtchn);
 375
 376
 377/**
 378 * xenbus_map_ring_valloc
 379 * @dev: xenbus device
 380 * @gnt_ref: grant reference
 381 * @vaddr: pointer to address to be filled out by mapping
 382 *
 383 * Based on Rusty Russell's skeleton driver's map_page.
 384 * Map a page of memory into this domain from another domain's grant table.
 385 * xenbus_map_ring_valloc allocates a page of virtual address space, maps the
 386 * page to that address, and sets *vaddr to that address.
 387 * Returns 0 on success, and GNTST_* (see xen/include/interface/grant_table.h)
 388 * or -ENOMEM on error. If an error is returned, device will switch to
 389 * XenbusStateClosing and the error message will be saved in XenStore.
 390 */
 391int xenbus_map_ring_valloc(struct xenbus_device *dev, int gnt_ref, void **vaddr)
 392{
 393        struct gnttab_map_grant_ref op = {
 394                .flags = GNTMAP_host_map,
 395                .ref   = gnt_ref,
 396                .dom   = dev->otherend_id,
 397        };
 398        struct vm_struct *area;
 399
 400        *vaddr = NULL;
 401
 402        area = xen_alloc_vm_area(PAGE_SIZE);
 403        if (!area)
 404                return -ENOMEM;
 405
 406        op.host_addr = (unsigned long)area->addr;
 407
 408        if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
 409                BUG();
 410
 411        if (op.status != GNTST_okay) {
 412                xen_free_vm_area(area);
 413                xenbus_dev_fatal(dev, op.status,
 414                                 "mapping in shared page %d from domain %d",
 415                                 gnt_ref, dev->otherend_id);
 416                return op.status;
 417        }
 418
 419        /* Stuff the handle in an unused field */
 420        area->phys_addr = (unsigned long)op.handle;
 421
 422        *vaddr = area->addr;
 423        return 0;
 424}
 425EXPORT_SYMBOL_GPL(xenbus_map_ring_valloc);
 426
 427
 428/**
 429 * xenbus_map_ring
 430 * @dev: xenbus device
 431 * @gnt_ref: grant reference
 432 * @handle: pointer to grant handle to be filled
 433 * @vaddr: address to be mapped to
 434 *
 435 * Map a page of memory into this domain from another domain's grant table.
 436 * xenbus_map_ring does not allocate the virtual address space (you must do
 437 * this yourself!). It only maps in the page to the specified address.
 438 * Returns 0 on success, and GNTST_* (see xen/include/interface/grant_table.h)
 439 * or -ENOMEM on error. If an error is returned, device will switch to
 440 * XenbusStateClosing and the error message will be saved in XenStore.
 441 */
 442int xenbus_map_ring(struct xenbus_device *dev, int gnt_ref,
 443                    grant_handle_t *handle, void *vaddr)
 444{
 445        struct gnttab_map_grant_ref op = {
 446                .host_addr = (unsigned long)vaddr,
 447                .flags     = GNTMAP_host_map,
 448                .ref       = gnt_ref,
 449                .dom       = dev->otherend_id,
 450        };
 451
 452        if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
 453                BUG();
 454
 455        if (op.status != GNTST_okay) {
 456                xenbus_dev_fatal(dev, op.status,
 457                                 "mapping in shared page %d from domain %d",
 458                                 gnt_ref, dev->otherend_id);
 459        } else
 460                *handle = op.handle;
 461
 462        return op.status;
 463}
 464EXPORT_SYMBOL_GPL(xenbus_map_ring);
 465
 466
 467/**
 468 * xenbus_unmap_ring_vfree
 469 * @dev: xenbus device
 470 * @vaddr: addr to unmap
 471 *
 472 * Based on Rusty Russell's skeleton driver's unmap_page.
 473 * Unmap a page of memory in this domain that was imported from another domain.
 474 * Use xenbus_unmap_ring_vfree if you mapped in your memory with
 475 * xenbus_map_ring_valloc (it will free the virtual address space).
 476 * Returns 0 on success and returns GNTST_* on error
 477 * (see xen/include/interface/grant_table.h).
 478 */
 479int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr)
 480{
 481        struct vm_struct *area;
 482        struct gnttab_unmap_grant_ref op = {
 483                .host_addr = (unsigned long)vaddr,
 484        };
 485
 486        /* It'd be nice if linux/vmalloc.h provided a find_vm_area(void *addr)
 487         * method so that we don't have to muck with vmalloc internals here.
 488         * We could force the user to hang on to their struct vm_struct from
 489         * xenbus_map_ring_valloc, but these 6 lines considerably simplify
 490         * this API.
 491         */
 492        read_lock(&vmlist_lock);
 493        for (area = vmlist; area != NULL; area = area->next) {
 494                if (area->addr == vaddr)
 495                        break;
 496        }
 497        read_unlock(&vmlist_lock);
 498
 499        if (!area) {
 500                xenbus_dev_error(dev, -ENOENT,
 501                                 "can't find mapped virtual address %p", vaddr);
 502                return GNTST_bad_virt_addr;
 503        }
 504
 505        op.handle = (grant_handle_t)area->phys_addr;
 506
 507        if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
 508                BUG();
 509
 510        if (op.status == GNTST_okay)
 511                xen_free_vm_area(area);
 512        else
 513                xenbus_dev_error(dev, op.status,
 514                                 "unmapping page at handle %d error %d",
 515                                 (int16_t)area->phys_addr, op.status);
 516
 517        return op.status;
 518}
 519EXPORT_SYMBOL_GPL(xenbus_unmap_ring_vfree);
 520
 521
 522/**
 523 * xenbus_unmap_ring
 524 * @dev: xenbus device
 525 * @handle: grant handle
 526 * @vaddr: addr to unmap
 527 *
 528 * Unmap a page of memory in this domain that was imported from another domain.
 529 * Returns 0 on success and returns GNTST_* on error
 530 * (see xen/include/interface/grant_table.h).
 531 */
 532int xenbus_unmap_ring(struct xenbus_device *dev,
 533                      grant_handle_t handle, void *vaddr)
 534{
 535        struct gnttab_unmap_grant_ref op = {
 536                .host_addr = (unsigned long)vaddr,
 537                .handle    = handle,
 538        };
 539
 540        if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
 541                BUG();
 542
 543        if (op.status != GNTST_okay)
 544                xenbus_dev_error(dev, op.status,
 545                                 "unmapping page at handle %d error %d",
 546                                 handle, op.status);
 547
 548        return op.status;
 549}
 550EXPORT_SYMBOL_GPL(xenbus_unmap_ring);
 551
 552
 553/**
 554 * xenbus_read_driver_state
 555 * @path: path for driver
 556 *
 557 * Return the state of the driver rooted at the given store path, or
 558 * XenbusStateUnknown if no state can be read.
 559 */
 560enum xenbus_state xenbus_read_driver_state(const char *path)
 561{
 562        enum xenbus_state result;
 563        int err = xenbus_gather(XBT_NIL, path, "state", "%d", &result, NULL);
 564        if (err)
 565                result = XenbusStateUnknown;
 566
 567        return result;
 568}
 569EXPORT_SYMBOL_GPL(xenbus_read_driver_state);
 570
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.