diff -r 5a93f63bbe04 -r 2c794c4e5b91 src/arch/alpha/faults.cc --- a/src/arch/alpha/faults.cc Thu Sep 08 03:30:17 2011 -0700 +++ b/src/arch/alpha/faults.cc Thu Sep 08 03:48:21 2011 -0700 @@ -201,8 +201,8 @@ TlbEntry entry; bool success = p->pTable->lookup(vaddr, entry); if (!success) { - p->checkAndAllocNextPage(vaddr); - success = p->pTable->lookup(vaddr, entry); + if (p->fixupStackFault(vaddr)) + success = p->pTable->lookup(vaddr, entry); } if (!success) { panic("Tried to access unmapped address %#x.\n", (Addr)vaddr); diff -r 5a93f63bbe04 -r 2c794c4e5b91 src/arch/sparc/faults.cc --- a/src/arch/sparc/faults.cc Thu Sep 08 03:30:17 2011 -0700 +++ b/src/arch/sparc/faults.cc Thu Sep 08 03:48:21 2011 -0700 @@ -643,8 +643,8 @@ TlbEntry entry; bool success = p->pTable->lookup(vaddr, entry); if (!success) { - p->checkAndAllocNextPage(vaddr); - success = p->pTable->lookup(vaddr, entry); + if (p->fixupStackFault(vaddr)) + success = p->pTable->lookup(vaddr, entry); } if (!success) { panic("Tried to access unmapped address %#x.\n", vaddr); diff -r 5a93f63bbe04 -r 2c794c4e5b91 src/arch/x86/tlb.cc --- a/src/arch/x86/tlb.cc Thu Sep 08 03:30:17 2011 -0700 +++ b/src/arch/x86/tlb.cc Thu Sep 08 03:48:21 2011 -0700 @@ -311,22 +311,11 @@ TlbEntry newEntry; bool success = p->pTable->lookup(vaddr, newEntry); if (!success && mode != Execute) { - // This may fail because for some reason the requested - // address is not allocatable on the stack. If it's a stack - // address, then it's because the address fell outside of - // max stack range and user should increase max size of - // stack. Otherwise, it could be a random address that was - // not in the page table and not on the stack. Either way, - // you'll end up with a page fault. - if (p->checkAndAllocNextPage(vaddr)) - // Might as well not check this if you failed to - // allocate. Partially nested this just so code - // maintainers can understand this is a separate and - // necessary step not sufficient just by reading return - // value of checkAndAlloc call because there is a side - // effect. This call will populate (it's called by - // reference). + // Check if we just need to grow the stack. + if (p->fixupStackFault(vaddr)) { + // If we did, lookup the entry for the new page. success = p->pTable->lookup(vaddr, newEntry); + } } if (!success) { return new PageFault(vaddr, true, mode, true, false); diff -r 5a93f63bbe04 -r 2c794c4e5b91 src/mem/translating_port.cc --- a/src/mem/translating_port.cc Thu Sep 08 03:30:17 2011 -0700 +++ b/src/mem/translating_port.cc Thu Sep 08 03:48:21 2011 -0700 @@ -90,7 +90,7 @@ VMPageSize); } else if (allocating == NextPage) { // check if we've accessed the next page on the stack - if (!process->checkAndAllocNextPage(gen.addr())) + if (!process->fixupStackFault(gen.addr())) panic("Page table fault when accessing virtual address %#x " "during functional write\n", gen.addr()); } else { diff -r 5a93f63bbe04 -r 2c794c4e5b91 src/sim/faults.cc --- a/src/sim/faults.cc Thu Sep 08 03:30:17 2011 -0700 +++ b/src/sim/faults.cc Thu Sep 08 03:48:21 2011 -0700 @@ -61,7 +61,7 @@ { Process *p = tc->getProcessPtr(); - if (!p->checkAndAllocNextPage(vaddr)) + if (!p->fixupStackFault(vaddr)) panic("Page table fault when accessing virtual address %#x\n", vaddr); } diff -r 5a93f63bbe04 -r 2c794c4e5b91 src/sim/process.hh --- a/src/sim/process.hh Thu Sep 08 03:30:17 2011 -0700 +++ b/src/sim/process.hh Thu Sep 08 03:48:21 2011 -0700 @@ -212,9 +212,9 @@ virtual void syscall(int64_t callnum, ThreadContext *tc) = 0; - // check if the this addr is on the next available page and allocate it - // if it's not we'll panic - bool checkAndAllocNextPage(Addr vaddr); + /// Attempt to fix up a fault at vaddr by allocating a page on the stack. + /// Returns if the fault should be fixed. + bool fixupStackFault(Addr vaddr); void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); diff -r 5a93f63bbe04 -r 2c794c4e5b91 src/sim/process.cc --- a/src/sim/process.cc Thu Sep 08 03:30:17 2011 -0700 +++ b/src/sim/process.cc Thu Sep 08 03:48:21 2011 -0700 @@ -329,29 +329,31 @@ } bool -Process::checkAndAllocNextPage(Addr vaddr) +Process::fixupStackFault(Addr vaddr) { - // if this is an initial write we might not have + // Check if this is already on the stack and there's just no page there + // yet. if (vaddr >= stack_min && vaddr < stack_base) { pTable->allocate(roundDown(vaddr, VMPageSize), VMPageSize); return true; } - // We've accessed the next page of the stack, so extend the stack - // to cover it. + // 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) + if (stack_base - stack_min > max_stack_size) fatal("Maximum stack size exceeded\n"); - if(stack_base - stack_min > 8*1024*1024) + if (stack_base - stack_min > 8 * 1024 * 1024) fatal("Over max stack size for one thread\n"); pTable->allocate(stack_min, TheISA::PageBytes); inform("Increasing stack size by one page."); }; return true; } - warn("Not increasing stack: requested vaddr is outside of stack range."); + warn("Not extending stack: address %#x isn't at the end of the stack.", + vaddr); return false; }