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  }