diff options
author | Dean Deng <deandeng@google.com> | 2020-07-23 16:22:41 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-07-23 16:25:34 -0700 |
commit | 8fed97794edcbaa7069dbd39604030e4fbb6891c (patch) | |
tree | 2bfacd76be57fd91a279f256c35c73ba640db164 /pkg/sentry/kernel/task_work.go | |
parent | 3a2fac0ab9e24382c8e19e6cf8170ba01e78930c (diff) |
Add task work mechanism.
Like task_work in Linux, this allows us to register callbacks to be executed
before returning to userspace. This is needed for kcov support, which requires
coverage information to be up-to-date whenever we are in user mode. We will
provide coverage data through the kcov interface to enable coverage-directed
fuzzing in syzkaller.
One difference from Linux is that task work cannot queue work before the
transition to userspace that it precedes; queued work will be picked up before
the next transition.
PiperOrigin-RevId: 322889984
Diffstat (limited to 'pkg/sentry/kernel/task_work.go')
-rw-r--r-- | pkg/sentry/kernel/task_work.go | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/pkg/sentry/kernel/task_work.go b/pkg/sentry/kernel/task_work.go new file mode 100644 index 000000000..dda5a433a --- /dev/null +++ b/pkg/sentry/kernel/task_work.go @@ -0,0 +1,38 @@ +// Copyright 2020 The gVisor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package kernel + +import "sync/atomic" + +// TaskWorker is a deferred task. +// +// This must be savable. +type TaskWorker interface { + // TaskWork will be executed prior to returning to user space. Note that + // TaskWork may call RegisterWork again, but this will not be executed until + // the next return to user space, unlike in Linux. This effectively allows + // registration of indefinite user return hooks, but not by default. + TaskWork(t *Task) +} + +// RegisterWork can be used to register additional task work that will be +// performed prior to returning to user space. See TaskWorker.TaskWork for +// semantics regarding registration. +func (t *Task) RegisterWork(work TaskWorker) { + t.taskWorkMu.Lock() + defer t.taskWorkMu.Unlock() + atomic.AddInt32(&t.taskWorkCount, 1) + t.taskWork = append(t.taskWork, work) +} |