add syscall emulation page table fault so we can allocate more stack pages
authorAli Saidi <saidi@eecs.umich.edu>
Mon, 26 Jun 2006 20:49:05 +0000 (16:49 -0400)
committerAli Saidi <saidi@eecs.umich.edu>
Mon, 26 Jun 2006 20:49:05 +0000 (16:49 -0400)
src/cpu/simple/base.cc:
    add syscall emulation page table fault so we can allocate more stack pages
    FaultBase::invoke will do this, we don't need to do it here
src/sim/faults.hh:
    I have no idea why this #if was there... gone
src/sim/process.cc:
    make stack_min actually be the current minimum

--HG--
extra : convert_revision : 9786b39f2747b94654a5d77c74243cd20503add4

src/arch/alpha/faults.cc
src/arch/alpha/faults.hh
src/arch/mips/faults.cc
src/arch/mips/faults.hh
src/arch/sparc/faults.cc
src/arch/sparc/faults.hh
src/cpu/simple/base.cc
src/mem/page_table.cc
src/sim/faults.hh
src/sim/process.cc

index 8493223ffb242efba0c50e0aec2918a10de58b23..06765768a17cd13d81381d9be1fa675d449bb2cb 100644 (file)
@@ -35,6 +35,9 @@
 #include "base/trace.hh"
 #if FULL_SYSTEM
 #include "arch/alpha/ev5.hh"
+#else
+#include "sim/process.hh"
+#include "mem/page_table.hh"
 #endif
 
 namespace AlphaISA
@@ -56,6 +59,12 @@ FaultName ArithmeticFault::_name = "arith";
 FaultVect ArithmeticFault::_vect = 0x0501;
 FaultStat ArithmeticFault::_count;
 
+#if !FULL_SYSTEM
+FaultName PageTableFault::_name = "page_table_fault";
+FaultVect PageTableFault::_vect = 0x0000;
+FaultStat PageTableFault::_count;
+#endif
+
 FaultName InterruptFault::_name = "interrupt";
 FaultVect InterruptFault::_vect = 0x0101;
 FaultStat InterruptFault::_count;
@@ -173,6 +182,28 @@ void ItbFault::invoke(ThreadContext * tc)
     AlphaFault::invoke(tc);
 }
 
+#else //!FULL_SYSTEM
+
+void PageTableFault::invoke(ThreadContext *tc)
+{
+    Process *p = tc->getProcessPtr();
+
+    // address is higher than the stack region or in the current stack region
+    if (vaddr > p->stack_base || vaddr > p->stack_min)
+        FaultBase::invoke(tc);
+
+    // We've accessed the next page
+    if (vaddr > p->stack_min - PageBytes) {
+        p->stack_min -= PageBytes;
+        if (p->stack_base - p->stack_min > 8*1024*1024)
+            fatal("Over max stack size for one thread\n");
+        p->pTable->allocate(p->stack_min, PageBytes);
+        warn("Increasing stack size by one page.");
+    } else {
+        FaultBase::invoke(tc);
+    }
+}
+
 #endif
 
 } // namespace AlphaISA
index f952cf9d69c7cad436a0a01f77ffeaf7c339917e..11a56817424f19d4ab415a908d8c4024331da768 100644 (file)
@@ -81,6 +81,29 @@ class AlignmentFault : public AlphaFault
     bool isAlignmentFault() {return true;}
 };
 
+#if !FULL_SYSTEM
+class PageTableFault : public AlphaFault
+{
+  private:
+    Addr vaddr;
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    PageTableFault(Addr va)
+        : vaddr(va) {}
+    FaultName name() {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+    void invoke(ThreadContext * tc);
+};
+
+static inline Fault genPageTableFault(Addr va)
+{
+    return new PageTableFault(va);
+}
+#endif
+
 static inline Fault genMachineCheckFault()
 {
     return new MachineCheckFault;
index 810c3fed4ce373579d0cc196708c7767bafb17cf..cfeb045ebb56380f09dcd8a7f887ae03f2ba8580 100644 (file)
 #include "cpu/thread_context.hh"
 #include "cpu/base.hh"
 #include "base/trace.hh"
+#if !FULL_SYSTEM
+#include "sim/process.hh"
+#include "mem/page_table.hh"
+#endif
 
 namespace MipsISA
 {
@@ -52,6 +56,12 @@ FaultName ArithmeticFault::_name = "arith";
 FaultVect ArithmeticFault::_vect = 0x0501;
 FaultStat ArithmeticFault::_count;
 
+#if !FULL_SYSTEM
+FaultName PageTableFault::_name = "page_table_fault";
+FaultVect PageTableFault::_vect = 0x0000;
+FaultStat PageTableFault::_count;
+#endif
+
 FaultName InterruptFault::_name = "interrupt";
 FaultVect InterruptFault::_vect = 0x0101;
 FaultStat InterruptFault::_count;
@@ -127,7 +137,28 @@ void ArithmeticFault::invoke(ThreadContext * tc)
     panic("Arithmetic traps are unimplemented!");
 }
 
-#endif
+#else //!FULL_SYSTEM
 
+void PageTableFault::invoke(ThreadContext *tc)
+{
+    Process *p = tc->getProcessPtr();
+
+    // address is higher than the stack region or in the current stack region
+    if (vaddr > p->stack_base || vaddr > p->stack_min)
+        FaultBase::invoke(tc);
+
+    // We've accessed the next page
+    if (vaddr > p->stack_min - PageBytes) {
+        p->stack_min -= PageBytes;
+        if (p->stack_base - p->stack_min > 8*1024*1024)
+            fatal("Over max stack size for one thread\n");
+        p->pTable->allocate(p->stack_min, PageBytes);
+        warn("Increasing stack size by one page.");
+    } else {
+        FaultBase::invoke(tc);
+    }
+}
+
+#endif
 } // namespace MipsISA
 
index d8bf59cc1f67b766a8ed1d0b5ab77abadfd9309a..95c61cfbcb73eef1485c073ada52763c7c28b8b9 100644 (file)
@@ -79,6 +79,30 @@ class AlignmentFault : public MipsFault
     bool isAlignmentFault() {return true;}
 };
 
+#if !FULL_SYSTEM
+class PageTableFault : public MipsFault
+{
+  private:
+    Addr vaddr;
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    PageTableFault(Addr va)
+        : vaddr(va) {}
+    FaultName name() {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+    void invoke(ThreadContext * tc);
+};
+
+static inline Fault genPageTableFault(Addr va)
+{
+    return new PageTableFault(va);
+}
+#endif
+
+
 static inline Fault genMachineCheckFault()
 {
     return new MachineCheckFault;
index 2af242bd8a820d72fd75ed6654482363656d0d84..7b7765935a27a5705ff153672d191929ebd3be2e 100644 (file)
 #include "cpu/thread_context.hh"
 #include "cpu/base.hh"
 #include "base/trace.hh"
+#if !FULL_SYSTEM
+#include "sim/process.hh"
+#include "mem/page_table.hh"
+#endif
 
 namespace SparcISA
 {
@@ -218,6 +222,13 @@ TrapType      TrapInstruction::_baseTrapType = 0x100;
 FaultPriority TrapInstruction::_priority = 16;
 FaultStat     TrapInstruction::_count;
 
+#if !FULL_SYSTEM
+FaultName PageTableFault::_name = "page_table_fault";
+TrapType PageTableFault::_trapType = 0x0000;
+FaultPriority PageTableFault::_priority = 0;
+FaultStat PageTableFault::_count;
+#endif
+
 #if FULL_SYSTEM
 
 void SparcFault::invoke(ThreadContext * tc)
@@ -252,6 +263,25 @@ void TrapInstruction::invoke(ThreadContext * tc)
     // Should be handled in ISA.
 }
 
+void PageTableFault::invoke(ThreadContext *tc)
+{
+    Process *p = tc->getProcessPtr();
+
+    // address is higher than the stack region or in the current stack region
+    if (vaddr > p->stack_base || vaddr > p->stack_min)
+        FaultBase::invoke(tc);
+
+    // We've accessed the next page
+    if (vaddr > p->stack_min - PageBytes) {
+        p->stack_min -= PageBytes;
+        if (p->stack_base - p->stack_min > 8*1024*1024)
+            fatal("Over max stack size for one thread\n");
+        p->pTable->allocate(p->stack_min, PageBytes);
+        warn("Increasing stack size by one page.");
+    } else {
+        FaultBase::invoke(tc);
+    }
+}
 #endif
 
 } // namespace SparcISA
index 9f595a28b701295177ba8904f4c5e2212c3823a1..b279f4911bf2a090ce8f85368771067178470c5f 100644 (file)
@@ -83,6 +83,31 @@ class MemAddressNotAligned : public SparcFault
     bool isAlignmentFault() {return true;}
 };
 
+#if !FULL_SYSTEM
+class PageTableFault : public SparcFault
+{
+  private:
+    Addr vaddr;
+    static FaultName _name;
+    static TrapType _trapType;
+    static FaultPriority _priority;
+    static FaultStat _count;
+  public:
+    PageTableFault(Addr va)
+        : vaddr(va) {}
+    FaultName name() {return _name;}
+    TrapType trapType() {return _trapType;}
+    FaultPriority priority() {return _priority;}
+    FaultStat & countStat() {return _count;}
+    void invoke(ThreadContext * tc);
+};
+
+static inline Fault genPageTableFault(Addr va)
+{
+    return new PageTableFault(va);
+}
+#endif
+
 static inline Fault genMachineCheckFault()
 {
     return new InternalProcessorError;
@@ -589,6 +614,7 @@ class TrapInstruction : public EnumeratedFault
 #endif
 };
 
+
 } // SparcISA namespace
 
 #endif // __FAULTS_HH__
index b4258fce68573bbe318132c3564a0db2de4b5621..db5dd2acf5fb823a8e62acc67cf866913d8c2ea7 100644 (file)
@@ -446,11 +446,7 @@ void
 BaseSimpleCPU::advancePC(Fault fault)
 {
     if (fault != NoFault) {
-#if FULL_SYSTEM
         fault->invoke(tc);
-#else // !FULL_SYSTEM
-        fatal("fault (%s) detected @ PC %08p", fault->name(), thread->readPC());
-#endif // FULL_SYSTEM
     }
     else {
         // go to the next instruction
index b5cecc7da9e9a2c17bea5df8a3468f4f004616e0..7daf319002137333bc9aa8c02f6bb3c16fdda28b 100644 (file)
@@ -130,7 +130,7 @@ PageTable::translate(RequestPtr &req)
     assert(pageAlign(req->getVaddr() + req->getSize() - 1)
            == pageAlign(req->getVaddr()));
     if (!translate(req->getVaddr(), paddr)) {
-        return genMachineCheckFault();
+        return genPageTableFault(req->getVaddr());
     }
     req->setPaddr(paddr);
     return page_check(req->getPaddr(), req->getSize());
index 23385c649a9a8e6093bf27e6a03221f76c9c2701..00264d8fc64b8fca78e11d6422d200c1a7383ce4 100644 (file)
@@ -54,11 +54,7 @@ class FaultBase : public RefCounted
 {
   public:
     virtual FaultName name() = 0;
-#if FULL_SYSTEM
     virtual void invoke(ThreadContext * tc);
-#else
-    virtual void invoke(ThreadContext * tc);
-#endif
 //    template<typename T>
 //    bool isA() {return dynamic_cast<T *>(this);}
     virtual bool isMachineCheckFault() {return false;}
index 5080c3ac1ac5b3a09d959a839811f11b2bbe6c3d..9cdc5b9f5dd04bdd614f2b6b5b5e90800b642dc5 100644 (file)
@@ -326,11 +326,10 @@ LiveProcess::argsInit(int intSize, int pageSize)
     // set bottom of stack
     stack_min = stack_base - space_needed;
     // align it
-    stack_min &= ~(intSize-1);
+    stack_min = roundDown(stack_min, pageSize);
     stack_size = stack_base - stack_min;
     // map memory
-    pTable->allocate(roundDown(stack_min, pageSize),
-                     roundUp(stack_size, pageSize));
+    pTable->allocate(stack_min, roundUp(stack_size, pageSize));
 
     // map out initial stack contents
     Addr argv_array_base = stack_min + intSize; // room for argc