From: Matthew Poremba Date: Tue, 17 Mar 2020 20:47:44 +0000 (-0500) Subject: sim-se: Switch to new MemState API X-Git-Tag: v20.0.0.0~262 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5c2fb0c65204960bb743ec06197d8994da71c82b;p=gem5.git sim-se: Switch to new MemState API 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 Maintainer: Jason Lowe-Power Tested-by: kokoro --- diff --git a/src/arch/arm/process.cc b/src/arch/arm/process.cc index c672444f5..12003f8cf 100644 --- a/src/arch/arm/process.cc +++ b/src/arch/arm/process.cc @@ -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; diff --git a/src/arch/mips/process.cc b/src/arch/mips/process.cc index a610fbe96..3e7b378da 100644 --- a/src/arch/mips/process.cc +++ b/src/arch/mips/process.cc @@ -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; diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc index 5cb9823de..914c99f66 100644 --- a/src/arch/power/process.cc +++ b/src/arch/power/process.cc @@ -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; diff --git a/src/arch/riscv/process.cc b/src/arch/riscv/process.cc index 474ed6873..402683627 100644 --- a/src/arch/riscv/process.cc +++ b/src/arch/riscv/process.cc @@ -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); diff --git a/src/arch/riscv/tlb.cc b/src/arch/riscv/tlb.cc index 1bf557ae5..ac4eca750 100644 --- a/src/arch/riscv/tlb.cc +++ b/src/arch/riscv/tlb.cc @@ -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); } diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index dc68c01bf..419761380 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -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); diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index c55e9cbbc..8dfe2e96f 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -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; diff --git a/src/arch/x86/faults.cc b/src/arch/x86/faults.cc index cb11eac78..ca890c3a3 100644 --- a/src/arch/x86/faults.cc +++ b/src/arch/x86/faults.cc @@ -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) diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index b98bb876a..b298362e5 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -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; diff --git a/src/arch/x86/pseudo_inst.cc b/src/arch/x86/pseudo_inst.cc index 2cc67ddab..e8fcfd38c 100644 --- a/src/arch/x86/pseudo_inst.cc +++ b/src/arch/x86/pseudo_inst.cc @@ -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; diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 740b6bc96..46bab4815 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -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); } diff --git a/src/gpu-compute/compute_unit.cc b/src/gpu-compute/compute_unit.cc index 4cf7f41fd..59bc6a004 100644 --- a/src/gpu-compute/compute_unit.cc +++ b/src/gpu-compute/compute_unit.cc @@ -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); diff --git a/src/gpu-compute/gpu_tlb.cc b/src/gpu-compute/gpu_tlb.cc index 73194de29..12fb9aa7e 100644 --- a/src/gpu-compute/gpu_tlb.cc +++ b/src/gpu-compute/gpu_tlb.cc @@ -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); } diff --git a/src/mem/se_translating_port_proxy.cc b/src/mem/se_translating_port_proxy.cc index 8af628f3b..bc1153ef1 100644 --- a/src/mem/se_translating_port_proxy.cc +++ b/src/mem/se_translating_port_proxy.cc @@ -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; } diff --git a/src/sim/faults.cc b/src/sim/faults.cc index 6a6352996..c2ce9784e 100644 --- a/src/sim/faults.cc +++ b/src/sim/faults.cc @@ -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); diff --git a/src/sim/process.cc b/src/sim/process.cc index 8cd12b54a..36f413f0c 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -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 diff --git a/src/sim/process.hh b/src/sim/process.hh index 7c152ae64..350057e0f 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -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. diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index d3743a328..08432e179 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -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(); }