1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build amd64
// +build amd64
package ring0
import (
"gvisor.dev/gvisor/pkg/cpuid"
"gvisor.dev/gvisor/pkg/hostarch"
)
// fxrstor restores floating point state.
func fxrstor(addr uintptr)
// xrstor restores floating point state.
func xrstor(addr uintptr)
// fxsave saves floating point state.
func fxsave(addr uintptr)
// xsave saves floating point state.
func xsave(addr uintptr)
// xsaveopt saves floating point state.
func xsaveopt(addr uintptr)
// writeFS sets the FS base address (selects one of wrfsbase or wrfsmsr).
func writeFS(addr uintptr)
// wrfsbase writes to the GS base address.
func wrfsbase(addr uintptr)
// wrfsmsr writes to the GS_BASE MSR.
func wrfsmsr(addr uintptr)
// writeGS sets the GS address (selects one of wrgsbase or wrgsmsr).
func writeGS(addr uintptr)
// wrgsbase writes to the GS base address.
func wrgsbase(addr uintptr)
// wrgsmsr writes to the GS_BASE MSR.
func wrgsmsr(addr uintptr)
// stmxcsr reads the MXCSR control and status register.
func stmxcsr(addr *uint32)
// ldmxcsr writes to the MXCSR control and status register.
func ldmxcsr(addr *uint32)
// readCR2 reads the current CR2 value.
func readCR2() uintptr
// fninit initializes the floating point unit.
func fninit()
// xsetbv writes to an extended control register.
func xsetbv(reg, value uintptr)
// xgetbv reads an extended control register.
func xgetbv(reg uintptr) uintptr
// wrmsr reads to the given MSR.
func wrmsr(reg, value uintptr)
// rdmsr reads the given MSR.
func rdmsr(reg uintptr) uintptr
// Mostly-constants set by Init.
var (
hasSMEP bool
hasSMAP bool
hasPCID bool
hasXSAVEOPT bool
hasXSAVE bool
hasFSGSBASE bool
validXCR0Mask uintptr
localXCR0 uintptr
)
// Init sets function pointers based on architectural features.
//
// This must be called prior to using ring0. It may be called with the
// auto-detected feature set using InitDefault. It may also be called at
// another time with a different FeatureSet.
func Init(fs cpuid.FeatureSet) {
// Initialize all sizes.
VirtualAddressBits = uintptr(fs.VirtualAddressBits())
// TODO(gvisor.dev/issue/7349): introduce support for 5-level paging.
// Four-level page tables allows to address up to 48-bit virtual
// addresses.
if VirtualAddressBits > 48 {
VirtualAddressBits = 48
}
PhysicalAddressBits = uintptr(fs.PhysicalAddressBits())
UserspaceSize = uintptr(1) << (VirtualAddressBits - 1)
MaximumUserAddress = (UserspaceSize - 1) & ^uintptr(hostarch.PageSize-1)
KernelStartAddress = ^uintptr(0) - (UserspaceSize - 1)
// Initialize all functions.
hasSMEP = fs.HasFeature(cpuid.X86FeatureSMEP)
hasSMAP = fs.HasFeature(cpuid.X86FeatureSMAP)
hasPCID = fs.HasFeature(cpuid.X86FeaturePCID)
hasXSAVEOPT = fs.UseXsaveopt()
hasXSAVE = fs.UseXsave()
hasFSGSBASE = fs.HasFeature(cpuid.X86FeatureFSGSBase)
validXCR0Mask = uintptr(fs.ValidXCR0Mask())
if hasXSAVE {
XCR0DisabledMask := uintptr((1 << 9) | (1 << 17) | (1 << 18))
localXCR0 = xgetbv(0) &^ XCR0DisabledMask
}
}
// InitDefault initializes ring0 with the auto-detected host feature set.
func InitDefault() {
cpuid.Initialize()
Init(cpuid.HostFeatureSet())
}
|