|
33 | 33 | #define ENTRY_STACK_TOP 264 // +checkoffset . kernelEntry.stackTop |
34 | 34 | #define ENTRY_CPU_SELF 272 // +checkoffset . kernelEntry.cpuSelf |
35 | 35 | #define ENTRY_KERNEL_CR3 280 // +checkoffset . kernelEntry.kernelCR3 |
| 36 | +#define ENTRY_ENABLE_VMCALL 288 // +checkoffset . kernelEntry.enableVMCALL |
36 | 37 |
|
37 | 38 | // Bits. |
38 | 39 | #define _RFLAGS_IF 512 // +checkconst . _RFLAGS_IF |
|
61 | 62 | #define SIMDFloatingPointException 19 // +checkconst . SIMDFloatingPointException |
62 | 63 | #define VirtualizationException 20 // +checkconst . VirtualizationException |
63 | 64 | #define SecurityException 30 // +checkconst . SecurityException |
| 65 | +#define OOMException 32 // +checkconst . OOMException |
64 | 66 | #define SyscallInt80 128 // +checkconst . SyscallInt80 |
65 | 67 | #define Syscall 256 // +checkconst . Syscall |
66 | 68 |
|
| 69 | +#define SyscallExit 60 // +checkconst . SyscallExit |
| 70 | +#define SyscallExitGroup 231 // +checkconst . SyscallExitGroup |
| 71 | +#define SyscallRedPill 4294967295 // +checkconst . SyscallRedPill |
| 72 | + |
| 73 | +#define CPUIntel 0 // +checkconst . CPUIntel |
| 74 | + |
67 | 75 | #define PTRACE_R15 0 // +checkoffset linux PtraceRegs.R15 |
68 | 76 | #define PTRACE_R14 8 // +checkoffset linux PtraceRegs.R14 |
69 | 77 | #define PTRACE_R13 16 // +checkoffset linux PtraceRegs.R13 |
|
160 | 168 | #define LOAD_KERNEL_STACK(entry) \ |
161 | 169 | MOVQ ENTRY_STACK_TOP(entry), SP; |
162 | 170 |
|
| 171 | +// VMCALL do vmcall/vmmcal instruction |
| 172 | +#define VMCALL() \ |
| 173 | + CMPQ ·CPUVendor(SB), $CPUIntel; \ |
| 174 | + JE 2(PC); \ |
| 175 | + JMP 5(PC); \ // vmmcall and vmcall will be treated as 3 independent instructions |
| 176 | + BYTE $0x0F; BYTE $0x01; BYTE $0xC1; \ |
| 177 | + JMP 4(PC); \ // vmmcall and vmcall will be treated as 3 independent instructions |
| 178 | + BYTE $0x0F; BYTE $0x01; BYTE $0xD9; |
| 179 | + |
163 | 180 | // ADDR_OF_FUNC defines a function named 'name' that returns the address of |
164 | 181 | // 'symbol'. |
165 | 182 | #define ADDR_OF_FUNC(name, symbol) \ |
@@ -488,6 +505,45 @@ sysenter_skip_gs: |
488 | 505 | RET |
489 | 506 |
|
490 | 507 | kernel: |
| 508 | + // Handle any syscalls from GR0 in HR3 when EnableVMCALL is false. |
| 509 | + // Currently there are 2 use cases: |
| 510 | + // 1. Using KVM platform. |
| 511 | + // 2. Upgrading SlimVM platform. This is one such method to return M to |
| 512 | + // user mode (HR3) for upgrading platform. |
| 513 | + CMPQ ENTRY_ENABLE_VMCALL(GS), $0 |
| 514 | + JE hr3_do_syscall |
| 515 | + |
| 516 | + CMPQ AX, $SyscallRedPill |
| 517 | + JE hr3_do_syscall |
| 518 | + |
| 519 | + CMPQ AX, $SyscallExit |
| 520 | + JE hr3_do_syscall |
| 521 | + |
| 522 | + CMPQ AX, $SyscallExitGroup |
| 523 | + JE hr3_do_syscall |
| 524 | + |
| 525 | +vmcall: |
| 526 | + // handle syscall from GR0 in host kernel |
| 527 | + // copy from "handle system calls from G0" part of __dune_syscall in libdune/dune.S |
| 528 | + PUSHQ R11 |
| 529 | + POPFQ |
| 530 | + |
| 531 | + CMPQ AX, $158 // arch_prctl syscall |
| 532 | + JNE 3(PC) |
| 533 | + CMPQ DI, $0x1002 //ARCH_SET_FS |
| 534 | + JE arch_prctl_vmcall |
| 535 | + |
| 536 | + VMCALL() |
| 537 | + JMP *CX |
| 538 | + |
| 539 | +arch_prctl_vmcall: |
| 540 | + VMCALL() |
| 541 | + CMPQ AX, $0 |
| 542 | + JNE 2(PC) |
| 543 | + MOVQ SI, CPU_REGISTERS+PTRACE_FS_BASE(GS) |
| 544 | + JMP *CX |
| 545 | + |
| 546 | +hr3_do_syscall: |
491 | 547 | // We can't restore the original stack, but we can access the registers |
492 | 548 | // in the CPU state directly. No need for temporary juggling. |
493 | 549 | MOVQ AX, ENTRY_SCRATCH0(GS) |
@@ -705,4 +761,5 @@ EXCEPTION_WITHOUT_ERROR(MachineCheck, ·machineCheck(SB), ·addrOfMachineCheck(S |
705 | 761 | EXCEPTION_WITHOUT_ERROR(SIMDFloatingPointException, ·simdFloatingPointException(SB), ·addrOfSimdFloatingPointException(SB)) |
706 | 762 | EXCEPTION_WITHOUT_ERROR(VirtualizationException, ·virtualizationException(SB), ·addrOfVirtualizationException(SB)) |
707 | 763 | EXCEPTION_WITH_ERROR(SecurityException, ·securityException(SB), ·addrOfSecurityException(SB)) |
| 764 | +EXCEPTION_WITH_ERROR(OOMException, ·oomException(SB), ·addrOfOOMException(SB)) |
708 | 765 | EXCEPTION_WITHOUT_ERROR(SyscallInt80, ·syscallInt80(SB), ·addrOfSyscallInt80(SB)) |
0 commit comments