summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Sandberg <andreas@sandberg.pp.se>2013-06-11 09:24:38 +0200
committerAndreas Sandberg <andreas@sandberg.pp.se>2013-06-11 09:24:38 +0200
commit0b4a8b40866a1ed44bacbccc788ce3001eab8b20 (patch)
tree103ebeb6693f4c02a12a5614e3ab4be9c34fbd91
parent2442aae54f1726b63674e47de1b62bf2af847f70 (diff)
downloadgem5-0b4a8b40866a1ed44bacbccc788ce3001eab8b20.tar.xz
x86: Fix bug when copying TSC on CPU handover
The TSC value stored in MISCREG_TSC is actually just an offset from the current CPU cycle to the actual TSC value. Writes with side-effects to the TSC subtract the current cycle count before storing the new value, while reads add the current cycle count. When switching CPUs, the current value is copied without side-effects. This works as long as the source and the destination CPUs have the same clock frequencies. The TSC will jump, sometimes backwards, if they have different clock frequencies. Most OSes assume the TSC to be monotonic and break when this happens. This changeset makes sure that the TSC is copied with side-effects to ensure that the offset is updated to match the new CPU.
-rw-r--r--src/arch/x86/utility.cc4
1 files changed, 4 insertions, 0 deletions
diff --git a/src/arch/x86/utility.cc b/src/arch/x86/utility.cc
index ae6c37be6..e3d25fcdf 100644
--- a/src/arch/x86/utility.cc
+++ b/src/arch/x86/utility.cc
@@ -209,6 +209,10 @@ copyMiscRegs(ThreadContext *src, ThreadContext *dest)
dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
}
+ // The TSC has to be updated with side-effects if the CPUs in a
+ // CPU switch have different frequencies.
+ dest->setMiscReg(MISCREG_TSC, src->readMiscReg(MISCREG_TSC));
+
dest->getITBPtr()->flushAll();
dest->getDTBPtr()->flushAll();
}