gem5 v24.0.0.0
Loading...
Searching...
No Matches
mem_state.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017-2020 Advanced Micro Devices, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include "sim/mem_state.hh"
30
31#include <cassert>
32
33#include "arch/generic/mmu.hh"
34#include "debug/Vma.hh"
36#include "sim/process.hh"
38#include "sim/system.hh"
39#include "sim/vma.hh"
40
41namespace gem5
42{
43
44MemState::MemState(Process *owner, Addr brk_point, Addr stack_base,
45 Addr max_stack_size, Addr next_thread_stack_base,
46 Addr mmap_end)
47 : _ownerProcess(owner),
48 _pageBytes(owner->pTable->pageSize()), _brkPoint(brk_point),
49 _stackBase(stack_base), _stackSize(max_stack_size),
50 _maxStackSize(max_stack_size), _stackMin(stack_base - max_stack_size),
51 _nextThreadStackBase(next_thread_stack_base),
52 _mmapEnd(mmap_end)
53{
54}
55
58{
59 if (this == &in)
60 return *this;
61
69 _mmapEnd = in._mmapEnd;
70 _vmaList = in._vmaList; /* This assignment does a deep copy. */
71
72 return *this;
73}
74
75void
77{
78 _ownerProcess = owner;
79}
80
81bool
82MemState::isUnmapped(Addr start_addr, Addr length)
83{
84 Addr end_addr = start_addr + length;
85 const AddrRange range(start_addr, end_addr);
86 for (const auto &vma : _vmaList) {
87 if (vma.intersects(range))
88 return false;
89 }
90
95 for (auto start = start_addr; start < end_addr;
96 start += _pageBytes) {
97 if (_ownerProcess->pTable->lookup(start) != nullptr) {
98 panic("Someone allocated physical memory at VA %p without "
99 "creating a VMA!\n", start);
100 return false;
101 }
102 }
103 return true;
104}
105
106void
108{
115 auto page_aligned_new_brk = roundUp(new_brk, _pageBytes);
116 auto page_aligned_old_brk = roundUp(old_brk, _pageBytes);
117
130 if (new_brk < old_brk) {
131 const auto length = page_aligned_old_brk - page_aligned_new_brk;
132 if (length > 0)
133 unmapRegion(page_aligned_new_brk, length);
134 _brkPoint = new_brk;
135 return;
136 }
137
147 if (page_aligned_new_brk > page_aligned_old_brk) {
148 auto length = page_aligned_new_brk - page_aligned_old_brk;
154 if (!isUnmapped(page_aligned_old_brk, length)) {
155 return;
156 }
157
165 mapRegion(page_aligned_old_brk, length, "heap");
166 }
167
168 _brkPoint = new_brk;
169}
170
171void
172MemState::mapRegion(Addr start_addr, Addr length,
173 const std::string& region_name, int sim_fd, Addr offset)
174{
175 DPRINTF(Vma, "memstate: creating vma (%s) [0x%x - 0x%x]\n",
176 region_name.c_str(), start_addr, start_addr + length);
177
182 assert(isUnmapped(start_addr, length));
183
187 _vmaList.emplace_back(AddrRange(start_addr, start_addr + length),
188 _pageBytes, region_name, sim_fd, offset);
189}
190
191void
192MemState::unmapRegion(Addr start_addr, Addr length)
193{
194 Addr end_addr = start_addr + length;
195 const AddrRange range(start_addr, end_addr);
196
197 auto vma = std::begin(_vmaList);
198 while (vma != std::end(_vmaList)) {
199 if (vma->isStrictSuperset(range)) {
200 DPRINTF(Vma, "memstate: split vma [0x%x - 0x%x] into "
201 "[0x%x - 0x%x] and [0x%x - 0x%x]\n",
202 vma->start(), vma->end(),
203 vma->start(), start_addr,
204 end_addr, vma->end());
209 _vmaList.push_back(*vma);
210 _vmaList.back().sliceRegionRight(start_addr);
211
215 vma->sliceRegionLeft(end_addr);
216
221 break;
222 } else if (vma->isSubset(range)) {
223 DPRINTF(Vma, "memstate: destroying vma [0x%x - 0x%x]\n",
224 vma->start(), vma->end());
228 vma = _vmaList.erase(vma);
229
230 continue;
231
232 } else if (vma->intersects(range)) {
236 if (vma->start() < start_addr) {
237 DPRINTF(Vma, "memstate: resizing vma [0x%x - 0x%x] "
238 "into [0x%x - 0x%x]\n",
239 vma->start(), vma->end(),
240 vma->start(), start_addr);
244 vma->sliceRegionRight(start_addr);
245 } else {
246 DPRINTF(Vma, "memstate: resizing vma [0x%x - 0x%x] "
247 "into [0x%x - 0x%x]\n",
248 vma->start(), vma->end(),
249 end_addr, vma->end());
253 vma->sliceRegionLeft(end_addr);
254 }
255 }
256
257 vma++;
258 }
259
268 for (auto *tc: _ownerProcess->system->threads) {
269 tc->getMMUPtr()->flushAll();
270 }
271
272 do {
273 if (!_ownerProcess->pTable->isUnmapped(start_addr, _pageBytes))
274 _ownerProcess->pTable->unmap(start_addr, _pageBytes);
275
276 start_addr += _pageBytes;
277
284 length -= _pageBytes;
285 } while (length > 0);
286}
287
288void
289MemState::remapRegion(Addr start_addr, Addr new_start_addr, Addr length)
290{
291 Addr end_addr = start_addr + length;
292 const AddrRange range(start_addr, end_addr);
293
294 auto vma = std::begin(_vmaList);
295 while (vma != std::end(_vmaList)) {
296 if (vma->isStrictSuperset(range)) {
300 _vmaList.push_back(*vma);
301 _vmaList.back().sliceRegionRight(start_addr);
302
306 _vmaList.push_back(*vma);
307 _vmaList.back().sliceRegionLeft(end_addr);
308
313 vma->sliceRegionLeft(start_addr);
314 vma->sliceRegionRight(end_addr);
315 vma->remap(new_start_addr);
316
321 break;
322 } else if (vma->isSubset(range)) {
326 vma->remap(vma->start() - start_addr + new_start_addr);
327 } else if (vma->intersects(range)) {
331 _vmaList.push_back(*vma);
332
333 if (vma->start() < start_addr) {
337 _vmaList.back().sliceRegionRight(start_addr);
338
342 vma->sliceRegionLeft(start_addr);
343 vma->remap(new_start_addr);
344 } else {
348 _vmaList.back().sliceRegionLeft(end_addr);
349
353 vma->sliceRegionRight(end_addr);
354 vma->remap(new_start_addr + vma->start() - start_addr);
355 }
356 }
357
358 vma++;
359 }
360
369 for (auto *tc: _ownerProcess->system->threads) {
370 tc->getMMUPtr()->flushAll();
371 }
372
373 do {
374 if (!_ownerProcess->pTable->isUnmapped(start_addr, _pageBytes))
375 _ownerProcess->pTable->remap(start_addr, _pageBytes,
376 new_start_addr);
377
378 start_addr += _pageBytes;
379 new_start_addr += _pageBytes;
380
387 length -= _pageBytes;
388 } while (length > 0);
389}
390
391bool
393{
398 for (const auto &vma : _vmaList) {
399 if (vma.contains(vaddr)) {
400 Addr vpage_start = roundDown(vaddr, _pageBytes);
401 _ownerProcess->allocateMem(vpage_start, _pageBytes);
402
409 if (vma.hasHostBuf()) {
414 for (auto &cid : _ownerProcess->contextIds) {
415 auto *tc = _ownerProcess->system->threads[cid];
417 virt_mem(tc, SETranslatingPortProxy::Always);
418 vma.fillMemPages(vpage_start, _pageBytes, virt_mem);
419 }
420 }
421 return true;
422 }
423 }
424
432 if (vaddr >= _stackMin && vaddr < _stackBase) {
434 return true;
435 }
436
442 while (vaddr < _stackMin) {
445 fatal("Maximum stack size exceeded\n");
446 }
448 inform("Increasing stack size by one page.");
449 }
450 return true;
451 }
452
453 return false;
454}
455
456Addr
458{
459 Addr start = _mmapEnd;
460
462 start = _mmapEnd - length;
463
464 // Look for a contiguous region of free virtual memory. We can't assume
465 // that the region beyond mmap_end is free because of fixed mappings from
466 // the user.
467 while (!isUnmapped(start, length)) {
468 DPRINTF(Vma, "memstate: cannot extend vma for mmap region at %p. "
469 "Virtual address range is already reserved! Skipping a page "
470 "and trying again!\n", start);
471 start = (_ownerProcess->mmapGrowsDown()) ? start - _pageBytes :
472 start + _pageBytes;
473 }
474
475 DPRINTF(Vma, "memstate: extending mmap region (old %p) (new %p)\n",
476 _mmapEnd,
477 _ownerProcess->mmapGrowsDown() ? start : start + length);
478
479 _mmapEnd = _ownerProcess->mmapGrowsDown() ? start : start + length;
480
481 return start;
482}
483
484std::string
486{
487 std::stringstream file_content;
488
489 for (auto vma : _vmaList) {
490 std::stringstream line;
491 line << std::hex << vma.start() << "-";
492 line << std::hex << vma.end() << " ";
493 line << "r-xp 00000000 00:00 0 ";
494 line << "[" << vma.getName() << "]" << std::endl;
495 file_content << line.str();
496 }
497
498 return file_content.str();
499}
500
501} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
Definition addr_range.hh:82
const Entry * lookup(Addr vaddr)
Lookup function.
virtual void remap(Addr vaddr, int64_t size, Addr new_vaddr)
Definition page_table.cc:75
virtual void unmap(Addr vaddr, int64_t size)
virtual bool isUnmapped(Addr vaddr, int64_t size)
Check if any pages in a region are already allocated.
This class holds the memory state for the Process class and all of its derived, architecture-specific...
Definition mem_state.hh:68
std::list< VMA > _vmaList
The _vmaList member is a list of virtual memory areas in the target application space that have been ...
Definition mem_state.hh:292
Process * _ownerProcess
Owner process of MemState.
Definition mem_state.hh:269
Addr extendMmap(Addr length)
Definition mem_state.cc:457
bool fixupFault(Addr vaddr)
Attempt to fix up a fault at vaddr by allocating a page.
Definition mem_state.cc:392
Addr _nextThreadStackBase
Definition mem_state.hh:277
void updateBrkRegion(Addr old_brk, Addr new_brk)
Change the end of a process' program break.
Definition mem_state.cc:107
std::string printVmaList()
Print the list of VMAs in a format similar to /proc/self/maps.
Definition mem_state.cc:485
bool isUnmapped(Addr start_addr, Addr length)
Check if any page in the virtual address range from start_addr to start_addr + length is already mapp...
Definition mem_state.cc:82
void resetOwner(Process *owner)
Change the Process owner in case this MemState is copied.
Definition mem_state.cc:76
MemState & operator=(const MemState &in)
Definition mem_state.cc:57
MemState(Process *owner, Addr brk_point, Addr stack_base, Addr max_stack_size, Addr next_thread_stack_base, Addr mmap_end)
Definition mem_state.cc:44
void unmapRegion(Addr start_addr, Addr length)
Unmap a pre-existing region.
Definition mem_state.cc:192
void remapRegion(Addr start_addr, Addr new_start_addr, Addr length)
Remap a pre-existing region.
Definition mem_state.cc:289
void mapRegion(Addr start_addr, Addr length, const std::string &name="anon", int sim_fd=-1, Addr offset=0)
Add a new memory region.
Definition mem_state.cc:172
virtual bool mmapGrowsDown() const
Does mmap region grow upward or downward from mmapEnd? Most platforms grow downward,...
Definition process.hh:146
void allocateMem(Addr vaddr, int64_t size, bool clobber=false)
Definition process.cc:317
std::vector< ContextID > contextIds
Definition process.hh:170
System * system
Definition process.hh:173
EmulationPageTable * pTable
Definition process.hh:184
Threads threads
Definition system.hh:310
static constexpr T roundDown(const T &val, const U &align)
This function is used to align addresses in memory.
Definition intmath.hh:279
static constexpr T roundUp(const T &val, const U &align)
This function is used to align addresses in memory.
Definition intmath.hh:260
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define fatal(...)
This implements a cprintf based fatal() function.
Definition logging.hh:200
#define inform(...)
Definition logging.hh:257
Bitfield< 23, 0 > offset
Definition types.hh:144
Bitfield< 7 > vma
Definition vector.hh:79
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147

Generated on Tue Jun 18 2024 16:24:06 for gem5 by doxygen 1.11.0