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 }