sim-se: Enhance clone for X86KvmCPU
authorAlexandru Dutu <alexandru.dutu@amd.com>
Tue, 16 Apr 2019 03:36:36 +0000 (23:36 -0400)
committerAlexandru Duțu <alexandru.dutu@amd.com>
Mon, 22 Apr 2019 23:11:31 +0000 (23:11 +0000)
This changeset enables clone to work with X86KvmCPU model, which
will allow running multi-threaded applications at near hardware
speeds. Even though the application is multi-threaded, the KvmCPU
model uses one event queue, therefore, only one hardware thread
will be used, through KVM, to simulate multiple application threads.

Change-Id: I2b2a7b1edb1c56eeb9c4fa0553cd236029cd53f8
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/18268
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Maintainer: Jason Lowe-Power <jason@lowepower.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/arch/x86/process.cc
src/mem/multi_level_page_table.hh
src/mem/page_table.hh
src/sim/process.cc
src/sim/process.hh
src/sim/syscall_emul.hh

index 04bc0ddc81403032ee6847d699834d9f72f8bfcc..9e34a7b5dab3c1bbc9150db892cbcf74df4ecefb 100644 (file)
@@ -165,6 +165,9 @@ I386Process::I386Process(ProcessParams *params, ObjectFile *objFile,
                          SyscallDesc *_syscallDescs, int _numSyscallDescs)
     : X86Process(params, objFile, _syscallDescs, _numSyscallDescs)
 {
+    if (kvmInSE)
+        panic("KVM CPU model does not support 32 bit processes");
+
     _gdtStart = ULL(0xffffd000);
     _gdtSize = PageBytes;
 
@@ -197,6 +200,9 @@ X86_64Process::initState()
 {
     X86Process::initState();
 
+    if (useForClone)
+        return;
+
     argsInit(PageBytes);
 
     // Set up the vsyscall page for this process.
index bd40d37c105f25f13627964de0c758dd64b1085d..f517eafe8c10df67670f4334f0683c22cfb8f557 100644 (file)
@@ -204,6 +204,9 @@ public:
     void
     initState(ThreadContext* tc) override
     {
+        if (shared)
+            return;
+
         _basePtr = prepTopTable<EntryTypes...>(system, pageSize);
     }
 
index 447d3a50f94d37bb074f7a5e9d4491d0511c80c2..03e18c2d0645558c7cd616fae9b79fb2ce867d54 100644 (file)
@@ -75,7 +75,7 @@ class EmulationPageTable : public Serializable
     EmulationPageTable(
             const std::string &__name, uint64_t _pid, Addr _pageSize) :
             pageSize(_pageSize), offsetMask(mask(floorLog2(_pageSize))),
-            _pid(_pid), _name(__name)
+            _pid(_pid), _name(__name), shared(false)
     {
         assert(isPowerOf2(pageSize));
     }
@@ -96,6 +96,9 @@ class EmulationPageTable : public Serializable
         ReadOnly    = 8,
     };
 
+    // flag which marks the page table as shared among software threads
+    bool shared;
+
     virtual void initState(ThreadContext* tc) {};
 
     // for DPRINTF compatibility
index c4dd641079151d0ef5021292fd667ecb4c6bf4c6..5cec2958edaeb729e9805de2df9b6ba11f06deee 100644 (file)
@@ -106,6 +106,7 @@ Process::Process(ProcessParams *params, EmulationPageTable *pTable,
     : SimObject(params), system(params->system),
       useArchPT(params->useArchPT),
       kvmInSE(params->kvmInSE),
+      useForClone(false),
       pTable(pTable),
       initVirtMem(system->getSystemPort(), this,
                   SETranslatingPortProxy::Always),
index c690e825e458d6a10c0a386cbdc34ec965a3faf3..a1ca84bf555d8e47956786b1ef05ea24d4db4fd8 100644 (file)
@@ -172,8 +172,12 @@ class Process : public SimObject
 
     Stats::Scalar numSyscalls;  // track how many system calls are executed
 
-    bool useArchPT; // flag for using architecture specific page table
-    bool kvmInSE;   // running KVM requires special initialization
+    // flag for using architecture specific page table
+    bool useArchPT;
+    // running KVM requires special initialization
+    bool kvmInSE;
+    // flag for using the process as a thread which shares page tables
+    bool useForClone;
 
     EmulationPageTable *pTable;
 
index 0378bd7704b9dc472ab8fd594ac55099942b4c05..87c16c4896caa45858dd8a2fb27b7084a2f6f231 100644 (file)
@@ -1551,6 +1551,8 @@ cloneFunc(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc)
 
     pp->pid = temp_pid;
     pp->ppid = (flags & OS::TGT_CLONE_THREAD) ? p->ppid() : p->pid();
+    pp->useArchPT = p->useArchPT;
+    pp->kvmInSE = p->kvmInSE;
     Process *cp = pp->create();
     delete pp;
 
@@ -1566,6 +1568,10 @@ cloneFunc(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc)
         ptidBuf.copyOut(tc->getMemProxy());
     }
 
+    if (flags & OS::TGT_CLONE_THREAD) {
+        cp->pTable->shared = true;
+        cp->useForClone = true;
+    }
     cp->initState();
     p->clone(tc, ctc, cp, flags);
 
@@ -1599,9 +1605,17 @@ cloneFunc(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc)
     ctc->setIntReg(TheISA::SyscallPseudoReturnReg, 1);
 #endif
 
-    TheISA::PCState cpc = tc->pcState();
-    cpc.advance();
-    ctc->pcState(cpc);
+    if (p->kvmInSE) {
+#if THE_ISA == X86_ISA
+        ctc->pcState(tc->readIntReg(TheISA::INTREG_RCX));
+#else
+        panic("KVM CPU model is not supported for this ISA");
+#endif
+    } else {
+        TheISA::PCState cpc = tc->pcState();
+        cpc.advance();
+        ctc->pcState(cpc);
+    }
     ctc->activate();
 
     return cp->pid();