sim-se: Switch to new MemState API
authorMatthew Poremba <matthew.poremba@amd.com>
Tue, 17 Mar 2020 20:47:44 +0000 (15:47 -0500)
committerMatthew Poremba <matthew.poremba@amd.com>
Wed, 25 Mar 2020 19:18:15 +0000 (19:18 +0000)
Switch over to the new MemState API by specifying memory regions for
stack in each ISA, changing brkFunc to use MemState for heap memory,
and calling the MemState fixup in fixupStackFault (renamed to just
fixupFault).

Change-Id: Ie3559a68ce476daedf1a3f28b168a8fbc7face5e
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/25366
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
18 files changed:
src/arch/arm/process.cc
src/arch/mips/process.cc
src/arch/power/process.cc
src/arch/riscv/process.cc
src/arch/riscv/tlb.cc
src/arch/sparc/faults.cc
src/arch/sparc/process.cc
src/arch/x86/faults.cc
src/arch/x86/process.cc
src/arch/x86/pseudo_inst.cc
src/arch/x86/tlb.cc
src/gpu-compute/compute_unit.cc
src/gpu-compute/gpu_tlb.cc
src/mem/se_translating_port_proxy.cc
src/sim/faults.cc
src/sim/process.cc
src/sim/process.hh
src/sim/syscall_emul.cc

index c672444f5c9523fa7ae422ac3003ceb1cf0d7a94..12003f8cfd7df7943649915a960316f1967e736b 100644 (file)
@@ -371,8 +371,8 @@ ArmProcess::argsInit(int pageSize, IntRegIndex spIndex)
     memState->setStackSize(memState->getStackBase() - memState->getStackMin());
 
     // map memory
-    allocateMem(roundDown(memState->getStackMin(), pageSize),
-                          roundUp(memState->getStackSize(), pageSize));
+    memState->mapRegion(roundDown(memState->getStackMin(), pageSize),
+                        roundUp(memState->getStackSize(), pageSize), "stack");
 
     // map out initial stack contents
     IntType sentry_base = memState->getStackBase() - sentry_size;
index a610fbe965b67449244ac176c862f76e99d03381..3e7b378da1a47c37ef5c3827708f466ad3e3653e 100644 (file)
@@ -151,8 +151,8 @@ MipsProcess::argsInit(int pageSize)
     memState->setStackMin(roundDown(memState->getStackMin(), pageSize));
     memState->setStackSize(memState->getStackBase() - memState->getStackMin());
     // map memory
-    allocateMem(memState->getStackMin(), roundUp(memState->getStackSize(),
-                pageSize));
+    memState->mapRegion(memState->getStackMin(),
+                        roundUp(memState->getStackSize(), pageSize), "stack");
 
     // map out initial stack contents; leave room for argc
     IntType argv_array_base = memState->getStackMin() + intSize;
index 5cb9823defdbef098c65f7f6060eafa2a6a2e2a2..914c99f6638e47c2311aebfede77da439bf72d25 100644 (file)
@@ -200,8 +200,8 @@ PowerProcess::argsInit(int intSize, int pageSize)
     memState->setStackSize(memState->getStackBase() - stack_min);
 
     // map memory
-    allocateMem(roundDown(stack_min, pageSize),
-                roundUp(memState->getStackSize(), pageSize));
+    memState->mapRegion(roundDown(stack_min, pageSize),
+                        roundUp(memState->getStackSize(), pageSize), "stack");
 
     // map out initial stack contents
     uint32_t sentry_base = memState->getStackBase() - sentry_size;
index 474ed68737ae39bc28711ef302e6181a1b7bc876..402683627da90f0b4092b3dd82cdc70dd4dd3d8a 100644 (file)
@@ -147,8 +147,8 @@ RiscvProcess::argsInit(int pageSize)
                    addrSize + 2 * sizeof(IntType) * auxv.size();
     stack_top &= -2*addrSize;
     memState->setStackSize(memState->getStackBase() - stack_top);
-    allocateMem(roundDown(stack_top, pageSize),
-            roundUp(memState->getStackSize(), pageSize));
+    memState->mapRegion(roundDown(stack_top, pageSize),
+                        roundUp(memState->getStackSize(), pageSize), "stack");
 
     // Copy random bytes (for AT_RANDOM) to stack
     memState->setStackMin(memState->getStackMin() - RandomBytes);
index 1bf557ae5999ea42173723d8da26133672dc9945..ac4eca750ed8becb4c2bdd95d5637b0c30a17bd8 100644 (file)
@@ -392,7 +392,7 @@ TLB::translateFunctional(const RequestPtr &req, ThreadContext *tc, Mode mode)
 
     if (!pte && mode != Execute) {
         // Check if we just need to grow the stack.
-        if (process->fixupStackFault(vaddr)) {
+        if (process->fixupFault(vaddr)) {
             // If we did, lookup the entry for the new page.
             pte = process->pTable->lookup(vaddr);
         }
index dc68c01bfa06a21692f12f97ce8853460d23585e..4197613803a6db0c0e5f88847df490a71206eecf 100644 (file)
@@ -683,7 +683,7 @@ FastDataAccessMMUMiss::invoke(ThreadContext *tc, const StaticInstPtr &inst)
 
     Process *p = tc->getProcessPtr();
     const EmulationPageTable::Entry *pte = p->pTable->lookup(vaddr);
-    if (!pte && p->fixupStackFault(vaddr))
+    if (!pte && p->fixupFault(vaddr))
         pte = p->pTable->lookup(vaddr);
     panic_if(!pte, "Tried to access unmapped address %#x.\n", vaddr);
 
index c55e9cbbc0ff7debb9b0bb76911febd20411e866..8dfe2e96fa5a57e40d9929b5862ecab96c477969 100644 (file)
@@ -317,8 +317,8 @@ SparcProcess::argsInit(int pageSize)
     memState->setStackSize(memState->getStackBase() - memState->getStackMin());
 
     // Allocate space for the stack
-    allocateMem(roundDown(memState->getStackMin(), pageSize),
-                roundUp(memState->getStackSize(), pageSize));
+    memState->mapRegion(roundDown(memState->getStackMin(), pageSize),
+                        roundUp(memState->getStackSize(), pageSize), "stack");
 
     // map out initial stack contents
     IntType sentry_base = memState->getStackBase() - sentry_size;
index cb11eac78a9761c2ef6bfb6c016c9244a29275db..ca890c3a38a3b8f3c513fa7cdefcc5159577e147 100644 (file)
@@ -47,6 +47,7 @@
 #include "cpu/thread_context.hh"
 #include "debug/Faults.hh"
 #include "sim/full_system.hh"
+#include "sim/process.hh"
 
 namespace X86ISA
 {
@@ -151,7 +152,7 @@ namespace X86ISA
             } else {
                 tc->setMiscReg(MISCREG_CR2, (uint32_t)addr);
             }
-        } else {
+        } else if (!tc->getProcessPtr()->fixupFault(addr)) {
             PageFaultErrorCode code = errorCode;
             const char *modeStr = "";
             if (code.fetch)
index b98bb876a78938479608ecae0f11862a059ebb71..b298362e56e73cdb8a92a8181945f818c8e271d7 100644 (file)
@@ -178,7 +178,7 @@ X86_64Process::initState()
     argsInit(PageBytes);
 
     // Set up the vsyscall page for this process.
-    allocateMem(vsyscallPage.base, vsyscallPage.size);
+    memState->mapRegion(vsyscallPage.base, vsyscallPage.size, "vsyscall");
     uint8_t vtimeBlob[] = {
         0x48,0xc7,0xc0,0xc9,0x00,0x00,0x00,    // mov    $0xc9,%rax
         0x0f,0x05,                             // syscall
@@ -629,7 +629,7 @@ I386Process::initState()
     }
 
     // Set up the vsyscall page for this process.
-    allocateMem(vsyscallPage.base, vsyscallPage.size);
+    memState->mapRegion(vsyscallPage.base, vsyscallPage.size, "vsyscall");
     uint8_t vsyscallBlob[] = {
         0x51,       // push %ecx
         0x52,       // push %edp
@@ -934,7 +934,7 @@ X86Process::argsInit(int pageSize,
     Addr stack_end = roundDown(stack_base - stack_size, pageSize);
 
     DPRINTF(Stack, "Mapping the stack: 0x%x %dB\n", stack_end, stack_size);
-    allocateMem(stack_end, stack_size);
+    memState->mapRegion(stack_end, stack_size, "stack");
 
     // map out initial stack contents
     IntType sentry_base = stack_base - sentry_size;
index 2cc67ddabbf22508b26b7cb6d800ce0f8bbaa2c4..e8fcfd38c944432445bee4854ed5ca1e43b86eff 100644 (file)
@@ -49,7 +49,7 @@ m5PageFault(ThreadContext *tc)
     DPRINTF(PseudoInst, "PseudoInst::m5PageFault()\n");
 
     Process *p = tc->getProcessPtr();
-    if (!p->fixupStackFault(tc->readMiscReg(MISCREG_CR2))) {
+    if (!p->fixupFault(tc->readMiscReg(MISCREG_CR2))) {
         PortProxy &proxy = tc->getVirtProxy();
         // at this point we should have 6 values on the interrupt stack
         int size = 6;
index 740b6bc9685c512144e5258cb108fe7a49c5e649..46bab4815db572b784aa19f3db77b3d1d6d620ae 100644 (file)
@@ -399,7 +399,7 @@ TLB::translate(const RequestPtr &req,
                         p->pTable->lookup(vaddr);
                     if (!pte && mode != Execute) {
                         // Check if we just need to grow the stack.
-                        if (p->fixupStackFault(vaddr)) {
+                        if (p->fixupFault(vaddr)) {
                             // If we did, lookup the entry for the new page.
                             pte = p->pTable->lookup(vaddr);
                         }
@@ -487,7 +487,7 @@ TLB::translateFunctional(const RequestPtr &req, ThreadContext *tc, Mode mode)
 
         if (!pte && mode != Execute) {
             // Check if we just need to grow the stack.
-            if (process->fixupStackFault(vaddr)) {
+            if (process->fixupFault(vaddr)) {
                 // If we did, lookup the entry for the new page.
                 pte = process->pTable->lookup(vaddr);
             }
index 4cf7f41fdda6b0a0bad0a693c0927fa1a6a79201..59bc6a0045060d0943c7a6518d6ca2c198467e37 100644 (file)
@@ -782,7 +782,7 @@ ComputeUnit::sendRequest(GPUDynInstPtr gpuDynInst, int index, PacketPtr pkt)
             Addr paddr;
 
             if (!p->pTable->translate(vaddr, paddr)) {
-                if (!p->fixupStackFault(vaddr)) {
+                if (!p->fixupFault(vaddr)) {
                     panic("CU%d: WF[%d][%d]: Fault on addr %#x!\n",
                           cu_id, gpuDynInst->simdId, gpuDynInst->wfSlotId,
                           vaddr);
index 73194de298f53e007f0764afa446ff948de55fa5..12fb9aa7e77dc9dc3efcaeb1f54cc04a1fe49d6f 100644 (file)
@@ -521,7 +521,7 @@ namespace X86ISA
                             if (timing)
                                 latency += missLatency2;
 
-                            if (p->fixupStackFault(vaddr))
+                            if (p->fixupFault(vaddr))
                                 pte = p->pTable->lookup(vaddr);
                         }
 
@@ -1044,7 +1044,7 @@ namespace X86ISA
     #endif
             const EmulationPageTable::Entry *pte = p->pTable->lookup(vaddr);
             if (!pte && sender_state->tlbMode != BaseTLB::Execute &&
-                    p->fixupStackFault(vaddr)) {
+                    p->fixupFault(vaddr)) {
                 pte = p->pTable->lookup(vaddr);
             }
 
@@ -1248,7 +1248,7 @@ namespace X86ISA
                 const EmulationPageTable::Entry *pte =
                         p->pTable->lookup(vaddr);
                 if (!pte && sender_state->tlbMode != BaseTLB::Execute &&
-                        p->fixupStackFault(vaddr)) {
+                        p->fixupFault(vaddr)) {
                     pte = p->pTable->lookup(vaddr);
                 }
 
index 8af628f3b9cc0f502728947cc36613ed0fda82a6..bc1153ef126d5634899be7c72f96bc8d5f919521 100644 (file)
@@ -57,7 +57,7 @@ SETranslatingPortProxy::fixupAddr(Addr addr, BaseTLB::Mode mode) const
         if (allocating == Always) {
             process->allocateMem(roundDown(addr, pageBytes), pageBytes);
             return true;
-        } else if (allocating == NextPage && process->fixupStackFault(addr)) {
+        } else if (allocating == NextPage && process->fixupFault(addr)) {
             // We've accessed the next page on the stack.
             return true;
         }
index 6a6352996993d51eacf65fbc79fee34fa0027085..c2ce9784ea9127c43032c9f2811ea6bc6217d347 100644 (file)
@@ -66,7 +66,7 @@ void GenericPageTableFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
     bool handled = false;
     if (!FullSystem) {
         Process *p = tc->getProcessPtr();
-        handled = p->fixupStackFault(vaddr);
+        handled = p->fixupFault(vaddr);
     }
     if (!handled)
         panic("Page table fault when accessing virtual address %#x\n", vaddr);
index 8cd12b54acc1f235043423b743d444b7ef7dd2dc..36f413f0c832fb769c5fa82cca0a8ce645e9a698 100644 (file)
@@ -352,33 +352,9 @@ Process::replicatePage(Addr vaddr, Addr new_paddr, ThreadContext *old_tc,
 }
 
 bool
-Process::fixupStackFault(Addr vaddr)
+Process::fixupFault(Addr vaddr)
 {
-    Addr stack_min = memState->getStackMin();
-    Addr stack_base = memState->getStackBase();
-    Addr max_stack_size = memState->getMaxStackSize();
-
-    // Check if this is already on the stack and there's just no page there
-    // yet.
-    if (vaddr >= stack_min && vaddr < stack_base) {
-        allocateMem(roundDown(vaddr, PageBytes), PageBytes);
-        return true;
-    }
-
-    // We've accessed the next page of the stack, so extend it to include
-    // this address.
-    if (vaddr < stack_min && vaddr >= stack_base - max_stack_size) {
-        while (vaddr < stack_min) {
-            stack_min -= TheISA::PageBytes;
-            if (stack_base - stack_min > max_stack_size)
-                fatal("Maximum stack size exceeded\n");
-            allocateMem(stack_min, TheISA::PageBytes);
-            inform("Increasing stack size by one page.");
-        }
-        memState->setStackMin(stack_min);
-        return true;
-    }
-    return false;
+    return memState->fixupFault(vaddr);
 }
 
 void
index 7c152ae6410d115e0f1ff8e37299f7086c734a57..350057e0f13b3bbaedfff85ec5f31a8f5644c27d 100644 (file)
@@ -108,7 +108,7 @@ class Process : public SimObject
 
     /// Attempt to fix up a fault at vaddr by allocating a page on the stack.
     /// @return Whether the fault has been fixed.
-    bool fixupStackFault(Addr vaddr);
+    bool fixupFault(Addr vaddr);
 
     // After getting registered with system object, tell process which
     // system-wide context id it is assigned.
index d3743a328583c408c0bc33d09017c0f445157f8a..08432e17903476cfc5a4ec4d3879cfea367fc12b 100644 (file)
@@ -254,39 +254,14 @@ brkFunc(SyscallDesc *desc, ThreadContext *tc, Addr new_brk)
 
     // in Linux at least, brk(0) returns the current break value
     // (note that the syscall and the glibc function have different behavior)
-    if (new_brk == 0)
+    if (new_brk == 0 || (new_brk == brk_point))
         return brk_point;
 
-    if (new_brk > brk_point) {
-        // might need to allocate some new pages
-        for (ChunkGenerator gen(brk_point,
-                                new_brk - brk_point,
-                                PageBytes); !gen.done(); gen.next()) {
-            if (!p->pTable->translate(gen.addr()))
-                p->allocateMem(roundDown(gen.addr(), PageBytes), PageBytes);
-
-            // if the address is already there, zero it out
-            else {
-                uint8_t zero = 0;
-                PortProxy &tp = tc->getVirtProxy();
-
-                // split non-page aligned accesses
-                Addr next_page = roundUp(gen.addr(), PageBytes);
-                uint32_t size_needed = next_page - gen.addr();
-                tp.memsetBlob(gen.addr(), zero, size_needed);
-                if (gen.addr() + PageBytes > next_page &&
-                    next_page < new_brk &&
-                    p->pTable->translate(next_page)) {
-                    size_needed = PageBytes - size_needed;
-                    tp.memsetBlob(next_page, zero, size_needed);
-                }
-            }
-        }
-    }
+    mem_state->updateBrkRegion(brk_point, new_brk);
 
-    mem_state->setBrkPoint(new_brk);
     DPRINTF_SYSCALL(Verbose, "brk: break point changed to: %#X\n",
                     mem_state->getBrkPoint());
+
     return mem_state->getBrkPoint();
 }