summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDaniel Dao <dqminh89@gmail.com>2021-03-26 11:15:23 +0000
committerDaniel Dao <dqminh89@gmail.com>2021-04-21 14:31:39 +0100
commit58843520b5eb64924d295ca2e03eeaecbf8d65a1 (patch)
tree61d260926d83b4d8d41bc3749faedc1733f7a204
parentfbec65fc3f21773cbec3db4aadf27b85e8859448 (diff)
Fallback to legacy system time logic when host does not have TSC_CONTROL
If the host doesn't have TSC scaling feature, then scaling down TSC to the lowest value will fail, and we will fall back to legacy logic anyway, but we leave an ugly log message in host's kernel log. kernel: user requested TSC rate below hardware speed Instead, check for KVM_CAP_TSC_CONTROL when initializing KVM, and fall back to legacy logic early if host's cpu doesn't support that. Signed-off-by: Daniel Dao <dqminh89@gmail.com>
-rw-r--r--pkg/sentry/platform/kvm/kvm_const.go1
-rw-r--r--pkg/sentry/platform/kvm/machine.go8
-rw-r--r--pkg/sentry/platform/kvm/machine_amd64.go5
3 files changed, 14 insertions, 0 deletions
diff --git a/pkg/sentry/platform/kvm/kvm_const.go b/pkg/sentry/platform/kvm/kvm_const.go
index 2492d57be..eb2dcccac 100644
--- a/pkg/sentry/platform/kvm/kvm_const.go
+++ b/pkg/sentry/platform/kvm/kvm_const.go
@@ -66,6 +66,7 @@ const (
_KVM_CAP_ARM_VM_IPA_SIZE = 0xa5
_KVM_CAP_VCPU_EVENTS = 0x29
_KVM_CAP_ARM_INJECT_SERROR_ESR = 0x9e
+ _KVM_CAP_TSC_CONTROL = 0x3c
)
// KVM limits.
diff --git a/pkg/sentry/platform/kvm/machine.go b/pkg/sentry/platform/kvm/machine.go
index 0e4cf01e1..cc0fb9892 100644
--- a/pkg/sentry/platform/kvm/machine.go
+++ b/pkg/sentry/platform/kvm/machine.go
@@ -67,6 +67,9 @@ type machine struct {
// maxSlots is the maximum number of memory slots supported by the machine.
maxSlots int
+ // tscControl checks whether cpu supports TSC scaling
+ tscControl bool
+
// usedSlots is the set of used physical addresses (sorted).
usedSlots []uintptr
@@ -214,6 +217,11 @@ func newMachine(vm int) (*machine, error) {
log.Debugf("The maximum number of slots is %d.", m.maxSlots)
m.usedSlots = make([]uintptr, m.maxSlots)
+ // Check TSC Scaling
+ hasTSCControl, _, errno := unix.RawSyscall(unix.SYS_IOCTL, uintptr(m.fd), _KVM_CHECK_EXTENSION, _KVM_CAP_TSC_CONTROL)
+ m.tscControl = errno == 0 && hasTSCControl == 1
+ log.Debugf("TSC scaling support: %t.", m.tscControl)
+
// Create the upper shared pagetables and kernel(sentry) pagetables.
m.upperSharedPageTables = pagetables.New(newAllocator())
m.mapUpperHalf(m.upperSharedPageTables)
diff --git a/pkg/sentry/platform/kvm/machine_amd64.go b/pkg/sentry/platform/kvm/machine_amd64.go
index 3af96c7e5..31f56e3c2 100644
--- a/pkg/sentry/platform/kvm/machine_amd64.go
+++ b/pkg/sentry/platform/kvm/machine_amd64.go
@@ -213,6 +213,11 @@ func (c *vCPU) setSystemTime() error {
// capabilities as it is emulated in KVM. We don't actually use this
// capability, but it means that this method should be robust to
// different hardware configurations.
+
+ // if tsc scaling is not supported, fallback to legacy mode
+ if !c.machine.tscControl {
+ return c.setSystemTimeLegacy()
+ }
rawFreq, err := c.getTSCFreq()
if err != nil {
return c.setSystemTimeLegacy()