github.com/metacubex/gvisor@v0.0.0-20240320004321-933faba989ec/pkg/ring0/lib_amd64.go (about) 1 // Copyright 2018 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 //go:build amd64 16 // +build amd64 17 18 package ring0 19 20 import ( 21 "github.com/metacubex/gvisor/pkg/cpuid" 22 "github.com/metacubex/gvisor/pkg/hostarch" 23 ) 24 25 // fxrstor restores floating point state. 26 func fxrstor(addr uintptr) 27 28 // xrstor restores floating point state. 29 func xrstor(addr uintptr) 30 31 // fxsave saves floating point state. 32 func fxsave(addr uintptr) 33 34 // xsave saves floating point state. 35 func xsave(addr uintptr) 36 37 // xsaveopt saves floating point state. 38 func xsaveopt(addr uintptr) 39 40 // writeFS sets the FS base address (selects one of wrfsbase or wrfsmsr). 41 func writeFS(addr uintptr) 42 43 // wrfsbase writes to the GS base address. 44 func wrfsbase(addr uintptr) 45 46 // wrfsmsr writes to the GS_BASE MSR. 47 func wrfsmsr(addr uintptr) 48 49 // writeGS sets the GS address (selects one of wrgsbase or wrgsmsr). 50 func writeGS(addr uintptr) 51 52 // wrgsbase writes to the GS base address. 53 func wrgsbase(addr uintptr) 54 55 // wrgsmsr writes to the GS_BASE MSR. 56 func wrgsmsr(addr uintptr) 57 58 // stmxcsr reads the MXCSR control and status register. 59 func stmxcsr(addr *uint32) 60 61 // ldmxcsr writes to the MXCSR control and status register. 62 func ldmxcsr(addr *uint32) 63 64 // readCR2 reads the current CR2 value. 65 func readCR2() uintptr 66 67 // fninit initializes the floating point unit. 68 func fninit() 69 70 // xsetbv writes to an extended control register. 71 func xsetbv(reg, value uintptr) 72 73 // xgetbv reads an extended control register. 74 func xgetbv(reg uintptr) uintptr 75 76 // wrmsr reads to the given MSR. 77 func wrmsr(reg, value uintptr) 78 79 // rdmsr reads the given MSR. 80 func rdmsr(reg uintptr) uintptr 81 82 // Mostly-constants set by Init. 83 var ( 84 hasSMEP bool 85 hasSMAP bool 86 hasPCID bool 87 hasXSAVEOPT bool 88 hasXSAVE bool 89 hasFSGSBASE bool 90 validXCR0Mask uintptr 91 localXCR0 uintptr 92 ) 93 94 // Init sets function pointers based on architectural features. 95 // 96 // This must be called prior to using ring0. It may be called with the 97 // auto-detected feature set using InitDefault. It may also be called at 98 // another time with a different FeatureSet. 99 func Init(fs cpuid.FeatureSet) { 100 // Initialize all sizes. 101 VirtualAddressBits = uintptr(fs.VirtualAddressBits()) 102 // TODO(gvisor.dev/issue/7349): introduce support for 5-level paging. 103 // Four-level page tables allows to address up to 48-bit virtual 104 // addresses. 105 if VirtualAddressBits > 48 { 106 VirtualAddressBits = 48 107 } 108 PhysicalAddressBits = uintptr(fs.PhysicalAddressBits()) 109 UserspaceSize = uintptr(1) << (VirtualAddressBits - 1) 110 MaximumUserAddress = (UserspaceSize - 1) & ^uintptr(hostarch.PageSize-1) 111 KernelStartAddress = ^uintptr(0) - (UserspaceSize - 1) 112 113 // Initialize all functions. 114 hasSMEP = fs.HasFeature(cpuid.X86FeatureSMEP) 115 hasSMAP = fs.HasFeature(cpuid.X86FeatureSMAP) 116 hasPCID = fs.HasFeature(cpuid.X86FeaturePCID) 117 hasXSAVEOPT = fs.UseXsaveopt() 118 hasXSAVE = fs.UseXsave() 119 hasFSGSBASE = fs.HasFeature(cpuid.X86FeatureFSGSBase) 120 validXCR0Mask = uintptr(fs.ValidXCR0Mask()) 121 if hasXSAVE { 122 XCR0DisabledMask := uintptr((1 << 9) | (1 << 17) | (1 << 18)) 123 localXCR0 = xgetbv(0) &^ XCR0DisabledMask 124 } 125 } 126 127 // InitDefault initializes ring0 with the auto-detected host feature set. 128 func InitDefault() { 129 cpuid.Initialize() 130 Init(cpuid.HostFeatureSet()) 131 }