static int rbd_make_request(struct vmm_request_queue *rq, struct vmm_request *r) { struct rbd *d = rq->priv; physical_addr_t pa; physical_size_t sz; pa = d->addr + r->lba * RBD_BLOCK_SIZE; sz = r->bcnt * RBD_BLOCK_SIZE; switch (r->type) { case VMM_REQUEST_READ: vmm_host_memory_read(pa, r->data, sz); vmm_blockdev_complete_request(r); break; case VMM_REQUEST_WRITE: vmm_host_memory_write(pa, r->data, sz); vmm_blockdev_complete_request(r); break; default: vmm_blockdev_fail_request(r); break; }; return VMM_OK; }
static int cmd_vfs_load(struct vmm_chardev *cdev, physical_addr_t pa, const char *path, u32 off, u32 len) { int fd, rc; size_t buf_rd, rd_count; char buf[VFS_LOAD_BUF_SZ]; struct stat st; fd = vfs_open(path, O_RDONLY, 0); if (fd < 0) { vmm_cprintf(cdev, "Failed to open %s\n", path); return fd; } rc = vfs_fstat(fd, &st); if (rc) { vfs_close(fd); vmm_cprintf(cdev, "Failed to stat %s\n", path); return rc; } if (!(st.st_mode & S_IFREG)) { vfs_close(fd); vmm_cprintf(cdev, "Cannot read %s\n", path); return VMM_EINVALID; } if (off >= st.st_size) { vfs_close(fd); vmm_cprintf(cdev, "Offset greater than file size\n", path); return VMM_EINVALID; } len = ((st.st_size - off) < len) ? (st.st_size - off) : len; rd_count = 0; while (len) { buf_rd = (len < VFS_LOAD_BUF_SZ) ? len : VFS_LOAD_BUF_SZ; buf_rd = vfs_read(fd, buf, buf_rd); if (buf_rd < 1) { break; } vmm_host_memory_write(pa, buf, buf_rd); len -= buf_rd; rd_count += buf_rd; } vmm_cprintf(cdev, "Loaded %d bytes\n", rd_count); rc = vfs_close(fd); if (rc) { vmm_cprintf(cdev, "Failed to close %s\n", path); return rc; } return VMM_OK; }
static int __init scu_cpu_prepare(unsigned int cpu) { int rc; u32 val = 0; physical_addr_t _start_secondary_pa; /* Get physical address secondary startup code */ rc = vmm_host_va2pa((virtual_addr_t)&_start_secondary_nopen, &_start_secondary_pa); if (rc) { return rc; } /* Enable snooping through SCU */ if (scu_base) { scu_enable((void *)scu_base); } /* Write to clear address */ if (clear_addr[cpu]) { arch_wmb(); val = ~0x0; vmm_host_memory_write(clear_addr[cpu], &val, sizeof(u32), FALSE); } /* Write to release address */ if (release_addr[cpu]) { arch_wmb(); val = _start_secondary_pa; vmm_host_memory_write(release_addr[cpu], &val, sizeof(u32), FALSE); } return VMM_OK; }
static int cmd_vfs_load(struct vmm_chardev *cdev, struct vmm_guest *guest, physical_addr_t pa, const char *path, u32 off, u32 len) { int fd, rc; loff_t rd_off; physical_addr_t wr_pa; size_t buf_wr, buf_rd, buf_count, wr_count; char buf[VFS_LOAD_BUF_SZ]; struct stat st; fd = vfs_open(path, O_RDONLY, 0); if (fd < 0) { vmm_cprintf(cdev, "Failed to open %s\n", path); return fd; } rc = vfs_fstat(fd, &st); if (rc) { vfs_close(fd); vmm_cprintf(cdev, "Failed to stat %s\n", path); return rc; } if (!(st.st_mode & S_IFREG)) { vfs_close(fd); vmm_cprintf(cdev, "Cannot read %s\n", path); return VMM_EINVALID; } if (off >= st.st_size) { vfs_close(fd); vmm_cprintf(cdev, "Offset greater than file size\n"); return VMM_EINVALID; } len = ((st.st_size - off) < len) ? (st.st_size - off) : len; rd_off = 0; wr_count = 0; wr_pa = pa; while (len) { buf_rd = (len < VFS_LOAD_BUF_SZ) ? len : VFS_LOAD_BUF_SZ; buf_count = vfs_read(fd, buf, buf_rd); if (buf_count < 1) { vmm_cprintf(cdev, "Failed to read " "%d bytes @ 0x%llx from %s\n", buf_rd, (u64)rd_off, path); break; } rd_off += buf_count; if (guest) { buf_wr = vmm_guest_memory_write(guest, wr_pa, buf, buf_count, FALSE); } else { buf_wr = vmm_host_memory_write(wr_pa, buf, buf_count, FALSE); } if (buf_wr != buf_count) { vmm_cprintf(cdev, "Failed to write " "%d bytes @ 0x%llx (%s)\n", buf_count, (u64)wr_pa, (guest) ? (guest->name) : "host"); break; } len -= buf_wr; wr_count += buf_wr; wr_pa += buf_wr; } vmm_cprintf(cdev, "%s: Loaded 0x%llx with %d bytes\n", (guest) ? (guest->name) : "host", (u64)pa, wr_count); rc = vfs_close(fd); if (rc) { vmm_cprintf(cdev, "Failed to close %s\n", path); return rc; } return VMM_OK; }