summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/kernel
diff options
context:
space:
mode:
authorZhaozhong Ni <nzz@google.com>2018-07-12 15:07:59 -0700
committerShentubot <shentubot@google.com>2018-07-12 15:09:02 -0700
commit1cd46c8dd1a92dd0ad3eeb60a763278f2e98d0b4 (patch)
tree970e90306e9a146f17014c8d4ec6ebb45a5e5dd7 /pkg/sentry/kernel
parentbb41ad808a75b8a945d82df51f0e322d98edf951 (diff)
sentry: wait for restore clock instead of panicing in Timekeeper.
PiperOrigin-RevId: 204372296 Change-Id: If1ed9843b93039806e0c65521f30177dc8036979
Diffstat (limited to 'pkg/sentry/kernel')
-rw-r--r--pkg/sentry/kernel/timekeeper.go25
-rw-r--r--pkg/sentry/kernel/timekeeper_state.go2
-rw-r--r--pkg/sentry/kernel/timekeeper_test.go4
3 files changed, 19 insertions, 12 deletions
diff --git a/pkg/sentry/kernel/timekeeper.go b/pkg/sentry/kernel/timekeeper.go
index 3f16c1676..4de8ac13b 100644
--- a/pkg/sentry/kernel/timekeeper.go
+++ b/pkg/sentry/kernel/timekeeper.go
@@ -44,14 +44,14 @@ type Timekeeper struct {
// It is set only once, by SetClocks.
monotonicOffset int64 `state:"nosave"`
- // restored indicates that this Timekeeper was restored from a state
- // file.
- restored bool `state:"nosave"`
+ // restored, if non-nil, indicates that this Timekeeper was restored
+ // from a state file. The clocks are not set until restored is closed.
+ restored chan struct{} `state:"nosave"`
// saveMonotonic is the (offset) value of the monotonic clock at the
// time of save.
//
- // It is only valid if restored is true.
+ // It is only valid if restored is non-nil.
//
// It is only used in SetClocks after restore to compute the new
// monotonicOffset.
@@ -59,7 +59,7 @@ type Timekeeper struct {
// saveRealtime is the value of the realtime clock at the time of save.
//
- // It is only valid if restored is true.
+ // It is only valid if restored is non-nil.
//
// It is only used in SetClocks after restore to compute the new
// monotonicOffset.
@@ -98,7 +98,7 @@ func NewTimekeeper(platform platform.Platform, paramPage platform.FileRange) (*T
func (t *Timekeeper) SetClocks(c sentrytime.Clocks) {
// Update the params, marking them "not ready", as we may need to
// restart calibration on this new machine.
- if t.restored {
+ if t.restored != nil {
if err := t.params.Write(func() vdsoParams {
return vdsoParams{}
}); err != nil {
@@ -135,7 +135,7 @@ func (t *Timekeeper) SetClocks(c sentrytime.Clocks) {
panic("Unable to get current realtime: " + err.Error())
}
- if t.restored {
+ if t.restored != nil {
wantMonotonic = t.saveMonotonic
elapsed := nowRealtime - t.saveRealtime
if elapsed > 0 {
@@ -145,7 +145,7 @@ func (t *Timekeeper) SetClocks(c sentrytime.Clocks) {
t.monotonicOffset = wantMonotonic - nowMonotonic
- if !t.restored {
+ if t.restored == nil {
// Hold on to the initial "boot" time.
t.bootTime = ktime.FromNanoseconds(nowRealtime)
}
@@ -153,6 +153,10 @@ func (t *Timekeeper) SetClocks(c sentrytime.Clocks) {
t.mu.Lock()
defer t.mu.Unlock()
t.startUpdater()
+
+ if t.restored != nil {
+ close(t.restored)
+ }
}
// startUpdater starts an update goroutine that keeps the clocks updated.
@@ -255,7 +259,10 @@ func (t *Timekeeper) ResumeUpdates() {
// GetTime returns the current time in nanoseconds.
func (t *Timekeeper) GetTime(c sentrytime.ClockID) (int64, error) {
if t.clocks == nil {
- panic("Timekeeper used before initialized with SetClocks")
+ if t.restored == nil {
+ panic("Timekeeper used before initialized with SetClocks")
+ }
+ <-t.restored
}
now, err := t.clocks.GetTime(c)
if err == nil && c == sentrytime.Monotonic {
diff --git a/pkg/sentry/kernel/timekeeper_state.go b/pkg/sentry/kernel/timekeeper_state.go
index aee983ac7..2e7fed4d8 100644
--- a/pkg/sentry/kernel/timekeeper_state.go
+++ b/pkg/sentry/kernel/timekeeper_state.go
@@ -37,5 +37,5 @@ func (t *Timekeeper) beforeSave() {
// afterLoad is invoked by stateify.
func (t *Timekeeper) afterLoad() {
- t.restored = true
+ t.restored = make(chan struct{})
}
diff --git a/pkg/sentry/kernel/timekeeper_test.go b/pkg/sentry/kernel/timekeeper_test.go
index 08bacba4f..34a5cec27 100644
--- a/pkg/sentry/kernel/timekeeper_test.go
+++ b/pkg/sentry/kernel/timekeeper_test.go
@@ -107,7 +107,7 @@ func TestTimekeeperMonotonicForward(t *testing.T) {
}
tk := stateTestClocklessTimekeeper(t)
- tk.restored = true
+ tk.restored = make(chan struct{})
tk.saveMonotonic = 100000
tk.saveRealtime = 400000
tk.SetClocks(c)
@@ -135,7 +135,7 @@ func TestTimekeeperMonotonicJumpBackwards(t *testing.T) {
}
tk := stateTestClocklessTimekeeper(t)
- tk.restored = true
+ tk.restored = make(chan struct{})
tk.saveMonotonic = 100000
tk.saveRealtime = 600000
tk.SetClocks(c)