예제 #1
0
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;
}
예제 #2
0
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++;
		}
	}
}
예제 #3
0
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;
}