summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/sentry/kernel')
-rw-r--r--pkg/sentry/kernel/BUILD3
-rw-r--r--pkg/sentry/kernel/contexttest/BUILD1
-rw-r--r--pkg/sentry/kernel/contexttest/contexttest.go2
-rw-r--r--pkg/sentry/kernel/kernel.go57
-rw-r--r--pkg/sentry/kernel/memevent/memory_events.go2
-rw-r--r--pkg/sentry/kernel/shm/BUILD1
-rw-r--r--pkg/sentry/kernel/shm/shm.go19
-rw-r--r--pkg/sentry/kernel/task.go5
-rw-r--r--pkg/sentry/kernel/task_context.go2
-rw-r--r--pkg/sentry/kernel/timekeeper.go5
-rw-r--r--pkg/sentry/kernel/timekeeper_test.go8
-rw-r--r--pkg/sentry/kernel/vdso.go17
12 files changed, 73 insertions, 49 deletions
diff --git a/pkg/sentry/kernel/BUILD b/pkg/sentry/kernel/BUILD
index d9bbfb556..4d34bc733 100644
--- a/pkg/sentry/kernel/BUILD
+++ b/pkg/sentry/kernel/BUILD
@@ -173,6 +173,7 @@ go_library(
"//pkg/sentry/loader",
"//pkg/sentry/memmap",
"//pkg/sentry/mm",
+ "//pkg/sentry/pgalloc",
"//pkg/sentry/platform",
"//pkg/sentry/safemem",
"//pkg/sentry/socket/netlink/port",
@@ -212,7 +213,7 @@ go_test(
"//pkg/sentry/kernel/kdefs",
"//pkg/sentry/kernel/sched",
"//pkg/sentry/limits",
- "//pkg/sentry/platform",
+ "//pkg/sentry/pgalloc",
"//pkg/sentry/time",
"//pkg/sentry/usage",
"//pkg/sentry/usermem",
diff --git a/pkg/sentry/kernel/contexttest/BUILD b/pkg/sentry/kernel/contexttest/BUILD
index 5769a3b28..bfb2a0b73 100644
--- a/pkg/sentry/kernel/contexttest/BUILD
+++ b/pkg/sentry/kernel/contexttest/BUILD
@@ -12,6 +12,7 @@ go_library(
"//pkg/sentry/context",
"//pkg/sentry/context/contexttest",
"//pkg/sentry/kernel",
+ "//pkg/sentry/pgalloc",
"//pkg/sentry/platform",
],
)
diff --git a/pkg/sentry/kernel/contexttest/contexttest.go b/pkg/sentry/kernel/contexttest/contexttest.go
index 9eb18e7e8..eb56a6a07 100644
--- a/pkg/sentry/kernel/contexttest/contexttest.go
+++ b/pkg/sentry/kernel/contexttest/contexttest.go
@@ -22,6 +22,7 @@ import (
"gvisor.googlesource.com/gvisor/pkg/sentry/context"
"gvisor.googlesource.com/gvisor/pkg/sentry/context/contexttest"
"gvisor.googlesource.com/gvisor/pkg/sentry/kernel"
+ "gvisor.googlesource.com/gvisor/pkg/sentry/pgalloc"
"gvisor.googlesource.com/gvisor/pkg/sentry/platform"
)
@@ -33,6 +34,7 @@ func Context(tb testing.TB) context.Context {
k := &kernel.Kernel{
Platform: platform.FromContext(ctx),
}
+ k.SetMemoryFile(pgalloc.MemoryFileFromContext(ctx))
ctx.(*contexttest.TestContext).RegisterValue(kernel.CtxKernel, k)
return ctx
}
diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go
index c6afae2e6..3533fd8f7 100644
--- a/pkg/sentry/kernel/kernel.go
+++ b/pkg/sentry/kernel/kernel.go
@@ -58,6 +58,7 @@ import (
"gvisor.googlesource.com/gvisor/pkg/sentry/limits"
"gvisor.googlesource.com/gvisor/pkg/sentry/loader"
"gvisor.googlesource.com/gvisor/pkg/sentry/mm"
+ "gvisor.googlesource.com/gvisor/pkg/sentry/pgalloc"
"gvisor.googlesource.com/gvisor/pkg/sentry/platform"
"gvisor.googlesource.com/gvisor/pkg/sentry/socket/netlink/port"
sentrytime "gvisor.googlesource.com/gvisor/pkg/sentry/time"
@@ -89,12 +90,14 @@ type Kernel struct {
// All of the following fields are immutable unless otherwise specified.
- // Platform is the platform that is used to execute tasks in the
- // created Kernel. It is embedded so that Kernel can directly serve as
- // Platform in mm logic and also serve as platform.MemoryProvider in
- // filemem S/R logic.
+ // Platform is the platform that is used to execute tasks in the created
+ // Kernel. See comment on pgalloc.MemoryFileProvider for why Platform is
+ // embedded anonymously (the same issue applies).
platform.Platform `state:"nosave"`
+ // mf provides application memory.
+ mf *pgalloc.MemoryFile `state:"nosave"`
+
// See InitKernelArgs for the meaning of these fields.
featureSet *cpuid.FeatureSet
timekeeper *Timekeeper
@@ -229,7 +232,8 @@ type InitKernelArgs struct {
// Init initialize the Kernel with no tasks.
//
-// Callers must manually set Kernel.Platform before caling Init.
+// Callers must manually set Kernel.Platform and call Kernel.SetMemoryFile
+// before calling Init.
func (k *Kernel) Init(args InitKernelArgs) error {
if args.FeatureSet == nil {
return fmt.Errorf("FeatureSet is nil")
@@ -332,15 +336,9 @@ func (k *Kernel) SaveTo(w io.Writer) error {
log.Infof("Kernel save stats: %s", &stats)
log.Infof("Kernel save took [%s].", time.Since(kernelStart))
- // Save the memory state.
- //
- // FIXME: In the future, this should not be dispatched via
- // an abstract memory type. This should be dispatched to a single
- // memory implementation that belongs to the kernel. (There is
- // currently a single implementation anyways, it just needs to be
- // "unabstracted" and reparented appropriately.)
+ // Save the memory file's state.
memoryStart := time.Now()
- if err := k.Platform.Memory().SaveTo(w); err != nil {
+ if err := k.mf.SaveTo(w); err != nil {
return err
}
log.Infof("Memory save took [%s].", time.Since(memoryStart))
@@ -418,13 +416,9 @@ func (ts *TaskSet) unregisterEpollWaiters() {
}
// LoadFrom returns a new Kernel loaded from args.
-func (k *Kernel) LoadFrom(r io.Reader, p platform.Platform, net inet.Stack) error {
+func (k *Kernel) LoadFrom(r io.Reader, net inet.Stack) error {
loadStart := time.Now()
- if p == nil {
- return fmt.Errorf("Platform is nil")
- }
- k.Platform = p
k.networkStack = net
initAppCores := k.applicationCores
@@ -438,11 +432,9 @@ func (k *Kernel) LoadFrom(r io.Reader, p platform.Platform, net inet.Stack) erro
log.Infof("Kernel load stats: %s", &stats)
log.Infof("Kernel load took [%s].", time.Since(kernelStart))
- // Load the memory state.
- //
- // See the note in SaveTo.
+ // Load the memory file's state.
memoryStart := time.Now()
- if err := k.Platform.Memory().LoadFrom(r); err != nil {
+ if err := k.mf.LoadFrom(r); err != nil {
return err
}
log.Infof("Memory load took [%s].", time.Since(memoryStart))
@@ -597,6 +589,10 @@ func (ctx *createProcessContext) Value(key interface{}) interface{} {
return ctx.k.RealtimeClock()
case limits.CtxLimits:
return ctx.args.Limits
+ case pgalloc.CtxMemoryFile:
+ return ctx.k.mf
+ case pgalloc.CtxMemoryFileProvider:
+ return ctx.k
case platform.CtxPlatform:
return ctx.k
case uniqueid.CtxGlobalUniqueID:
@@ -1018,6 +1014,17 @@ func (k *Kernel) NowMonotonic() int64 {
return now
}
+// SetMemoryFile sets Kernel.mf. SetMemoryFile must be called before Init or
+// LoadFrom.
+func (k *Kernel) SetMemoryFile(mf *pgalloc.MemoryFile) {
+ k.mf = mf
+}
+
+// MemoryFile implements pgalloc.MemoryFileProvider.MemoryFile.
+func (k *Kernel) MemoryFile() *pgalloc.MemoryFile {
+ return k.mf
+}
+
// SupervisorContext returns a Context with maximum privileges in k. It should
// only be used by goroutines outside the control of the emulated kernel
// defined by e.
@@ -1083,7 +1090,7 @@ func (k *Kernel) ListSockets(family int) []*refs.WeakRef {
socks := []*refs.WeakRef{}
if table, ok := k.socketTable[family]; ok {
socks = make([]*refs.WeakRef, 0, len(table))
- for s, _ := range table {
+ for s := range table {
socks = append(socks, s)
}
}
@@ -1123,6 +1130,10 @@ func (ctx supervisorContext) Value(key interface{}) interface{} {
case limits.CtxLimits:
// No limits apply.
return limits.NewLimitSet()
+ case pgalloc.CtxMemoryFile:
+ return ctx.k.mf
+ case pgalloc.CtxMemoryFileProvider:
+ return ctx.k
case platform.CtxPlatform:
return ctx.k
case uniqueid.CtxGlobalUniqueID:
diff --git a/pkg/sentry/kernel/memevent/memory_events.go b/pkg/sentry/kernel/memevent/memory_events.go
index b6283c5d1..d09d6debf 100644
--- a/pkg/sentry/kernel/memevent/memory_events.go
+++ b/pkg/sentry/kernel/memevent/memory_events.go
@@ -95,7 +95,7 @@ func (m *MemoryEvents) run() {
}
func (m *MemoryEvents) emit() {
- totalPlatform, err := m.k.Platform.Memory().TotalUsage()
+ totalPlatform, err := m.k.MemoryFile().TotalUsage()
if err != nil {
log.Warningf("Failed to fetch memory usage for memory events: %v", err)
return
diff --git a/pkg/sentry/kernel/shm/BUILD b/pkg/sentry/kernel/shm/BUILD
index f45770eef..bc2089872 100644
--- a/pkg/sentry/kernel/shm/BUILD
+++ b/pkg/sentry/kernel/shm/BUILD
@@ -20,6 +20,7 @@ go_library(
"//pkg/sentry/kernel/auth",
"//pkg/sentry/kernel/time",
"//pkg/sentry/memmap",
+ "//pkg/sentry/pgalloc",
"//pkg/sentry/platform",
"//pkg/sentry/usage",
"//pkg/sentry/usermem",
diff --git a/pkg/sentry/kernel/shm/shm.go b/pkg/sentry/kernel/shm/shm.go
index 96414d060..4525aabf4 100644
--- a/pkg/sentry/kernel/shm/shm.go
+++ b/pkg/sentry/kernel/shm/shm.go
@@ -45,6 +45,7 @@ import (
"gvisor.googlesource.com/gvisor/pkg/sentry/kernel/auth"
ktime "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time"
"gvisor.googlesource.com/gvisor/pkg/sentry/memmap"
+ "gvisor.googlesource.com/gvisor/pkg/sentry/pgalloc"
"gvisor.googlesource.com/gvisor/pkg/sentry/platform"
"gvisor.googlesource.com/gvisor/pkg/sentry/usage"
"gvisor.googlesource.com/gvisor/pkg/sentry/usermem"
@@ -199,19 +200,19 @@ func (r *Registry) FindOrCreate(ctx context.Context, pid int32, key Key, size ui
//
// Precondition: Caller must hold r.mu.
func (r *Registry) newShm(ctx context.Context, pid int32, key Key, creator fs.FileOwner, perms fs.FilePermissions, size uint64) (*Shm, error) {
- p := platform.FromContext(ctx)
- if p == nil {
- panic(fmt.Sprintf("context.Context %T lacks non-nil value for key %T", ctx, platform.CtxPlatform))
+ mfp := pgalloc.MemoryFileProviderFromContext(ctx)
+ if mfp == nil {
+ panic(fmt.Sprintf("context.Context %T lacks non-nil value for key %T", ctx, pgalloc.CtxMemoryFileProvider))
}
effectiveSize := uint64(usermem.Addr(size).MustRoundUp())
- fr, err := p.Memory().Allocate(effectiveSize, usage.Anonymous)
+ fr, err := mfp.MemoryFile().Allocate(effectiveSize, usage.Anonymous)
if err != nil {
return nil, err
}
shm := &Shm{
- p: p,
+ mfp: mfp,
registry: r,
creator: creator,
size: size,
@@ -312,7 +313,7 @@ type Shm struct {
// destruction.
refs.AtomicRefCount
- p platform.Platform
+ mfp pgalloc.MemoryFileProvider
// registry points to the shm registry containing this segment. Immutable.
registry *Registry
@@ -333,7 +334,7 @@ type Shm struct {
// Invariant: effectiveSize must be a multiple of usermem.PageSize.
effectiveSize uint64
- // fr is the offset into platform.Memory() that backs this contents of this
+ // fr is the offset into mfp.MemoryFile() that backs this contents of this
// segment. Immutable.
fr platform.FileRange
@@ -452,7 +453,7 @@ func (s *Shm) Translate(ctx context.Context, required, optional memmap.MappableR
return []memmap.Translation{
{
Source: source,
- File: s.p.Memory(),
+ File: s.mfp.MemoryFile(),
Offset: s.fr.Start + source.Start,
},
}, err
@@ -599,7 +600,7 @@ func (s *Shm) Set(ctx context.Context, ds *linux.ShmidDS) error {
}
func (s *Shm) destroy() {
- s.p.Memory().DecRef(s.fr)
+ s.mfp.MemoryFile().DecRef(s.fr)
s.registry.remove(s)
}
diff --git a/pkg/sentry/kernel/task.go b/pkg/sentry/kernel/task.go
index 702e40cce..e9f133c0b 100644
--- a/pkg/sentry/kernel/task.go
+++ b/pkg/sentry/kernel/task.go
@@ -29,6 +29,7 @@ import (
"gvisor.googlesource.com/gvisor/pkg/sentry/kernel/sched"
ktime "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time"
"gvisor.googlesource.com/gvisor/pkg/sentry/limits"
+ "gvisor.googlesource.com/gvisor/pkg/sentry/pgalloc"
"gvisor.googlesource.com/gvisor/pkg/sentry/platform"
"gvisor.googlesource.com/gvisor/pkg/sentry/unimpl"
"gvisor.googlesource.com/gvisor/pkg/sentry/uniqueid"
@@ -587,6 +588,10 @@ func (t *Task) Value(key interface{}) interface{} {
return t.k.RealtimeClock()
case limits.CtxLimits:
return t.tg.limits
+ case pgalloc.CtxMemoryFile:
+ return t.k.mf
+ case pgalloc.CtxMemoryFileProvider:
+ return t.k
case platform.CtxPlatform:
return t.k
case uniqueid.CtxGlobalUniqueID:
diff --git a/pkg/sentry/kernel/task_context.go b/pkg/sentry/kernel/task_context.go
index ee3e49d17..d1c82f2aa 100644
--- a/pkg/sentry/kernel/task_context.go
+++ b/pkg/sentry/kernel/task_context.go
@@ -144,7 +144,7 @@ func (t *Task) Stack() *arch.Stack {
// * fs: Binary FeatureSet
func (k *Kernel) LoadTaskImage(ctx context.Context, mounts *fs.MountNamespace, root, wd *fs.Dirent, maxTraversals *uint, filename string, argv, envv []string, fs *cpuid.FeatureSet) (*TaskContext, *syserr.Error) {
// Prepare a new user address space to load into.
- m := mm.NewMemoryManager(k)
+ m := mm.NewMemoryManager(k, k)
defer m.DecUsers(ctx)
os, ac, name, err := loader.Load(ctx, m, mounts, root, wd, maxTraversals, fs, filename, argv, envv, k.extraAuxv, k.vdso)
diff --git a/pkg/sentry/kernel/timekeeper.go b/pkg/sentry/kernel/timekeeper.go
index 6bff80f13..d7bd85e78 100644
--- a/pkg/sentry/kernel/timekeeper.go
+++ b/pkg/sentry/kernel/timekeeper.go
@@ -21,6 +21,7 @@ import (
"gvisor.googlesource.com/gvisor/pkg/log"
ktime "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time"
+ "gvisor.googlesource.com/gvisor/pkg/sentry/pgalloc"
"gvisor.googlesource.com/gvisor/pkg/sentry/platform"
sentrytime "gvisor.googlesource.com/gvisor/pkg/sentry/time"
)
@@ -85,9 +86,9 @@ type Timekeeper struct {
// NewTimekeeper does not take ownership of paramPage.
//
// SetClocks must be called on the returned Timekeeper before it is usable.
-func NewTimekeeper(platform platform.Platform, paramPage platform.FileRange) (*Timekeeper, error) {
+func NewTimekeeper(mfp pgalloc.MemoryFileProvider, paramPage platform.FileRange) (*Timekeeper, error) {
return &Timekeeper{
- params: NewVDSOParamPage(platform, paramPage),
+ params: NewVDSOParamPage(mfp, paramPage),
}, nil
}
diff --git a/pkg/sentry/kernel/timekeeper_test.go b/pkg/sentry/kernel/timekeeper_test.go
index 71674c21c..6084bcb18 100644
--- a/pkg/sentry/kernel/timekeeper_test.go
+++ b/pkg/sentry/kernel/timekeeper_test.go
@@ -18,7 +18,7 @@ import (
"testing"
"gvisor.googlesource.com/gvisor/pkg/sentry/context/contexttest"
- "gvisor.googlesource.com/gvisor/pkg/sentry/platform"
+ "gvisor.googlesource.com/gvisor/pkg/sentry/pgalloc"
sentrytime "gvisor.googlesource.com/gvisor/pkg/sentry/time"
"gvisor.googlesource.com/gvisor/pkg/sentry/usage"
"gvisor.googlesource.com/gvisor/pkg/sentry/usermem"
@@ -53,13 +53,13 @@ func (c *mockClocks) GetTime(id sentrytime.ClockID) (int64, error) {
// SetClocks called.
func stateTestClocklessTimekeeper(tb testing.TB) *Timekeeper {
ctx := contexttest.Context(tb)
- p := platform.FromContext(ctx)
- fr, err := p.Memory().Allocate(usermem.PageSize, usage.Anonymous)
+ mfp := pgalloc.MemoryFileProviderFromContext(ctx)
+ fr, err := mfp.MemoryFile().Allocate(usermem.PageSize, usage.Anonymous)
if err != nil {
tb.Fatalf("failed to allocate memory: %v", err)
}
return &Timekeeper{
- params: NewVDSOParamPage(p, fr),
+ params: NewVDSOParamPage(mfp, fr),
}
}
diff --git a/pkg/sentry/kernel/vdso.go b/pkg/sentry/kernel/vdso.go
index 0ec858a4a..3a35f1d00 100644
--- a/pkg/sentry/kernel/vdso.go
+++ b/pkg/sentry/kernel/vdso.go
@@ -18,6 +18,7 @@ import (
"fmt"
"gvisor.googlesource.com/gvisor/pkg/binary"
+ "gvisor.googlesource.com/gvisor/pkg/sentry/pgalloc"
"gvisor.googlesource.com/gvisor/pkg/sentry/platform"
"gvisor.googlesource.com/gvisor/pkg/sentry/safemem"
"gvisor.googlesource.com/gvisor/pkg/sentry/usermem"
@@ -55,9 +56,9 @@ type vdsoParams struct {
//
// +stateify savable
type VDSOParamPage struct {
- // The parameter page is fr, allocated from platform.Memory().
- platform platform.Platform
- fr platform.FileRange
+ // The parameter page is fr, allocated from mfp.MemoryFile().
+ mfp pgalloc.MemoryFileProvider
+ fr platform.FileRange
// seq is the current sequence count written to the page.
//
@@ -73,20 +74,20 @@ type VDSOParamPage struct {
//
// Preconditions:
//
-// * fr is a single page allocated from platform.Memory(). VDSOParamPage does
+// * fr is a single page allocated from mfp.MemoryFile(). VDSOParamPage does
// not take ownership of fr; it must remain allocated for the lifetime of the
// VDSOParamPage.
//
// * VDSOParamPage must be the only writer to fr.
//
-// * platform.Memory().MapInternal(fr) must return a single safemem.Block.
-func NewVDSOParamPage(platform platform.Platform, fr platform.FileRange) *VDSOParamPage {
- return &VDSOParamPage{platform: platform, fr: fr}
+// * mfp.MemoryFile().MapInternal(fr) must return a single safemem.Block.
+func NewVDSOParamPage(mfp pgalloc.MemoryFileProvider, fr platform.FileRange) *VDSOParamPage {
+ return &VDSOParamPage{mfp: mfp, fr: fr}
}
// access returns a mapping of the param page.
func (v *VDSOParamPage) access() (safemem.Block, error) {
- bs, err := v.platform.Memory().MapInternal(v.fr, usermem.ReadWrite)
+ bs, err := v.mfp.MemoryFile().MapInternal(v.fr, usermem.ReadWrite)
if err != nil {
return safemem.Block{}, err
}