github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/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 CONTEXT_PC 0x1B8 33 #define CONTEXT_R0 0xB8 34 35 // getTLS returns the value of TPIDR_EL0 register. 36 TEXT ·getTLS(SB),NOSPLIT,$0-8 37 MRS TPIDR_EL0, R1 38 MOVD R1, ret+0(FP) 39 RET 40 41 // setTLS writes the TPIDR_EL0 value. 42 TEXT ·setTLS(SB),NOSPLIT,$0-8 43 MOVD addr+0(FP), R1 44 MSR R1, TPIDR_EL0 45 RET 46 47 // See bluepill.go. 48 TEXT ·bluepill(SB),NOSPLIT,$0 49 begin: 50 MOVD vcpu+0(FP), R8 51 MOVD $VCPU_CPU(R8), R9 52 ORR $0xffff000000000000, R9, R9 53 // Trigger sigill. 54 // In ring0.Start(), the value of R8 will be stored into tpidr_el1. 55 // When the context was loaded into vcpu successfully, 56 // we will check if the value of R10 and R9 are the same. 57 WORD $0xd538d08a // MRS TPIDR_EL1, R10 58 check_vcpu: 59 CMP R10, R9 60 BEQ right_vCPU 61 wrong_vcpu: 62 CALL ·redpill(SB) 63 B begin 64 right_vCPU: 65 RET 66 67 // sighandler: see bluepill.go for documentation. 68 // 69 // The arguments are the following: 70 // 71 // R0 - The signal number. 72 // R1 - Pointer to siginfo_t structure. 73 // R2 - Pointer to ucontext structure. 74 // 75 TEXT ·sighandler(SB),NOSPLIT,$0 76 // si_signo should be sigill. 77 MOVD SIGINFO_SIGNO(R1), R7 78 CMPW $4, R7 79 BNE fallback 80 81 MOVD CONTEXT_PC(R2), R7 82 CMPW $0, R7 83 BEQ fallback 84 85 MOVD R2, 8(RSP) 86 BL ·bluepillHandler(SB) // Call the handler. 87 88 RET 89 90 fallback: 91 // Jump to the previous signal handler. 92 MOVD ·savedHandler(SB), R7 93 B (R7) 94 95 // func addrOfSighandler() uintptr 96 TEXT ·addrOfSighandler(SB), $0-8 97 MOVD $·sighandler(SB), R0 98 MOVD R0, ret+0(FP) 99 RET 100 101 // dieTrampoline: see bluepill.go, bluepill_arm64_unsafe.go for documentation. 102 TEXT ·dieTrampoline(SB),NOSPLIT,$0 103 // R0: Fake the old PC as caller 104 // R1: First argument (vCPU) 105 MOVD.P R1, 8(RSP) // R1: First argument (vCPU) 106 MOVD.P R0, 8(RSP) // R0: Fake the old PC as caller 107 B ·dieHandler(SB) 108 109 // func addrOfDieTrampoline() uintptr 110 TEXT ·addrOfDieTrampoline(SB), $0-8 111 MOVD $·dieTrampoline(SB), R0 112 MOVD R0, ret+0(FP) 113 RET