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
============================