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 <jason@lowepower.com> Maintainer: Jason Lowe-Power <jason@lowepower.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
committed by
Alexandru Duțu
parent
382263c670
commit
c5b3db6da2
@@ -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.
|
||||
|
||||
@@ -204,6 +204,9 @@ public:
|
||||
void
|
||||
initState(ThreadContext* tc) override
|
||||
{
|
||||
if (shared)
|
||||
return;
|
||||
|
||||
_basePtr = prepTopTable<EntryTypes...>(system, pageSize);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user