gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/ring0/entry_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  	"gvisor.dev/gvisor/pkg/sentry/arch"
    22  )
    23  
    24  // This is an assembly function.
    25  //
    26  // The sysenter function is invoked in two situations:
    27  //
    28  //	(1) The guest kernel has executed a system call.
    29  //	(2) The guest application has executed a system call.
    30  //
    31  // The interrupt flag is examined to determine whether the system call was
    32  // executed from kernel mode or not and the appropriate stub is called.
    33  func sysenter()
    34  
    35  // addrOfSysenter returns the start address of sysenter.
    36  //
    37  // In Go 1.17+, Go references to assembly functions resolve to an ABIInternal
    38  // wrapper function rather than the function itself. We must reference from
    39  // assembly to get the ABI0 (i.e., primary) address.
    40  func addrOfSysenter() uintptr
    41  
    42  // jumpToKernel jumps to the kernel version of the current RIP.
    43  func jumpToKernel()
    44  
    45  // jumpToUser jumps to the user version of the current RIP.
    46  func jumpToUser()
    47  
    48  // sysret returns to userspace from a system call.
    49  //
    50  // The return code is the vector that interrupted execution.
    51  //
    52  // See stubs.go for a note regarding the frame size of this function.
    53  func sysret(cpu *CPU, regs *arch.Registers, userCR3 uintptr) Vector
    54  
    55  // "iret is the cadillac of CPL switching."
    56  //
    57  //	-- Neel Natu
    58  //
    59  // iret is nearly identical to sysret, except an iret is used to fully restore
    60  // all user state. This must be called in cases where all registers need to be
    61  // restored.
    62  func iret(cpu *CPU, regs *arch.Registers, userCR3 uintptr) Vector
    63  
    64  // exception is the generic exception entry.
    65  //
    66  // This is called by the individual stub definitions.
    67  func exception()
    68  
    69  // resume is a stub that restores the CPU kernel registers.
    70  //
    71  // This is used when processing kernel exceptions and syscalls.
    72  func resume()
    73  
    74  // start is the CPU entrypoint.
    75  //
    76  // See requirements below.
    77  func start()
    78  
    79  // AddrOfStart return the address of the CPU entrypoint.
    80  //
    81  // The following start conditions must be satisfied:
    82  //
    83  //   - AX should contain the CPU pointer.
    84  //   - c.GDT() should be loaded as the GDT.
    85  //   - c.IDT() should be loaded as the IDT.
    86  //   - c.CR0() should be the current CR0 value.
    87  //   - c.CR3() should be set to the kernel PageTables.
    88  //   - c.CR4() should be the current CR4 value.
    89  //   - c.EFER() should be the current EFER value.
    90  //
    91  // The CPU state will be set to c.Registers().
    92  //
    93  // In Go 1.17+, Go references to assembly functions resolve to an ABIInternal
    94  // wrapper function rather than the function itself. We must reference from
    95  // assembly to get the ABI0 (i.e., primary) address.
    96  func AddrOfStart() uintptr
    97  
    98  // Exception stubs.
    99  func divideByZero()
   100  func debug()
   101  func nmi()
   102  func breakpoint()
   103  func overflow()
   104  func boundRangeExceeded()
   105  func invalidOpcode()
   106  func deviceNotAvailable()
   107  func doubleFault()
   108  func coprocessorSegmentOverrun()
   109  func invalidTSS()
   110  func segmentNotPresent()
   111  func stackSegmentFault()
   112  func generalProtectionFault()
   113  func pageFault()
   114  func x87FloatingPointException()
   115  func alignmentCheck()
   116  func machineCheck()
   117  func simdFloatingPointException()
   118  func virtualizationException()
   119  func securityException()
   120  func syscallInt80()
   121  
   122  // These returns the start address of the functions above.
   123  //
   124  // In Go 1.17+, Go references to assembly functions resolve to an ABIInternal
   125  // wrapper function rather than the function itself. We must reference from
   126  // assembly to get the ABI0 (i.e., primary) address.
   127  func addrOfDivideByZero() uintptr
   128  func addrOfDebug() uintptr
   129  func addrOfNMI() uintptr
   130  func addrOfBreakpoint() uintptr
   131  func addrOfOverflow() uintptr
   132  func addrOfBoundRangeExceeded() uintptr
   133  func addrOfInvalidOpcode() uintptr
   134  func addrOfDeviceNotAvailable() uintptr
   135  func addrOfDoubleFault() uintptr
   136  func addrOfCoprocessorSegmentOverrun() uintptr
   137  func addrOfInvalidTSS() uintptr
   138  func addrOfSegmentNotPresent() uintptr
   139  func addrOfStackSegmentFault() uintptr
   140  func addrOfGeneralProtectionFault() uintptr
   141  func addrOfPageFault() uintptr
   142  func addrOfX87FloatingPointException() uintptr
   143  func addrOfAlignmentCheck() uintptr
   144  func addrOfMachineCheck() uintptr
   145  func addrOfSimdFloatingPointException() uintptr
   146  func addrOfVirtualizationException() uintptr
   147  func addrOfSecurityException() uintptr
   148  func addrOfSyscallInt80() uintptr
   149  
   150  // Exception handler index.
   151  var handlers = map[Vector]uintptr{
   152  	DivideByZero:               addrOfDivideByZero(),
   153  	Debug:                      addrOfDebug(),
   154  	NMI:                        addrOfNMI(),
   155  	Breakpoint:                 addrOfBreakpoint(),
   156  	Overflow:                   addrOfOverflow(),
   157  	BoundRangeExceeded:         addrOfBoundRangeExceeded(),
   158  	InvalidOpcode:              addrOfInvalidOpcode(),
   159  	DeviceNotAvailable:         addrOfDeviceNotAvailable(),
   160  	DoubleFault:                addrOfDoubleFault(),
   161  	CoprocessorSegmentOverrun:  addrOfCoprocessorSegmentOverrun(),
   162  	InvalidTSS:                 addrOfInvalidTSS(),
   163  	SegmentNotPresent:          addrOfSegmentNotPresent(),
   164  	StackSegmentFault:          addrOfStackSegmentFault(),
   165  	GeneralProtectionFault:     addrOfGeneralProtectionFault(),
   166  	PageFault:                  addrOfPageFault(),
   167  	X87FloatingPointException:  addrOfX87FloatingPointException(),
   168  	AlignmentCheck:             addrOfAlignmentCheck(),
   169  	MachineCheck:               addrOfMachineCheck(),
   170  	SIMDFloatingPointException: addrOfSimdFloatingPointException(),
   171  	VirtualizationException:    addrOfVirtualizationException(),
   172  	SecurityException:          addrOfSecurityException(),
   173  	SyscallInt80:               addrOfSyscallInt80(),
   174  }