@@ -22,11 +22,11 @@ namespace tinykvm {
2222static constexpr bool VERBOSE_MMAP = false ;
2323
2424vMemory::vMemory (Machine& m, const MachineOptions& options,
25- uint64_t ph, uint64_t sf, char * p, size_t s, bool own)
25+ uint64_t ph, uint64_t sf, char * p, size_t s, int fd, bool own)
2626 : machine(m), physbase(ph), safebase(sf),
2727 // Over-allocate in order to avoid trouble with 2MB-aligned operations
28- ptr (p), size(overaligned_memsize(s)), owned(own),
29- has_snapshot_area (own && !options.snapshot_file.empty() ),
28+ ptr (p), size(overaligned_memsize(s)),
29+ owned (own), snapshot_fd(fd ),
3030 main_memory_writes(options.master_direct_memory_writes),
3131 split_hugepages(options.split_hugepages),
3232 executable_heap(options.executable_heap),
@@ -55,7 +55,7 @@ vMemory::vMemory(Machine& m, const MachineOptions& options,
5555 }
5656}
5757vMemory::vMemory (Machine& m, const MachineOptions& options, const vMemory& other)
58- : vMemory{m, options, other.physbase , other.safebase , other.ptr , other.size , false }
58+ : vMemory{m, options, other.physbase , other.safebase , other.ptr , other.size , - 1 , false }
5959{
6060 this ->executable_heap = other.executable_heap ;
6161 this ->mmap_physical_begin = other.mmap_physical_begin ;
@@ -379,7 +379,7 @@ vMemory::AllocationResult vMemory::allocate_mapped_memory(
379379 if (advice != 0x0 ) {
380380 madvise (ptr, size, advice);
381381 }
382- return AllocationResult{ptr, size};
382+ return AllocationResult{ptr, size, - 1 };
383383}
384384vMemory::AllocationResult
385385 vMemory::allocate_filebacked_memory (const MachineOptions& options, size_t size)
@@ -406,7 +406,10 @@ vMemory::AllocationResult
406406 close (fd);
407407 throw std::runtime_error (" Failed to stat VM snapshot file: " + filename);
408408 }
409- if (st.st_size != off_t (size)) {
409+ bool already_right_size = (st.st_size == off_t (size));
410+ char * ptr = (char *)MAP_FAILED;
411+ // If the file is not the correct size, resize it
412+ if (!already_right_size) {
410413 if (st.st_size != 0 ) {
411414 close (fd);
412415 throw std::runtime_error (" VM snapshot file has incorrect size: " + filename);
@@ -416,14 +419,18 @@ vMemory::AllocationResult
416419 close (fd);
417420 throw std::runtime_error (" Failed to set size of VM snapshot file: " + filename);
418421 }
422+ ptr = (char *) mmap (NULL , size, PROT_READ | PROT_WRITE,
423+ MAP_SHARED | MAP_NORESERVE, fd, 0 );
424+ } else {
425+ // Map an existing file, which should not be modified on disk
426+ ptr = (char *) mmap (NULL , size, PROT_READ | PROT_WRITE,
427+ MAP_PRIVATE | MAP_NORESERVE, fd, 0 );
419428 }
420- char * ptr = (char *) mmap (NULL , size, PROT_READ | PROT_WRITE,
421- MAP_SHARED | MAP_NORESERVE, fd, 0 );
422429 close (fd);
423430 if (ptr == MAP_FAILED) {
424431 memory_exception (" Failed to mmap VM snapshot file" , 0 , size);
425432 }
426- return AllocationResult{ptr, size - ColdStartStateSize ()};
433+ return AllocationResult{ptr, size - ColdStartStateSize (), fd };
427434}
428435
429436vMemory vMemory::New (Machine& m, const MachineOptions& options,
@@ -435,12 +442,12 @@ vMemory vMemory::New(Machine& m, const MachineOptions& options,
435442 size = vMemory::overaligned_memsize (size);
436443 // Use file-backed memory if requested
437444 if (!options.snapshot_file .empty ()) {
438- const auto [res_ptr, res_size] = allocate_filebacked_memory (options, size);
439- return vMemory (m, options, phys, safe, res_ptr, res_size);
445+ const auto [res_ptr, res_size, fd ] = allocate_filebacked_memory (options, size);
446+ return vMemory (m, options, phys, safe, res_ptr, res_size, fd );
440447 }
441448 // Normal 2MB main memory allocation
442- const auto [res_ptr, res_size] = allocate_mapped_memory (options, size);
443- return vMemory (m, options, phys, safe, res_ptr, res_size);
449+ const auto [res_ptr, res_size, fd ] = allocate_mapped_memory (options, size);
450+ return vMemory (m, options, phys, safe, res_ptr, res_size, - 1 );
444451}
445452
446453VirtualMem vMemory::vmem () const
0 commit comments