44 #include <sys/types.h> 56 #include "debug/AddrRanges.hh" 57 #include "debug/Checkpoint.hh" 66 #if defined(__APPLE__) || defined(__FreeBSD__) 68 #define MAP_NORESERVE 0 76 bool mmap_using_noreserve) :
77 _name(_name), size(0), mmapUsingNoReserve(mmap_using_noreserve)
79 if (mmap_using_noreserve)
80 warn(
"Not reserving swap space. May cause SIGSEGV on actual usage\n");
84 for (
const auto&
m : _memories) {
86 if (
m->isInAddrMap()) {
87 memories.push_back(
m);
94 fatal_if(addrMap.insert(
m->getAddrRange(),
m) == addrMap.end(),
95 "Memory address range for %s is overlapping\n",
102 "Skipping memory %s that is not in global address map\n",
106 fatal_if(
m->getAddrRange().interleaved(),
107 "Memory %s that is not in the global address map cannot " 108 "be interleaved\n",
m->name());
114 createBackingStore(
m->getAddrRange(), unmapped_mems,
115 m->isConfReported(),
m->isInAddrMap(),
125 for (
const auto&
r : addrMap) {
128 if (!
r.second->isNull()) {
130 if (
r.first.interleaved()) {
134 if (!intlv_ranges.empty() &&
135 !intlv_ranges.back().mergesWith(
r.first)) {
139 for (
const auto&
c : curr_memories)
143 fatal(
"Inconsistent flags in an interleaved " 146 createBackingStore(merged_range, curr_memories,
150 intlv_ranges.clear();
151 curr_memories.clear();
153 intlv_ranges.push_back(
r.first);
154 curr_memories.push_back(
r.second);
157 createBackingStore(
r.first, single_memory,
158 r.second->isConfReported(),
159 r.second->isInAddrMap(),
160 r.second->isKvmMap());
167 if (!intlv_ranges.empty()) {
171 for (
const auto&
c : curr_memories)
175 fatal(
"Inconsistent flags in an interleaved " 178 createBackingStore(merged_range, curr_memories,
187 bool conf_table_reported,
188 bool in_addr_map,
bool kvm_map)
191 "Cannot create backing store for interleaved range %s\n",
195 DPRINTF(AddrRanges,
"Creating backing store for range %s with size %d\n",
197 int map_flags = MAP_ANON | MAP_PRIVATE;
201 if (mmapUsingNoReserve) {
202 map_flags |= MAP_NORESERVE;
205 uint8_t* pmem = (uint8_t*) mmap(NULL, range.
size(),
206 PROT_READ | PROT_WRITE,
209 if (pmem == (uint8_t*) MAP_FAILED) {
211 fatal(
"Could not mmap %d bytes for range %s!\n", range.
size(),
217 backingStore.emplace_back(range, pmem,
218 conf_table_reported, in_addr_map, kvm_map);
221 for (
const auto&
m : _memories) {
222 DPRINTF(AddrRanges,
"Mapping memory %s to backing store\n",
224 m->setBackingStore(pmem);
231 for (
auto&
s : backingStore)
232 munmap((
char*)
s.pmem,
s.range.size());
238 return addrMap.contains(addr) != addrMap.end();
248 for (
const auto&
r : addrMap) {
249 if (
r.second->isConfReported()) {
251 if (
r.first.interleaved()) {
255 if (!intlv_ranges.empty() &&
256 !intlv_ranges.back().mergesWith(
r.first)) {
257 ranges.push_back(
AddrRange(intlv_ranges));
258 intlv_ranges.clear();
260 intlv_ranges.push_back(
r.first);
263 ranges.push_back(
r.first);
270 if (!intlv_ranges.empty()) {
271 ranges.push_back(
AddrRange(intlv_ranges));
282 assert(m != addrMap.end());
283 m->second->access(pkt);
291 assert(m != addrMap.end());
292 m->second->functionalAccess(pkt);
302 for (
auto&
m : memories) {
304 for (
const auto&
l : locked_addrs) {
305 lal_addr.push_back(
l.addr);
306 lal_cid.push_back(
l.contextId);
314 unsigned int nbr_of_stores = backingStore.size();
317 unsigned int store_id = 0;
319 for (
auto&
s : backingStore) {
321 serializeStore(cp, store_id++,
s.range,
s.pmem);
331 string filename =
name() +
".store" +
to_string(store_id) +
".pmem";
332 long range_size = range.
size();
334 DPRINTF(Checkpoint,
"Serializing physical memory %s with size %d\n",
335 filename, range_size);
343 gzFile compressed_mem = gzopen(filepath.c_str(),
"wb");
344 if (compressed_mem == NULL)
345 fatal(
"Can't open physical memory checkpoint file '%s'\n",
348 uint64_t pass_size = 0;
351 for (uint64_t written = 0; written < range.
size();
352 written += pass_size) {
353 pass_size = (uint64_t)INT_MAX < (range.
size() - written) ?
354 (uint64_t)INT_MAX : (range.
size() - written);
356 if (gzwrite(compressed_mem, pmem + written,
357 (
unsigned int) pass_size) != (int) pass_size) {
358 fatal(
"Write failed on physical memory checkpoint file '%s'\n",
365 if (gzclose(compressed_mem))
366 fatal(
"Close failed on physical memory checkpoint file '%s'\n",
380 for (
size_t i = 0;
i < lal_addr.size(); ++
i) {
381 const auto&
m = addrMap.contains(lal_addr[
i]);
382 m->second->addLockedAddr(
LockedAddr(lal_addr[i], lal_cid[i]));
386 unsigned int nbr_of_stores;
389 for (
unsigned int i = 0;
i < nbr_of_stores; ++
i) {
391 unserializeStore(cp);
399 const uint32_t chunk_size = 16384;
401 unsigned int store_id;
406 string filepath = cp.
cptDir +
"/" + filename;
409 gzFile compressed_mem = gzopen(filepath.c_str(),
"rb");
410 if (compressed_mem == NULL)
411 fatal(
"Can't open physical memory checkpoint file '%s'", filename);
414 uint8_t* pmem = backingStore[store_id].pmem;
415 AddrRange range = backingStore[store_id].range;
420 DPRINTF(Checkpoint,
"Unserializing physical memory %s with size %d\n",
421 filename, range_size);
423 if (range_size != range.
size())
424 fatal(
"Memory range size has changed! Saw %lld, expected %lld\n",
425 range_size, range.
size());
427 uint64_t curr_size = 0;
428 long* temp_page =
new long[chunk_size];
431 while (curr_size < range.
size()) {
432 bytes_read = gzread(compressed_mem, temp_page, chunk_size);
436 assert(bytes_read %
sizeof(
long) == 0);
438 for (uint32_t
x = 0;
x < bytes_read /
sizeof(long);
x++) {
441 if (*(temp_page +
x) != 0) {
442 pmem_current = (
long*)(pmem + curr_size +
x *
sizeof(
long));
443 *pmem_current = *(temp_page +
x);
446 curr_size += bytes_read;
451 if (gzclose(compressed_mem))
452 fatal(
"Close failed on physical memory checkpoint file '%s'\n",
void serialize(CheckpointOut &cp) const override
Serialize all the memories in the system.
#define fatal(...)
This implements a cprintf based fatal() function.
const std::string name() const
Locked address class that represents a physical address and a context id.
bool isConfReported() const
Should this memory be passed to the kernel and part of the OS physical memory layout.
Overload hash function for BasicBlockRange type.
std::unordered_map< int, std::stack< Addr > > locked_addrs
AbstractMemory declaration.
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
#define UNSERIALIZE_SCALAR(scalar)
#define SERIALIZE_CONTAINER(member)
std::string csprintf(const char *format, const Args &...args)
void createBackingStore(AddrRange range, const std::vector< AbstractMemory *> &_memories, bool conf_table_reported, bool in_addr_map, bool kvm_map)
Create the memory region providing the backing store for a given address range that corresponds to a ...
bool isMemAddr(Addr addr) const
Check if a physical address is within a range of a memory that is part of the global address map...
AddrRangeList getConfAddrRanges() const
Get the memory ranges for all memories that are to be reported to the configuration table...
AddrRange getAddrRange() const
Get address range to which this packet belongs.
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
#define UNSERIALIZE_CONTAINER(member)
PhysicalMemory(const PhysicalMemory &)
void unserialize(CheckpointIn &cp) override
Unserialize the memories in the system.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
void access(PacketPtr pkt)
Perform an untimed memory access and update all the state (e.g.
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
#define SERIALIZE_SCALAR(scalar)
void serializeStore(CheckpointOut &cp, unsigned int store_id, AddrRange range, uint8_t *pmem) const
Serialize a specific store.
~PhysicalMemory()
Unmap all the backing store we have used.
bool interleaved() const
Determine if the range is interleaved or not.
std::ostream CheckpointOut
void functionalAccess(PacketPtr pkt)
Perform an untimed memory read or write without changing anything but the memory itself.
An abstract memory represents a contiguous block of physical memory, with an associated address range...
bool isInAddrMap() const
Some memories are used as shadow memories or should for other reasons not be part of the global addre...
Addr size() const
Get the size of the address range.
bool isKvmMap() const
When shadow memories are in use, KVM may want to make one or the other, but cannot map both into the ...
void unserializeStore(CheckpointIn &cp)
Unserialize a specific backing store, identified by a section.
std::string to_string() const
Get a string representation of the range.
Scoped checkpoint section helper class.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
const std::string to_string(sc_enc enc)