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; }
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); }
/* 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); } /* ... */ }
/*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); } }
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); }
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; } }
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"); } }
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); }
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); }
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); }
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); }
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, ¤t_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; }
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; }
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); }
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); }
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); }
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; }
char *xenbus_mkdir(xenbus_transaction_t xbt, const char *path) { return xenbus_write(xbt, path, ""); }
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); }
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; }
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; }