KVM: arm64: Add documentation for protected KVM (pKVM) features Signed-off-by: Will Deacon <will@kernel.org>
diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index aeeb071..8a71e1f 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst
@@ -6925,6 +6925,66 @@ This is intended to support intra-host migration of VMs between userspace VMMs, upgrading the VMM process without interrupting the guest. +7.30 KVM_CAP_ARM_PROTECTED_VM +----------------------------- + +:Architectures: arm64 +:Target: VM +:Parameters: flags is a single KVM_CAP_ARM_PROTECTED_VM_FLAGS_* value + +This capability is only present for virtual machines created using the +KVM_VM_TYPE_ARM_PROTECTED machine type identifier. See +Documentation/virt/kvm/arm/pkvm.rst for more information. + +The 'flags' parameter is defined as follows: + +7.30.1 KVM_CAP_ARM_PROTECTED_VM_FLAGS_SET_FW_IPA +------------------------------------------------ + +:Capability: 'flag' parameter to KVM_CAP_ARM_PROTECTED_VM +:Architectures: arm64 +:Target: VM +:Parameters: args[0] specifies the IPA base at which to load the guest firmware +:Returns: 0 on success; negative error code on failure + +This capability sets the base address of a contiguous region of guest physical +memory specified by the IPA passed in arg[0] at which the guest firmware image +provided by the host firmware is to be loaded when the guest is run. + +The first vCPU to enter the guest is defined to be the primary vCPU. All other +vCPUs belonging to the VM are secondary vCPUs. + +The general purpose registers of the primary vCPU belonging to a VM with this +capability enabled are initialised as follows: + + =========== =========== + Register(s) Reset value + =========== =========== + X0-X14: Preserved (see KVM_SET_ONE_REG) + X15: Boot protocol version (0) + X16-X30: Reserved (0) + PC: IPA base of firmware image (args[0]) + =========== =========== + +Secondary vCPUs belonging to a VM with this capability enabled will return +-EPERM in response to a KVM_RUN ioctl() if the vCPU was not initialised with +the KVM_ARM_VCPU_POWER_OFF feature. + +It is an error to enable this capability on a VM after issuing a KVM_RUN +ioctl() on one of its vCPUs. + +7.30.2 KVM_CAP_ARM_PROTECTED_VM_FLAGS_INFO +------------------------------------------ + +:Capability: 'flag' parameter to KVM_CAP_ARM_PROTECTED_VM +:Architectures: arm64 +:Target: VM +:Parameters: args[0] contains a pointer to a 'struct kvm_protected_vm_info' +:Returns: 0 on success; negative error code on failure + +Populates the 'struct kvm_protected_vm_info' pointed to by args[0] with +information about the protected environment for the VM. + 8. Other capabilities. ======================
diff --git a/Documentation/virt/kvm/arm/index.rst b/Documentation/virt/kvm/arm/index.rst index 78a9b67..8554614 100644 --- a/Documentation/virt/kvm/arm/index.rst +++ b/Documentation/virt/kvm/arm/index.rst
@@ -8,6 +8,7 @@ :maxdepth: 2 hyp-abi + pkvm psci pvtime ptp_kvm
diff --git a/Documentation/virt/kvm/arm/pkvm.rst b/Documentation/virt/kvm/arm/pkvm.rst new file mode 100644 index 0000000..2c4f5c2 --- /dev/null +++ b/Documentation/virt/kvm/arm/pkvm.rst
@@ -0,0 +1,141 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Protected virtual machines +========================== + +* What is it +* VM creation + * Machine type + * Non-protected VMs +* Configuration + * Fixed vCPU configuration (reset state and caps) + * GIC and timers + * Booting (PC/X0; pvmfw) +* Memory + * Pinning + * Bad access to guest memory + * Page clearing +* Hypercalls + * Memory sharing + * MMIO guard + * TRNG + * PSCI + + + +* ARM_SMCCC_KVM_FUNC_HYP_MEMINFO + + ============== ======== ================================== + Function ID: (uint32) 0xC6000002 + Arguments: (uint64) Must be zero (r1). + (uint64) Must be zero (r2). + (uint64) Must be zero (r3). + Return Values: (int64) INVALID_PARAMETER(-3) on error, or + (uint64) Protection Granule (PG) size in + bytes (r0) + ============== ======== ================================== + +* ARM_SMCCC_KVM_FUNC_MEM_SHARE + + ============== ======== =================================== + Function ID: (uint32) 0xC6000003 + Arguments: (uint64) The base of the PG-sized IPA range + to be shared with the KVM host. + Must be aligned to the PG size (r1) + (uint64) Must be zero (r2). + (uint64) Must be zero (r3). + Return Values: (int64) INVALID_PARAMETER(-3) on error, or + RET_SUCCESS(0) (r0) + ============== ======== =================================== + +* ARM_SMCCC_KVM_FUNC_MEM_UNSHARE + + ============== ======== =================================== + Function ID: (uint32) 0xC6000003 + Arguments: (uint64) The base of the previously shared + PG-sized IPA range to be unshared + with the KVM host. + Must be aligned to the PG size (r1) + (uint64) Must be zero (r2). + (uint64) Must be zero (r3). + Return Values: (int64) INVALID_PARAMETER(-3) on error, or + RET_SUCCESS(0) (r0) + ============== ======== ================================== + + + + +TODO: update numbers. Remove MMIO_GUARD_INFO? + +============== +KVM MMIO guard +============== + +KVM implements device emulation by handling translation faults to any +IPA range that is not contained in a memory slot. Such a translation +fault is in most cases passed on to userspace (or in rare cases to the +host kernel) with the address, size and possibly data of the access +for emulation. + +Should the guest exit with an address that is not one that corresponds +to an emulatable device, userspace may take measures that are not the +most graceful as far as the guest is concerned (such as terminating it +or delivering a fatal exception). + +There is also an element of trust: by forwarding the request to +userspace, the kernel assumes that the guest trusts userspace to do +the right thing. + +The KVM MMIO guard offers a way to mitigate this last point: a guest +can request that only certain regions of the IPA space are valid as +MMIO. Only these regions will be handled as an MMIO, and any other +will result in an exception being delivered to the guest. + +This relies on a set of hypercalls defined in the KVM-specific range, +using the HVC64 calling convention. + +* ARM_SMCCC_KVM_FUNC_MMIO_GUARD_INFO + + ============== ======== ================================ + Function ID: (uint32) 0xC6000002 + Arguments: none + Return Values: (int64) NOT_SUPPORTED(-1) on error, or + (uint64) Protection Granule (PG) size in + bytes (r0) + ============== ======== ================================ + +* ARM_SMCCC_KVM_FUNC_MMIO_GUARD_ENROLL + + ============== ======== ============================== + Function ID: (uint32) 0xC6000003 + Arguments: none + Return Values: (int64) NOT_SUPPORTED(-1) on error, or + RET_SUCCESS(0) (r0) + ============== ======== ============================== + +* ARM_SMCCC_KVM_FUNC_MMIO_GUARD_MAP + + ============== ======== ==================================== + Function ID: (uint32) 0xC6000004 + Arguments: (uint64) The base of the PG-sized IPA range + that is allowed to be accessed as + MMIO. Must be aligned to the PG size + (r1) + (uint64) Index in the MAIR_EL1 register + providing the memory attribute that + is used by the guest (r2) + Return Values: (int64) NOT_SUPPORTED(-1) on error, or + RET_SUCCESS(0) (r0) + ============== ======== ==================================== + +* ARM_SMCCC_KVM_FUNC_MMIO_GUARD_UNMAP + + ============== ======== ====================================== + Function ID: (uint32) 0xC6000005 + Arguments: (uint64) PG-sized IPA range aligned to the PG + size which has been previously mapped. + Must be aligned to the PG size and + have been previously mapped (r1) + Return Values: (int64) NOT_SUPPORTED(-1) on error, or + RET_SUCCESS(0) (r0) + ============== ======== ======================================
diff --git a/Documentation/virt/kvm/hypercalls.rst b/Documentation/virt/kvm/hypercalls.rst index e56fa8b..43496f5 100644 --- a/Documentation/virt/kvm/hypercalls.rst +++ b/Documentation/virt/kvm/hypercalls.rst
@@ -37,6 +37,12 @@ number in $2 (v0). Up to four arguments may be placed in $4-$7 (a0-a3) and the return value is placed in $2 (v0). +Arm64: + KVM hypercalls use the HVC instruction according to version 1.1 of the Arm + SMC Calling Convention and place KVM-specific hypercalls into the "vendor + specific" service range using a UID of 28b46fb6-2ec5-11e9-a9ca-4b564d003a74. + See Documentation/virt/kvm/arm/ for information about specific hypercalls. + KVM Hypercalls Documentation ============================