github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/ring0/defs_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/hostarch"
    21  )
    22  
    23  var (
    24  	// UserspaceSize is the total size of userspace.
    25  	UserspaceSize = uintptr(1) << (VirtualAddressBits() - 1)
    26  
    27  	// MaximumUserAddress is the largest possible user address.
    28  	MaximumUserAddress = (UserspaceSize - 1) & ^uintptr(hostarch.PageSize-1)
    29  
    30  	// KernelStartAddress is the starting kernel address.
    31  	KernelStartAddress = ^uintptr(0) - (UserspaceSize - 1)
    32  )
    33  
    34  // Segment indices and Selectors.
    35  const (
    36  	// Index into GDT array.
    37  	_          = iota // Null descriptor first.
    38  	_                 // Reserved (Linux is kernel 32).
    39  	segKcode          // Kernel code (64-bit).
    40  	segKdata          // Kernel data.
    41  	segUcode32        // User code (32-bit).
    42  	segUdata          // User data.
    43  	segUcode64        // User code (64-bit).
    44  	segTss            // Task segment descriptor.
    45  	segTssHi          // Upper bits for TSS.
    46  	segLast           // Last segment (terminal, not included).
    47  )
    48  
    49  // Selectors.
    50  const (
    51  	Kcode   Selector = segKcode << 3
    52  	Kdata   Selector = segKdata << 3
    53  	Ucode32 Selector = (segUcode32 << 3) | 3
    54  	Udata   Selector = (segUdata << 3) | 3
    55  	Ucode64 Selector = (segUcode64 << 3) | 3
    56  	Tss     Selector = segTss << 3
    57  )
    58  
    59  // Standard segments.
    60  var (
    61  	UserCodeSegment32 SegmentDescriptor
    62  	UserDataSegment   SegmentDescriptor
    63  	UserCodeSegment64 SegmentDescriptor
    64  	KernelCodeSegment SegmentDescriptor
    65  	KernelDataSegment SegmentDescriptor
    66  )
    67  
    68  // KernelArchState contains architecture-specific state.
    69  type KernelArchState struct {
    70  	// cpuEntries is array of kernelEntry for all cpus.
    71  	cpuEntries []kernelEntry
    72  
    73  	// globalIDT is our set of interrupt gates.
    74  	globalIDT *idt64
    75  }
    76  
    77  // kernelEntry contains minimal CPU-specific arch state
    78  // that can be mapped at the upper of the address space.
    79  // Malicious APP might steal info from it via CPU bugs.
    80  type kernelEntry struct {
    81  	// stack is the stack used for interrupts on this CPU.
    82  	stack [256]byte
    83  
    84  	// scratch space for temporary usage.
    85  	scratch0 uint64
    86  
    87  	// stackTop is the top of the stack.
    88  	stackTop uint64
    89  
    90  	// cpuSelf is back reference to CPU.
    91  	cpuSelf *CPU
    92  
    93  	// kernelCR3 is the cr3 used for sentry kernel.
    94  	kernelCR3 uintptr
    95  
    96  	// gdt is the CPU's descriptor table.
    97  	gdt descriptorTable
    98  
    99  	// tss is the CPU's task state.
   100  	tss TaskState64
   101  }
   102  
   103  // CPUArchState contains CPU-specific arch state.
   104  type CPUArchState struct {
   105  	// errorCode is the error code from the last exception.
   106  	errorCode uintptr
   107  
   108  	// errorType indicates the type of error code here, it is always set
   109  	// along with the errorCode value above.
   110  	//
   111  	// It will either by 1, which indicates a user error, or 0 indicating a
   112  	// kernel error. If the error code below returns false (kernel error),
   113  	// then it cannot provide relevant information about the last
   114  	// exception.
   115  	errorType uintptr
   116  
   117  	*kernelEntry
   118  }
   119  
   120  // ErrorCode returns the last error code.
   121  //
   122  // The returned boolean indicates whether the error code corresponds to the
   123  // last user error or not. If it does not, then fault information must be
   124  // ignored. This is generally the result of a kernel fault while servicing a
   125  // user fault.
   126  //
   127  //go:nosplit
   128  func (c *CPU) ErrorCode() (value uintptr, user bool) {
   129  	return c.errorCode, c.errorType != 0
   130  }
   131  
   132  // ClearErrorCode resets the error code.
   133  //
   134  //go:nosplit
   135  func (c *CPU) ClearErrorCode() {
   136  	c.errorCode = 0 // No code.
   137  	c.errorType = 1 // User mode.
   138  }
   139  
   140  // SwitchArchOpts are embedded in SwitchOpts.
   141  type SwitchArchOpts struct {
   142  	// UserPCID indicates that the application PCID to be used on switch,
   143  	// assuming that PCIDs are supported.
   144  	//
   145  	// Per pagetables_x86.go, a zero PCID implies a flush.
   146  	UserPCID uint16
   147  
   148  	// KernelPCID indicates that the kernel PCID to be used on return,
   149  	// assuming that PCIDs are supported.
   150  	//
   151  	// Per pagetables_x86.go, a zero PCID implies a flush.
   152  	KernelPCID uint16
   153  }
   154  
   155  func init() {
   156  	KernelCodeSegment.setCode64(0, 0, 0)
   157  	KernelDataSegment.setData(0, 0xffffffff, 0)
   158  	UserCodeSegment32.setCode64(0, 0, 3)
   159  	UserDataSegment.setData(0, 0xffffffff, 3)
   160  	UserCodeSegment64.setCode64(0, 0, 3)
   161  }