On 2019/4/3 23:35, Laszlo Ersek wrote: >> I thought about your comments and wrote the following patch (just for test) >> which uses a file mapping to replace the anonymous mapping. UEFI seems to >> work >> fine. So why not use a file mapping to read or write a pflash device? > Honestly I can't answer "why not do this". Maybe we should. > > Regarding "why not do this *exactly as shown below*" -- probably because > then we'd have updates to the same underlying regular file via both > mmap() and write(), and the interactions between those are really tricky > (= best avoided). > > One of my favorite questions over the years used to be posting a matrix > of possible mmap() and file descriptor r/w/sync interactions, with the > outcomes as they were "implied" by POSIX, and then asking at the bottom, > "is my understanding correct?" I've never ever received an answer to > that. :)
In my opinion, it's feasible to r/w/sync the memory devices which use a block backend via mmap() and write(). > > Also... although we don't really use them in practice, some QCOW2 > features for pflash block backends are -- or would be -- nice. (Not the > internal snapshots or the live RAM dumps, of course.) Regarding sparse files, can we read actual backend size data for the read-only pflash memory as the following steps shown? 1) Create a sparse file -- QEMU_EFI-test.raw: dd if=/dev/zero of=QEMU_EFI-test.raw bs=1M seek=64 count=0 2) Read from QEMU_EFI.fd and write to QEMU_EFI-test.raw: dd of="QEMU_EFI-test.raw" if="QEMU_EFI.fd" conv=notrunc 3) Use QEMU_EFI-test.raw as the read-only pflash and start qemu with the below patch applied: ---8>--- diff --git a/hw/block/block.c b/hw/block/block.c index bf56c76..ad18d5e 100644 --- a/hw/block/block.c +++ b/hw/block/block.c @@ -30,7 +30,7 @@ bool blk_check_size_and_read_all(BlockBackend *blk, void *buf, hwaddr size, Error **errp) { - int64_t blk_len; + int64_t blk_len, actual_len; int ret; blk_len = blk_getlength(blk); @@ -53,7 +53,9 @@ bool blk_check_size_and_read_all(BlockBackend *blk, void *buf, hwaddr size, * block device and read only on demand. */ assert(size <= BDRV_REQUEST_MAX_BYTES); - ret = blk_pread(blk, 0, buf, size); + actual_len = bdrv_get_allocated_file_size(blk_bs(blk)); + ret = blk_pread(blk, 0, buf, + (!blk_is_read_only(blk) || actual_len < 0) ? size : actual_len); if (ret < 0) { error_setg_errno(errp, -ret, "can't read block backend"); return false; -- 1.8.3.1 -- Thanks, Xiang