summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/platform/ring0/pagetables/pagetables_x86.go
diff options
context:
space:
mode:
authorAdin Scannell <ascannell@google.com>2018-06-06 21:47:39 -0700
committerShentubot <shentubot@google.com>2018-06-06 21:48:24 -0700
commit1b5062263b4a3ca3dc0271d9e06ad0113197344c (patch)
tree69d6536240ffa1db76aaef0d4f3a873d86a0dfaf /pkg/sentry/platform/ring0/pagetables/pagetables_x86.go
parent206e90d057211f2ac53174907b2ff04801f9a481 (diff)
Add allocator abstraction for page tables.
In order to prevent possible garbage collection and reuse of page table pages prior to invalidation, introduce a former allocator abstraction that can ensure entries are held during a single traversal. This also cleans up the abstraction and splits it out of the machine itself. PiperOrigin-RevId: 199581636 Change-Id: I2257d5d7ffd9c36f9b7ecd42f769261baeaf115c
Diffstat (limited to 'pkg/sentry/platform/ring0/pagetables/pagetables_x86.go')
-rw-r--r--pkg/sentry/platform/ring0/pagetables/pagetables_x86.go15
1 files changed, 10 insertions, 5 deletions
diff --git a/pkg/sentry/platform/ring0/pagetables/pagetables_x86.go b/pkg/sentry/platform/ring0/pagetables/pagetables_x86.go
index 8ba78ed0d..72a955d08 100644
--- a/pkg/sentry/platform/ring0/pagetables/pagetables_x86.go
+++ b/pkg/sentry/platform/ring0/pagetables/pagetables_x86.go
@@ -70,9 +70,9 @@ func (p *PageTables) CR3() uint64 {
// Bit 63 is set to avoid flushing the PCID (per SDM 4.10.4.1).
const noFlushBit uint64 = 0x8000000000000000
if p.pcid != 0 {
- return noFlushBit | uint64(p.root.physical) | uint64(p.pcid)
+ return noFlushBit | uint64(p.rootPhysical) | uint64(p.pcid)
}
- return uint64(p.root.physical)
+ return uint64(p.rootPhysical)
}
// FlushCR3 returns the CR3 value that flushes the TLB.
@@ -81,7 +81,7 @@ func (p *PageTables) CR3() uint64 {
//
//go:nosplit
func (p *PageTables) FlushCR3() uint64 {
- return uint64(p.root.physical) | uint64(p.pcid)
+ return uint64(p.rootPhysical) | uint64(p.pcid)
}
// Bits in page table entries.
@@ -200,8 +200,13 @@ func (p *PTE) Set(addr uintptr, opts MapOpts) {
// be cleared. This is used explicitly for breaking super pages.
//
//go:nosplit
-func (p *PTE) setPageTable(addr uintptr) {
- v := (addr &^ optionMask) | present | user | writable | accessed | dirty
+func (p *PTE) setPageTable(pt *PageTables, ptes *PTEs) {
+ addr := pt.Allocator.PhysicalFor(ptes)
+ if addr&^optionMask != addr {
+ // This should never happen.
+ panic("unaligned physical address!")
+ }
+ v := addr | present | user | writable | accessed | dirty
atomic.StoreUintptr((*uintptr)(p), v)
}