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

vmbus: add infrastructure to save/load vmbus requests

This can be allow to include controller-specific data while
saving/loading in-flight scsi requests of the vmbus scsi controller.

Signed-off-by: Roman Kagan <rkagan@virtuozzo.com>
Signed-off-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
Signed-off-by: Jon Doron <arilou@gmail.com>
Message-Id: <20200424123444.3481728-7-arilou@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

authored by

Jon Doron and committed by
Paolo Bonzini
4dd8a706 6775d15d

+102
+99
hw/hyperv/vmbus.c
··· 1272 1272 g_free(req); 1273 1273 } 1274 1274 1275 + static const VMStateDescription vmstate_sgent = { 1276 + .name = "vmbus/sgentry", 1277 + .version_id = 0, 1278 + .minimum_version_id = 0, 1279 + .fields = (VMStateField[]) { 1280 + VMSTATE_UINT64(base, ScatterGatherEntry), 1281 + VMSTATE_UINT64(len, ScatterGatherEntry), 1282 + VMSTATE_END_OF_LIST() 1283 + } 1284 + }; 1285 + 1286 + typedef struct VMBusChanReqSave { 1287 + uint16_t chan_idx; 1288 + uint16_t pkt_type; 1289 + uint32_t msglen; 1290 + void *msg; 1291 + uint64_t transaction_id; 1292 + bool need_comp; 1293 + uint32_t num; 1294 + ScatterGatherEntry *sgl; 1295 + } VMBusChanReqSave; 1296 + 1297 + static const VMStateDescription vmstate_vmbus_chan_req = { 1298 + .name = "vmbus/vmbus_chan_req", 1299 + .version_id = 0, 1300 + .minimum_version_id = 0, 1301 + .fields = (VMStateField[]) { 1302 + VMSTATE_UINT16(chan_idx, VMBusChanReqSave), 1303 + VMSTATE_UINT16(pkt_type, VMBusChanReqSave), 1304 + VMSTATE_UINT32(msglen, VMBusChanReqSave), 1305 + VMSTATE_VBUFFER_ALLOC_UINT32(msg, VMBusChanReqSave, 0, NULL, msglen), 1306 + VMSTATE_UINT64(transaction_id, VMBusChanReqSave), 1307 + VMSTATE_BOOL(need_comp, VMBusChanReqSave), 1308 + VMSTATE_UINT32(num, VMBusChanReqSave), 1309 + VMSTATE_STRUCT_VARRAY_POINTER_UINT32(sgl, VMBusChanReqSave, num, 1310 + vmstate_sgent, ScatterGatherEntry), 1311 + VMSTATE_END_OF_LIST() 1312 + } 1313 + }; 1314 + 1315 + void vmbus_save_req(QEMUFile *f, VMBusChanReq *req) 1316 + { 1317 + VMBusChanReqSave req_save; 1318 + 1319 + req_save.chan_idx = req->chan->subchan_idx; 1320 + req_save.pkt_type = req->pkt_type; 1321 + req_save.msglen = req->msglen; 1322 + req_save.msg = req->msg; 1323 + req_save.transaction_id = req->transaction_id; 1324 + req_save.need_comp = req->need_comp; 1325 + req_save.num = req->sgl.nsg; 1326 + req_save.sgl = g_memdup(req->sgl.sg, 1327 + req_save.num * sizeof(ScatterGatherEntry)); 1328 + 1329 + vmstate_save_state(f, &vmstate_vmbus_chan_req, &req_save, NULL); 1330 + 1331 + g_free(req_save.sgl); 1332 + } 1333 + 1334 + void *vmbus_load_req(QEMUFile *f, VMBusDevice *dev, uint32_t size) 1335 + { 1336 + VMBusChanReqSave req_save; 1337 + VMBusChanReq *req = NULL; 1338 + VMBusChannel *chan = NULL; 1339 + uint32_t i; 1340 + 1341 + vmstate_load_state(f, &vmstate_vmbus_chan_req, &req_save, 0); 1342 + 1343 + if (req_save.chan_idx >= dev->num_channels) { 1344 + error_report("%s: %u(chan_idx) > %u(num_channels)", __func__, 1345 + req_save.chan_idx, dev->num_channels); 1346 + goto out; 1347 + } 1348 + chan = &dev->channels[req_save.chan_idx]; 1349 + 1350 + if (vmbus_channel_reserve(chan, 0, req_save.msglen)) { 1351 + goto out; 1352 + } 1353 + 1354 + req = vmbus_alloc_req(chan, size, req_save.pkt_type, req_save.msglen, 1355 + req_save.transaction_id, req_save.need_comp); 1356 + if (req_save.msglen) { 1357 + memcpy(req->msg, req_save.msg, req_save.msglen); 1358 + } 1359 + 1360 + for (i = 0; i < req_save.num; i++) { 1361 + qemu_sglist_add(&req->sgl, req_save.sgl[i].base, req_save.sgl[i].len); 1362 + } 1363 + 1364 + out: 1365 + if (req_save.msglen) { 1366 + g_free(req_save.msg); 1367 + } 1368 + if (req_save.num) { 1369 + g_free(req_save.sgl); 1370 + } 1371 + return req; 1372 + } 1373 + 1275 1374 static void channel_event_cb(EventNotifier *e) 1276 1375 { 1277 1376 VMBusChannel *chan = container_of(e, VMBusChannel, notifier);
+3
include/hw/hyperv/vmbus.h
··· 224 224 void vmbus_unmap_sgl(VMBusChanReq *req, DMADirection dir, struct iovec *iov, 225 225 unsigned iov_cnt, size_t accessed); 226 226 227 + void vmbus_save_req(QEMUFile *f, VMBusChanReq *req); 228 + void *vmbus_load_req(QEMUFile *f, VMBusDevice *dev, uint32_t size); 229 + 227 230 #endif