diff options
50 files changed, 1174 insertions, 938 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index dc674c2b8b31..f038f8cafa70 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt | |||
| @@ -4120,3 +4120,44 @@ This capability indicates that guest using memory monotoring instructions | |||
| 4120 | (MWAIT/MWAITX) to stop the virtual CPU will not cause a VM exit. As such time | 4120 | (MWAIT/MWAITX) to stop the virtual CPU will not cause a VM exit. As such time |
| 4121 | spent while virtual CPU is halted in this way will then be accounted for as | 4121 | spent while virtual CPU is halted in this way will then be accounted for as |
| 4122 | guest running time on the host (as opposed to e.g. HLT). | 4122 | guest running time on the host (as opposed to e.g. HLT). |
| 4123 | |||
| 4124 | 8.9 KVM_CAP_ARM_USER_IRQ | ||
| 4125 | |||
| 4126 | Architectures: arm, arm64 | ||
| 4127 | This capability, if KVM_CHECK_EXTENSION indicates that it is available, means | ||
| 4128 | that if userspace creates a VM without an in-kernel interrupt controller, it | ||
| 4129 | will be notified of changes to the output level of in-kernel emulated devices, | ||
| 4130 | which can generate virtual interrupts, presented to the VM. | ||
| 4131 | For such VMs, on every return to userspace, the kernel | ||
| 4132 | updates the vcpu's run->s.regs.device_irq_level field to represent the actual | ||
| 4133 | output level of the device. | ||
| 4134 | |||
| 4135 | Whenever kvm detects a change in the device output level, kvm guarantees at | ||
| 4136 | least one return to userspace before running the VM. This exit could either | ||
| 4137 | be a KVM_EXIT_INTR or any other exit event, like KVM_EXIT_MMIO. This way, | ||
| 4138 | userspace can always sample the device output level and re-compute the state of | ||
| 4139 | the userspace interrupt controller. Userspace should always check the state | ||
| 4140 | of run->s.regs.device_irq_level on every kvm exit. | ||
| 4141 | The value in run->s.regs.device_irq_level can represent both level and edge | ||
| 4142 | triggered interrupt signals, depending on the device. Edge triggered interrupt | ||
| 4143 | signals will exit to userspace with the bit in run->s.regs.device_irq_level | ||
| 4144 | set exactly once per edge signal. | ||
| 4145 | |||
| 4146 | The field run->s.regs.device_irq_level is available independent of | ||
| 4147 | run->kvm_valid_regs or run->kvm_dirty_regs bits. | ||
| 4148 | |||
| 4149 | If KVM_CAP_ARM_USER_IRQ is supported, the KVM_CHECK_EXTENSION ioctl returns a | ||
| 4150 | number larger than 0 indicating the version of this capability is implemented | ||
| 4151 | and thereby which bits in in run->s.regs.device_irq_level can signal values. | ||
| 4152 | |||
| 4153 | Currently the following bits are defined for the device_irq_level bitmap: | ||
| 4154 | |||
| 4155 | KVM_CAP_ARM_USER_IRQ >= 1: | ||
| 4156 | |||
| 4157 | KVM_ARM_DEV_EL1_VTIMER - EL1 virtual timer | ||
| 4158 | KVM_ARM_DEV_EL1_PTIMER - EL1 physical timer | ||
| 4159 | KVM_ARM_DEV_PMU - ARM PMU overflow interrupt signal | ||
| 4160 | |||
| 4161 | Future versions of kvm may implement additional events. These will get | ||
| 4162 | indicated by returning a higher number from KVM_CHECK_EXTENSION and will be | ||
| 4163 | listed above. | ||
diff --git a/Documentation/virtual/kvm/arm/hyp-abi.txt b/Documentation/virtual/kvm/arm/hyp-abi.txt new file mode 100644 index 000000000000..a20a0bee268d --- /dev/null +++ b/Documentation/virtual/kvm/arm/hyp-abi.txt | |||
| @@ -0,0 +1,53 @@ | |||
| 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. | ||
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 9150f9732785..7c711ba61417 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S | |||
| @@ -422,7 +422,17 @@ dtb_check_done: | |||
| 422 | cmp r0, #HYP_MODE | 422 | cmp r0, #HYP_MODE |
| 423 | bne 1f | 423 | bne 1f |
| 424 | 424 | ||
| 425 | bl __hyp_get_vectors | 425 | /* |
| 426 | * Compute the address of the hyp vectors after relocation. | ||
| 427 | * This requires some arithmetic since we cannot directly | ||
| 428 | * reference __hyp_stub_vectors in a PC-relative way. | ||
| 429 | * Call __hyp_set_vectors with the new address so that we | ||
| 430 | * can HVC again after the copy. | ||
| 431 | */ | ||
| 432 | 0: adr r0, 0b | ||
| 433 | movw r1, #:lower16:__hyp_stub_vectors - 0b | ||
| 434 | movt r1, #:upper16:__hyp_stub_vectors - 0b | ||
| 435 | add r0, r0, r1 | ||
| 426 | sub r0, r0, r5 | 436 | sub r0, r0, r5 |
| 427 | add r0, r0, r10 | 437 | add r0, r0, r10 |
| 428 | bl __hyp_set_vectors | 438 | bl __hyp_set_vectors |
diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h index 8ef05381984b..14d68a4d826f 100644 --- a/arch/arm/include/asm/kvm_asm.h +++ b/arch/arm/include/asm/kvm_asm.h | |||
| @@ -33,7 +33,7 @@ | |||
