changeset fb040456eb46 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=fb040456eb46
description:
        kvm: Allow architectures to override the cycle accounting mechanism

        Some architectures have special registers in the guest that can be
        used to do cycle accounting. This is generally preferrable since the
        prevents the guest from seeing a non-monotonic clock. This changeset
        adds a virtual method, getHostCycles(), that the architecture-specific
        code can override to implement this functionallity. The default
        implementation uses the hwCycles counter.

diffstat:

 src/cpu/kvm/base.cc |  16 ++++++++++++----
 src/cpu/kvm/base.hh |  15 +++++++++++++++
 2 files changed, 27 insertions(+), 4 deletions(-)

diffs (68 lines):

diff -r 749e3799e532 -r fb040456eb46 src/cpu/kvm/base.cc
--- a/src/cpu/kvm/base.cc       Mon Jun 03 13:38:59 2013 +0200
+++ b/src/cpu/kvm/base.cc       Mon Jun 03 13:39:11 2013 +0200
@@ -456,12 +456,15 @@
     }
 }
 
+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
@@ -478,6 +481,11 @@
     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
@@ -497,7 +505,7 @@
         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));
diff -r 749e3799e532 -r fb040456eb46 src/cpu/kvm/base.hh
--- a/src/cpu/kvm/base.hh       Mon Jun 03 13:38:59 2013 +0200
+++ b/src/cpu/kvm/base.hh       Mon Jun 03 13:39:11 2013 +0200
@@ -154,6 +154,21 @@
     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.
      *
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to