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