changeset b0d7c64ada19 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=b0d7c64ada19
description:
syscall_emul: implement MAP_FIXED option to mmap()
diffstat:
src/arch/alpha/linux/linux.hh | 1 +
src/arch/alpha/tru64/tru64.hh | 1 +
src/arch/arm/linux/linux.hh | 1 +
src/arch/mips/linux/linux.hh | 1 +
src/arch/power/linux/linux.hh | 1 +
src/arch/sparc/linux/linux.hh | 1 +
src/arch/sparc/solaris/solaris.hh | 1 +
src/arch/x86/linux/linux.hh | 2 +
src/mem/page_table.cc | 26 +++++++++++++++-----
src/mem/page_table.hh | 10 +++++++-
src/sim/syscall_emul.hh | 47 +++++++++++++++++++++++++++++---------
11 files changed, 73 insertions(+), 19 deletions(-)
diffs (234 lines):
diff -r 30d0e4c249b5 -r b0d7c64ada19 src/arch/alpha/linux/linux.hh
--- a/src/arch/alpha/linux/linux.hh Sat Oct 22 16:52:07 2011 -0700
+++ b/src/arch/alpha/linux/linux.hh Sat Oct 22 22:30:07 2011 -0700
@@ -69,6 +69,7 @@
/// For mmap().
static const unsigned TGT_MAP_ANONYMOUS = 0x10;
+ static const unsigned TGT_MAP_FIXED = 0x100;
//@{
/// For getsysinfo().
diff -r 30d0e4c249b5 -r b0d7c64ada19 src/arch/alpha/tru64/tru64.hh
--- a/src/arch/alpha/tru64/tru64.hh Sat Oct 22 16:52:07 2011 -0700
+++ b/src/arch/alpha/tru64/tru64.hh Sat Oct 22 22:30:07 2011 -0700
@@ -64,6 +64,7 @@
/// For mmap().
static const unsigned TGT_MAP_ANONYMOUS = 0x10;
+ static const unsigned TGT_MAP_FIXED = 0x100;
//@{
/// For getsysinfo().
diff -r 30d0e4c249b5 -r b0d7c64ada19 src/arch/arm/linux/linux.hh
--- a/src/arch/arm/linux/linux.hh Sat Oct 22 16:52:07 2011 -0700
+++ b/src/arch/arm/linux/linux.hh Sat Oct 22 22:30:07 2011 -0700
@@ -91,6 +91,7 @@
/// For mmap().
static const unsigned TGT_MAP_ANONYMOUS = 0x20;
+ static const unsigned TGT_MAP_FIXED = 0x10;
//@{
/// For getrusage().
diff -r 30d0e4c249b5 -r b0d7c64ada19 src/arch/mips/linux/linux.hh
--- a/src/arch/mips/linux/linux.hh Sat Oct 22 16:52:07 2011 -0700
+++ b/src/arch/mips/linux/linux.hh Sat Oct 22 22:30:07 2011 -0700
@@ -65,6 +65,7 @@
/// For mmap().
static const unsigned TGT_MAP_ANONYMOUS = 0x800;
+ static const unsigned TGT_MAP_FIXED = 0x10;
//@{
/// For getsysinfo().
diff -r 30d0e4c249b5 -r b0d7c64ada19 src/arch/power/linux/linux.hh
--- a/src/arch/power/linux/linux.hh Sat Oct 22 16:52:07 2011 -0700
+++ b/src/arch/power/linux/linux.hh Sat Oct 22 22:30:07 2011 -0700
@@ -127,6 +127,7 @@
/// For mmap().
static const unsigned TGT_MAP_ANONYMOUS = 0x20;
+ static const unsigned TGT_MAP_FIXED = 0x10;
//@{
/// ioctl() command codes.
diff -r 30d0e4c249b5 -r b0d7c64ada19 src/arch/sparc/linux/linux.hh
--- a/src/arch/sparc/linux/linux.hh Sat Oct 22 16:52:07 2011 -0700
+++ b/src/arch/sparc/linux/linux.hh Sat Oct 22 22:30:07 2011 -0700
@@ -77,6 +77,7 @@
static const int NUM_OPEN_FLAGS;
static const unsigned TGT_MAP_ANONYMOUS = 0x20;
+ static const unsigned TGT_MAP_FIXED = 0x10;
typedef struct {
int64_t uptime; /* Seconds since boot */
diff -r 30d0e4c249b5 -r b0d7c64ada19 src/arch/sparc/solaris/solaris.hh
--- a/src/arch/sparc/solaris/solaris.hh Sat Oct 22 16:52:07 2011 -0700
+++ b/src/arch/sparc/solaris/solaris.hh Sat Oct 22 22:30:07 2011 -0700
@@ -59,6 +59,7 @@
static const int NUM_OPEN_FLAGS;
static const unsigned TGT_MAP_ANONYMOUS = 0x100;
+ static const unsigned TGT_MAP_FIXED = 0x10;
};
#endif
diff -r 30d0e4c249b5 -r b0d7c64ada19 src/arch/x86/linux/linux.hh
--- a/src/arch/x86/linux/linux.hh Sat Oct 22 16:52:07 2011 -0700
+++ b/src/arch/x86/linux/linux.hh Sat Oct 22 22:30:07 2011 -0700
@@ -88,6 +88,7 @@
static const int NUM_OPEN_FLAGS;
static const unsigned TGT_MAP_ANONYMOUS = 0x20;
+ static const unsigned TGT_MAP_FIXED = 0x10;
typedef struct {
uint64_t iov_base; // void *
@@ -158,6 +159,7 @@
static const int NUM_OPEN_FLAGS;
static const unsigned TGT_MAP_ANONYMOUS = 0x20;
+ static const unsigned TGT_MAP_FIXED = 0x10;
typedef struct {
int32_t uptime; /* Seconds since boot */
diff -r 30d0e4c249b5 -r b0d7c64ada19 src/mem/page_table.cc
--- a/src/mem/page_table.cc Sat Oct 22 16:52:07 2011 -0700
+++ b/src/mem/page_table.cc Sat Oct 22 22:30:07 2011 -0700
@@ -67,7 +67,7 @@
}
void
-PageTable::allocate(Addr vaddr, int64_t size)
+PageTable::allocate(Addr vaddr, int64_t size, bool clobber)
{
// starting address must be page aligned
assert(pageOffset(vaddr) == 0);
@@ -75,16 +75,13 @@
DPRINTF(MMU, "Allocating Page: %#x-%#x\n", vaddr, vaddr+ size);
for (; size > 0; size -= pageSize, vaddr += pageSize) {
- PTableItr iter = pTable.find(vaddr);
-
- if (iter != pTable.end()) {
+ if (!clobber && (pTable.find(vaddr) != pTable.end())) {
// already mapped
- fatal("PageTable::allocate: address 0x%x already mapped",
- vaddr);
+ fatal("PageTable::allocate: address 0x%x already mapped", vaddr);
}
pTable[vaddr] = TheISA::TlbEntry(process->M5_pid, vaddr,
- process->system->new_page());
+ process->system->new_page());
updateCache(vaddr, pTable[vaddr]);
}
}
@@ -128,6 +125,21 @@
}
bool
+PageTable::isUnmapped(Addr vaddr, int64_t size)
+{
+ // starting address must be page aligned
+ assert(pageOffset(vaddr) == 0);
+
+ for (; size > 0; size -= pageSize, vaddr += pageSize) {
+ if (pTable.find(vaddr) != pTable.end()) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool
PageTable::lookup(Addr vaddr, TheISA::TlbEntry &entry)
{
Addr page_addr = pageAlign(vaddr);
diff -r 30d0e4c249b5 -r b0d7c64ada19 src/mem/page_table.hh
--- a/src/mem/page_table.hh Sat Oct 22 16:52:07 2011 -0700
+++ b/src/mem/page_table.hh Sat Oct 22 22:30:07 2011 -0700
@@ -79,11 +79,19 @@
Addr pageAlign(Addr a) { return (a & ~offsetMask); }
Addr pageOffset(Addr a) { return (a & offsetMask); }
- void allocate(Addr vaddr, int64_t size);
+ void allocate(Addr vaddr, int64_t size, bool clobber = false);
void remap(Addr vaddr, int64_t size, Addr new_vaddr);
void deallocate(Addr vaddr, int64_t size);
/**
+ * Check if any pages in a region are already allocated
+ * @param vaddr The starting virtual address of the region.
+ * @param size The length of the region.
+ * @return True if no pages in the region are mapped.
+ */
+ bool isUnmapped(Addr vaddr, int64_t size);
+
+ /**
* Lookup function
* @param vaddr The virtual address.
* @return entry The page table entry corresponding to vaddr.
diff -r 30d0e4c249b5 -r b0d7c64ada19 src/sim/syscall_emul.hh
--- a/src/sim/syscall_emul.hh Sat Oct 22 16:52:07 2011 -0700
+++ b/src/sim/syscall_emul.hh Sat Oct 22 22:30:07 2011 -0700
@@ -1027,20 +1027,45 @@
return -EINVAL;
}
- if (start != 0) {
- warn("mmap: ignoring suggested map address 0x%x, using 0x%x",
- start, p->mmap_end);
+ // are we ok with clobbering existing mappings? only set this to
+ // true if the user has been warned.
+ bool clobber = false;
+
+ // try to use the caller-provided address if there is one
+ bool use_provided_address = (start != 0);
+
+ if (use_provided_address) {
+ // check to see if the desired address is already in use
+ if (!p->pTable->isUnmapped(start, length)) {
+ // there are existing mappings in the desired range
+ // whether we clobber them or not depends on whether the caller
+ // specified MAP_FIXED
+ if (flags & OS::TGT_MAP_FIXED) {
+ // MAP_FIXED specified: clobber existing mappings
+ warn("mmap: MAP_FIXED at 0x%x overwrites existing mappings\n",
+ start);
+ clobber = true;
+ } else {
+ // MAP_FIXED not specified: ignore suggested start address
+ warn("mmap: ignoring suggested map address 0x%x\n", start);
+ use_provided_address = false;
+ }
+ }
}
- // pick next address from our "mmap region"
- if (OS::mmapGrowsDown()) {
- start = p->mmap_end - length;
- p->mmap_end = start;
- } else {
- start = p->mmap_end;
- p->mmap_end += length;
+ if (!use_provided_address) {
+ // no address provided, or provided address unusable:
+ // pick next address from our "mmap region"
+ if (OS::mmapGrowsDown()) {
+ start = p->mmap_end - length;
+ p->mmap_end = start;
+ } else {
+ start = p->mmap_end;
+ p->mmap_end += length;
+ }
}
- p->pTable->allocate(start, length);
+
+ p->pTable->allocate(start, length, clobber);
return start;
}
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev