From f96513fd042c3a1843eb4a3131d08b0fe0aa947f Mon Sep 17 00:00:00 2001 From: Emin Gadzhiev Date: Fri, 2 Dec 2022 02:18:44 +0300 Subject: [PATCH] sim,sim-se: Fix restoring of VMAs of memory-mapped files This patch fixes a problem that occurs when restoring from a checkpoint where Mapped File Buffers are not restored. This causes errors and unexpected behavior during further execution. Since the checkpoint already has the size of the area (address range) and the file name, only the offset is missing to restore the Mapped File Buffer. Having the offset value, it's possible to open those files for which an offset is specified and create a VMA with a Mapped File Buffer. Change-Id: Ib9dfa174cda6348b966b892184c36daeaba80e81 Signed-off-by: Emin Gadzhiev Issue-On: https://gem5.atlassian.net/browse/GEM5-1302 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/66311 Reviewed-by: Jason Lowe-Power Tested-by: kokoro Maintainer: Jason Lowe-Power --- src/sim/mem_state.hh | 18 +++++++++++++++++- src/sim/vma.cc | 2 +- src/sim/vma.hh | 6 ++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/sim/mem_state.hh b/src/sim/mem_state.hh index 05f2239f96..b2b50d0760 100644 --- a/src/sim/mem_state.hh +++ b/src/sim/mem_state.hh @@ -29,6 +29,9 @@ #ifndef SRC_SIM_MEM_STATE_HH #define SRC_SIM_MEM_STATE_HH +#include +#include + #include #include #include @@ -199,6 +202,9 @@ class MemState : public Serializable for (auto vma : _vmaList) { ScopedCheckpointSection sec(cp, csprintf("Vma%d", count++)); paramOut(cp, "name", vma.getName()); + if (vma.hasHostBuf()) { + paramOut(cp, "fileOffset", vma.getFileMappingOffset()); + } paramOut(cp, "addrRangeStart", vma.start()); paramOut(cp, "addrRangeEnd", vma.end()); } @@ -223,10 +229,20 @@ class MemState : public Serializable std::string name; Addr start; Addr end; + off_t offset = 0; + int host_fd = -1; paramIn(cp, "name", name); + if (optParamIn(cp, "fileOffset", offset, false)) { + host_fd = open(name.c_str(), O_RDONLY); + fatal_if(host_fd < 0, + "Failed to open %s file " + "while unserializing file-backed VMA\n", name); + } paramIn(cp, "addrRangeStart", start); paramIn(cp, "addrRangeEnd", end); - _vmaList.emplace_back(AddrRange(start, end), _pageBytes, name); + _vmaList.emplace_back(AddrRange(start, end), _pageBytes, name, + host_fd, offset); + close(host_fd); } } diff --git a/src/sim/vma.cc b/src/sim/vma.cc index 7e5ed1c491..ff5a4fe3cc 100644 --- a/src/sim/vma.cc +++ b/src/sim/vma.cc @@ -120,7 +120,7 @@ VMA::sanityCheck() VMA::MappedFileBuffer::MappedFileBuffer(int fd, size_t length, off_t offset) - : _buffer(nullptr), _length(length) + : _buffer(nullptr), _length(length), _offset(offset) { panic_if(_length == 0, "Tried to mmap file of length zero"); diff --git a/src/sim/vma.hh b/src/sim/vma.hh index b238a2e416..8f2a77f36c 100644 --- a/src/sim/vma.hh +++ b/src/sim/vma.hh @@ -105,6 +105,10 @@ class VMA void sliceRegionLeft(Addr slice_addr); const std::string& getName() { return _vmaName; } + off_t getFileMappingOffset() const + { + return hasHostBuf() ? _origHostBuf->getOffset() : 0; + } /** * Defer AddrRange related calls to the AddrRange. @@ -191,10 +195,12 @@ class VMA void *getBuffer() const { return _buffer; } uint64_t getLength() const { return _length; } + off_t getOffset() const { return _offset; } private: void *_buffer; // Host buffer ptr size_t _length; // Length of host ptr + off_t _offset; // Offset in file at which mapping starts }; };