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