Merge pull request #4791 from lubinszARM:pr_pt_upper

PiperOrigin-RevId: 343130667
This commit is contained in:
gVisor bot
2020-11-18 12:20:22 -08:00
5 changed files with 38 additions and 14 deletions
@@ -58,6 +58,15 @@ type PageTables struct {
readOnlyShared bool
}
// Init initializes a set of PageTables.
//
//go:nosplit
func (p *PageTables) Init(allocator Allocator) {
p.Allocator = allocator
p.root = p.Allocator.NewPTEs()
p.rootPhysical = p.Allocator.PhysicalFor(p.root)
}
// NewWithUpper returns new PageTables.
//
// upperSharedPageTables are used for mapping the upper of addresses,
@@ -73,14 +82,17 @@ type PageTables struct {
func NewWithUpper(a Allocator, upperSharedPageTables *PageTables, upperStart uintptr) *PageTables {
p := new(PageTables)
p.Init(a)
if upperSharedPageTables != nil {
if !upperSharedPageTables.readOnlyShared {
panic("Only read-only shared pagetables can be used as upper")
}
p.upperSharedPageTables = upperSharedPageTables
p.upperStart = upperStart
p.cloneUpperShared()
}
p.InitArch(a)
return p
}
@@ -24,6 +24,14 @@ import (
// archPageTables is architecture-specific data.
type archPageTables struct {
// root is the pagetable root for kernel space.
root *PTEs
// rootPhysical is the cached physical address of the root.
//
// This is saved only to prevent constant translation.
rootPhysical uintptr
asid uint16
}
@@ -38,7 +46,7 @@ func (p *PageTables) TTBR0_EL1(noFlush bool, asid uint16) uint64 {
//
//go:nosplit
func (p *PageTables) TTBR1_EL1(noFlush bool, asid uint16) uint64 {
return uint64(p.upperSharedPageTables.rootPhysical) | (uint64(asid)&ttbrASIDMask)<<ttbrASIDOffset
return uint64(p.archPageTables.rootPhysical) | (uint64(asid)&ttbrASIDMask)<<ttbrASIDOffset
}
// Bits in page table entries.
@@ -41,13 +41,13 @@ const (
entriesPerPage = 512
)
// Init initializes a set of PageTables.
// InitArch does some additional initialization related to the architecture.
//
//go:nosplit
func (p *PageTables) Init(allocator Allocator) {
p.Allocator = allocator
p.root = p.Allocator.NewPTEs()
p.rootPhysical = p.Allocator.PhysicalFor(p.root)
func (p *PageTables) InitArch(allocator Allocator) {
if p.upperSharedPageTables != nil {
p.cloneUpperShared()
}
}
func pgdIndex(upperStart uintptr) uintptr {
@@ -42,13 +42,16 @@ const (
entriesPerPage = 512
)
// Init initializes a set of PageTables.
// InitArch does some additional initialization related to the architecture.
//
//go:nosplit
func (p *PageTables) Init(allocator Allocator) {
p.Allocator = allocator
p.root = p.Allocator.NewPTEs()
p.rootPhysical = p.Allocator.PhysicalFor(p.root)
func (p *PageTables) InitArch(allocator Allocator) {
if p.upperSharedPageTables != nil {
p.cloneUpperShared()
} else {
p.archPageTables.root = p.Allocator.NewPTEs()
p.archPageTables.rootPhysical = p.Allocator.PhysicalFor(p.archPageTables.root)
}
}
// cloneUpperShared clone the upper from the upper shared page tables.
@@ -59,7 +62,8 @@ func (p *PageTables) cloneUpperShared() {
panic("upperStart should be the same as upperBottom")
}
// nothing to do for arm.
p.archPageTables.root = p.upperSharedPageTables.archPageTables.root
p.archPageTables.rootPhysical = p.upperSharedPageTables.archPageTables.rootPhysical
}
// PTEs is a collection of entries.
@@ -116,7 +116,7 @@ func next(start uintptr, size uintptr) uintptr {
func (w *Walker) iterateRangeCanonical(start, end uintptr) {
pgdEntryIndex := w.pageTables.root
if start >= upperBottom {
pgdEntryIndex = w.pageTables.upperSharedPageTables.root
pgdEntryIndex = w.pageTables.archPageTables.root
}
for pgdIndex := (uint16((start & pgdMask) >> pgdShift)); start < end && pgdIndex < entriesPerPage; pgdIndex++ {