When memory page is converted from private to shared, the original private memory is back'ed by guest_memfd. Introduce ram_block_discard_guest_memfd_range() for discarding memory in guest_memfd. Originally-from: Isaku Yamahata <isaku.yamahata@xxxxxxxxx> Codeveloped-by: Xiaoyao Li <xiaoyao.li@xxxxxxxxx> Signed-off-by: Xiaoyao Li <xiaoyao.li@xxxxxxxxx> Reviewed-by: David Hildenbrand <david@xxxxxxxxxx> --- Changes in v5: - Collect Reviewed-by from David; Changes in in v4: - Drop ram_block_convert_range() and open code its implementation in the next Patch. --- include/exec/cpu-common.h | 2 ++ system/physmem.c | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h index 9ead1be10057..ccd46ad3e173 100644 --- a/include/exec/cpu-common.h +++ b/include/exec/cpu-common.h @@ -166,6 +166,8 @@ typedef int (RAMBlockIterFunc)(RAMBlock *rb, void *opaque); int qemu_ram_foreach_block(RAMBlockIterFunc func, void *opaque); int ram_block_discard_range(RAMBlock *rb, uint64_t start, size_t length); +int ram_block_discard_guest_memfd_range(RAMBlock *rb, uint64_t start, + size_t length); #endif diff --git a/system/physmem.c b/system/physmem.c index c4fc1e506de8..8c9368bc99ef 100644 --- a/system/physmem.c +++ b/system/physmem.c @@ -3618,6 +3618,29 @@ err: return ret; } +int ram_block_discard_guest_memfd_range(RAMBlock *rb, uint64_t start, + size_t length) +{ + int ret = -1; + +#ifdef CONFIG_FALLOCATE_PUNCH_HOLE + ret = fallocate(rb->guest_memfd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, + start, length); + + if (ret) { + ret = -errno; + error_report("%s: Failed to fallocate %s:%" PRIx64 " +%zx (%d)", + __func__, rb->idstr, start, length, ret); + } +#else + ret = -ENOSYS; + error_report("%s: fallocate not available %s:%" PRIx64 " +%zx (%d)", + __func__, rb->idstr, start, length, ret); +#endif + + return ret; +} + bool ramblock_is_pmem(RAMBlock *rb) { return rb->flags & RAM_PMEM; -- 2.34.1