static int cd(int argc, char *argv[]) { errval_t err; if (argc != 2) { printf("Usage: %s DIR\n", argv[0]); return 1; } char *newcwd = vfs_path_mkabsolute(cwd, argv[1]); // ensure directory exists, by attempting to open it vfs_handle_t dh; err = vfs_opendir(newcwd, &dh); if (err_is_fail(err)) { printf("cd to %s (-> %s) failed: %s\n", argv[1], newcwd, err_getstring(err)); free(newcwd); return 1; } vfs_closedir(dh); // ok! free(cwd); cwd = newcwd; return 0; }
static void memcpy_req_cb(errval_t err, dma_req_id_t id, void *st) { XDMA_DEBUG("memcpy_req_cb %lx, %s\n", id, err_getstring(err)); dma_service_send_done(st, err, id); }
static void cap_send_request_tx_cont(errval_t err, struct captx_prepare_state *captx_st, intermon_captx_t *captx, void *st_) { DEBUG_CAPOPS("%s: %s [%p]\n", __FUNCTION__, err_getstring(err), __builtin_return_address(0)); errval_t queue_err; struct send_cap_st *send_st = (struct send_cap_st*)st_; if (err_is_fail(err)) { // XXX: should forward error here DEBUG_ERR(err, "preparing cap tx failed"); free(send_st); return; } send_st->captx = *captx; DEBUG_CAPOPS("%s: enqueueing send\n", __FUNCTION__); send_st->qe.cont = cap_send_tx_cont; struct remote_conn_state *conn = remote_conn_lookup(send_st->my_mon_id); struct intermon_binding *binding = conn->mon_binding; struct intermon_state *inter_st = (struct intermon_state*)binding->st; queue_err = intermon_enqueue_send(binding, &inter_st->queue, binding->waitset, (struct msg_queue_elem*)send_st); if (err_is_fail(queue_err)) { DEBUG_ERR(queue_err, "enqueuing cap_send_request failed"); free(send_st); } }
static int touch(int argc, char *argv[]) { if(argc < 2) { printf("Usage: %s [file...]\n", argv[0]); return 1; } vfs_handle_t vh; errval_t err; int ret = 0; for (int i = 1; i < argc; i++) { char *path = vfs_path_mkabsolute(cwd, argv[i]); err = vfs_create(path, &vh); free(path); if (err_is_fail(err)) { printf("%s: %s\n", argv[i], err_getstring(err)); DEBUG_ERR(err, "vfs_create failed"); ret = 1; continue; } err = vfs_close(vh); if (err_is_fail(err)) { DEBUG_ERR(err, "in vfs_close"); } } return ret; }
errval_t blockdevfs_ata_flush(void *handle) { struct ata_handle *h = handle; errval_t err, status; err = h->ata_rw28_rpc.vtbl.flush_cache(&h->ata_rw28_rpc, &status); if (err_is_fail(err)) { printf("failed calling flush_cache\n"); return err; } VFS_BLK_DEBUG("status: %s\n", err_getstring(status)); return err; }
static int execute_program(coreid_t coreid, int argc, char *argv[], domainid_t *retdomainid) { vfs_handle_t vh; errval_t err; // if the name contains a directory separator, assume it is relative to PWD char *prog = argv[0]; if (strchr(argv[0], VFS_PATH_SEP) != NULL) { prog = vfs_path_mkabsolute(cwd, argv[0]); // check it exists err = vfs_open(prog, &vh); if (err_is_fail(err)) { printf("%s: file not found: %s\n", prog, err_getstring(err)); free(prog); return -1; } vfs_close(vh); } assert(retdomainid != NULL); argv[argc] = NULL; err = spawn_program(coreid, prog, argv, NULL, SPAWN_NEW_DOMAIN, retdomainid); if (prog != argv[0]) { free(prog); } if (err_is_fail(err)) { printf("%s: error spawning: %s\n", argv[0], err_getstring(err)); DEBUG_ERR(err, "Spawning Error\n"); return -1; } return 0; }
/** * \brief XOMP channel connect callback called by the Flounder backend * * \param st Supplied worker state * \param err outcome of the connect attempt * \param xb XOMP Flounder binding */ static void master_bind_cb(void *st, errval_t err, struct xomp_binding *xb) { XWI_DEBUG("bound to master: %s\n", err_getstring(err)); txq_init(&txq, xb, xb->waitset, (txq_register_fn_t) xb->register_send, sizeof(struct xomp_msg_st)); xb->rx_vtbl = rx_vtbl; xbinding = xb; is_bound = 0x1; }
static void ahci_init_cb(void *st, errval_t err, struct ahci_binding *binding) { struct ahci_handle *h = st; if (err_is_fail(err)) { printf("ahci_init_cb returned '%s'\n", err_getstring(err)); h->wait_status = err; h->waiting = false; return; } h->binding = binding; binding->st = h; h->waiting = false; }
errval_t blockdevfs_ahci_close(void *handle) { struct ahci_handle *h = handle; h->waiting = true; errval_t err = ahci_close(h->binding, MKCLOSURE(ahci_close_cb, h)); if (err_is_fail(err)) { printf("ahci_init failed: '%s'\n", err_getstring(err)); h->waiting = false; return err; } while (h->waiting) { messages_wait_and_handle_next(); } return SYS_ERR_OK; }
static int rmdir(int argc, char *argv[]) { if(argc != 2) { printf("Usage: %s dir\n", argv[0]); return 1; } char *path = vfs_path_mkabsolute(cwd, argv[1]); errval_t err = vfs_rmdir(path); free(path); if (err_is_fail(err)) { printf("%s\n", err_getstring(err)); return 1; } else { return 0; } }
static void pci_dev_init_manager(struct device_mem *bar_info, int nr_mapped_bars) { errval_t err; DEV_DEBUG("Initialize device @ [%016lx] with %u bars\n", bar_info->paddr, nr_mapped_bars); if (nr_mapped_bars != 1) { DEV_ERR("number of mapped bars is wrong. Skipping initialization\n"); return; } err = ioat_mgr_svc_add_device(bar_info->frame_cap); if (err_is_fail(err)) { DEV_ERR("Device coult not be added to the manager: %s\n", err_getstring(err)); } }
static int rm(int argc, char *argv[]) { if(argc < 2) { printf("Usage: %s file...\n", argv[0]); return 1; } int ret = 0; for (int i = 1; i < argc; i++) { char *path = vfs_path_mkabsolute(cwd, argv[i]); errval_t err = vfs_remove(path); free(path); if (err_is_fail(err)) { printf("%s: %s\n", argv[i], err_getstring(err)); ret = 1; } } return ret; }
static void pci_dev_init_service(struct device_mem *bar_info, int nr_mapped_bars) { errval_t err; DEV_DEBUG("Initialize device @ [%016lx] with %u bars\n", bar_info->paddr, nr_mapped_bars); if (nr_mapped_bars != 1) { DEV_ERR("number of mapped bars is wrong. Skipping initialization\n"); return; } /* initialize the device */ err = ioat_dma_device_init(*bar_info->frame_cap, &devices[device_count]); if (err_is_fail(err)) { DEV_ERR("Could not initialize the device: %s\n", err_getstring(err)); return; } device_count++; }
errval_t blockdevfs_ata_open(void *handle) { VFS_BLK_DEBUG("blockdevfs_ata_open: entering\n"); errval_t err; struct ata_handle *h = handle; h->wait_status = SYS_ERR_OK; h->waiting = true; err = ahci_init(h->port_num, ahci_init_cb, h, get_default_waitset()); if (err_is_fail(err)) { printf("ahci_init failed: '%s'\n", err_getstring(err)); h->waiting = false; return err; } // XXX: block for command completion (broken API!) while (h->waiting) { err = event_dispatch(get_default_waitset()); if (err_is_fail(err)) { USER_PANIC_ERR(err, "error in event_dispatch for blockdevfs_ata_open"); } } struct ahci_ata_rw28_binding *ahci_ata_rw28_binding; ahci_ata_rw28_binding = calloc(1, sizeof(struct ahci_ata_rw28_binding)); ahci_ata_rw28_init(ahci_ata_rw28_binding, get_default_waitset(), h->ahci_binding); h->ata_rw28_binding = (struct ata_rw28_binding*)ahci_ata_rw28_binding; err = ata_rw28_rpc_client_init(&h->ata_rw28_rpc, h->ata_rw28_binding); if (err_is_fail(err)) { // TODO: bindings leak VFS_BLK_DEBUG("blockdevfs_ata_open: failed to init ata_rw28 rpc client\n"); return err; } VFS_BLK_DEBUG("blockdevfs_ata_open: exiting\n"); return h->wait_status; }
errval_t blockdevfs_ahci_open(void *handle) { VFS_BLK_DEBUG("blockdevfs_ahci_open: entering\n"); errval_t err; struct ahci_handle *h = handle; h->wait_status = SYS_ERR_OK; h->waiting = true; err = ahci_init(h->port_num, ahci_init_cb, h, get_default_waitset()); if (err_is_fail(err)) { printf("ahci_init failed: '%s'\n", err_getstring(err)); h->waiting = false; return err; } // XXX: block for command completion (broken API!) while (h->waiting) { messages_wait_and_handle_next(); } VFS_BLK_DEBUG("blockdevfs_ahci_open: exiting\n"); return h->wait_status; }
static int rand_bench_time(char *target, uint8_t *buffer, size_t filesize, size_t blocksize, size_t count, size_t randval, struct bench_res *result) { size_t randbit; size_t rsize = 0; size_t wsize = 0; int ret = 0; #define RAND_NEXT do {\ randbit = ((randval >> 0) ^ (randval >> 3)) & 1;\ randval = (randval >> 1) | (randbit << (sizeof(size_t) * CHAR_BIT - 1));\ } while (0) #define RAND_BLOCK ((randval % (filesize / blocksize)) * blocksize) if (filesize % blocksize != 0) { printf("Please spcifiy the filesize as a multiple of blocksize\n"); return 0; } errval_t err; vfs_handle_t f = NULL; char *path = vfs_path_mkabsolute(cwd, target); err = vfs_open(path, &f); if (err_is_fail(err)) { printf("%s: %s\n", path, err_getstring(err)); return 1; } #if defined(__x86_64__) || defined(__i386__) uint64_t tscperms; err = sys_debug_get_tsc_per_ms(&tscperms); assert(err_is_ok(err)); //printf("ticks per millisec: %" PRIu64 "\n", tscperms); uint64_t start = rdtsc(); #endif size_t count2 = count; while (count2--) { RAND_NEXT; vfs_seek(f, VFS_SEEK_SET, RAND_BLOCK); err = vfs_read(f, buffer, blocksize, &rsize); if (err_is_fail(err)) { DEBUG_ERR(err, "error reading file"); ret = 1; goto out; } assert(rsize == blocksize); } #if defined(__x86_64__) || defined(__i386__) uint64_t stop = rdtsc(); uint64_t elapsed_msecs = ((stop - start) / tscperms); double elapsed_secs = (double)elapsed_msecs/1000.0; result->read = elapsed_secs; start = rdtsc(); #endif count2 = count; while(count2--) { RAND_NEXT; vfs_seek(f, VFS_SEEK_SET, RAND_BLOCK); err = vfs_write(f, buffer, blocksize, &wsize); if (err_is_fail(err) || wsize == 0) { DEBUG_ERR(err, "error writing file"); ret = 1; goto out; } assert(wsize == blocksize); vfs_flush(f); } #if defined(__x86_64__) || defined(__i386__) stop = rdtsc(); elapsed_msecs = ((stop - start) / tscperms); elapsed_secs = (double)elapsed_msecs/1000.0; result->write = elapsed_secs; #endif out: if (f != NULL) { err = vfs_close(f); if (err_is_fail(err)) { DEBUG_ERR(err, "in vfs_close"); } } return ret; }
static double dd_bench(char *source, char *target, size_t blocksize, size_t count) { vfs_handle_t source_vh = NULL; vfs_handle_t target_vh = NULL; size_t blocks_written = 0; size_t total_bytes_read = 0; size_t total_bytes_written = 0; errval_t err; double ret = 0; double kbps = 0.0; err = vfs_open(source, &source_vh); if (err_is_fail(err)) { printf("%s: %s (%ld)\n", source, err_getstring(err), err); return -1; } err = vfs_create(target, &target_vh); if (err_is_fail(err)) { // close source handle if (source_vh != NULL) vfs_close(source_vh); printf("%s: %s (%ld)\n", target, err_getstring(err), err); return -1; } uint8_t *buffer = malloc(blocksize); #if defined(__x86_64__) || defined(__i386__) uint64_t tscperms; err = sys_debug_get_tsc_per_ms(&tscperms); assert(err_is_ok(err)); uint64_t start = rdtsc(); #endif if (buffer == NULL) { ret = -2; printf("failed to allocate buffer of size %zd\n", blocksize); goto out; } size_t rsize, wsize; do { err = vfs_read(source_vh, buffer, blocksize, &rsize); if (err_is_fail(err)) { DEBUG_ERR(err, "error reading file"); ret = -1; goto out; } total_bytes_read += rsize; size_t wpos = 0; while (wpos < rsize) { if (wpos > 0) printf("was unable to write the whole chunk of size %zd. Now at pos: %zd of buffer\n", rsize, wpos); err = vfs_write(target_vh, &buffer[wpos], rsize - wpos, &wsize); if (err_is_fail(err) || wsize == 0) { DEBUG_ERR(err, "error writing file"); ret = -1; goto out; } wpos += wsize; total_bytes_written += wsize; } blocks_written++; } while (rsize > 0 && !(count > 0 && blocks_written >= count)); out: if (buffer != NULL) free(buffer); if (source_vh != NULL) { err = vfs_close(source_vh); if (err_is_fail(err)) { DEBUG_ERR(err, "in vfs_close"); } } if (target_vh != NULL) { err = vfs_close(target_vh); if (err_is_fail(err)) { DEBUG_ERR(err, "in vfs_close"); } } #if defined(__x86_64__) || defined(__i386__) uint64_t stop = rdtsc(); uint64_t elapsed_msecs = ((stop - start) / tscperms); double elapsed_secs = (double)elapsed_msecs/1000.0; kbps = ((double)total_bytes_written / 1024.0) / elapsed_secs; if (ret == 0) return kbps; else return ret; #else return ret; #endif }
static int shuffle_file(int argc, char *argv[]) { if (argc != 6) { printf("Usage: %s <file> <filesize> <blocksize> <count> <seed>\n", argv[0]); return 0; } size_t filesize = atoi(argv[2]); size_t blocksize = atoi(argv[3]); size_t count = atoi(argv[4]); size_t randval = atoi(argv[5]); size_t randbit; char * filename = argv[1]; size_t rsize = 0; size_t wsize = 0; int ret = 0; #define RAND_NEXT do {\ randbit = ((randval >> 0) ^ (randval >> 3)) & 1;\ randval = (randval >> 1) | (randbit << (sizeof(size_t) * CHAR_BIT - 1));\ } while (0) #define RAND_BLOCK ((randval % (filesize / blocksize)) * blocksize) if (filesize % blocksize != 0) { printf("Please spcifiy the filesize as a multiple of blocksize\n"); return 0; } uint8_t * buffer = malloc(blocksize); if (buffer == NULL) { printf("failed to allocate buffer of size %zd\n", blocksize); return 1; } errval_t err; vfs_handle_t f = NULL; char *path = vfs_path_mkabsolute(cwd, filename); err = vfs_open(path, &f); if (err_is_fail(err)) { printf("%s: %s\n", path, err_getstring(err)); return 1; } #if defined(__x86_64__) || defined(__i386__) uint64_t tscperms; err = sys_debug_get_tsc_per_ms(&tscperms); assert(err_is_ok(err)); //printf("ticks per millisec: %" PRIu64 "\n", tscperms); uint64_t start = rdtsc(); #endif size_t count2 = count; while (count2--) { RAND_NEXT; vfs_seek(f, VFS_SEEK_SET, RAND_BLOCK); err = vfs_read(f, buffer, blocksize, &rsize); if (err_is_fail(err)) { DEBUG_ERR(err, "error reading file"); ret = 1; goto out; } assert(rsize == blocksize); RAND_NEXT; vfs_seek(f, VFS_SEEK_SET, RAND_BLOCK); err = vfs_write(f, buffer, blocksize, &wsize); if (err_is_fail(err) || wsize == 0) { DEBUG_ERR(err, "error writing file"); ret = 1; goto out; } assert(wsize == blocksize); } #if defined(__x86_64__) || defined(__i386__) uint64_t stop = rdtsc(); uint64_t elapsed_msecs = ((stop - start) / tscperms); double elapsed_secs = (double)elapsed_msecs/1000.0; printf("start: %" PRIu64 " stop: %" PRIu64 "\n", start, stop); double kbps = ((double)(count * blocksize) / 1024.0) / elapsed_secs; printf("%zu bytes read. %zu bytes written. %f s, %f kB/s\n", count * blocksize, count * blocksize, elapsed_secs, kbps); #endif out: if (buffer != NULL) free(buffer); if (f != NULL) { err = vfs_close(f); if (err_is_fail(err)) { DEBUG_ERR(err, "in vfs_close"); } } return ret; }
static errval_t fill_bench(char *target, uint8_t *buffer, size_t blocksize, size_t count, struct bench_res *result) { vfs_handle_t target_vh = NULL; size_t blocks_written = 0; size_t blocks_read = 0; size_t total_bytes_read = 0; size_t total_bytes_written = 0; uint64_t start = 0, stop = 0; errval_t err; #if defined(__x86_64__) || defined(__i386__) uint64_t tscperms; err = sys_debug_get_tsc_per_ms(&tscperms); assert(err_is_ok(err)); #endif errval_t ret = 0; err = vfs_open(target, &target_vh); if (err_is_fail(err)) { printf("%s: %s (%ld)\n", target, err_getstring(err), err); return err; } #if defined(__x86_64__) || defined(__i386__) start = rdtsc(); #endif if (buffer == NULL) { ret = -2; printf("failed to allocate buffer of size %zd\n", blocksize); goto out; } size_t wsize; do { // initialize buffer for (size_t i = 0; i < blocksize; i += sizeof(size_t)) *((size_t *)(buffer + i)) = blocks_written; // write to file size_t wpos = 0; while (wpos < blocksize) { if (wpos > 0) printf("was unable to write the whole chunk of size %zd. Now at pos: %zd of buffer\n", blocksize, wpos); err = vfs_write(target_vh, &buffer[wpos], blocksize - wpos, &wsize); if (err_is_fail(err) || wsize == 0) { DEBUG_ERR(err, "error writing file"); ret = err; goto out; } wpos += wsize; total_bytes_written += wsize; } blocks_written++; } while (blocksize > 0 && !(count > 0 && blocks_written >= count)); err = vfs_close(target_vh); if (err_is_fail(err)) { DEBUG_ERR(err, "in vfs_close"); goto out; } #if defined(__x86_64__) || defined(__i386__) stop = rdtsc(); { uint64_t elapsed_msecs = ((stop - start) / tscperms); double elapsed_secs = (double)elapsed_msecs/1000.0; result->write = ((double)total_bytes_written / 1024.0) / elapsed_secs; printf("%lf\n", result->write); } #endif err = vfs_open(target, &target_vh); if (err_is_fail(err)) { printf("%s: %s (%ld)\n", target, err_getstring(err), err); goto out; } err = vfs_seek(target_vh, VFS_SEEK_SET, 0); if (err_is_fail(err)) { DEBUG_ERR(err, "seeking failed"); ret = err; goto out; } #if defined(__x86_64__) || defined(__i386__) start = rdtsc(); #endif size_t rsize; do { // read size_t rpos = 0; while (rpos < blocksize) { if (rpos > 0) printf("was unable to read whole chunk of size %zd. Now at pos: %zd of buffer\n", blocksize, rpos); err = vfs_read(target_vh, &buffer[rpos], blocksize - rpos, &rsize); if (err_is_fail(err) || wsize == 0) { DEBUG_ERR(err, "error reading file"); ret = err; goto out; } rpos += rsize; total_bytes_read += rsize; } // verify data for (size_t i = 0; i < blocksize; i += sizeof(size_t)) { if (*((size_t *)(buffer + i)) != blocks_read) { printf("Verification failed! Block %zd, value %zd\n", blocks_read, *((size_t *)(buffer + i)) ); ret = err; goto out; } } blocks_read++; } while (blocksize > 0 && !(count > 0 && blocks_read >= count)); out: if (target_vh != NULL) { err = vfs_close(target_vh); if (err_is_fail(err)) { DEBUG_ERR(err, "in vfs_close"); ret = err; } } #if defined(__x86_64__) || defined(__i386__) stop = rdtsc(); { uint64_t elapsed_msecs = ((stop - start) / tscperms); double elapsed_secs = (double)elapsed_msecs/1000.0; result->read = ((double)total_bytes_read / 1024.0) / elapsed_secs; printf("%lf\n", result->read); } #endif return ret; }
void remove_empty_vnodes(struct pmap_x86 *pmap, struct vnode *root, uint32_t entry, size_t len) { errval_t err; uint32_t end_entry = entry + len; for (struct vnode *n = root->u.vnode.children; n; n = n->next) { if (n->entry >= entry && n->entry < end_entry) { // sanity check and skip leaf entries if (!n->is_vnode) { continue; } // here we know that all vnodes we're interested in are // page tables assert(n->is_vnode); if (n->u.vnode.children) { remove_empty_vnodes(pmap, n, 0, PTABLE_SIZE); } // unmap err = vnode_unmap(root->u.vnode.cap, n->mapping); if (err_is_fail(err)) { debug_printf("remove_empty_vnodes: vnode_unmap: %s\n", err_getstring(err)); } // delete mapping cap first: underlying cap needs to exist for // this to work properly! err = cap_delete(n->mapping); if (err_is_fail(err)) { debug_printf("remove_empty_vnodes: cap_delete (mapping): %s\n", err_getstring(err)); } err = pmap->p.slot_alloc->free(pmap->p.slot_alloc, n->mapping); if (err_is_fail(err)) { debug_printf("remove_empty_vnodes: slot_free (mapping): %s\n", err_getstring(err)); } // delete capability err = cap_delete(n->u.vnode.cap); if (err_is_fail(err)) { debug_printf("remove_empty_vnodes: cap_delete (vnode): %s\n", err_getstring(err)); } if (!capcmp(n->u.vnode.cap, n->u.vnode.invokable)) { // invokable is always allocated in our cspace err = cap_destroy(n->u.vnode.invokable); if (err_is_fail(err)) { debug_printf("remove_empty_vnodes: cap_delete (vnode.invokable): %s\n", err_getstring(err)); } } err = pmap->p.slot_alloc->free(pmap->p.slot_alloc, n->u.vnode.cap); if (err_is_fail(err)) { debug_printf("remove_empty_vnodes: slot_free (vnode): %s\n", err_getstring(err)); } // remove vnode from list remove_vnode(root, n); slab_free(&pmap->slab, n); } } }
static int cp(int argc, char *argv[]) { if(argc != 3) { printf("Usage: %s src dest\n", argv[0]); return 1; } static uint8_t buf[32768]; size_t rsize, wsize; vfs_handle_t src = NULL, dst = NULL; errval_t err; int ret = 0; char *path = vfs_path_mkabsolute(cwd, argv[1]); err = vfs_open(path, &src); free(path); if (err_is_fail(err)) { printf("%s: %s\n", argv[1], err_getstring(err)); return 1; } path = vfs_path_mkabsolute(cwd, argv[2]); err = vfs_create(path, &dst); free(path); if (err_is_fail(err)) { printf("%s: %s\n", argv[2], err_getstring(err)); ret = 1; goto out; } err = vfs_truncate(dst, 0); if (err_is_fail(err)) { printf("truncate %s: %s\n", argv[2], err_getstring(err)); ret = 1; goto out; } do { err = vfs_read(src, buf, sizeof(buf), &rsize); if (err_is_fail(err)) { DEBUG_ERR(err, "error reading file"); ret = 1; goto out; } size_t wpos = 0; while (wpos < rsize) { err = vfs_write(dst, &buf[wpos], rsize - wpos, &wsize); if (err_is_fail(err) || wsize == 0) { DEBUG_ERR(err, "error writing file"); ret = 1; goto out; } wpos += wsize; } } while(rsize > 0); out: if (src != NULL) { err = vfs_close(src); if (err_is_fail(err)) { DEBUG_ERR(err, "in vfs_close"); } } if (dst != NULL) { err = vfs_close(dst); if (err_is_fail(err)) { DEBUG_ERR(err, "in vfs_close"); } } return ret; }
int main (int argc, char *argv[]) { errval_t err; char *cardName = NULL; const char *imagefile = IMAGEFILE; vfs_init(); err = timer_init(); if (err_is_fail(err)) { USER_PANIC_ERR(err, "error initialising timer client library\n"); } if (argc < 3) { printf("Usage: %s <Network card Name> <vfs mount URI> [disk image path]\n", argv[0]); printf("<Network card Name> value is ignored in this version\n"); return 1; } if(argc > 3) { imagefile = argv[3]; } cardName = argv[1]; printf("vmkitmon: start\n"); printf("Ignoring the cardname [%s], and using the default one from vfs_mount\n", cardName); vfs_mkdir(VFS_MOUNTPOINT); err = vfs_mount(VFS_MOUNTPOINT, argv[2]); if (err_is_fail(err)) { printf("vmkitmon: error mounting %s: %s\n", argv[2], err_getstring(err)); return 1; } /* Initialization */ err = realmode_init(); assert_err(err, "realmode_init"); // fetch all relevant multiboot data //load_multiboot_files(); // aquire the standard input #if 1 err = terminal_want_stdin(TERMINAL_SOURCE_SERIAL); assert_err(err, "terminal_want_stdin"); #endif // load files // FIXME: use a dynamic way to specify those arguments printf("Loading file [%s]\n", GRUB_IMG_PATH); vfs_load_file_to_memory(GRUB_IMG_PATH, &grub_image, &grub_image_size); printf("Loading file [%s]\n", imagefile); vfs_load_file_to_memory(imagefile, &hdd0_image, &hdd0_image_size); printf("Done with file loading\n"); /* Guest execution */ // perform some sanity checks if (grub_image == NULL) { printf("vmkitmon: no grub image available, abort\n"); return 1; } guest = guest_create (); assert(guest != NULL); err = guest_make_runnable(guest, true); assert_err(err, "guest_make_runnable"); printf("vmkitmon: end\n"); messages_handler_loop(); }
int invalid_mappings(void) { // outline: // get pml4, pdpt, pdir, ptable, and frame // check all combinations to make sure that restrictions are implemented // correctly in kernel space // VALID: // map pdpt in pml4 // map pdir in pdpt // map pt in pdir // map frame in {pt, pdir, pdpt} // INVALID: // all other combinations errval_t err; struct capref caps[7]; struct capref mapping; // allocate slot for mapping cap: can reuse` err = slot_alloc(&mapping); if (err_is_fail(err)) { debug_printf("slot_alloc: %s (%ld)\n", err_getstring(err), err); return 1; } // allocate caps for (int i = 0; i < 5; i++) { // get 4k block struct capref mem; err = ram_alloc(&mem, BASE_PAGE_BITS); if (err_is_fail(err)) { debug_printf("ram_alloc: %s (%ld)\n", err_getstring(err), err); return 1; } // get slot for retype dest err = slot_alloc(&caps[i]); if (err_is_fail(err)) { debug_printf("slot_alloc: %s (%ld)\n", err_getstring(err), err); return 1; } // retype to selected type err = cap_retype(caps[i], mem, types[i], BASE_PAGE_BITS); if (err_is_fail(err)) { debug_printf("cap_retype: %s (%ld)\n", err_getstring(err), err); return 1; } // cleanup source cap DEBUG_INVALID_MAPPINGS("delete ram cap\n"); err = cap_destroy(mem); if (err_is_fail(err)) { debug_printf("cap_delete(mem): %s (%ld)\n", err_getstring(err), err); return 1; } } // cap 6: 2M frame size_t rb = 0; err = frame_alloc(&caps[5], X86_64_LARGE_PAGE_SIZE, &rb); if (err_is_fail(err) || rb != X86_64_LARGE_PAGE_SIZE) { debug_printf("frame_alloc: %s (%ld)\n", err_getstring(err), err); return 1; } // cap 7: 1G frame err = frame_alloc(&caps[6], X86_64_HUGE_PAGE_SIZE, &rb); if (err_is_fail(err) || rb != X86_64_HUGE_PAGE_SIZE) { debug_printf("frame_alloc: %s (%ld)\n", err_getstring(err), err); return 1; } paging_x86_64_flags_t attr = 0; // select dest (ignore frame, asserts) for (int i = 0; i < 4; i++) { // select source for (int j = 0; j < 7; j++) { if (j >= 4) { // frame attr = FRAME_ACCESS_DEFAULT; } else { // ptable attr = PTABLE_ACCESS_DEFAULT; } // try mapping err = vnode_map(caps[i], caps[j], /*slot*/0, attr, /*off*/0, /*count*/1, mapping); check_result(err, i, j); // unmap if mapping succeeded if (err_is_ok(err)) { err = vnode_unmap(caps[i], mapping); if (err_is_fail(err)) { DEBUG_ERR(err, "vnode_unmap"); } assert(err_is_ok(err)); // XXX: better API? err = cap_delete(mapping); assert(err_is_ok(err)); } } } printf("All tests executed: %d PASSED, %d FAILED\n", pass, fail); return 0; }
static void impl_test(void) { errval_t err; debug_printf("Doing an implementation test\n"); struct capref frame; err = frame_alloc(&frame, 2 * BUFFER_SIZE, NULL); assert(err_is_ok(err)); struct frame_identity id; err = invoke_frame_identify(frame, &id); assert(err_is_ok(err)); void *buf; err = vspace_map_one_frame(&buf, 1UL << id.bits, frame, NULL, NULL); assert(err_is_ok(err)); memset(buf, 0, 1UL << id.bits); memset(buf, 0xA5, BUFFER_SIZE); struct ioat_dma_req_setup setup = { .type = IOAT_DMA_REQ_TYPE_MEMCPY, .src = id.base, .dst = id.base + BUFFER_SIZE, .bytes = BUFFER_SIZE, .done_cb = impl_test_cb, .arg = buf }; int reps = 10; do { debug_printf("!!!!!! NEW ROUND\n"); err = ioat_dma_request_memcpy(dma_ctrl.devices, &setup); assert(err_is_ok(err)); uint32_t i = 10; while(i--) { ioat_dma_device_poll_channels(dma_ctrl.devices); } }while(reps--); } #endif int main(int argc, char *argv[]) { errval_t err; debug_printf("I/O AT DMA driver started\n"); /* * Parsing of cmdline arguments. * * When started by Kaluga, the last element of the cmdline will contain * the basic PCI information of the device. * VENDORID:DEVICEID:BUS:DEV:FUN */ uint32_t vendor_id, device_id; struct pci_addr addr = { .bus = PCI_ADDR_DONT_CARE, .device = PCI_ADDR_DONT_CARE, .device = PCI_ADDR_DONT_CARE }; enum device_type devtype = IOAT_DEVICE_INVAL; if (argc > 1) { uint32_t parsed = sscanf(argv[argc - 1], "%x:%x:%x:%x:%x", &vendor_id, &device_id, &addr.bus, &addr.device, &addr.function); if (parsed != 5) { DEBUGPRINT("WARNING: cmdline parsing failed. Using PCI Address [0,0,0]"); } else { if (vendor_id != 0x8086) { USER_PANIC("unexpected vendor [%x]", vendor_id); } switch ((device_id & 0xFFF0)) { case PCI_DEVICE_IOAT_IVB0: devtype = IOAT_DEVICE_IVB; break; case PCI_DEVICE_IOAT_HSW0: devtype = IOAT_DEVICE_HSW; break; default: USER_PANIC("unexpected device [%x]", device_id) ; break; } DEBUGPRINT("Initializing I/O AT DMA device with PCI address [%u,%u,%u]\n", addr.bus, addr.device, addr.function); } } else { DEBUGPRINT("WARNING: Initializing I/O AT DMA device with unknown PCI address " "[0,0,0]\n"); } err = ioat_device_discovery(addr, devtype, IOAT_DMA_OPERATION); if (err_is_fail(err)) { USER_PANIC_ERR(err, "DMA Device discovery failed"); } #if DMA_BENCH_RUN_BENCHMARK struct ioat_dma_device *dev = ioat_device_get_next(); dma_bench_run_default(dev); #endif #if IOAT_DMA_OPERATION == IOAT_DMA_OPERATION_SERVICE iref_t svc_iref; char svc_name[30]; uint8_t numa_node = (disp_get_core_id() >= 20); snprintf(svc_name, 30, "%s.%u", IOAT_DMA_SERVICE_NAME, numa_node); err = dma_service_init_with_name(svc_name, &dma_svc_cb, NULL, &svc_iref); if (err_is_fail(err)) { USER_PANIC_ERR(err, "Failed to start the DMA service"); } err = dma_manager_register_driver(0, 1ULL << 40, DMA_DEV_TYPE_IOAT, svc_iref); if (err_is_fail(err)) { USER_PANIC_ERR(err, "Failed to register with the DMA manager\n"); } DEBUGPRINT("Driver registered with DMA manager. Serving requests now.\n"); #endif #if IOAT_DMA_OPERATION == IOAT_DMA_OPERATION_LIBRARY #endif uint8_t idle = 0x1; uint32_t idle_counter = 0xFF; while (1) { err = ioat_device_poll(); switch (err_no(err)) { case DMA_ERR_DEVICE_IDLE: idle = idle && 0x1; break; case SYS_ERR_OK: idle = 0; break; default: debug_printf("I/O AT DMA driver terminated: in poll, %s\n", err_getstring(err)); return err; } err = event_dispatch_non_block(get_default_waitset()); switch (err_no(err)) { case SYS_ERR_OK: idle = 0; break; case LIB_ERR_NO_EVENT: idle &= 1; break; default: debug_printf("I/O AT DMA driver terminated in dispatch, %s\n", err_getstring(err)); return err; } if (idle) { idle_counter--; } if (idle_counter == 0) { idle_counter = 0xFF; thread_yield(); } } return 0; }
static int dd(int argc, char *argv[]) { // parse options char *source = NULL; char *target = NULL; vfs_handle_t source_vh = NULL; vfs_handle_t target_vh = NULL; size_t blocksize = 512; size_t count = 0; size_t skip = 0; size_t seek = 0; size_t rsize = 0; size_t wsize = 0; size_t blocks_written = 0; size_t total_bytes_read = 0; size_t total_bytes_written = 0; size_t progress = 0; errval_t err; int ret = 0; for (int i = 1; i < argc; i++) { if (!strncmp(argv[i], "bs=", 3)) blocksize = atoi(argv[i] + 3); else if (!strncmp(argv[i], "count=", 6)) count = atoi(argv[i] + 6); else if (!strncmp(argv[i], "skip=", 5)) skip = atoi(argv[i] + 5); else if (!strncmp(argv[i], "seek=", 5)) seek = atoi(argv[i] + 5); else if (!strncmp(argv[i], "if=", 3)) source = (argv[i] + 3); else if (!strncmp(argv[i], "of=", 3)) target = (argv[i] + 3); else if (!strncmp(argv[i], "progress", 8)) progress = 1; } size_t one_per_cent = (blocksize * count) / 100; printf("from: %s to: %s bs=%zd count=%zd seek=%zd skip=%zd\n", source, target, blocksize, count, seek, skip); if (source != NULL) { char *path = vfs_path_mkabsolute(cwd, source); err = vfs_open(path, &source_vh); free(path); if (err_is_fail(err)) { printf("%s: %s\n", source, err_getstring(err)); return 1; } if (skip != 0) { // TODO: skip } } if (target != NULL) { char *path = vfs_path_mkabsolute(cwd, target); err = vfs_create(path, &target_vh); free(path); if (err_is_fail(err)) { // close source handle if (source_vh != NULL) vfs_close(source_vh); printf("%s: %s\n", target, err_getstring(err)); return 1; } if (seek != 0) { // TODO: seek } } uint8_t * buffer = malloc(blocksize); #if defined(__x86_64__) || defined(__i386__) uint64_t tscperms; err = sys_debug_get_tsc_per_ms(&tscperms); assert(err_is_ok(err)); //printf("ticks per millisec: %" PRIu64 "\n", tscperms); uint64_t start = rdtsc(); #endif if (buffer == NULL) { ret = 2; printf("failed to allocate buffer of size %zd\n", blocksize); goto out; } do { //printf("copying block\n"); size_t read_bytes = 0; do { err = vfs_read(source_vh, buffer, blocksize, &rsize); if (err_is_fail(err)) { DEBUG_ERR(err, "error reading file"); ret = 1; goto out; } total_bytes_read += rsize; read_bytes += rsize; size_t wpos = 0; while (wpos < rsize) { if (wpos > 0) printf("was unable to write the whole chunk of size %zd. Now at pos: %zd of buffer\n", rsize, wpos); err = vfs_write(target_vh, &buffer[wpos], rsize - wpos, &wsize); if (err_is_fail(err) || wsize == 0) { DEBUG_ERR(err, "error writing file"); ret = 1; goto out; } wpos += wsize; total_bytes_written += wsize; } } while(read_bytes < blocksize); blocks_written++; if (progress && one_per_cent && total_bytes_written % one_per_cent == 0) { printf("."); } //printf("block successfully copied. read: %zd. blocks written: %zd\n", rsize, blocks_written); } while (rsize > 0 && !(count > 0 && blocks_written >= count)); if (progress) printf("\n"); out: if (buffer != NULL) free(buffer); if (source_vh != NULL) { err = vfs_close(source_vh); if (err_is_fail(err)) { DEBUG_ERR(err, "in vfs_close"); } } if (target_vh != NULL) { err = vfs_close(target_vh); if (err_is_fail(err)) { DEBUG_ERR(err, "in vfs_close"); } } #if defined(__x86_64__) || defined(__i386__) uint64_t stop = rdtsc(); uint64_t elapsed_msecs = ((stop - start) / tscperms); double elapsed_secs = (double)elapsed_msecs/1000.0; printf("start: %" PRIu64 " stop: %" PRIu64 "\n", start, stop); double kbps = ((double)total_bytes_written / 1024.0) / elapsed_secs; printf("%zd bytes read. %zd bytes written. %f s, %f kB/s\n", total_bytes_read, total_bytes_written, elapsed_secs, kbps); #else printf("%zd bytes read. %zd bytes written.\n", total_bytes_read, total_bytes_written); #endif return ret; }
/** * \brief initializes a DMA client device with the giving capability * * \param info stores information how to find the device driver service * \param dev returns a pointer to the device structure * * \returns SYS_ERR_OK on success * errval on error */ errval_t dma_client_device_init(struct dma_client_info *info, struct dma_client_device **dev) { errval_t err; struct dma_client_device *cdev = calloc(1, sizeof(*cdev)); if (cdev == NULL) { return LIB_ERR_MALLOC_FAIL; } #if DMA_BENCH_ENABLED bench_init(); #endif struct dma_device *dma_dev = (struct dma_device *) cdev; CLIENTDEV_DEBUG("initialzing new client device\n", device_id); iref_t service_iref = 0; switch (info->type) { case DMA_CLIENT_INFO_TYPE_ADDR: assert(!"NYI: lookup based on physical address range"); break; case DMA_CLIENT_INFO_TYPE_IREF: service_iref = info->args.iref; break; case DMA_CLIENT_INFO_TYPE_NAME: CLIENTDEV_DEBUG("looking up iref for name {%s}\n", device_id, info->args.name); err = nameservice_blocking_lookup(info->args.name, &service_iref); if (err_is_fail(err)) { free(cdev); return err; } CLIENTDEV_DEBUG("driver service {%s} @ iref:%"PRIxIREF"\n", device_id, info->args.name, service_iref); break; default: return DMA_ERR_DEVICE_UNSUPPORTED; break; } if (cdev->info.iref == 0) { err = dma_manager_lookup_by_iref(service_iref, &cdev->info); if (err_is_fail(err)) { CLIENTDEV_DEBUG("ERROR: obtaining driver info from DMA manager: %s\n", device_id, err_getstring(err)); free(cdev); return err; } } assert(service_iref != 0); dma_dev->type = DMA_DEV_TYPE_CLIENT; dma_dev->id = device_id++; dma_dev->channels.count = DMA_CLIENT_DEVICE_CONNECTIONS; dma_dev->channels.c = calloc(dma_dev->channels.count, sizeof(*dma_dev->channels.c)); if (dma_dev->channels.c == NULL) { free(cdev); return LIB_ERR_MALLOC_FAIL; } /* channel enumeration */ CLIENTDEV_DEBUG("doing channel enumeration. discovered %u channels\n", cdev->common.id, cdev->common.channels.count); for (uint8_t i = 0; i < dma_dev->channels.count; ++i) { struct dma_channel **chan = &dma_dev->channels.c[i]; err = dma_client_channel_init(cdev, i, service_iref, (struct dma_client_channel **) chan); if (err_is_fail(err)) { free(cdev->common.channels.c); free(cdev); return err; } } dma_dev->f.deregister_memory = dma_client_deregister_memory; dma_dev->f.register_memory = dma_client_register_memory; dma_dev->f.poll = dma_client_device_poll; *dev = cdev; return SYS_ERR_OK; }
static int ahci_read_write(int argc, char *argv[]) { if (argc != 4) { printf("usage: %s <block device> <blocksize> <count>\n", argv[0]); return 1; } char *dev = argv[1]; size_t blocksize = atoi(argv[2]); size_t count = atoi(argv[3]); printf("malloc buf\n"); uint8_t *buf = malloc(blocksize); int ret = 0; errval_t err; vfs_handle_t f = NULL; char *path = vfs_path_mkabsolute(cwd, dev); printf("open\n"); err = vfs_open(path, &f); if (err_is_fail(err)) { printf("%s: %s\n", path, err_getstring(err)); ret = 1; goto out; } for (int i = 0; i < count; i++) { size_t read = 0; size_t rsize; while(read < blocksize) { printf("read\n"); err = vfs_read(f, &buf[read], blocksize, &rsize); if (err_is_fail(err)) { DEBUG_ERR(err, "error reading file"); ret = 1; goto out; } read += rsize; } size_t written = 0; size_t wsize; while(written < blocksize) { printf("write\n"); err = vfs_write(f, &buf[written], blocksize, &wsize); if (err_is_fail(err)) { DEBUG_ERR(err, "error writing file"); ret = 1; goto out; } written += wsize; } } out: if (buf) printf("free\n"); free(buf); if (f) { printf("close\n"); err = vfs_close(f); if (err_is_fail(err)) { DEBUG_ERR(err, "in vfs_close"); } } return ret; }
int map_unmap(void) { errval_t err; struct capref mem; DEBUG_MAP_UNMAP("ram_alloc\n"); err = ram_alloc(&mem, BASE_PAGE_BITS); if (err_is_fail(err)) { printf("ram_alloc: %s (%"PRIuERRV")\n", err_getstring(err), err); return 1; } struct capref frame; DEBUG_MAP_UNMAP("retype\n"); err = slot_alloc(&frame); if (err_is_fail(err)) { printf("slot_alloc: %s (%"PRIuERRV")\n", err_getstring(err), err); return 1; } err = cap_retype(frame, mem, ObjType_Frame, BASE_PAGE_BITS); if (err_is_fail(err)) { printf("cap_retype: %s (%"PRIuERRV")\n", err_getstring(err), err); return 1; } DEBUG_MAP_UNMAP("delete ram cap\n"); err = cap_destroy(mem); if (err_is_fail(err)) { printf("cap_delete(mem): %s (%"PRIuERRV")\n", err_getstring(err), err); return 1; } struct frame_identity fi; err = invoke_frame_identify(frame, &fi); if (err_is_fail(err)) { printf("frame_identify: %s (%"PRIuERRV")\n", err_getstring(err), err); return 1; } DEBUG_MAP_UNMAP("frame: base = 0x%"PRIxGENPADDR", bits = %d\n", fi.base, fi.bits); #ifdef NKMTEST_DEBUG_MAP_UNMAP dump_pmap(get_current_pmap()); #endif struct vregion *vr; struct memobj *memobj; void *vaddr; DEBUG_MAP_UNMAP("map\n"); err = vspace_map_one_frame(&vaddr, BASE_PAGE_SIZE, frame, &memobj, &vr); if (err_is_fail(err)) { printf("vspace_map_one_frame: %s (%"PRIuERRV")\n", err_getstring(err), err); } char *memory = vaddr; DEBUG_MAP_UNMAP("vaddr = %p\n", vaddr); #ifdef NKMTEST_DEBUG_MAP_UNMAP dump_pmap(get_current_pmap()); #endif DEBUG_MAP_UNMAP("write 1\n"); int i; for (i = 0; i < BASE_PAGE_SIZE; i++) { memory[i] = i % INT8_MAX; } DEBUG_MAP_UNMAP("verify 1\n"); for (i = 0; i < BASE_PAGE_SIZE; i++) { assert(memory[i] == i % INT8_MAX); } DEBUG_MAP_UNMAP("delete frame cap\n"); err = cap_destroy(frame); if (err_is_fail(err)) { printf("cap_delete(frame): %s (%"PRIuERRV")\n", err_getstring(err), err); return 1; } #ifdef NKMTEST_DEBUG_MAP_UNMAP // no mapping should remain here dump_pmap(get_current_pmap()); err = debug_dump_hw_ptables(); if (err_is_fail(err)) { printf("kernel dump ptables: %s (%"PRIuERRV")\n", err_getstring(err), err); return 1; } #endif printf("%s: done\n", __FUNCTION__); return 0; }
static errval_t cow_init(size_t bufsize, size_t granularity, struct cnoderef *cow_cn, size_t *frame_count) { assert(cow_cn); assert(frame_count); errval_t err; struct capref frame, cncap; struct cnoderef cnode; // get RAM cap bufsize = (bufsize / granularity + 1) * granularity; err = slot_alloc(&frame); assert(err_is_ok(err)); size_t rambits = log2floor(bufsize); debug_printf("bits = %zu\n", rambits); err = ram_alloc(&frame, rambits); assert(err_is_ok(err)); // calculate #slots cslot_t cap_count = bufsize / granularity; cslot_t slots; // get CNode err = cnode_create(&cncap, &cnode, cap_count, &slots); assert(err_is_ok(err)); assert(slots >= cap_count); // retype RAM into Frames struct capref first_frame = (struct capref) { .cnode = cnode, .slot = 0 }; err = cap_retype(first_frame, frame, ObjType_Frame, log2floor(granularity)); assert(err_is_ok(err)); err = cap_destroy(frame); assert(err_is_ok(err)); *frame_count = slots; *cow_cn = cnode; return SYS_ERR_OK; } // create cow-enabled vregion & backing // Can copy-on-write in granularity-sized chunks static errval_t vspace_map_one_frame_cow(void **buf, size_t size, struct capref frame, vregion_flags_t flags, struct memobj **memobj, struct vregion **vregion, size_t granularity) { errval_t err; if (!memobj) { memobj = malloc(sizeof(*memobj)); } assert(memobj); if (!vregion) { vregion = malloc(sizeof(*vregion)); } assert(vregion); err = vspace_map_anon_attr(buf, memobj, vregion, size, &size, flags); assert(err_is_ok(err)); size_t chunks = size / granularity; cslot_t slots; struct capref cncap; struct cnoderef cnode; err = cnode_create(&cncap, &cnode, chunks, &slots); assert(err_is_ok(err)); assert(slots >= chunks); struct capref fc = (struct capref) { .cnode = cnode, .slot = 0 }; for (int i = 0; i < chunks; i++) { err = cap_copy(fc, frame); assert(err_is_ok(err)); err = (*memobj)->f.fill_foff(*memobj, i * granularity, fc, granularity, i*granularity); assert(err_is_ok(err)); err = (*memobj)->f.pagefault(*memobj, *vregion, i * granularity, 0); assert(err_is_ok(err)); fc.slot++; } return SYS_ERR_OK; } int main(int argc, char *argv[]) { errval_t err; struct capref frame; size_t retsize; void *vbuf; struct vregion *vregion; uint8_t *buf; debug_printf("%s:%d\n", __FUNCTION__, __LINE__); err = frame_alloc(&frame, BUFSIZE, &retsize); assert(retsize >= BUFSIZE); if (err_is_fail(err)) { debug_printf("frame_alloc: %s\n", err_getstring(err)); return 1; } debug_printf("%s:%d: %zu\n", __FUNCTION__, __LINE__, retsize); // setup region err = vspace_map_one_frame_attr(&vbuf, retsize, frame, VREGION_FLAGS_READ_WRITE, NULL, &vregion); if (err_is_fail(err)) { debug_printf("vspace_map: %s\n", err_getstring(err)); return 1; } debug_printf("vaddr: %p\n", vbuf); // write stuff to region buf = vbuf; debug_printf("%s:%d: %p, %lu pages\n", __FUNCTION__, __LINE__, buf, BUFSIZE / BASE_PAGE_SIZE); memset(buf, 0xAA, BUFSIZE); debug_printf("%s:%d\n", __FUNCTION__, __LINE__); // create cow copy // setup exception handler thread_set_exception_handler(handler, NULL, ex_stack, ex_stack+EX_STACK_SIZE, NULL, NULL); assert(err_is_ok(err)); debug_printf("%s:%d\n", __FUNCTION__, __LINE__); err = cow_init(BUFSIZE, BASE_PAGE_SIZE, &cow_frames, &cow_frame_count); assert(err_is_ok(err)); // create r/o copy of region and tell exception handler bounds debug_printf("%s:%d\n", __FUNCTION__, __LINE__); err = vspace_map_one_frame_cow(&cow_vbuf, retsize, frame, VREGION_FLAGS_READ, NULL, &cow_vregion, BASE_PAGE_SIZE); if (err_is_fail(err)) { debug_printf("vspace_map: %s\n", err_getstring(err)); return 1; } debug_printf("cow_vaddr: %p\n", cow_vbuf); // do stuff cow copy uint8_t *cbuf = cow_vbuf; for (int i = 0; i < BUFSIZE / BASE_PAGE_SIZE; i+=2) { cbuf[i * BASE_PAGE_SIZE + 1] = 0x55; } // verify results for (int i = 0; i < BUFSIZE / BASE_PAGE_SIZE; i++) { printf("page %d\n", i); printf("buf[0] = %d; cbuf[0] = %d\n", buf[i*BASE_PAGE_SIZE], cbuf[i*BASE_PAGE_SIZE]); printf("buf[1] = %d; cbuf[1] = %d\n", buf[i*BASE_PAGE_SIZE+1], cbuf[i*BASE_PAGE_SIZE+1]); } debug_dump_hw_ptables(); return EXIT_SUCCESS; }