Пример #1
0
int fork_xenbus(void)
{
	char path[50];
    char *flag = "fork", *err;
    xenbus_event_queue events = NULL;

    sprintf(path,"fork/requests");
    xenbus_watch_path_token(XBT_NIL, path, path, &events);
	xenbus_write(XBT_NIL, path, "fork");

    while(1){

        xenbus_wait_for_watch(&events);

        if ((err = xenbus_read(XBT_NIL, path, &flag))) {
            free(err);
            continue;
        }

        if (!strcmp(flag, "") || !strcmp(flag, "fork")) {
            free(flag);
            flag = NULL;
            continue;
        }else if (!strcmp(flag, "0"))
        	return 0;
        else if (!strcmp(flag, "1"))
            return 1;

        err = xenbus_write(XBT_NIL, path, "");
        free(err);
        free(flag);
        flag = NULL;
    }
    return -1;
}
Пример #2
0
static void shutdown_thread(void *p)
{
    const char *path = "control/shutdown";
    const char *token = path;
    xenbus_event_queue events = NULL;
    char *shutdown = NULL, *err;
    unsigned int shutdown_reason;
    xenbus_watch_path_token(XBT_NIL, path, token, &events);
    while ((err = xenbus_read(XBT_NIL, path, &shutdown)) != NULL || !strcmp(shutdown, ""))
    {
        free(err);
        free(shutdown);
        shutdown = NULL;
        xenbus_wait_for_watch(&events);
    }
    err = xenbus_unwatch_path_token(XBT_NIL, path, token);
    free(err);
    err = xenbus_write(XBT_NIL, path, "");
    free(err);
    printk("Shutting down (%s)\n", shutdown);

    if (!strcmp(shutdown, "poweroff"))
        shutdown_reason = SHUTDOWN_poweroff;
    else if (!strcmp(shutdown, "reboot"))
        shutdown_reason = SHUTDOWN_reboot;
    else
        /* Unknown */
        shutdown_reason = SHUTDOWN_crash;
    app_shutdown(shutdown_reason);
    free(shutdown);
}
Пример #3
0
/* Write a grant ref and ec port to xenstore in a transaction for whatever
 * your pThing is. Also some non-transaction read/write stuff.
 */
static NTSTATUS
GrantAndEventChannelInATransaction(CHAR *pFrontendPath, struct THING *pThing)
{
    NTSTATUS Status;
    CHAR *pMyData;
    xenbus_transaction_t Xbt;
    
    do {
        xenbus_transaction_start(&Xbt);
        xenbus_write_grant_ref(Xbt, pFrontendPath, "ring-ref",
                               pThing->RingGrantRef);

        xenbus_write_evtchn_port(Xbt, pFrontendPath, "event-channel",
                                 pThing->EvtchnPort);

        Status = xenbus_transaction_end(Xbt, 0);

    } while (Status == STATUS_RETRY);

    if (Status != STATUS_SUCCESS) {
        DbgPrint("Failed to end transaction, 0x%08x.\n", Status);
        /* Handle failure */
    }

    /* A write and read w/o a transaction */
    xenbus_write(XBT_NIL, "drivers/mydriver", "1.2.3.4");

    Status = xenbus_read(XBT_NIL, "drivers/mydriver/mydata", &pMyData);
    if (NT_SUCCESS(Status)) {
        DbgPrint("Read MyData: %s\n", pMyData);
        XmFreeMemory(pMyData);
    }

    /* ... */
}
Пример #4
0
/*ARGSUSED*/
static void
xen_shutdown_handler(struct xenbus_watch *watch, const char **vec,
	unsigned int len)
{
	char *str;
	xenbus_transaction_t xbt;
	int err, shutdown_code = SHUTDOWN_INVALID;
	unsigned int slen;

again:
	err = xenbus_transaction_start(&xbt);
	if (err)
		return;
	if (xenbus_read(xbt, "control", "shutdown", (void *)&str, &slen)) {
		(void) xenbus_transaction_end(xbt, 1);
		return;
	}

	SUSPEND_DEBUG("%d: xen_shutdown_handler: \"%s\"\n", CPU->cpu_id, str);

	/*
	 * If this is a watch fired from our write below, check out early to
	 * avoid an infinite loop.
	 */
	if (strcmp(str, "") == 0) {
		(void) xenbus_transaction_end(xbt, 0);
		kmem_free(str, slen);
		return;
	} else if (strcmp(str, "poweroff") == 0) {
		shutdown_code = SHUTDOWN_POWEROFF;
	} else if (strcmp(str, "reboot") == 0) {
		shutdown_code = SHUTDOWN_REBOOT;
	} else if (strcmp(str, "suspend") == 0) {
		shutdown_code = SHUTDOWN_SUSPEND;
	} else if (strcmp(str, "halt") == 0) {
		shutdown_code = SHUTDOWN_HALT;
	} else {
		printf("Ignoring shutdown request: %s\n", str);
	}

	/*
	 * XXPV	Should we check the value of xenbus_write() too, or are all
	 *	errors automatically folded into xenbus_transaction_end() ??
	 */
	(void) xenbus_write(xbt, "control", "shutdown", "");
	err = xenbus_transaction_end(xbt, 0);
	if (err == EAGAIN) {
		SUSPEND_DEBUG("%d: trying again\n", CPU->cpu_id);
		kmem_free(str, slen);
		goto again;
	}

	kmem_free(str, slen);
	if (shutdown_code != SHUTDOWN_INVALID) {
		(void) taskq_dispatch(xen_shutdown_tq, xen_shutdown,
		    (void *)(intptr_t)shutdown_code, 0);
	}
}
Пример #5
0
static void shutdown_handler(struct xenbus_watch *watch,
			     const char **vec, unsigned int len)
{
	char *str;
	struct xenbus_transaction xbt;
	int err;
	static struct shutdown_handler handlers[] = {
		{ "poweroff",	do_poweroff },
		{ "halt",	do_poweroff },
		{ "reboot",	do_reboot   },
#ifdef CONFIG_HIBERNATE_CALLBACKS
		{ "suspend",	do_suspend  },
#endif
		{NULL, NULL},
	};
	static struct shutdown_handler *handler;

	if (shutting_down != SHUTDOWN_INVALID)
		return;

 again:
	err = xenbus_transaction_start(&xbt);
	if (err)
		return;

	str = (char *)xenbus_read(xbt, "control", "shutdown", NULL);
	/* Ignore read errors and empty reads. */
	if (XENBUS_IS_ERR_READ(str)) {
		xenbus_transaction_end(xbt, 1);
		return;
	}

	for (handler = &handlers[0]; handler->command; handler++) {
		if (strcmp(str, handler->command) == 0)
			break;
	}

	/* Only acknowledge commands which we are prepared to handle. */
	if (handler->cb)
		xenbus_write(xbt, "control", "shutdown", "");

	err = xenbus_transaction_end(xbt, 0);
	if (err == -EAGAIN) {
		kfree(str);
		goto again;
	}

	if (handler->cb) {
		handler->cb();
	} else {
		pr_info("Ignoring shutdown request: %s\n", str);
		shutting_down = SHUTDOWN_INVALID;
	}

	kfree(str);
}
Пример #6
0
static void xenkbd_backend_changed(struct xenbus_device *dev,
				   enum xenbus_state backend_state)
{
	struct xenkbd_info *info = dev_get_drvdata(&dev->dev);
	int ret, val;

	switch (backend_state) {
	case XenbusStateInitialising:
	case XenbusStateInitialised:
	case XenbusStateReconfiguring:
	case XenbusStateReconfigured:
	case XenbusStateUnknown:
		break;

	case XenbusStateInitWait:
InitWait:
		if (xenbus_read_unsigned(info->xbdev->otherend,
					 "feature-abs-pointer", 0)) {
			ret = xenbus_write(XBT_NIL, info->xbdev->nodename,
					   "request-abs-pointer", "1");
			if (ret)
				pr_warning("xenkbd: can't request abs-pointer");
		}

		xenbus_switch_state(dev, XenbusStateConnected);
		break;

	case XenbusStateConnected:
		/*
		 * Work around xenbus race condition: If backend goes
		 * through InitWait to Connected fast enough, we can
		 * get Connected twice here.
		 */
		if (dev->state != XenbusStateConnected)
			goto InitWait; /* no InitWait seen yet, fudge it */

		/* Set input abs params to match backend screen res */
		if (xenbus_scanf(XBT_NIL, info->xbdev->otherend,
				 "width", "%d", &val) > 0)
			input_set_abs_params(info->ptr, ABS_X, 0, val, 0, 0);

		if (xenbus_scanf(XBT_NIL, info->xbdev->otherend,
				 "height", "%d", &val) > 0)
			input_set_abs_params(info->ptr, ABS_Y, 0, val, 0, 0);

		break;

	case XenbusStateClosed:
		if (dev->state == XenbusStateClosed)
			break;
		/* Missed the backend's CLOSING state -- fallthrough */
	case XenbusStateClosing:
		xenbus_frontend_closed(dev);
		break;
	}
}
Пример #7
0
static void do_write_test(const char *path, const char *val)
{
    char *msg;
    printk("Write %s to %s...\n", val, path);
    msg = xenbus_write(XBT_NIL, path, val);
    if (msg) {
	printk("Result %s\n", msg);
	free(msg);
    } else {
	printk("Success.\n");
    }
}
Пример #8
0
static void shutdown_handler(struct xenbus_watch *watch,
                             const char **vec, unsigned int len)
{
    char *str;
    struct xenbus_transaction xbt;
    int err;

    if (shutting_down != SHUTDOWN_INVALID)
        return;

again:
    err = xenbus_transaction_start(&xbt);
    if (err)
        return;

    str = (char *)xenbus_read(xbt, "control", "shutdown", NULL);
    /* Ignore read errors and empty reads. */
    if (XENBUS_IS_ERR_READ(str)) {
        xenbus_transaction_end(xbt, 1);
        return;
    }

    xenbus_write(xbt, "control", "shutdown", "");

    err = xenbus_transaction_end(xbt, 0);
    if (err == -EAGAIN) {
        kfree(str);
        goto again;
    }

    if (strcmp(str, "poweroff") == 0 ||
            strcmp(str, "halt") == 0) {
        shutting_down = SHUTDOWN_POWEROFF;
        orderly_poweroff(false);
    } else if (strcmp(str, "reboot") == 0) {
        shutting_down = SHUTDOWN_POWEROFF; /* ? */
        ctrl_alt_del();
#ifdef CONFIG_PM_SLEEP
    } else if (strcmp(str, "suspend") == 0) {
        do_suspend();
#endif
    } else {
        printk(KERN_INFO "Ignoring shutdown request: %s\n", str);
        shutting_down = SHUTDOWN_INVALID;
    }

    kfree(str);
}
Пример #9
0
static void shutdown_handler(struct xenbus_watch *watch,
			     const char **vec, unsigned int len)
{
	extern void ctrl_alt_del(void);
	char *str;
	struct xenbus_transaction xbt;
	int err;

	if (shutting_down != SHUTDOWN_INVALID)
		return;

 again:
	err = xenbus_transaction_start(&xbt);
	if (err)
		return;
	str = (char *)xenbus_read(xbt, "control", "shutdown", NULL);
	/* Ignore read errors and empty reads. */
	if (XENBUS_IS_ERR_READ(str)) {
		xenbus_transaction_end(xbt, 1);
		return;
	}

	xenbus_write(xbt, "control", "shutdown", "");

	err = xenbus_transaction_end(xbt, 0);
	if (err == -EAGAIN) {
		kfree(str);
		goto again;
	}

	if (strcmp(str, "poweroff") == 0)
		shutting_down = SHUTDOWN_POWEROFF;
	else if (strcmp(str, "reboot") == 0)
		ctrl_alt_del();
	else if (strcmp(str, "suspend") == 0)
		shutting_down = SHUTDOWN_SUSPEND;
	else if (strcmp(str, "halt") == 0)
		shutting_down = SHUTDOWN_HALT;
	else {
		printk("Ignoring shutdown request: %s\n", str);
		shutting_down = SHUTDOWN_INVALID;
	}

	if (shutting_down != SHUTDOWN_INVALID)
		schedule_work(&shutdown_work);

	kfree(str);
}
Пример #10
0
char* xenbus_printf(xenbus_transaction_t xbt,
                                  const char* node, const char* path,
                                  const char* fmt, ...)
{
#define BUFFER_SIZE 256
    char fullpath[BUFFER_SIZE];
    char val[BUFFER_SIZE];
    va_list args;

    BUG_ON(strlen(node) + strlen(path) + 1 >= BUFFER_SIZE);
    sprintf(fullpath,"%s/%s", node, path);
    va_start(args, fmt);
    vsprintf(val, fmt, args);
    va_end(args);
    return xenbus_write(xbt,fullpath,val);
}
Пример #11
0
static void shutdown_handler(struct xenbus_watch *watch,
			     const char *path, const char *token)
{
	char *str;
	struct xenbus_transaction xbt;
	int err;
	int idx;

	if (shutting_down != SHUTDOWN_INVALID)
		return;

 again:
	err = xenbus_transaction_start(&xbt);
	if (err)
		return;

	str = (char *)xenbus_read(xbt, "control", "shutdown", NULL);
	/* Ignore read errors and empty reads. */
	if (XENBUS_IS_ERR_READ(str)) {
		xenbus_transaction_end(xbt, 1);
		return;
	}

	for (idx = 0; idx < ARRAY_SIZE(shutdown_handlers); idx++) {
		if (strcmp(str, shutdown_handlers[idx].command) == 0)
			break;
	}

	/* Only acknowledge commands which we are prepared to handle. */
	if (idx < ARRAY_SIZE(shutdown_handlers))
		xenbus_write(xbt, "control", "shutdown", "");

	err = xenbus_transaction_end(xbt, 0);
	if (err == -EAGAIN) {
		kfree(str);
		goto again;
	}

	if (idx < ARRAY_SIZE(shutdown_handlers)) {
		shutdown_handlers[idx].cb();
	} else {
		pr_info("Ignoring shutdown request: %s\n", str);
		shutting_down = SHUTDOWN_INVALID;
	}

	kfree(str);
}
Пример #12
0
char *xenbus_switch_state(xenbus_transaction_t xbt, const char* path, XenbusState state)
{
    char *current_state;
    char *msg = NULL;
    char *msg2 = NULL;
    char value[2];
    XenbusState rs;
    int xbt_flag = 0;
    int retry = 0;

    do {
        if (xbt == XBT_NIL) {
            msg = xenbus_transaction_start(&xbt);
            if (msg) goto exit;
            xbt_flag = 1;
        }

        msg = xenbus_read(xbt, path, &current_state);
        if (msg) goto exit;

        rs = (XenbusState) (current_state[0] - '0');
        free(current_state);
        if (rs == state) {
            msg = NULL;
            goto exit;
        }

        snprintf(value, 2, "%d", state);
        msg = xenbus_write(xbt, path, value);

exit:
        if (xbt_flag) {
            msg2 = xenbus_transaction_end(xbt, 0, &retry);
            xbt = XBT_NIL;
        }
        if (msg == NULL && msg2 != NULL)
            msg = msg2;
    } while (retry);

    return msg;
}
Пример #13
0
static int setup_suspend_evtchn(void)
{
	static int irq;
	int port;
	char portstr[16];

	if (irq > 0)
		unbind_from_irqhandler(irq, NULL);

	irq = bind_listening_port_to_irqhandler(0, suspend_int, 0, "suspend",
						NULL);
	if (irq <= 0)
		return -1;

	port = irq_to_evtchn_port(irq);
	printk(KERN_INFO "suspend: event channel %d\n", port);
	(void)snprintf(portstr,sizeof(portstr), "%d", port);
	xenbus_write(XBT_NIL, "device/suspend", "event-channel", portstr);

	return 0;
}
Пример #14
0
static void
_dev_error(struct xenbus_device *dev, int err, const char *fmt,
		va_list ap)
{
	int ret;
	unsigned int len;
	char *printf_buffer = NULL, *path_buffer = NULL;

#define PRINTF_BUFFER_SIZE 4096
	printf_buffer = malloc(PRINTF_BUFFER_SIZE, M_DEVBUF, M_NOWAIT);
	if (printf_buffer == NULL)
		goto fail;

	len = snprintf(printf_buffer, PRINTF_BUFFER_SIZE, "%i ", -err);
	ret = vsnprintf(printf_buffer+len, PRINTF_BUFFER_SIZE-len, fmt, ap);

	KASSERT(len + ret < PRINTF_BUFFER_SIZE);
	dev->xbusd_has_error = 1;

	path_buffer = error_path(dev);

	if (path_buffer == NULL) {
		printk("xenbus: failed to write error node for %s (%s)\n",
		       dev->xbusd_path, printf_buffer);
		goto fail;
	}

	if (xenbus_write(NULL, path_buffer, "error", printf_buffer) != 0) {
		printk("xenbus: failed to write error node for %s (%s)\n",
		       dev->xbusd_path, printf_buffer);
		goto fail;
	}

fail:
	if (printf_buffer)
		free(printf_buffer, M_DEVBUF);
	if (path_buffer)
		free(path_buffer, M_DEVBUF);
}
Пример #15
0
static void xenbus_va_dev_error(struct xenbus_device *dev, int err,
				const char *fmt, va_list ap)
{
	int ret;
	unsigned int len;
	char *printf_buffer = NULL;
	char *path_buffer = NULL;

#define PRINTF_BUFFER_SIZE 4096
	printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL);
	if (printf_buffer == NULL)
		goto fail;

	len = sprintf(printf_buffer, "%i ", -err);
	ret = vsnprintf(printf_buffer+len, PRINTF_BUFFER_SIZE-len, fmt, ap);

	BUG_ON(len + ret > PRINTF_BUFFER_SIZE-1);

	dev_err(&dev->dev, "%s\n", printf_buffer);

	path_buffer = error_path(dev);

	if (path_buffer == NULL) {
		dev_err(&dev->dev, "failed to write error node for %s (%s)\n",
		       dev->nodename, printf_buffer);
		goto fail;
	}

	if (xenbus_write(XBT_NIL, path_buffer, "error", printf_buffer) != 0) {
		dev_err(&dev->dev, "failed to write error node for %s (%s)\n",
		       dev->nodename, printf_buffer);
		goto fail;
	}

fail:
	kfree(printf_buffer);
	kfree(path_buffer);
}
Пример #16
0
void pcifront_watches(void *opaque)
{
    XenbusState state;
    char *err = NULL, *msg = NULL;
    char *be_path, *be_state;
    char* nodename = opaque ? opaque : "device/pci/0";
    char path[strlen(nodename) + 9];
    char fe_state[strlen(nodename) + 7];
    xenbus_event_queue events = NULL;

    snprintf(path, sizeof(path), "%s/backend", nodename);
    snprintf(fe_state, sizeof(fe_state), "%s/state", nodename);

    while (1) {
        printk("pcifront_watches: waiting for backend path to appear %s\n", path);
        xenbus_watch_path_token(XBT_NIL, path, path, &events);
        while ((err = xenbus_read(XBT_NIL, path, &be_path)) != NULL) {
            free(err);
            xenbus_wait_for_watch(&events);
        }
        xenbus_unwatch_path_token(XBT_NIL, path, path);
        printk("pcifront_watches: waiting for backend to get into the right state %s\n", be_path);
        be_state = (char *) malloc(strlen(be_path) +  7);
        snprintf(be_state, strlen(be_path) +  7, "%s/state", be_path);
        xenbus_watch_path_token(XBT_NIL, be_state, be_state, &events);
        while ((err = xenbus_read(XBT_NIL, be_state, &msg)) != NULL || msg[0] > '4') {
            free(msg);
            free(err);
            xenbus_wait_for_watch(&events);
        }
        xenbus_unwatch_path_token(XBT_NIL, be_state, be_state);
        if (init_pcifront(NULL) == NULL) {
            free(be_state);
            free(be_path);
            continue;
        }
        xenbus_watch_path_token(XBT_NIL, be_state, be_state, &events);
        state = XenbusStateConnected;
        printk("pcifront_watches: waiting for backend events %s\n", be_state);
        while ((err = xenbus_wait_for_state_change(be_state, &state, &events)) == NULL &&
               (err = xenbus_read(XBT_NIL, pcidev->backend, &msg)) == NULL) {
            free(msg);
            printk("pcifront_watches: backend state changed: %s %d\n", be_state, state);
            if (state == XenbusStateReconfiguring) {
                printk("pcifront_watches: writing %s %d\n", fe_state, XenbusStateReconfiguring);
                if ((err = xenbus_switch_state(XBT_NIL, fe_state, XenbusStateReconfiguring)) != NULL) {
                    printk("pcifront_watches: error changing state to %d: %s\n",
                            XenbusStateReconfiguring, err);
                    if (!strcmp(err, "ENOENT")) {
                        xenbus_write(XBT_NIL, fe_state, "7");
                        free(err);
                    }
                }
            } else if (state == XenbusStateReconfigured) {
                printk("pcifront_watches: writing %s %d\n", fe_state, XenbusStateConnected);
                printk("pcifront_watches: changing state to %d\n", XenbusStateConnected);
                if ((err = xenbus_switch_state(XBT_NIL, fe_state, XenbusStateConnected)) != NULL) {
                    printk("pcifront_watches: error changing state to %d: %s\n",
                            XenbusStateConnected, err);
                    if (!strcmp(err, "ENOENT")) {
                        xenbus_write(XBT_NIL, fe_state, "4");
                        free(err);
                    }
                }
            } else if (state == XenbusStateClosing)
                break;
        }
        if (err) {
            printk("pcifront_watches: done waiting err=%s\n", err);
            free(err);
        } else
            printk("pcifront_watches: done waiting\n");
        err = xenbus_unwatch_path_token(XBT_NIL, be_state, be_state);
        shutdown_pcifront(pcidev);
        free(be_state);
        free(be_path);
        free(err);
        pcidev = NULL;
    }

    xenbus_unwatch_path_token(XBT_NIL, path, path);
}
Пример #17
0
struct tpmfront_dev* init_tpmfront(const char* _nodename)
{
   struct tpmfront_dev* dev;
   const char* nodename;
   char path[512];
   char* value, *err;
   unsigned long long ival;

   printk("============= Init TPM Front ================\n");

   dev = malloc(sizeof(struct tpmfront_dev));
   memset(dev, 0, sizeof(struct tpmfront_dev));

#ifdef HAVE_LIBC
   dev->fd = -1;
#endif

   nodename = _nodename ? _nodename : "device/vtpm/0";
   dev->nodename = strdup(nodename);

   init_waitqueue_head(&dev->waitq);

   /* Get backend domid */
   snprintf(path, 512, "%s/backend-id", dev->nodename);
   if((err = xenbus_read(XBT_NIL, path, &value))) {
      TPMFRONT_ERR("Unable to read %s during tpmfront initialization! error = %s\n", path, err);
      free(err);
      goto error;
   }
   if(sscanf(value, "%llu", &ival) != 1) {
      TPMFRONT_ERR("%s has non-integer value (%s)\n", path, value);
      free(value);
      goto error;
   }
   free(value);
   dev->bedomid = ival;

   /* Get backend xenstore path */
   snprintf(path, 512, "%s/backend", dev->nodename);
   if((err = xenbus_read(XBT_NIL, path, &dev->bepath))) {
      TPMFRONT_ERR("Unable to read %s during tpmfront initialization! error = %s\n", path, err);
      free(err);
      goto error;
   }

   /* Publish protocol v2 feature */
   snprintf(path, 512, "%s/feature-protocol-v2", dev->nodename);
   if ((err = xenbus_write(XBT_NIL, path, "1")))
   {
      TPMFRONT_ERR("Unable to write feature-protocol-v2 node: %s\n", err);
      free(err);
      goto error;
   }

   /* Create and publish grant reference and event channel */
   if (tpmfront_connect(dev)) {
      goto error;
   }

   /* Wait for backend to connect */
   if( wait_for_backend_state_changed(dev, XenbusStateConnected)) {
      goto error;
   }

   /* Ensure backend is also using protocol v2 */
   snprintf(path, 512, "%s/feature-protocol-v2", dev->bepath);
   if((err = xenbus_read(XBT_NIL, path, &value))) {
      TPMFRONT_ERR("Unable to read %s during tpmfront initialization! error = %s\n", path, err);
      free(err);
      goto error;
   }
   if(strcmp(value, "1")) {
      TPMFRONT_ERR("%s has an invalid value (%s)\n", path, value);
      free(value);
      goto error;
   }
   free(value);

   TPMFRONT_LOG("Initialization Completed successfully\n");

   return dev;

error:
   shutdown_tpmfront(dev);
   return NULL;
}
Пример #18
0
char *xenbus_mkdir(xenbus_transaction_t xbt, const char *path)
{
     return xenbus_write(xbt, path, "");
}
Пример #19
0
static int increase_reservation(unsigned long nr_pages)
{
	unsigned long  pfn, i, flags;
	struct page   *page;
	long           rc;
	struct xen_memory_reservation reservation = {
		.address_bits = 0,
		.extent_order = 0,
		.domid        = DOMID_SELF
	};

	if (nr_pages > ARRAY_SIZE(frame_list))
		nr_pages = ARRAY_SIZE(frame_list);

	spin_lock_irqsave(&balloon_lock, flags);

	page = balloon_first_page();
	for (i = 0; i < nr_pages; i++) {
		BUG_ON(page == NULL);
		frame_list[i] = page_to_pfn(page);
		page = balloon_next_page(page);
	}

	set_xen_guest_handle(reservation.extent_start, frame_list);
	reservation.nr_extents = nr_pages;
	rc = HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation);
	if (rc < 0)
		goto out;

	for (i = 0; i < rc; i++) {
		page = balloon_retrieve();
		BUG_ON(page == NULL);

		pfn = page_to_pfn(page);
		BUG_ON(!xen_feature(XENFEAT_auto_translated_physmap) &&
		       phys_to_machine_mapping_valid(pfn));

		set_phys_to_machine(pfn, frame_list[i]);

		/* Link back into the page tables if not highmem. */
#ifdef CONFIG_PVM
		if (!xen_hvm_domain() && pfn < max_low_pfn) {
			int ret;
			ret = HYPERVISOR_update_va_mapping(
				(unsigned long)__va(pfn << PAGE_SHIFT),
				mfn_pte(frame_list[i], PAGE_KERNEL),
				0);
			BUG_ON(ret);
		}
#endif
		/* Relinquish the page back to the allocator. */
		ClearPageReserved(page);
		init_page_count(page);
		__free_page(page);
	}

	balloon_stats.current_pages += rc;
   	if (old_totalram_pages + rc < totalram_pages)
   	{
        printk(KERN_INFO "old_totalram=%luKB, totalram_pages=%luKB\n", old_totalram_pages*4, totalram_pages*4);
       	balloon_stats.current_pages = totalram_pages + totalram_bias;
        printk(KERN_INFO "when ballooning, the mem online! totalram=%luKB, current=%luKB\n", totalram_pages*4, balloon_stats.current_pages*4);
   	}
   	old_totalram_pages = totalram_pages;
	

 out:
	spin_unlock_irqrestore(&balloon_lock, flags);

	return rc < 0 ? rc : rc != nr_pages;
}

static int decrease_reservation(unsigned long nr_pages)
{
	unsigned long  pfn, i, flags;
	struct page   *page;
	int            need_sleep = 0;
	int ret;
	struct xen_memory_reservation reservation = {
		.address_bits = 0,
		.extent_order = 0,
		.domid        = DOMID_SELF
	};

	if (nr_pages > ARRAY_SIZE(frame_list))
		nr_pages = ARRAY_SIZE(frame_list);

	for (i = 0; i < nr_pages; i++) {
		if ((page = alloc_page(GFP_BALLOON)) == NULL) {
			nr_pages = i;
			need_sleep = 1;
			break;
		}

		pfn = page_to_pfn(page);
		frame_list[i] = pfn_to_mfn(pfn);

		scrub_page(page);

		if (!xen_hvm_domain() && !PageHighMem(page)) {
			ret = HYPERVISOR_update_va_mapping(
				(unsigned long)__va(pfn << PAGE_SHIFT),
				__pte_ma(0), 0);
			BUG_ON(ret);
                }

	}

	/* Ensure that ballooned highmem pages don't have kmaps. */
#ifdef CONFIG_PVM
	kmap_flush_unused();
	flush_tlb_all();
#endif
	spin_lock_irqsave(&balloon_lock, flags);

	/* No more mappings: invalidate P2M and add to balloon. */
	for (i = 0; i < nr_pages; i++) {
		pfn = mfn_to_pfn(frame_list[i]);
		set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
		balloon_append(pfn_to_page(pfn));
	}

	set_xen_guest_handle(reservation.extent_start, frame_list);
	reservation.nr_extents   = nr_pages;
	ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
	BUG_ON(ret != nr_pages);

	balloon_stats.current_pages -= nr_pages;
   	if(old_totalram_pages < totalram_pages + nr_pages)
   	{
        printk(KERN_INFO "old_totalram=%luKB, totalram_pages=%luKB\n", old_totalram_pages*4, totalram_pages*4);
       	balloon_stats.current_pages = totalram_pages + totalram_bias;
        printk(KERN_INFO "when ballooning, the mem online! totalram=%luKB, current=%luKB\n", totalram_pages*4, balloon_stats.current_pages*4);
   	}
   	old_totalram_pages = totalram_pages;
	
	spin_unlock_irqrestore(&balloon_lock, flags);

	return need_sleep;
}

/*
 * We avoid multiple worker processes conflicting via the balloon mutex.
 * We may of course race updates of the target counts (which are protected
 * by the balloon lock), or with changes to the Xen hard limit, but we will
 * recover from these in time.
 */
static void balloon_process(struct work_struct *work)
{
	int need_sleep = 0;
	long credit;
    long total_increase = 0;
	char buffer[16];

	mutex_lock(&balloon_mutex);
    printk(KERN_INFO "totalram_pages=%luKB, current_pages=%luKB,totalram_bias=%luKB\n", totalram_pages*4, balloon_stats.current_pages*4, totalram_bias*4);

    if (totalram_pages > old_totalram_pages)
    {
        //TODO:Just know that totalram_pages will increase.
        total_increase = (totalram_pages - old_totalram_pages) % GB2PAGE;
        if (totalram_bias > total_increase )
        {
            totalram_bias = totalram_bias - total_increase;
        }
        balloon_stats.current_pages = totalram_pages + totalram_bias;
        old_totalram_pages = totalram_pages;
    }
    printk(KERN_INFO "totalram_pages=%luKB, current_pages=%luKB, totalram_bias=%luKB,total_increase=%ld\n", totalram_pages*4, balloon_stats.current_pages*4, totalram_bias*4, total_increase*4);
	xenbus_write(XBT_NIL, "control/uvp", "Balloon_flag", "1");
	do {
		credit = current_target() - balloon_stats.current_pages;
		if (credit > 0)
			need_sleep = (increase_reservation(credit) != 0);
		if (credit < 0)
			need_sleep = (decrease_reservation(-credit) != 0);

#ifndef CONFIG_PREEMPT
		if (need_resched())
			schedule();
#endif
	} while ((credit != 0) && !need_sleep);

	/* Schedule more work if there is some still to be done. */
	if (current_target() != balloon_stats.current_pages)
	{
		mod_timer(&balloon_timer, jiffies + HZ);
		sprintf(buffer,"%lu",balloon_stats.current_pages<<(PAGE_SHIFT-10));
		xenbus_write(XBT_NIL, "memory", "target", buffer);
	}
	xenbus_write(XBT_NIL, "control/uvp", "Balloon_flag", "0");
	mutex_unlock(&balloon_mutex);
}
Пример #20
0
static int xenkbd_probe(struct xenbus_device *dev,
				  const struct xenbus_device_id *id)
{
	int ret, i;
	unsigned int abs;
	struct xenkbd_info *info;
	struct input_dev *kbd, *ptr;

	info = kzalloc(sizeof(*info), GFP_KERNEL);
	if (!info) {
		xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure");
		return -ENOMEM;
	}
	dev_set_drvdata(&dev->dev, info);
	info->xbdev = dev;
	info->irq = -1;
	info->gref = -1;
	snprintf(info->phys, sizeof(info->phys), "xenbus/%s", dev->nodename);

	info->page = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
	if (!info->page)
		goto error_nomem;

	abs = xenbus_read_unsigned(dev->otherend, "feature-abs-pointer", 0);
	if (abs) {
		ret = xenbus_write(XBT_NIL, dev->nodename,
				   "request-abs-pointer", "1");
		if (ret) {
			pr_warning("xenkbd: can't request abs-pointer");
			abs = 0;
		}
	}

	/* keyboard */
	kbd = input_allocate_device();
	if (!kbd)
		goto error_nomem;
	kbd->name = "Xen Virtual Keyboard";
	kbd->phys = info->phys;
	kbd->id.bustype = BUS_PCI;
	kbd->id.vendor = 0x5853;
	kbd->id.product = 0xffff;

	__set_bit(EV_KEY, kbd->evbit);
	for (i = KEY_ESC; i < KEY_UNKNOWN; i++)
		__set_bit(i, kbd->keybit);
	for (i = KEY_OK; i < KEY_MAX; i++)
		__set_bit(i, kbd->keybit);

	ret = input_register_device(kbd);
	if (ret) {
		input_free_device(kbd);
		xenbus_dev_fatal(dev, ret, "input_register_device(kbd)");
		goto error;
	}
	info->kbd = kbd;

	/* pointing device */
	ptr = input_allocate_device();
	if (!ptr)
		goto error_nomem;
	ptr->name = "Xen Virtual Pointer";
	ptr->phys = info->phys;
	ptr->id.bustype = BUS_PCI;
	ptr->id.vendor = 0x5853;
	ptr->id.product = 0xfffe;

	if (abs) {
		__set_bit(EV_ABS, ptr->evbit);
		input_set_abs_params(ptr, ABS_X, 0, XENFB_WIDTH, 0, 0);
		input_set_abs_params(ptr, ABS_Y, 0, XENFB_HEIGHT, 0, 0);
	} else {
		input_set_capability(ptr, EV_REL, REL_X);
		input_set_capability(ptr, EV_REL, REL_Y);
	}
	input_set_capability(ptr, EV_REL, REL_WHEEL);

	__set_bit(EV_KEY, ptr->evbit);
	for (i = BTN_LEFT; i <= BTN_TASK; i++)
		__set_bit(i, ptr->keybit);

	ret = input_register_device(ptr);
	if (ret) {
		input_free_device(ptr);
		xenbus_dev_fatal(dev, ret, "input_register_device(ptr)");
		goto error;
	}
	info->ptr = ptr;

	ret = xenkbd_connect_backend(dev, info);
	if (ret < 0)
		goto error;

	return 0;

 error_nomem:
	ret = -ENOMEM;
	xenbus_dev_fatal(dev, ret, "allocating device memory");
 error:
	xenkbd_remove(dev);
	return ret;
}
Пример #21
0
NDIS_STATUS 
MiniportInitialize (
    IN  NDIS_HANDLE                        MiniportAdapterHandle,
    IN  NDIS_HANDLE                        MiniportDriverContext,
    IN  PNDIS_MINIPORT_INIT_PARAMETERS     MiniportInitParameters
    )
{
    PADAPTER adapter = NULL;
    NDIS_STATUS ndisStatus;
    PCHAR path;
    PDEVICE_OBJECT pdo;
    PCHAR xenbusPath = NULL;
    int i;

    UNREFERENCED_PARAMETER(MiniportDriverContext);
    UNREFERENCED_PARAMETER(MiniportInitParameters);

    TraceVerbose(("====> '%s'.\n", __FUNCTION__));

    //
    // Wait for xenbus to come up.  SMP guests sometimes try and
    // initialise xennet and xenvbd in parallel when they come back
    // from hibernation, and that causes problems.
    //

    if (!xenbus_await_initialisation()) {
        ndisStatus = NDIS_STATUS_DEVICE_FAILED;
        goto exit;
    }

    //
    // 8021P support is disabled by default.
    // It can be turned on by specifying the appropriate PV boot option.
    //

    if (XenPVFeatureEnabled(DEBUG_NIC_8021_P)) {
        XennetMacOptions |= NDIS_MAC_OPTION_8021P_PRIORITY;
    }

    xenbus_write(XBT_NIL, "drivers/xenwnet", XENNET_VERSION);
    NdisMGetDeviceProperty(MiniportAdapterHandle,
                           &pdo,
                           NULL,
                           NULL,
                           NULL,
                           NULL);

    xenbusPath = xenbus_find_frontend(pdo);
    if (!xenbusPath) {
        ndisStatus = NDIS_STATUS_ADAPTER_NOT_FOUND;
        goto exit;
    }

    TraceNotice(("Found '%s' frontend.\n", xenbusPath));
    adapter = XmAllocateZeroedMemory(sizeof(ADAPTER));
    if (adapter == NULL) {
        ndisStatus = NDIS_STATUS_RESOURCES;
        goto exit;
    }

    path = xenbusPath;
    xenbusPath = NULL;

    i = 0;
    do {
        ndisStatus = AdapterInitialize(adapter, MiniportAdapterHandle, path);
        if (ndisStatus != NDIS_STATUS_SUCCESS) {
            TraceWarning (("Waiting for backend...\n"));
            NdisMSleep (1000000);   // 1 sec
        }
    } while ((ndisStatus != NDIS_STATUS_SUCCESS) && (++i < 30));
    if (ndisStatus != NDIS_STATUS_SUCCESS) {
        goto exit;
    }

exit:
    if (ndisStatus != NDIS_STATUS_SUCCESS) {
        if (adapter) {
			XmFreeMemory(adapter->BackendPath);
			adapter->BackendPath = NULL;
            AdapterDelete(&adapter);
        }

        if (xenbusPath) {
            XmFreeMemory(xenbusPath);
        }
    }

    TraceVerbose(("<==== '%s'.\n", __FUNCTION__));
    return ndisStatus;
}