arm64 kvm bug fix: pagetables_test & kvm_test failed due to upper-shared-pt feature

Signed-off-by: Robin Luk <lubin.lu@alibaba-inc.com>
This commit is contained in:
Bin Lu 2020-11-12 02:46:12 +00:00 committed by Robin Luk
parent 9c4102896d
commit c755eaff1c
5 changed files with 38 additions and 14 deletions

View File

@ -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
}

View File

@ -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.

View File

@ -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 {

View File

@ -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.

View File

@ -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++ {