Marc Zyngier | d824ca5 | 2017-04-03 19:38:07 +0100 | [diff] [blame] | 1 | * Internal ABI between the kernel and HYP |
| 2 | |
| 3 | This file documents the interaction between the Linux kernel and the |
| 4 | hypervisor layer when running Linux as a hypervisor (for example |
| 5 | KVM). It doesn't cover the interaction of the kernel with the |
| 6 | hypervisor when running as a guest (under Xen, KVM or any other |
| 7 | hypervisor), or any hypervisor-specific interaction when the kernel is |
| 8 | used as a host. |
| 9 | |
| 10 | On arm and arm64 (without VHE), the kernel doesn't run in hypervisor |
| 11 | mode, but still needs to interact with it, allowing a built-in |
| 12 | hypervisor to be either installed or torn down. |
| 13 | |
| 14 | In order to achieve this, the kernel must be booted at HYP (arm) or |
| 15 | EL2 (arm64), allowing it to install a set of stubs before dropping to |
| 16 | SVC/EL1. These stubs are accessible by using a 'hvc #0' instruction, |
| 17 | and only act on individual CPUs. |
| 18 | |
| 19 | Unless specified otherwise, any built-in hypervisor must implement |
| 20 | these functions (see arch/arm{,64}/include/asm/virt.h): |
| 21 | |
| 22 | * r0/x0 = HVC_SET_VECTORS |
| 23 | r1/x1 = vectors |
| 24 | |
| 25 | Set HVBAR/VBAR_EL2 to 'vectors' to enable a hypervisor. 'vectors' |
| 26 | must be a physical address, and respect the alignment requirements |
| 27 | of the architecture. Only implemented by the initial stubs, not by |
| 28 | Linux hypervisors. |
| 29 | |
| 30 | * r0/x0 = HVC_RESET_VECTORS |
| 31 | |
| 32 | Turn HYP/EL2 MMU off, and reset HVBAR/VBAR_EL2 to the initials |
| 33 | stubs' exception vector value. This effectively disables an existing |
| 34 | hypervisor. |
| 35 | |
| 36 | * r0/x0 = HVC_SOFT_RESTART |
| 37 | r1/x1 = restart address |
| 38 | x2 = x0's value when entering the next payload (arm64) |
| 39 | x3 = x1's value when entering the next payload (arm64) |
| 40 | x4 = x2's value when entering the next payload (arm64) |
| 41 | |
| 42 | Mask all exceptions, disable the MMU, move the arguments into place |
| 43 | (arm64 only), and jump to the restart address while at HYP/EL2. This |
| 44 | hypercall is not expected to return to its caller. |
| 45 | |
| 46 | Any other value of r0/x0 triggers a hypervisor-specific handling, |
| 47 | which is not documented here. |
| 48 | |
| 49 | The return value of a stub hypercall is held by r0/x0, and is 0 on |
| 50 | success, and HVC_STUB_ERR on error. A stub hypercall is allowed to |
| 51 | clobber any of the caller-saved registers (x0-x18 on arm64, r0-r3 and |
| 52 | ip on arm). It is thus recommended to use a function call to perform |
| 53 | the hypercall. |