xref: /OK3568_Linux_fs/kernel/Documentation/virt/kvm/arm/hyp-abi.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun.. SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun
3*4882a593Smuzhiyun=======================================
4*4882a593SmuzhiyunInternal ABI between the kernel and HYP
5*4882a593Smuzhiyun=======================================
6*4882a593Smuzhiyun
7*4882a593SmuzhiyunThis file documents the interaction between the Linux kernel and the
8*4882a593Smuzhiyunhypervisor layer when running Linux as a hypervisor (for example
9*4882a593SmuzhiyunKVM). It doesn't cover the interaction of the kernel with the
10*4882a593Smuzhiyunhypervisor when running as a guest (under Xen, KVM or any other
11*4882a593Smuzhiyunhypervisor), or any hypervisor-specific interaction when the kernel is
12*4882a593Smuzhiyunused as a host.
13*4882a593Smuzhiyun
14*4882a593SmuzhiyunNote: KVM/arm has been removed from the kernel. The API described
15*4882a593Smuzhiyunhere is still valid though, as it allows the kernel to kexec when
16*4882a593Smuzhiyunbooted at HYP. It can also be used by a hypervisor other than KVM
17*4882a593Smuzhiyunif necessary.
18*4882a593Smuzhiyun
19*4882a593SmuzhiyunOn arm and arm64 (without VHE), the kernel doesn't run in hypervisor
20*4882a593Smuzhiyunmode, but still needs to interact with it, allowing a built-in
21*4882a593Smuzhiyunhypervisor to be either installed or torn down.
22*4882a593Smuzhiyun
23*4882a593SmuzhiyunIn order to achieve this, the kernel must be booted at HYP (arm) or
24*4882a593SmuzhiyunEL2 (arm64), allowing it to install a set of stubs before dropping to
25*4882a593SmuzhiyunSVC/EL1. These stubs are accessible by using a 'hvc #0' instruction,
26*4882a593Smuzhiyunand only act on individual CPUs.
27*4882a593Smuzhiyun
28*4882a593SmuzhiyunUnless specified otherwise, any built-in hypervisor must implement
29*4882a593Smuzhiyunthese functions (see arch/arm{,64}/include/asm/virt.h):
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun* ::
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun    r0/x0 = HVC_SET_VECTORS
34*4882a593Smuzhiyun    r1/x1 = vectors
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun  Set HVBAR/VBAR_EL2 to 'vectors' to enable a hypervisor. 'vectors'
37*4882a593Smuzhiyun  must be a physical address, and respect the alignment requirements
38*4882a593Smuzhiyun  of the architecture. Only implemented by the initial stubs, not by
39*4882a593Smuzhiyun  Linux hypervisors.
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun* ::
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun    r0/x0 = HVC_RESET_VECTORS
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun  Turn HYP/EL2 MMU off, and reset HVBAR/VBAR_EL2 to the initials
46*4882a593Smuzhiyun  stubs' exception vector value. This effectively disables an existing
47*4882a593Smuzhiyun  hypervisor.
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun* ::
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun    r0/x0 = HVC_SOFT_RESTART
52*4882a593Smuzhiyun    r1/x1 = restart address
53*4882a593Smuzhiyun    x2 = x0's value when entering the next payload (arm64)
54*4882a593Smuzhiyun    x3 = x1's value when entering the next payload (arm64)
55*4882a593Smuzhiyun    x4 = x2's value when entering the next payload (arm64)
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun  Mask all exceptions, disable the MMU, clear I+D bits, move the arguments
58*4882a593Smuzhiyun  into place (arm64 only), and jump to the restart address while at HYP/EL2.
59*4882a593Smuzhiyun  This hypercall is not expected to return to its caller.
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun* ::
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun    x0 = HVC_VHE_RESTART (arm64 only)
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun  Attempt to upgrade the kernel's exception level from EL1 to EL2 by enabling
66*4882a593Smuzhiyun  the VHE mode. This is conditioned by the CPU supporting VHE, the EL2 MMU
67*4882a593Smuzhiyun  being off, and VHE not being disabled by any other means (command line
68*4882a593Smuzhiyun  option, for example).
69*4882a593Smuzhiyun
70*4882a593SmuzhiyunAny other value of r0/x0 triggers a hypervisor-specific handling,
71*4882a593Smuzhiyunwhich is not documented here.
72*4882a593Smuzhiyun
73*4882a593SmuzhiyunThe return value of a stub hypercall is held by r0/x0, and is 0 on
74*4882a593Smuzhiyunsuccess, and HVC_STUB_ERR on error. A stub hypercall is allowed to
75*4882a593Smuzhiyunclobber any of the caller-saved registers (x0-x18 on arm64, r0-r3 and
76*4882a593Smuzhiyunip on arm). It is thus recommended to use a function call to perform
77*4882a593Smuzhiyunthe hypercall.
78