diff options
author | Andrei Vagin <avagin@google.com> | 2021-04-30 23:03:38 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-04-30 23:07:15 -0700 |
commit | cde8e8b7a905ce53fe72a1a71b86e9ef352bbc3a (patch) | |
tree | da490778e2ed80b9f92a14066d69bf5e8410a758 | |
parent | 6fb8c01bb488e22c741a307e030b61c512dcd34f (diff) |
kvm: prefault a root table page before switching into a user address space
The root table physical page has to be mapped to not fault in iret or sysret
after switching into a user address space. sysret and iret are in the upper
half that is global and so page tables of lower levels are already mapped.
Fixes #5742
PiperOrigin-RevId: 371458644
-rw-r--r-- | pkg/ring0/pagetables/pagetables.go | 9 | ||||
-rw-r--r-- | pkg/sentry/platform/kvm/machine_amd64.go | 4 |
2 files changed, 13 insertions, 0 deletions
diff --git a/pkg/ring0/pagetables/pagetables.go b/pkg/ring0/pagetables/pagetables.go index 3f17fba49..9dac53c80 100644 --- a/pkg/ring0/pagetables/pagetables.go +++ b/pkg/ring0/pagetables/pagetables.go @@ -322,3 +322,12 @@ func (p *PageTables) Lookup(addr hostarch.Addr, findFirst bool) (virtual hostarc func (p *PageTables) MarkReadOnlyShared() { p.readOnlyShared = true } + +// PrefaultRootTable touches the root table page to be sure that its physical +// pages are mapped. +// +//go:nosplit +//go:noinline +func (p *PageTables) PrefaultRootTable() PTE { + return p.root[0] +} diff --git a/pkg/sentry/platform/kvm/machine_amd64.go b/pkg/sentry/platform/kvm/machine_amd64.go index d7abfefb4..f727e61b0 100644 --- a/pkg/sentry/platform/kvm/machine_amd64.go +++ b/pkg/sentry/platform/kvm/machine_amd64.go @@ -351,6 +351,10 @@ func (c *vCPU) SwitchToUser(switchOpts ring0.SwitchOpts, info *arch.SignalInfo) // allocations occur. entersyscall() bluepill(c) + // The root table physical page has to be mapped to not fault in iret + // or sysret after switching into a user address space. sysret and + // iret are in the upper half that is global and already mapped. + switchOpts.PageTables.PrefaultRootTable() prefaultFloatingPointState(switchOpts.FloatingPointState) vector = c.CPU.SwitchToUser(switchOpts) exitsyscall() |