diff options
author | Bin Lu <bin.lu@arm.com> | 2020-10-22 01:35:11 -0400 |
---|---|---|
committer | Bin Lu <bin.lu@arm.com> | 2020-10-22 01:46:09 -0400 |
commit | 56b5c71bac55439e0f8cfc91d3803b49548eb4fd (patch) | |
tree | 09fc7807efde8a2f228cae59147e36d514a9070f /pkg/sentry/platform/kvm/machine.go | |
parent | 4e389c785779114620b47e005d08ca469cc1ed68 (diff) |
arm64 kvm: added the implementation of setSystemTimeLegacy()
I have added support for setSystemTimeLegacy() by setting cntvoff.
With this pr, TestRdtsc and other kvm syscall test cases(nanosleep,
wait...) can be passed on Arm64.
TO-DO: Add precise synchronization to KVM for Arm64.
Reference PR: https://github.com/google/gvisor/pull/4397
Signed-off-by: Bin Lu <bin.lu@arm.com>
Diffstat (limited to 'pkg/sentry/platform/kvm/machine.go')
-rw-r--r-- | pkg/sentry/platform/kvm/machine.go | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/pkg/sentry/platform/kvm/machine.go b/pkg/sentry/platform/kvm/machine.go index 61ed24d01..f70d761fd 100644 --- a/pkg/sentry/platform/kvm/machine.go +++ b/pkg/sentry/platform/kvm/machine.go @@ -25,6 +25,7 @@ import ( "gvisor.dev/gvisor/pkg/procid" "gvisor.dev/gvisor/pkg/sentry/platform/ring0" "gvisor.dev/gvisor/pkg/sentry/platform/ring0/pagetables" + ktime "gvisor.dev/gvisor/pkg/sentry/time" "gvisor.dev/gvisor/pkg/sync" "gvisor.dev/gvisor/pkg/usermem" ) @@ -625,3 +626,35 @@ func (c *vCPU) BounceToKernel() { func (c *vCPU) BounceToHost() { c.bounce(true) } + +// setSystemTimeLegacy calibrates and sets an approximate system time. +func (c *vCPU) setSystemTimeLegacy() error { + const minIterations = 10 + minimum := uint64(0) + for iter := 0; ; iter++ { + // Try to set the TSC to an estimate of where it will be + // on the host during a "fast" system call iteration. + start := uint64(ktime.Rdtsc()) + if err := c.setTSC(start + (minimum / 2)); err != nil { + return err + } + // See if this is our new minimum call time. Note that this + // serves two functions: one, we make sure that we are + // accurately predicting the offset we need to set. Second, we + // don't want to do the final set on a slow call, which could + // produce a really bad result. + end := uint64(ktime.Rdtsc()) + if end < start { + continue // Totally bogus: unstable TSC? + } + current := end - start + if current < minimum || iter == 0 { + minimum = current // Set our new minimum. + } + // Is this past minIterations and within ~10% of minimum? + upperThreshold := (((minimum << 3) + minimum) >> 3) + if iter >= minIterations && current <= upperThreshold { + return nil + } + } +} |