From: Alexandru Dutu Date: Tue, 16 Apr 2019 03:36:36 +0000 (-0400) Subject: sim-se: Enhance clone for X86KvmCPU X-Git-Tag: v19.0.0.0~952 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c5b3db6da28611280c291d9e0540f087cf55a54e;p=gem5.git sim-se: Enhance clone for X86KvmCPU 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 Maintainer: Jason Lowe-Power Tested-by: kokoro --- diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 04bc0ddc8..9e34a7b5d 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -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. diff --git a/src/mem/multi_level_page_table.hh b/src/mem/multi_level_page_table.hh index bd40d37c1..f517eafe8 100644 --- a/src/mem/multi_level_page_table.hh +++ b/src/mem/multi_level_page_table.hh @@ -204,6 +204,9 @@ public: void initState(ThreadContext* tc) override { + if (shared) + return; + _basePtr = prepTopTable(system, pageSize); } diff --git a/src/mem/page_table.hh b/src/mem/page_table.hh index 447d3a50f..03e18c2d0 100644 --- a/src/mem/page_table.hh +++ b/src/mem/page_table.hh @@ -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 diff --git a/src/sim/process.cc b/src/sim/process.cc index c4dd64107..5cec2958e 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -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), diff --git a/src/sim/process.hh b/src/sim/process.hh index c690e825e..a1ca84bf5 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -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; diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index 0378bd770..87c16c489 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -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();