github.com/nicocha30/gvisor-ligolo@v0.0.0-20230726075806-989fa2c0a413/pkg/ring0/defs.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  package ring0
    16  
    17  import (
    18  	"github.com/nicocha30/gvisor-ligolo/pkg/ring0/pagetables"
    19  	"github.com/nicocha30/gvisor-ligolo/pkg/sentry/arch"
    20  	"github.com/nicocha30/gvisor-ligolo/pkg/sentry/arch/fpu"
    21  )
    22  
    23  // Kernel is a global kernel object.
    24  //
    25  // This contains global state, shared by multiple CPUs.
    26  type Kernel struct {
    27  	// PageTables are the kernel pagetables; this must be provided.
    28  	PageTables *pagetables.PageTables
    29  
    30  	KernelArchState
    31  }
    32  
    33  // Hooks are hooks for kernel functions.
    34  type Hooks interface {
    35  	// KernelSyscall is called for kernel system calls.
    36  	//
    37  	// Return from this call will restore registers and return to the kernel: the
    38  	// registers must be modified directly.
    39  	//
    40  	// If this function is not provided, a kernel exception results in halt.
    41  	//
    42  	// This must be go:nosplit, as this will be on the interrupt stack.
    43  	// Closures are permitted, as the pointer to the closure frame is not
    44  	// passed on the stack.
    45  	KernelSyscall()
    46  
    47  	// KernelException handles an exception during kernel execution.
    48  	//
    49  	// Return from this call will restore registers and return to the kernel: the
    50  	// registers must be modified directly.
    51  	//
    52  	// If this function is not provided, a kernel exception results in halt.
    53  	//
    54  	// This must be go:nosplit, as this will be on the interrupt stack.
    55  	// Closures are permitted, as the pointer to the closure frame is not
    56  	// passed on the stack.
    57  	KernelException(Vector)
    58  }
    59  
    60  // CPU is the per-CPU struct.
    61  type CPU struct {
    62  	// self is a self reference.
    63  	//
    64  	// This is always guaranteed to be at offset zero.
    65  	self *CPU
    66  
    67  	// kernel is reference to the kernel that this CPU was initialized
    68  	// with. This reference is kept for garbage collection purposes: CPU
    69  	// registers may refer to objects within the Kernel object that cannot
    70  	// be safely freed.
    71  	kernel *Kernel
    72  
    73  	// CPUArchState is architecture-specific state.
    74  	CPUArchState
    75  
    76  	// registers is a set of registers; these may be used on kernel system
    77  	// calls and exceptions via the Registers function.
    78  	registers arch.Registers
    79  
    80  	// floatingPointState holds floating point state.
    81  	floatingPointState fpu.State
    82  
    83  	// hooks are kernel hooks.
    84  	hooks Hooks
    85  }
    86  
    87  // Registers returns a modifiable-copy of the kernel registers.
    88  //
    89  // This is explicitly safe to call during KernelException and KernelSyscall.
    90  //
    91  //go:nosplit
    92  func (c *CPU) Registers() *arch.Registers {
    93  	return &c.registers
    94  }
    95  
    96  // FloatingPointState returns the kernel floating point state.
    97  //
    98  // This is explicitly safe to call during KernelException and KernelSyscall.
    99  //
   100  //go:nosplit
   101  func (c *CPU) FloatingPointState() *fpu.State {
   102  	return &c.floatingPointState
   103  }
   104  
   105  // SwitchOpts are passed to the Switch function.
   106  type SwitchOpts struct {
   107  	// Registers are the user register state.
   108  	Registers *arch.Registers
   109  
   110  	// FloatingPointState is a byte pointer where floating point state is
   111  	// saved and restored.
   112  	FloatingPointState *fpu.State
   113  
   114  	// PageTables are the application page tables.
   115  	PageTables *pagetables.PageTables
   116  
   117  	// Flush indicates that a TLB flush should be forced on switch.
   118  	Flush bool
   119  
   120  	// FullRestore indicates that an iret-based restore should be used.
   121  	FullRestore bool
   122  
   123  	// SwitchArchOpts are architecture-specific options.
   124  	SwitchArchOpts
   125  }