github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/ring0/kernel_arm64.go (about) 1 // Copyright 2019 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 arm64 16 17 package ring0 18 19 // HaltAndResume halts execution and point the pointer to the resume function. 20 //go:nosplit 21 func HaltAndResume() 22 23 // HaltEl1SvcAndResume calls Hooks.KernelSyscall and resume. 24 //go:nosplit 25 func HaltEl1SvcAndResume() 26 27 // HaltEl1ExceptionAndResume calls Hooks.KernelException and resume. 28 //go:nosplit 29 func HaltEl1ExceptionAndResume() 30 31 // init initializes architecture-specific state. 32 func (k *Kernel) init(maxCPUs int) { 33 } 34 35 // init initializes architecture-specific state. 36 func (c *CPU) init(cpuID int) { 37 // Set the kernel stack pointer(virtual address). 38 c.registers.Sp = uint64(c.StackTop()) 39 40 } 41 42 // StackTop returns the kernel's stack address. 43 // 44 //go:nosplit 45 func (c *CPU) StackTop() uint64 { 46 return uint64(kernelAddr(&c.stack[0])) + uint64(len(c.stack)) 47 } 48 49 // IsCanonical indicates whether addr is canonical per the arm64 spec. 50 // 51 //go:nosplit 52 func IsCanonical(addr uint64) bool { 53 return addr <= 0x0000ffffffffffff || addr > 0xffff000000000000 54 } 55 56 // SwitchToUser performs an eret. 57 // 58 // The return value is the exception vector. 59 // 60 // +checkescape:all 61 // 62 //go:nosplit 63 func (c *CPU) SwitchToUser(switchOpts SwitchOpts) (vector Vector) { 64 storeAppASID(uintptr(switchOpts.UserASID)) 65 storeEl0Fpstate(switchOpts.FloatingPointState.BytePointer()) 66 67 if switchOpts.Flush { 68 LocalFlushTlbByASID(uintptr(switchOpts.UserASID)) 69 } 70 71 regs := switchOpts.Registers 72 73 regs.Pstate &= ^uint64(PsrFlagsClear) 74 regs.Pstate |= UserFlagsSet 75 76 fpDisableTrap := CPACREL1() 77 if fpDisableTrap != 0 { 78 FPSIMDEnableTrap() 79 } 80 81 kernelExitToEl0() 82 83 fpDisableTrap = CPACREL1() 84 if fpDisableTrap != 0 { 85 SaveFloatingPoint(switchOpts.FloatingPointState.BytePointer()) 86 } 87 88 vector = c.vecCode 89 90 return 91 } 92 93 // RestoreKernelFPState restores the Sentry floating point state. 94 // 95 //go:nosplit 96 func RestoreKernelFPState() { 97 }