int xb_read(void *data, unsigned len) { struct xenstore_domain_interface *intf = xenstore_domain_interface(); XENSTORE_RING_IDX cons, prod; int s = spltty(); while (len != 0) { unsigned int avail; const char *src; while (intf->rsp_cons == intf->rsp_prod) tsleep(&xenstore_interface, PRIBIO, "rdst", 0); /* Read indexes, then verify. */ cons = intf->rsp_cons; prod = intf->rsp_prod; xen_rmb(); if (!check_indexes(cons, prod)) { XENPRINTF(("xb_read EIO\n")); splx(s); return EIO; } src = get_input_chunk(cons, prod, intf->rsp, &avail); if (avail == 0) continue; if (avail > len) avail = len; /* We must read header before we read data. */ xen_rmb(); memcpy(data, src, avail); data = (char *)data + avail; len -= avail; /* Other side must not see free space until we've copied out */ xen_rmb(); intf->rsp_cons += avail; xen_rmb(); XENPRINTF(("Finished read of %i bytes (%i to go)\n", avail, len)); hypervisor_notify_via_evtchn(xen_start_info.store_evtchn); } splx(s); return 0; }
int xb_write(const void *data, unsigned len) { struct xenstore_domain_interface *intf = xenstore_domain_interface(); XENSTORE_RING_IDX cons, prod; int s = spltty(); while (len != 0) { void *dst; unsigned int avail; while ((intf->req_prod - intf->req_cons) == XENSTORE_RING_SIZE) { XENPRINTF(("xb_write tsleep\n")); tsleep(&xenstore_interface, PRIBIO, "wrst", 0); XENPRINTF(("xb_write tsleep done\n")); } /* Read indexes, then verify. */ cons = intf->req_cons; prod = intf->req_prod; xen_rmb(); if (!check_indexes(cons, prod)) { splx(s); return EIO; } dst = get_output_chunk(cons, prod, intf->req, &avail); if (avail == 0) continue; if (avail > len) avail = len; memcpy(dst, data, avail); data = (const char *)data + avail; len -= avail; /* Other side must not see new header until data is there. */ xen_rmb(); intf->req_prod += avail; xen_rmb(); hypervisor_notify_via_evtchn(xen_start_info.store_evtchn); } splx(s); return 0; }
void xen_set_ldt(vaddr_t base, uint32_t entries) { vaddr_t va; vaddr_t end; pt_entry_t *ptp; int s; #ifdef __x86_64__ end = base + (entries << 3); #else end = base + entries * sizeof(union descriptor); #endif for (va = base; va < end; va += PAGE_SIZE) { KASSERT(va >= VM_MIN_KERNEL_ADDRESS); ptp = kvtopte(va); XENPRINTF(("xen_set_ldt %#" PRIxVADDR " %d %p\n", base, entries, ptp)); pmap_pte_clearbits(ptp, PG_RW); } s = splvm(); xpq_queue_set_ldt(base, entries); splx(s); }