github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/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  // +build amd64
    16  
    17  package ring0
    18  
    19  import (
    20  	"github.com/SagerNet/gvisor/pkg/sentry/arch"
    21  )
    22  
    23  // This is an assembly function.
    24  //
    25  // The sysenter function is invoked in two situations:
    26  //
    27  //  (1) The guest kernel has executed a system call.
    28  //  (2) The guest application has executed a system call.
    29  //
    30  // The interrupt flag is examined to determine whether the system call was
    31  // executed from kernel mode or not and the appropriate stub is called.
    32  func sysenter()
    33  
    34  // swapgs swaps the current GS value.
    35  //
    36  // This must be called prior to sysret/iret.
    37  func swapgs()
    38  
    39  // jumpToKernel jumps to the kernel version of the current RIP.
    40  func jumpToKernel()
    41  
    42  // sysret returns to userspace from a system call.
    43  //
    44  // The return code is the vector that interrupted execution.
    45  //
    46  // See stubs.go for a note regarding the frame size of this function.
    47  func sysret(cpu *CPU, regs *arch.Registers, userCR3 uintptr) Vector
    48  
    49  // "iret is the cadillac of CPL switching."
    50  //
    51  //				-- Neel Natu
    52  //
    53  // iret is nearly identical to sysret, except an iret is used to fully restore
    54  // all user state. This must be called in cases where all registers need to be
    55  // restored.
    56  func iret(cpu *CPU, regs *arch.Registers, userCR3 uintptr) Vector
    57  
    58  // exception is the generic exception entry.
    59  //
    60  // This is called by the individual stub definitions.
    61  func exception()
    62  
    63  // resume is a stub that restores the CPU kernel registers.
    64  //
    65  // This is used when processing kernel exceptions and syscalls.
    66  func resume()
    67  
    68  // Start is the CPU entrypoint.
    69  //
    70  // The following start conditions must be satisfied:
    71  //
    72  //  * AX should contain the CPU pointer.
    73  //  * c.GDT() should be loaded as the GDT.
    74  //  * c.IDT() should be loaded as the IDT.
    75  //  * c.CR0() should be the current CR0 value.
    76  //  * c.CR3() should be set to the kernel PageTables.
    77  //  * c.CR4() should be the current CR4 value.
    78  //  * c.EFER() should be the current EFER value.
    79  //
    80  // The CPU state will be set to c.Registers().
    81  func Start()
    82  
    83  // Exception stubs.
    84  func divideByZero()
    85  func debug()
    86  func nmi()
    87  func breakpoint()
    88  func overflow()
    89  func boundRangeExceeded()
    90  func invalidOpcode()
    91  func deviceNotAvailable()
    92  func doubleFault()
    93  func coprocessorSegmentOverrun()
    94  func invalidTSS()
    95  func segmentNotPresent()
    96  func stackSegmentFault()
    97  func generalProtectionFault()
    98  func pageFault()
    99  func x87FloatingPointException()
   100  func alignmentCheck()
   101  func machineCheck()
   102  func simdFloatingPointException()
   103  func virtualizationException()
   104  func securityException()
   105  func syscallInt80()
   106  
   107  // Exception handler index.
   108  var handlers = map[Vector]func(){
   109  	DivideByZero:               divideByZero,
   110  	Debug:                      debug,
   111  	NMI:                        nmi,
   112  	Breakpoint:                 breakpoint,
   113  	Overflow:                   overflow,
   114  	BoundRangeExceeded:         boundRangeExceeded,
   115  	InvalidOpcode:              invalidOpcode,
   116  	DeviceNotAvailable:         deviceNotAvailable,
   117  	DoubleFault:                doubleFault,
   118  	CoprocessorSegmentOverrun:  coprocessorSegmentOverrun,
   119  	InvalidTSS:                 invalidTSS,
   120  	SegmentNotPresent:          segmentNotPresent,
   121  	StackSegmentFault:          stackSegmentFault,
   122  	GeneralProtectionFault:     generalProtectionFault,
   123  	PageFault:                  pageFault,
   124  	X87FloatingPointException:  x87FloatingPointException,
   125  	AlignmentCheck:             alignmentCheck,
   126  	MachineCheck:               machineCheck,
   127  	SIMDFloatingPointException: simdFloatingPointException,
   128  	VirtualizationException:    virtualizationException,
   129  	SecurityException:          securityException,
   130  	SyscallInt80:               syscallInt80,
   131  }