kvm: Add an option to force context sync on kvm entry/exit
This changeset adds an option to force the kvm-based CPUs to always synchronize the gem5 thread context representation on entry/exit into the kernel. This is very useful for debugging. Unfortunately, it is also the only way to get reliable register contents when using remote gdb functionality. The long-term solution for the latter would be to implement a kvm-specific thread context. Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-by: Curtis Dunham <curtis.dunham@arm.com> Reviewed-by: Alexandru Dutu <alexandru.dutu@amd.com>
This commit is contained in:
parent
d4eb354e30
commit
a3efb6bd1d
3 changed files with 15 additions and 0 deletions
|
@ -71,6 +71,8 @@ class BaseKvmCPU(BaseCPU):
|
||||||
kvmVM = Param.KvmVM(Parent.any, 'KVM VM (i.e., shared memory domain)')
|
kvmVM = Param.KvmVM(Parent.any, 'KVM VM (i.e., shared memory domain)')
|
||||||
useCoalescedMMIO = Param.Bool(False, "Use coalesced MMIO (EXPERIMENTAL)")
|
useCoalescedMMIO = Param.Bool(False, "Use coalesced MMIO (EXPERIMENTAL)")
|
||||||
usePerfOverflow = Param.Bool(False, "Use perf event overflow counters (EXPERIMENTAL)")
|
usePerfOverflow = Param.Bool(False, "Use perf event overflow counters (EXPERIMENTAL)")
|
||||||
|
alwaysSyncTC = Param.Bool(False,
|
||||||
|
"Always sync thread contexts on entry/exit")
|
||||||
|
|
||||||
hostFreq = Param.Clock("2GHz", "Host clock frequency")
|
hostFreq = Param.Clock("2GHz", "Host clock frequency")
|
||||||
hostFactor = Param.Float(1.0, "Cycle scale factor")
|
hostFactor = Param.Float(1.0, "Cycle scale factor")
|
||||||
|
|
|
@ -69,6 +69,7 @@ BaseKvmCPU::BaseKvmCPU(BaseKvmCPUParams *params)
|
||||||
_status(Idle),
|
_status(Idle),
|
||||||
dataPort(name() + ".dcache_port", this),
|
dataPort(name() + ".dcache_port", this),
|
||||||
instPort(name() + ".icache_port", this),
|
instPort(name() + ".icache_port", this),
|
||||||
|
alwaysSyncTC(params->alwaysSyncTC),
|
||||||
threadContextDirty(true),
|
threadContextDirty(true),
|
||||||
kvmStateDirty(false),
|
kvmStateDirty(false),
|
||||||
vcpuID(vm.allocVCPUID()), vcpuFD(-1), vcpuMMapSize(0),
|
vcpuID(vm.allocVCPUID()), vcpuFD(-1), vcpuMMapSize(0),
|
||||||
|
@ -557,6 +558,9 @@ BaseKvmCPU::tick()
|
||||||
nextInstEvent > ctrInsts ?
|
nextInstEvent > ctrInsts ?
|
||||||
curEventQueue()->nextTick() - curTick() : 0);
|
curEventQueue()->nextTick() - curTick() : 0);
|
||||||
|
|
||||||
|
if (alwaysSyncTC)
|
||||||
|
threadContextDirty = true;
|
||||||
|
|
||||||
// We might need to update the KVM state.
|
// We might need to update the KVM state.
|
||||||
syncKvmState();
|
syncKvmState();
|
||||||
|
|
||||||
|
@ -588,6 +592,9 @@ BaseKvmCPU::tick()
|
||||||
// dirty with respect to the cached thread context.
|
// dirty with respect to the cached thread context.
|
||||||
kvmStateDirty = true;
|
kvmStateDirty = true;
|
||||||
|
|
||||||
|
if (alwaysSyncTC)
|
||||||
|
syncThreadContext();
|
||||||
|
|
||||||
// Enter into the RunningService state unless the
|
// Enter into the RunningService state unless the
|
||||||
// simulation was stopped by a timer.
|
// simulation was stopped by a timer.
|
||||||
if (_kvmRun->exit_reason != KVM_EXIT_INTR) {
|
if (_kvmRun->exit_reason != KVM_EXIT_INTR) {
|
||||||
|
|
|
@ -574,6 +574,12 @@ class BaseKvmCPU : public BaseCPU
|
||||||
/** Unused dummy port for the instruction interface */
|
/** Unused dummy port for the instruction interface */
|
||||||
KVMCpuPort instPort;
|
KVMCpuPort instPort;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Be conservative and always synchronize the thread context on
|
||||||
|
* KVM entry/exit.
|
||||||
|
*/
|
||||||
|
const bool alwaysSyncTC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is the gem5 context dirty? Set to true to force an update of
|
* Is the gem5 context dirty? Set to true to force an update of
|
||||||
* the KVM vCPU state upon the next call to kvmRun().
|
* the KVM vCPU state upon the next call to kvmRun().
|
||||||
|
|
Loading…
Reference in a new issue