github.com/metacubex/gvisor@v0.0.0-20240320004321-933faba989ec/pkg/sentry/platform/kvm/bluepill_arm64.s (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 #include "textflag.h" 16 17 // VCPU_CPU is the location of the CPU in the vCPU struct. 18 // 19 // This is guaranteed to be zero. 20 #define VCPU_CPU 0x0 21 22 // CPU_SELF is the self reference in ring0's percpu. 23 // 24 // This is guaranteed to be zero. 25 #define CPU_SELF 0x0 26 27 // Context offsets. 28 // 29 // Only limited use of the context is done in the assembly stub below, most is 30 // done in the Go handlers. 31 #define SIGINFO_SIGNO 0x0 32 #define SIGINFO_CODE 0x8 33 #define CONTEXT_PC 0x1B8 34 #define CONTEXT_R0 0xB8 35 36 #define SYS_MMAP 222 37 38 // getTLS returns the value of TPIDR_EL0 register. 39 TEXT ·getTLS(SB),NOSPLIT,$0-8 40 MRS TPIDR_EL0, R1 41 MOVD R1, value+0(FP) 42 RET 43 44 // setTLS writes the TPIDR_EL0 value. 45 TEXT ·setTLS(SB),NOSPLIT,$0-8 46 MOVD value+0(FP), R1 47 MSR R1, TPIDR_EL0 48 RET 49 50 // See bluepill.go. 51 TEXT ·bluepill(SB),NOSPLIT,$0 52 begin: 53 MOVD arg+0(FP), R8 54 MOVD $VCPU_CPU(R8), R9 55 ORR $0xffff000000000000, R9, R9 56 // Trigger sigill. 57 // In ring0.Start(), the value of R8 will be stored into tpidr_el1. 58 // When the context was loaded into vcpu successfully, 59 // we will check if the value of R10 and R9 are the same. 60 WORD $0xd538d08a // MRS TPIDR_EL1, R10 61 check_vcpu: 62 CMP R10, R9 63 BEQ right_vCPU 64 wrong_vcpu: 65 CALL ·redpill(SB) 66 B begin 67 right_vCPU: 68 RET 69 70 // sighandler: see bluepill.go for documentation. 71 // 72 // The arguments are the following: 73 // 74 // R0 - The signal number. 75 // R1 - Pointer to siginfo_t structure. 76 // R2 - Pointer to ucontext structure. 77 // 78 TEXT ·sighandler(SB),NOSPLIT,$0 79 // si_signo should be sigill. 80 MOVD SIGINFO_SIGNO(R1), R7 81 CMPW $4, R7 82 BNE fallback 83 84 MOVD CONTEXT_PC(R2), R7 85 CMPW $0, R7 86 BEQ fallback 87 88 MOVD R2, 8(RSP) 89 BL ·bluepillHandler(SB) // Call the handler. 90 91 RET 92 93 fallback: 94 // Jump to the previous signal handler. 95 MOVD ·savedHandler(SB), R7 96 B (R7) 97 98 // func addrOfSighandler() uintptr 99 TEXT ·addrOfSighandler(SB), $0-8 100 MOVD $·sighandler(SB), R0 101 MOVD R0, ret+0(FP) 102 RET 103 104 // The arguments are the following: 105 // 106 // R0 - The signal number. 107 // R1 - Pointer to siginfo_t structure. 108 // R2 - Pointer to ucontext structure. 109 // 110 TEXT ·sigsysHandler(SB),NOSPLIT,$0 111 // si_code should be SYS_SECCOMP. 112 MOVD SIGINFO_CODE(R1), R7 113 CMPW $1, R7 114 BNE fallback 115 116 CMPW $SYS_MMAP, R8 117 BNE fallback 118 119 MOVD R2, 8(RSP) 120 BL ·seccompMmapHandler(SB) // Call the handler. 121 122 RET 123 124 fallback: 125 // Jump to the previous signal handler. 126 MOVD ·savedHandler(SB), R7 127 B (R7) 128 129 // func addrOfSighandler() uintptr 130 TEXT ·addrOfSigsysHandler(SB), $0-8 131 MOVD $·sigsysHandler(SB), R0 132 MOVD R0, ret+0(FP) 133 RET 134 135 // dieTrampoline: see bluepill.go, bluepill_arm64_unsafe.go for documentation. 136 TEXT ·dieTrampoline(SB),NOSPLIT,$0 137 // R0: Fake the old PC as caller 138 // R1: First argument (vCPU) 139 MOVD.P R1, 8(RSP) // R1: First argument (vCPU) 140 MOVD.P R0, 8(RSP) // R0: Fake the old PC as caller 141 B ·dieHandler(SB) 142 143 // func addrOfDieTrampoline() uintptr 144 TEXT ·addrOfDieTrampoline(SB), $0-8 145 MOVD $·dieTrampoline(SB), R0 146 MOVD R0, ret+0(FP) 147 RET