summaryrefslogtreecommitdiff
path: root/src/sim/syscall_emul.hh
diff options
context:
space:
mode:
authorRico Amslinger <rico.amslinger@informatik.uni-augsburg.de>2017-09-18 13:44:06 +0200
committerRico Amslinger <rico.amslinger@informatik.uni-augsburg.de>2017-09-28 07:55:18 +0000
commit1ff5e31e53cc1f6ae27285a456f380327dc09a0b (patch)
treea49ccb6d07ee53214b00da76881721e1bef17537 /src/sim/syscall_emul.hh
parent0b77e05cb21ad946f12b67cf3336ba92b2a1a522 (diff)
downloadgem5-1ff5e31e53cc1f6ae27285a456f380327dc09a0b.tar.xz
sim-se: Fix mremap for downward growing mmap regions
mremapFunc(...) did not respect Process::mmapGrowsDown(). This resulted in an attempt to remap into an already allocated region and a panic in FuncPageTable::allocate(...). This behavior can be observed in 435.gromacs. Change-Id: Ib3ad33816126c76506d69679bdcefa7a98ef69f9 Reviewed-on: https://gem5-review.googlesource.com/4700 Reviewed-by: Jason Lowe-Power <jason@lowepower.com> Maintainer: Brandon Potter <Brandon.Potter@amd.com>
Diffstat (limited to 'src/sim/syscall_emul.hh')
-rw-r--r--src/sim/syscall_emul.hh20
1 files changed, 15 insertions, 5 deletions
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index 7efd7c7e6..fa0959f0e 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -932,6 +932,8 @@ mremapFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc)
if ((start + old_length) == mmap_end &&
(!use_provided_address || provided_address == start)) {
+ // This case cannot occur when growing downward, as
+ // start is greater than or equal to mmap_end.
uint64_t diff = new_length - old_length;
process->allocateMem(mmap_end, diff);
mem_state->setMmapEnd(mmap_end + diff);
@@ -941,8 +943,15 @@ mremapFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc)
warn("can't remap here and MREMAP_MAYMOVE flag not set\n");
return -ENOMEM;
} else {
- uint64_t new_start = use_provided_address ?
- provided_address : mmap_end;
+ uint64_t new_start = provided_address;
+ if (!use_provided_address) {
+ new_start = process->mmapGrowsDown() ?
+ mmap_end - new_length : mmap_end;
+ mmap_end = process->mmapGrowsDown() ?
+ new_start : mmap_end + new_length;
+ mem_state->setMmapEnd(mmap_end);
+ }
+
process->pTable->remap(start, old_length, new_start);
warn("mremapping to new vaddr %08p-%08p, adding %d\n",
new_start, new_start + new_length,
@@ -951,10 +960,11 @@ mremapFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc)
process->allocateMem(new_start + old_length,
new_length - old_length,
use_provided_address /* clobber */);
- if (!use_provided_address)
- mem_state->setMmapEnd(mmap_end + new_length);
if (use_provided_address &&
- new_start + new_length > mem_state->getMmapEnd()) {
+ ((new_start + new_length > mem_state->getMmapEnd() &&
+ !process->mmapGrowsDown()) ||
+ (new_start < mem_state->getMmapEnd() &&
+ process->mmapGrowsDown()))) {
// something fishy going on here, at least notify the user
// @todo: increase mmap_end?
warn("mmap region limit exceeded with MREMAP_FIXED\n");