}
}
+uint64_t
+BaseKvmCPU::getHostCycles() const
+{
+ return hwCycles.read();
+}
+
Tick
BaseKvmCPU::kvmRun(Tick ticks)
{
- uint64_t baseCycles(hwCycles.read());
- uint64_t baseInstrs(hwInstructions.read());
-
// We might need to update the KVM state.
syncKvmState();
// Entering into KVM implies that we'll have to reload the thread
DPRINTF(KvmRun, "KVM: Executing for %i ticks\n", ticks);
timerOverflowed = false;
+ // Get hardware statistics after synchronizing contexts. The KVM
+ // state update might affect guest cycle counters.
+ uint64_t baseCycles(getHostCycles());
+ uint64_t baseInstrs(hwInstructions.read());
+
// Arm the run timer and start the cycle timer if it isn't
// controlled by the overflow timer. Starting/stopping the cycle
// timer automatically starts the other perf timers as they are in
hwCycles.stop();
- const uint64_t hostCyclesExecuted(hwCycles.read() - baseCycles);
+ const uint64_t hostCyclesExecuted(getHostCycles() - baseCycles);
const uint64_t simCyclesExecuted(hostCyclesExecuted * hostFactor);
const uint64_t instsExecuted(hwInstructions.read() - baseInstrs);
const Tick ticksExecuted(runTimer->ticksFromHostCycles(hostCyclesExecuted));
*/
virtual void tick();
+ /**
+ * Get the value of the hardware cycle counter in the guest.
+ *
+ * This method is supposed to return the total number of cycles
+ * executed in hardware mode relative to some arbitrary point in
+ * the past. It's mainly used when estimating the number of cycles
+ * actually executed by the CPU in kvmRun(). The default behavior
+ * of this method is to use the cycles performance counter, but
+ * some architectures may want to use internal registers instead.
+ *
+ * @return Number of host cycles executed relative to an undefined
+ * point in the past.
+ */
+ virtual uint64_t getHostCycles() const;
+
/**
* Request KVM to run the guest for a given number of ticks. The
* method returns the approximate number of ticks executed.