Revision fa6111f2
b/hw/iov.c | ||
---|---|---|
31 | 31 |
} |
32 | 32 |
return offset; |
33 | 33 |
} |
34 |
|
|
35 |
size_t iov_to_buf(const struct iovec *iov, const unsigned int iovcnt, |
|
36 |
void *buf, size_t offset, size_t size) |
|
37 |
{ |
|
38 |
uint8_t *ptr; |
|
39 |
size_t iov_off, buf_off; |
|
40 |
unsigned int i; |
|
41 |
|
|
42 |
ptr = buf; |
|
43 |
iov_off = 0; |
|
44 |
buf_off = 0; |
|
45 |
for (i = 0; i < iovcnt && size; i++) { |
|
46 |
if (offset < (iov_off + iov[i].iov_len)) { |
|
47 |
size_t len = MIN((iov_off + iov[i].iov_len) - offset , size); |
|
48 |
|
|
49 |
memcpy(ptr + buf_off, iov[i].iov_base + (offset - iov_off), len); |
|
50 |
|
|
51 |
buf_off += len; |
|
52 |
offset += len; |
|
53 |
size -= len; |
|
54 |
} |
|
55 |
iov_off += iov[i].iov_len; |
|
56 |
} |
|
57 |
return buf_off; |
|
58 |
} |
|
59 |
|
|
60 |
size_t iov_size(const struct iovec *iov, const unsigned int iovcnt) |
|
61 |
{ |
|
62 |
size_t len; |
|
63 |
unsigned int i; |
|
64 |
|
|
65 |
len = 0; |
|
66 |
for (i = 0; i < iovcnt; i++) { |
|
67 |
len += iov[i].iov_len; |
|
68 |
} |
|
69 |
return len; |
|
70 |
} |
b/hw/iov.h | ||
---|---|---|
14 | 14 |
|
15 | 15 |
size_t iov_from_buf(struct iovec *iov, unsigned int iovcnt, |
16 | 16 |
const void *buf, size_t size); |
17 |
size_t iov_to_buf(const struct iovec *iov, const unsigned int iovcnt, |
|
18 |
void *buf, size_t offset, size_t size); |
|
19 |
size_t iov_size(const struct iovec *iov, const unsigned int iovcnt); |
b/hw/virtio-balloon.c | ||
---|---|---|
11 | 11 |
* |
12 | 12 |
*/ |
13 | 13 |
|
14 |
#include "iov.h" |
|
14 | 15 |
#include "qemu-common.h" |
15 | 16 |
#include "virtio.h" |
16 | 17 |
#include "pc.h" |
... | ... | |
92 | 93 |
return QOBJECT(dict); |
93 | 94 |
} |
94 | 95 |
|
95 |
/* FIXME: once we do a virtio refactoring, this will get subsumed into common |
|
96 |
* code */ |
|
97 |
static size_t memcpy_from_iovector(void *data, size_t offset, size_t size, |
|
98 |
struct iovec *iov, int iovlen) |
|
99 |
{ |
|
100 |
int i; |
|
101 |
uint8_t *ptr = data; |
|
102 |
size_t iov_off = 0; |
|
103 |
size_t data_off = 0; |
|
104 |
|
|
105 |
for (i = 0; i < iovlen && size; i++) { |
|
106 |
if (offset < (iov_off + iov[i].iov_len)) { |
|
107 |
size_t len = MIN((iov_off + iov[i].iov_len) - offset , size); |
|
108 |
|
|
109 |
memcpy(ptr + data_off, iov[i].iov_base + (offset - iov_off), len); |
|
110 |
|
|
111 |
data_off += len; |
|
112 |
offset += len; |
|
113 |
size -= len; |
|
114 |
} |
|
115 |
|
|
116 |
iov_off += iov[i].iov_len; |
|
117 |
} |
|
118 |
|
|
119 |
return data_off; |
|
120 |
} |
|
121 |
|
|
122 | 96 |
static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq) |
123 | 97 |
{ |
124 | 98 |
VirtIOBalloon *s = to_virtio_balloon(vdev); |
... | ... | |
128 | 102 |
size_t offset = 0; |
129 | 103 |
uint32_t pfn; |
130 | 104 |
|
131 |
while (memcpy_from_iovector(&pfn, offset, 4, |
|
132 |
elem.out_sg, elem.out_num) == 4) { |
|
105 |
while (iov_to_buf(elem.out_sg, elem.out_num, &pfn, offset, 4) == 4) { |
|
133 | 106 |
ram_addr_t pa; |
134 | 107 |
ram_addr_t addr; |
135 | 108 |
|
... | ... | |
181 | 154 |
*/ |
182 | 155 |
reset_stats(s); |
183 | 156 |
|
184 |
while (memcpy_from_iovector(&stat, offset, sizeof(stat), elem->out_sg,
|
|
185 |
elem->out_num) == sizeof(stat)) {
|
|
157 |
while (iov_to_buf(elem->out_sg, elem->out_num, &stat, offset, sizeof(stat))
|
|
158 |
== sizeof(stat)) { |
|
186 | 159 |
uint16_t tag = tswap16(stat.tag); |
187 | 160 |
uint64_t val = tswap64(stat.val); |
188 | 161 |
|
Also available in: Unified diff