github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/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 // +build amd64 16 17 package ring0 18 19 import ( 20 "github.com/SagerNet/gvisor/pkg/cpuid" 21 ) 22 23 // LoadFloatingPoint loads floating point state by the most efficient mechanism 24 // available (set by Init). 25 var LoadFloatingPoint func(*byte) 26 27 // SaveFloatingPoint saves floating point state by the most efficient mechanism 28 // available (set by Init). 29 var SaveFloatingPoint func(*byte) 30 31 // fxrstor uses fxrstor64 to load floating point state. 32 func fxrstor(*byte) 33 34 // xrstor uses xrstor to load floating point state. 35 func xrstor(*byte) 36 37 // fxsave uses fxsave64 to save floating point state. 38 func fxsave(*byte) 39 40 // xsave uses xsave to save floating point state. 41 func xsave(*byte) 42 43 // xsaveopt uses xsaveopt to save floating point state. 44 func xsaveopt(*byte) 45 46 // WriteFS sets the GS address (set by init). 47 var WriteFS func(addr uintptr) 48 49 // wrfsbase writes to the GS base address. 50 func wrfsbase(addr uintptr) 51 52 // wrfsmsr writes to the GS_BASE MSR. 53 func wrfsmsr(addr uintptr) 54 55 // WriteGS sets the GS address (set by init). 56 var WriteGS func(addr uintptr) 57 58 // wrgsbase writes to the GS base address. 59 func wrgsbase(addr uintptr) 60 61 // wrgsmsr writes to the GS_BASE MSR. 62 func wrgsmsr(addr uintptr) 63 64 // stmxcsr reads the MXCSR control and status register. 65 func stmxcsr(addr *uint32) 66 67 // ldmxcsr writes to the MXCSR control and status register. 68 func ldmxcsr(addr *uint32) 69 70 // readCR2 reads the current CR2 value. 71 func readCR2() uintptr 72 73 // fninit initializes the floating point unit. 74 func fninit() 75 76 // xsetbv writes to an extended control register. 77 func xsetbv(reg, value uintptr) 78 79 // xgetbv reads an extended control register. 80 func xgetbv(reg uintptr) uintptr 81 82 // wrmsr reads to the given MSR. 83 func wrmsr(reg, value uintptr) 84 85 // rdmsr reads the given MSR. 86 func rdmsr(reg uintptr) uintptr 87 88 // Mostly-constants set by Init. 89 var ( 90 hasSMEP bool 91 hasPCID bool 92 hasXSAVEOPT bool 93 hasXSAVE bool 94 hasFSGSBASE bool 95 validXCR0Mask uintptr 96 ) 97 98 // Init sets function pointers based on architectural features. 99 // 100 // This must be called prior to using ring0. 101 func Init(featureSet *cpuid.FeatureSet) { 102 hasSMEP = featureSet.HasFeature(cpuid.X86FeatureSMEP) 103 hasPCID = featureSet.HasFeature(cpuid.X86FeaturePCID) 104 hasXSAVEOPT = featureSet.UseXsaveopt() 105 hasXSAVE = featureSet.UseXsave() 106 hasFSGSBASE = featureSet.HasFeature(cpuid.X86FeatureFSGSBase) 107 validXCR0Mask = uintptr(featureSet.ValidXCR0Mask()) 108 if hasXSAVEOPT { 109 SaveFloatingPoint = xsaveopt 110 LoadFloatingPoint = xrstor 111 } else if hasXSAVE { 112 SaveFloatingPoint = xsave 113 LoadFloatingPoint = xrstor 114 } else { 115 SaveFloatingPoint = fxsave 116 LoadFloatingPoint = fxrstor 117 } 118 if hasFSGSBASE { 119 WriteFS = wrfsbase 120 WriteGS = wrgsbase 121 } else { 122 WriteFS = wrfsmsr 123 WriteGS = wrgsmsr 124 } 125 }