github.com/MerlinKodo/gvisor@v0.0.0-20231110090155-957f62ecf90e/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/MerlinKodo/gvisor/pkg/cpuid"
    22  	"github.com/MerlinKodo/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  		localXCR0 = xgetbv(0)
   123  	}
   124  }
   125  
   126  // InitDefault initializes ring0 with the auto-detected host feature set.
   127  func InitDefault() {
   128  	cpuid.Initialize()
   129  	Init(cpuid.HostFeatureSet())
   130  }