qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

Revert "9p: init_in_iov_from_pdu can truncate the size"

This reverts commit 16724a173049ac29c7b5ade741da93a0f46edff7.
It causes https://bugs.launchpad.net/bugs/1877688.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
Reviewed-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
Message-Id: <20200521192627.15259-1-sstabellini@kernel.org>
Signed-off-by: Greg Kurz <groug@kaod.org>

authored by

Stefano Stabellini and committed by
Greg Kurz
cf45183b ed463454

+22 -39
+11 -22
hw/9pfs/9p.c
··· 2103 2103 * with qemu_iovec_destroy(). 2104 2104 */ 2105 2105 static void v9fs_init_qiov_from_pdu(QEMUIOVector *qiov, V9fsPDU *pdu, 2106 - size_t skip, size_t *size, 2106 + size_t skip, size_t size, 2107 2107 bool is_write) 2108 2108 { 2109 2109 QEMUIOVector elem; 2110 2110 struct iovec *iov; 2111 2111 unsigned int niov; 2112 - size_t alloc_size = *size + skip; 2113 2112 2114 2113 if (is_write) { 2115 - pdu->s->transport->init_out_iov_from_pdu(pdu, &iov, &niov, alloc_size); 2116 - } else { 2117 - pdu->s->transport->init_in_iov_from_pdu(pdu, &iov, &niov, &alloc_size); 2118 - } 2119 - 2120 - if (alloc_size < skip) { 2121 - *size = 0; 2114 + pdu->s->transport->init_out_iov_from_pdu(pdu, &iov, &niov, size + skip); 2122 2115 } else { 2123 - *size = alloc_size - skip; 2116 + pdu->s->transport->init_in_iov_from_pdu(pdu, &iov, &niov, size + skip); 2124 2117 } 2125 2118 2126 2119 qemu_iovec_init_external(&elem, iov, niov); 2127 2120 qemu_iovec_init(qiov, niov); 2128 - qemu_iovec_concat(qiov, &elem, skip, *size); 2121 + qemu_iovec_concat(qiov, &elem, skip, size); 2129 2122 } 2130 2123 2131 2124 static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp, ··· 2133 2126 { 2134 2127 ssize_t err; 2135 2128 size_t offset = 7; 2136 - size_t read_count; 2129 + uint64_t read_count; 2137 2130 QEMUIOVector qiov_full; 2138 2131 2139 2132 if (fidp->fs.xattr.len < off) { 2140 2133 read_count = 0; 2141 - } else if (fidp->fs.xattr.len - off < max_count) { 2142 - read_count = fidp->fs.xattr.len - off; 2143 2134 } else { 2135 + read_count = fidp->fs.xattr.len - off; 2136 + } 2137 + if (read_count > max_count) { 2144 2138 read_count = max_count; 2145 2139 } 2146 2140 err = pdu_marshal(pdu, offset, "d", read_count); ··· 2149 2143 } 2150 2144 offset += err; 2151 2145 2152 - v9fs_init_qiov_from_pdu(&qiov_full, pdu, offset, &read_count, false); 2146 + v9fs_init_qiov_from_pdu(&qiov_full, pdu, offset, read_count, false); 2153 2147 err = v9fs_pack(qiov_full.iov, qiov_full.niov, 0, 2154 2148 ((char *)fidp->fs.xattr.value) + off, 2155 2149 read_count); ··· 2278 2272 QEMUIOVector qiov_full; 2279 2273 QEMUIOVector qiov; 2280 2274 int32_t len; 2281 - size_t size = max_count; 2282 2275 2283 - v9fs_init_qiov_from_pdu(&qiov_full, pdu, offset + 4, &size, false); 2276 + v9fs_init_qiov_from_pdu(&qiov_full, pdu, offset + 4, max_count, false); 2284 2277 qemu_iovec_init(&qiov, qiov_full.niov); 2285 - max_count = size; 2286 2278 do { 2287 2279 qemu_iovec_reset(&qiov); 2288 2280 qemu_iovec_concat(&qiov, &qiov_full, count, qiov_full.size - count); ··· 2533 2525 int32_t len = 0; 2534 2526 int32_t total = 0; 2535 2527 size_t offset = 7; 2536 - size_t size; 2537 2528 V9fsFidState *fidp; 2538 2529 V9fsPDU *pdu = opaque; 2539 2530 V9fsState *s = pdu->s; ··· 2546 2537 return; 2547 2538 } 2548 2539 offset += err; 2549 - size = count; 2550 - v9fs_init_qiov_from_pdu(&qiov_full, pdu, offset, &size, true); 2551 - count = size; 2540 + v9fs_init_qiov_from_pdu(&qiov_full, pdu, offset, count, true); 2552 2541 trace_v9fs_write(pdu->tag, pdu->id, fid, off, count, qiov_full.niov); 2553 2542 2554 2543 fidp = get_fid(pdu, fid);
+1 -1
hw/9pfs/9p.h
··· 436 436 ssize_t (*pdu_vunmarshal)(V9fsPDU *pdu, size_t offset, const char *fmt, 437 437 va_list ap); 438 438 void (*init_in_iov_from_pdu)(V9fsPDU *pdu, struct iovec **piov, 439 - unsigned int *pniov, size_t *size); 439 + unsigned int *pniov, size_t size); 440 440 void (*init_out_iov_from_pdu)(V9fsPDU *pdu, struct iovec **piov, 441 441 unsigned int *pniov, size_t size); 442 442 void (*push_and_notify)(V9fsPDU *pdu);
+4 -7
hw/9pfs/virtio-9p-device.c
··· 147 147 } 148 148 149 149 static void virtio_init_in_iov_from_pdu(V9fsPDU *pdu, struct iovec **piov, 150 - unsigned int *pniov, size_t *size) 150 + unsigned int *pniov, size_t size) 151 151 { 152 152 V9fsState *s = pdu->s; 153 153 V9fsVirtioState *v = container_of(s, V9fsVirtioState, state); 154 154 VirtQueueElement *elem = v->elems[pdu->idx]; 155 155 size_t buf_size = iov_size(elem->in_sg, elem->in_num); 156 156 157 - if (buf_size < P9_IOHDRSZ) { 157 + if (buf_size < size) { 158 158 VirtIODevice *vdev = VIRTIO_DEVICE(v); 159 159 160 160 virtio_error(vdev, 161 - "VirtFS reply type %d needs %zu bytes, buffer has %zu, less than minimum", 162 - pdu->id + 1, *size, buf_size); 163 - } 164 - if (buf_size < *size) { 165 - *size = buf_size; 161 + "VirtFS reply type %d needs %zu bytes, buffer has %zu", 162 + pdu->id + 1, size, buf_size); 166 163 } 167 164 168 165 *piov = elem->in_sg;
+6 -9
hw/9pfs/xen-9p-backend.c
··· 188 188 static void xen_9pfs_init_in_iov_from_pdu(V9fsPDU *pdu, 189 189 struct iovec **piov, 190 190 unsigned int *pniov, 191 - size_t *size) 191 + size_t size) 192 192 { 193 193 Xen9pfsDev *xen_9pfs = container_of(pdu->s, Xen9pfsDev, state); 194 194 Xen9pfsRing *ring = &xen_9pfs->rings[pdu->tag % xen_9pfs->num_rings]; ··· 198 198 g_free(ring->sg); 199 199 200 200 ring->sg = g_new0(struct iovec, 2); 201 - xen_9pfs_in_sg(ring, ring->sg, &num, pdu->idx, *size); 201 + xen_9pfs_in_sg(ring, ring->sg, &num, pdu->idx, size); 202 202 203 203 buf_size = iov_size(ring->sg, num); 204 - if (buf_size < P9_IOHDRSZ) { 205 - xen_pv_printf(&xen_9pfs->xendev, 0, "Xen 9pfs reply type %d needs " 206 - "%zu bytes, buffer has %zu, less than minimum\n", 207 - pdu->id + 1, *size, buf_size); 204 + if (buf_size < size) { 205 + xen_pv_printf(&xen_9pfs->xendev, 0, "Xen 9pfs request type %d" 206 + "needs %zu bytes, buffer has %zu\n", pdu->id, size, 207 + buf_size); 208 208 xen_be_set_state(&xen_9pfs->xendev, XenbusStateClosing); 209 209 xen_9pfs_disconnect(&xen_9pfs->xendev); 210 - } 211 - if (buf_size < *size) { 212 - *size = buf_size; 213 210 } 214 211 215 212 *piov = ring->sg;