github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/sentry/platform/kvm/bluepill_amd64.s (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 #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 // Context offsets. 23 // 24 // Only limited use of the context is done in the assembly stub below, most is 25 // done in the Go handlers. However, the RIP must be examined. 26 #define CONTEXT_RAX 0x90 27 #define CONTEXT_RIP 0xa8 28 #define CONTEXT_FP 0xe0 29 30 // CLI is the literal byte for the disable interrupts instruction. 31 // 32 // This is checked as the source of the fault. 33 #define CLI $0xfa 34 35 // See bluepill.go. 36 TEXT ·bluepill(SB),NOSPLIT,$0 37 begin: 38 MOVQ vcpu+0(FP), AX 39 LEAQ VCPU_CPU(AX), BX 40 BYTE CLI; 41 check_vcpu: 42 MOVQ ENTRY_CPU_SELF(GS), CX 43 CMPQ BX, CX 44 JE right_vCPU 45 wrong_vcpu: 46 CALL ·redpill(SB) 47 JMP begin 48 right_vCPU: 49 RET 50 51 // sighandler: see bluepill.go for documentation. 52 // 53 // The arguments are the following: 54 // 55 // DI - The signal number. 56 // SI - Pointer to siginfo_t structure. 57 // DX - Pointer to ucontext structure. 58 // 59 TEXT ·sighandler(SB),NOSPLIT,$0 60 // Check if the signal is from the kernel. 61 MOVQ $0x80, CX 62 CMPL CX, 0x8(SI) 63 JNE fallback 64 65 // Check if RIP is disable interrupts. 66 MOVQ CONTEXT_RIP(DX), CX 67 CMPQ CX, $0x0 68 JE fallback 69 CMPB 0(CX), CLI 70 JNE fallback 71 72 // Call the bluepillHandler. 73 PUSHQ DX // First argument (context). 74 CALL ·bluepillHandler(SB) // Call the handler. 75 POPQ DX // Discard the argument. 76 RET 77 78 fallback: 79 // Jump to the previous signal handler. 80 XORQ CX, CX 81 MOVQ ·savedHandler(SB), AX 82 JMP AX 83 84 // func addrOfSighandler() uintptr 85 TEXT ·addrOfSighandler(SB), $0-8 86 MOVQ $·sighandler(SB), AX 87 MOVQ AX, ret+0(FP) 88 RET 89 90 // dieTrampoline: see bluepill.go, bluepill_amd64_unsafe.go for documentation. 91 TEXT ·dieTrampoline(SB),NOSPLIT,$0 92 PUSHQ BX // First argument (vCPU). 93 PUSHQ AX // Fake the old RIP as caller. 94 JMP ·dieHandler(SB) 95 96 // func addrOfDieTrampoline() uintptr 97 TEXT ·addrOfDieTrampoline(SB), $0-8 98 MOVQ $·dieTrampoline(SB), AX 99 MOVQ AX, ret+0(FP) 100 RET