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 <e.gadzhiev.mhk@gmail.com>
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 <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
This commit is contained in:
Emin Gadzhiev
2022-12-02 02:18:44 +03:00
parent f7d0808a5c
commit f96513fd04
3 changed files with 24 additions and 2 deletions

View File

@@ -29,6 +29,9 @@
#ifndef SRC_SIM_MEM_STATE_HH #ifndef SRC_SIM_MEM_STATE_HH
#define SRC_SIM_MEM_STATE_HH #define SRC_SIM_MEM_STATE_HH
#include <fcntl.h>
#include <unistd.h>
#include <list> #include <list>
#include <memory> #include <memory>
#include <string> #include <string>
@@ -199,6 +202,9 @@ class MemState : public Serializable
for (auto vma : _vmaList) { for (auto vma : _vmaList) {
ScopedCheckpointSection sec(cp, csprintf("Vma%d", count++)); ScopedCheckpointSection sec(cp, csprintf("Vma%d", count++));
paramOut(cp, "name", vma.getName()); paramOut(cp, "name", vma.getName());
if (vma.hasHostBuf()) {
paramOut(cp, "fileOffset", vma.getFileMappingOffset());
}
paramOut(cp, "addrRangeStart", vma.start()); paramOut(cp, "addrRangeStart", vma.start());
paramOut(cp, "addrRangeEnd", vma.end()); paramOut(cp, "addrRangeEnd", vma.end());
} }
@@ -223,10 +229,20 @@ class MemState : public Serializable
std::string name; std::string name;
Addr start; Addr start;
Addr end; Addr end;
off_t offset = 0;
int host_fd = -1;
paramIn(cp, "name", name); 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, "addrRangeStart", start);
paramIn(cp, "addrRangeEnd", end); 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);
} }
} }

View File

@@ -120,7 +120,7 @@ VMA::sanityCheck()
VMA::MappedFileBuffer::MappedFileBuffer(int fd, size_t length, VMA::MappedFileBuffer::MappedFileBuffer(int fd, size_t length,
off_t offset) off_t offset)
: _buffer(nullptr), _length(length) : _buffer(nullptr), _length(length), _offset(offset)
{ {
panic_if(_length == 0, "Tried to mmap file of length zero"); panic_if(_length == 0, "Tried to mmap file of length zero");

View File

@@ -105,6 +105,10 @@ class VMA
void sliceRegionLeft(Addr slice_addr); void sliceRegionLeft(Addr slice_addr);
const std::string& getName() { return _vmaName; } const std::string& getName() { return _vmaName; }
off_t getFileMappingOffset() const
{
return hasHostBuf() ? _origHostBuf->getOffset() : 0;
}
/** /**
* Defer AddrRange related calls to the AddrRange. * Defer AddrRange related calls to the AddrRange.
@@ -191,10 +195,12 @@ class VMA
void *getBuffer() const { return _buffer; } void *getBuffer() const { return _buffer; }
uint64_t getLength() const { return _length; } uint64_t getLength() const { return _length; }
off_t getOffset() const { return _offset; }
private: private:
void *_buffer; // Host buffer ptr void *_buffer; // Host buffer ptr
size_t _length; // Length of host ptr size_t _length; // Length of host ptr
off_t _offset; // Offset in file at which mapping starts
}; };
}; };