github.com/nicocha30/gvisor-ligolo@v0.0.0-20230726075806-989fa2c0a413/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 // ENTRY_CPU_SELF is the location of the CPU in the entry struct. 23 // 24 // This is sourced from ring0. 25 #define ENTRY_CPU_SELF 272 // +checkoffset ring0 kernelEntry.cpuSelf 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. However, the RIP must be examined. 31 #define CONTEXT_RAX 0x90 32 #define CONTEXT_RIP 0xa8 33 #define CONTEXT_FP 0xe0 34 35 // CLI is the literal byte for the disable interrupts instruction. 36 // 37 // This is checked as the source of the fault. 38 #define CLI $0xfa 39 40 // System call definitions. 41 #define SYS_MMAP 9 42 43 // See bluepill.go. 44 TEXT ·bluepill(SB),NOSPLIT|NOFRAME,$0 45 begin: 46 MOVQ arg+0(FP), AX 47 LEAQ VCPU_CPU(AX), BX 48 49 // The gorountine stack will be changed in guest which renders 50 // the frame pointer outdated and misleads perf tools. 51 // Disconnect the frame-chain with the zeroed frame pointer 52 // when it is saved in the frame in bluepillHandler(). 53 MOVQ BP, CX 54 MOVQ $0, BP 55 BYTE CLI; 56 MOVQ CX, BP 57 check_vcpu: 58 MOVQ ENTRY_CPU_SELF(GS), CX 59 CMPQ BX, CX 60 JE right_vCPU 61 wrong_vcpu: 62 CALL ·redpill(SB) 63 JMP begin 64 right_vCPU: 65 RET 66 67 // sighandler: see bluepill.go for documentation. 68 // 69 // The arguments are the following: 70 // 71 // DI - The signal number. 72 // SI - Pointer to siginfo_t structure. 73 // DX - Pointer to ucontext structure. 74 // 75 TEXT ·sighandler(SB),NOSPLIT|NOFRAME,$0 76 // Check if the signal is from the kernel. 77 MOVQ $0x80, CX 78 CMPL CX, 0x8(SI) 79 JNE fallback 80 81 // Check if RIP is disable interrupts. 82 MOVQ CONTEXT_RIP(DX), CX 83 CMPQ CX, $0x0 84 JE fallback 85 CMPB 0(CX), CLI 86 JNE fallback 87 88 // Call the bluepillHandler. 89 PUSHQ DX // First argument (context). 90 CALL ·bluepillHandler(SB) // Call the handler. 91 POPQ DX // Discard the argument. 92 RET 93 94 fallback: 95 // Jump to the previous signal handler. 96 XORQ CX, CX 97 MOVQ ·savedHandler(SB), AX 98 JMP AX 99 100 // func addrOfSighandler() uintptr 101 TEXT ·addrOfSighandler(SB), $0-8 102 MOVQ $·sighandler(SB), AX 103 MOVQ AX, ret+0(FP) 104 RET 105 106 TEXT ·sigsysHandler(SB),NOSPLIT|NOFRAME,$0 107 // Check if the signal is from the kernel. 108 MOVQ $1, CX 109 CMPL CX, 0x8(SI) 110 JNE fallback 111 112 MOVL CONTEXT_RAX(DX), CX 113 CMPL CX, $SYS_MMAP 114 JNE fallback 115 PUSHQ DX // First argument (context). 116 CALL ·seccompMmapHandler(SB) // Call the handler. 117 POPQ DX // Discard the argument. 118 RET 119 fallback: 120 // Jump to the previous signal handler. 121 XORQ CX, CX 122 MOVQ ·savedSigsysHandler(SB), AX 123 JMP AX 124 125 // func addrOfSighandler() uintptr 126 TEXT ·addrOfSigsysHandler(SB), $0-8 127 MOVQ $·sigsysHandler(SB), AX 128 MOVQ AX, ret+0(FP) 129 RET 130 131 // dieTrampoline: see bluepill.go, bluepill_amd64_unsafe.go for documentation. 132 TEXT ·dieTrampoline(SB),NOSPLIT|NOFRAME,$0 133 PUSHQ BX // First argument (vCPU). 134 PUSHQ AX // Fake the old RIP as caller. 135 JMP ·dieHandler(SB) 136 137 // func addrOfDieTrampoline() uintptr 138 TEXT ·addrOfDieTrampoline(SB), $0-8 139 MOVQ $·dieTrampoline(SB), AX 140 MOVQ AX, ret+0(FP) 141 RET