github.com/MerlinKodo/gvisor@v0.0.0-20231110090155-957f62ecf90e/pkg/ring0/pagetables/pagetables_arm64.go (about)

     1  // Copyright 2019 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package pagetables
    16  
    17  // Address constraints.
    18  //
    19  // The lowerTop and upperBottom currently apply to four-level pagetables;
    20  // additional refactoring would be necessary to support five-level pagetables.
    21  const (
    22  	lowerTop    = 0x0000ffffffffffff
    23  	upperBottom = 0xffff000000000000
    24  	pteShift    = 12
    25  	pmdShift    = 21
    26  	pudShift    = 30
    27  	pgdShift    = 39
    28  
    29  	pteMask = 0x1ff << pteShift
    30  	pmdMask = 0x1ff << pmdShift
    31  	pudMask = 0x1ff << pudShift
    32  	pgdMask = 0x1ff << pgdShift
    33  
    34  	pteSize = 1 << pteShift
    35  	pmdSize = 1 << pmdShift
    36  	pudSize = 1 << pudShift
    37  	pgdSize = 1 << pgdShift
    38  
    39  	ttbrASIDOffset = 48
    40  	ttbrASIDMask   = 0xff
    41  
    42  	entriesPerPage = 512
    43  )
    44  
    45  // InitArch does some additional initialization related to the architecture.
    46  //
    47  // +checkescape:hard,stack
    48  //
    49  //go:nosplit
    50  func (p *PageTables) InitArch(allocator Allocator) {
    51  	if p.upperSharedPageTables != nil {
    52  		p.cloneUpperShared()
    53  	} else {
    54  		p.archPageTables.root = p.Allocator.NewPTEs()
    55  		p.archPageTables.rootPhysical = p.Allocator.PhysicalFor(p.archPageTables.root)
    56  	}
    57  }
    58  
    59  // cloneUpperShared clone the upper from the upper shared page tables.
    60  //
    61  //go:nosplit
    62  func (p *PageTables) cloneUpperShared() {
    63  	if p.upperStart != upperBottom {
    64  		panic("upperStart should be the same as upperBottom")
    65  	}
    66  
    67  	p.archPageTables.root = p.upperSharedPageTables.archPageTables.root
    68  	p.archPageTables.rootPhysical = p.upperSharedPageTables.archPageTables.rootPhysical
    69  }
    70  
    71  // PTEs is a collection of entries.
    72  type PTEs [entriesPerPage]PTE