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

qcow: make encrypt_sectors encrypt in place

Instead of requiring separate input/output buffers for
encrypting data, change encrypt_sectors() to assume
use of a single buffer, encrypting in place. One current
caller uses the same buffer for input/output already
and the other two callers are easily converted to do so.

Reviewed-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Message-id: 20170623162419.26068-9-berrange@redhat.com
Signed-off-by: Max Reitz <mreitz@redhat.com>

authored by

Daniel P. Berrange and committed by
Max Reitz
1fad1f94 0cb8d47b

+15 -30
+15 -30
block/qcow.c
··· 322 322 } 323 323 324 324 /* The crypt function is compatible with the linux cryptoloop 325 - algorithm for < 4 GB images. NOTE: out_buf == in_buf is 326 - supported */ 325 + algorithm for < 4 GB images. */ 327 326 static int encrypt_sectors(BDRVQcowState *s, int64_t sector_num, 328 - uint8_t *out_buf, const uint8_t *in_buf, 329 - int nb_sectors, bool enc, Error **errp) 327 + uint8_t *buf, int nb_sectors, bool enc, 328 + Error **errp) 330 329 { 331 330 union { 332 331 uint64_t ll[2]; ··· 345 344 } 346 345 if (enc) { 347 346 ret = qcrypto_cipher_encrypt(s->cipher, 348 - in_buf, 349 - out_buf, 347 + buf, buf, 350 348 512, 351 349 errp); 352 350 } else { 353 351 ret = qcrypto_cipher_decrypt(s->cipher, 354 - in_buf, 355 - out_buf, 352 + buf, buf, 356 353 512, 357 354 errp); 358 355 } ··· 360 357 return -1; 361 358 } 362 359 sector_num++; 363 - in_buf += 512; 364 - out_buf += 512; 360 + buf += 512; 365 361 } 366 362 return 0; 367 363 } ··· 481 477 uint64_t start_sect; 482 478 assert(s->cipher); 483 479 start_sect = (offset & ~(s->cluster_size - 1)) >> 9; 484 - memset(s->cluster_data + 512, 0x00, 512); 485 480 for(i = 0; i < s->cluster_sectors; i++) { 486 481 if (i < n_start || i >= n_end) { 487 482 Error *err = NULL; 483 + memset(s->cluster_data, 0x00, 512); 488 484 if (encrypt_sectors(s, start_sect + i, 489 - s->cluster_data, 490 - s->cluster_data + 512, 1, 485 + s->cluster_data, 1, 491 486 true, &err) < 0) { 492 487 error_free(err); 493 488 errno = EIO; ··· 665 660 } 666 661 if (bs->encrypted) { 667 662 assert(s->cipher); 668 - if (encrypt_sectors(s, sector_num, buf, buf, 663 + if (encrypt_sectors(s, sector_num, buf, 669 664 n, false, &err) < 0) { 670 665 goto fail; 671 666 } ··· 700 695 BDRVQcowState *s = bs->opaque; 701 696 int index_in_cluster; 702 697 uint64_t cluster_offset; 703 - const uint8_t *src_buf; 704 698 int ret = 0, n; 705 - uint8_t *cluster_data = NULL; 706 699 struct iovec hd_iov; 707 700 QEMUIOVector hd_qiov; 708 701 uint8_t *buf; ··· 710 703 711 704 s->cluster_cache_offset = -1; /* disable compressed cache */ 712 705 713 - if (qiov->niov > 1) { 706 + /* We must always copy the iov when encrypting, so we 707 + * don't modify the original data buffer during encryption */ 708 + if (bs->encrypted || qiov->niov > 1) { 714 709 buf = orig_buf = qemu_try_blockalign(bs, qiov->size); 715 710 if (buf == NULL) { 716 711 return -ENOMEM; ··· 740 735 if (bs->encrypted) { 741 736 Error *err = NULL; 742 737 assert(s->cipher); 743 - if (!cluster_data) { 744 - cluster_data = g_malloc0(s->cluster_size); 745 - } 746 - if (encrypt_sectors(s, sector_num, cluster_data, buf, 747 - n, true, &err) < 0) { 738 + if (encrypt_sectors(s, sector_num, buf, n, true, &err) < 0) { 748 739 error_free(err); 749 740 ret = -EIO; 750 741 break; 751 742 } 752 - src_buf = cluster_data; 753 - } else { 754 - src_buf = buf; 755 743 } 756 744 757 - hd_iov.iov_base = (void *)src_buf; 745 + hd_iov.iov_base = (void *)buf; 758 746 hd_iov.iov_len = n * 512; 759 747 qemu_iovec_init_external(&hd_qiov, &hd_iov, 1); 760 748 qemu_co_mutex_unlock(&s->lock); ··· 773 761 } 774 762 qemu_co_mutex_unlock(&s->lock); 775 763 776 - if (qiov->niov > 1) { 777 - qemu_vfree(orig_buf); 778 - } 779 - g_free(cluster_data); 764 + qemu_vfree(orig_buf); 780 765 781 766 return ret; 782 767 }