u32 virtio_buf_to_iovec_write(struct virtio_device *dev, struct virtio_iovec *iov, u32 iov_cnt, void *buf, u32 buf_len) { u32 i = 0, pos = 0, len = 0; for (i = 0; i < iov_cnt && pos < buf_len; i++) { len = ((buf_len - pos) < iov[i].len) ? (buf_len - pos) : iov[i].len; len = vmm_guest_memory_write(dev->guest, iov[i].addr, buf + pos, len); if (!len) { break; } pos += len; } return pos; }
void virtio_iovec_fill_zeros(struct virtio_device *dev, struct virtio_iovec *iov, u32 iov_cnt) { u32 i = 0, pos = 0, len = 0; u8 zeros[16]; memset(zeros, 0, sizeof(zeros)); while (i < iov_cnt) { len = (iov[i].len < 16) ? iov[i].len : 16; len = vmm_guest_memory_write(dev->guest, iov[i].addr + pos, zeros, len); if (!len) { break; } pos += len; if (pos == iov[i].len) { pos = 0; i++; } } }
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; }