ANDROID: KVM: arm64: Add documentation for range-based guest HVCs

A new flag (KVM_FUNC_HAS_RANGE) advertises the availability of ranges
for mmio-guard and memory sharing. It is recommended to use these new
HVCs whenever a region bigger than the granule size needs to be
processed. Document them.

Bug: 357781595
Bug: 243642516
Change-Id: I1dc9e9c3ce983f35566470260ca7266cf2c54cf3
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
diff --git a/Documentation/virt/kvm/arm/hypercalls.rst b/Documentation/virt/kvm/arm/hypercalls.rst
index 07c4b07..d4db1a2 100644
--- a/Documentation/virt/kvm/arm/hypercalls.rst
+++ b/Documentation/virt/kvm/arm/hypercalls.rst
@@ -65,6 +65,9 @@
 +---------------------+----------+----+---------------------------------------------+
 | Return Values:      | (int64)  | R0 | ``INVALID_PARAMETER (-3)`` on error, else   |
 |                     |          |    | memory protection granule in bytes          |
+|                     +----------+----+---------------------------------------------+
+|                     | (int64)  | R1 | ``KVM_FUNC_HAS_RANGE (1)`` if MEM_SHARE and |
+|                     |          |    | MEM_UNSHARE take a range argument.          |
 +---------------------+----------+----+---------------------------------------------+
 
 ``ARM_SMCCC_KVM_FUNC_MEM_SHARE``
@@ -72,7 +75,9 @@
 
 Share a region of memory with the KVM host, granting it read, write and execute
 permissions. The size of the region is equal to the memory protection granule
-advertised by ``ARM_SMCCC_KVM_FUNC_HYP_MEMINFO``.
+advertised by ``ARM_SMCCC_KVM_FUNC_HYP_MEMINFO`` times the number of granules
+set in R2. See the ``KVM_FUNC_HAS_RANGE`` paragraph for more details about this
+argument.
 
 +---------------------+-------------------------------------------------------------+
 | Presence:           | Optional; protected guests only.                            |
@@ -83,13 +88,15 @@
 +---------------------+----------+----+---------------------------------------------+
 | Arguments:          | (uint64) | R1 | Base IPA of memory region to share          |
 |                     +----------+----+---------------------------------------------+
-|                     | (uint64) | R2 | Reserved / Must be zero                     |
+|                     | (uint64) | R2 | Number of granules to share                 |
 |                     +----------+----+---------------------------------------------+
 |                     | (uint64) | R3 | Reserved / Must be zero                     |
 +---------------------+----------+----+---------------------------------------------+
 | Return Values:      | (int64)  | R0 | ``SUCCESS (0)``                             |
 |                     |          |    +---------------------------------------------+
 |                     |          |    | ``INVALID_PARAMETER (-3)``                  |
+|                     +----------+----+---------------------------------------------+
+|                     | (uint64) | R1 | Number of shared granules                   |
 +---------------------+----------+----+---------------------------------------------+
 
 ``ARM_SMCCC_KVM_FUNC_MEM_UNSHARE``
@@ -97,7 +104,9 @@
 
 Revoke access permission from the KVM host to a memory region previously shared
 with ``ARM_SMCCC_KVM_FUNC_MEM_SHARE``. The size of the region is equal to the
-memory protection granule advertised by ``ARM_SMCCC_KVM_FUNC_HYP_MEMINFO``.
+memory protection granule advertised by ``ARM_SMCCC_KVM_FUNC_HYP_MEMINFO`` times
+the number of granules set in R2. See the ``KVM_FUNC_HAS_RANGE`` paragraph for
+more details about this argument.
 
 +---------------------+-------------------------------------------------------------+
 | Presence:           | Optional; protected guests only.                            |
@@ -108,13 +117,15 @@
 +---------------------+----------+----+---------------------------------------------+
 | Arguments:          | (uint64) | R1 | Base IPA of memory region to unshare        |
 |                     +----------+----+---------------------------------------------+
-|                     | (uint64) | R2 | Reserved / Must be zero                     |
+|                     | (uint64) | R2 | Number of granules to unshare               |
 |                     +----------+----+---------------------------------------------+
 |                     | (uint64) | R3 | Reserved / Must be zero                     |
 +---------------------+----------+----+---------------------------------------------+
 | Return Values:      | (int64)  | R0 | ``SUCCESS (0)``                             |
 |                     |          |    +---------------------------------------------+
 |                     |          |    | ``INVALID_PARAMETER (-3)``                  |
+|                     +----------+----+---------------------------------------------+
+|                     | (uint64) | R1 | Number of unshared granules                 |
 +---------------------+----------+----+---------------------------------------------+
 
 ``ARM_SMCCC_KVM_FUNC_HYP_MEMINFO``
@@ -248,3 +259,30 @@
 -----------------------------------
 
 See mmio-guard.rst
+
+``KVM_FUNC_HAS_RANGE``
+----------------------
+
+This flag, when set in ARM_SMCCC_KVM_FUNC_HYP_MEMINFO, indicates the guest can
+pass a number of granules as an argument to:
+
+  * ARM_SMCCC_KVM_FUNC_MEM_SHARE
+  * ARM_SMCCC_KVM_FUNC_MEM_UNSHARE
+
+In order to support legacy guests, the kernel still accepts ``0`` as a value. In
+that case a single granule is shared/unshared.
+
+When set in ARM_SMCCC_KVM_FUNC_MMIO_GUARD_INFO, indicates the guest can call the
+HVCs:
+
+  * ARM_SMCCC_KVM_FUNC_MMIO_RGUARD_MAP
+  * ARM_SMCCC_KVM_FUNC_MMIO_RGUARD_UNMAP
+
+For all those HVCs, the hypervisor is free to stop the process at any time
+either because the range isn't physically contiguous or to limit the time spent
+at EL2. In a such case, the number of actually shared granules is returned (R1)
+and the caller can start again where it stopped, that is, the base IPA + (Number
+of processed granules * protection granule size).
+
+If the number of processed granules returned is zero (R1), an error (R0) will be
+set.
diff --git a/Documentation/virt/kvm/arm/mmio-guard.rst b/Documentation/virt/kvm/arm/mmio-guard.rst
index c1ba749..7c5e8cc 100644
--- a/Documentation/virt/kvm/arm/mmio-guard.rst
+++ b/Documentation/virt/kvm/arm/mmio-guard.rst
@@ -27,6 +27,12 @@
 This relies on a set of hypercalls defined in the KVM-specific range,
 using the HVC64 calling convention.
 
+When operating on a range of contiguous IPA space, it is recommended
+to use ARM_SMCCC_KVM_FUNC_MMIO_RGUARD_MAP and
+ARM_SMCCC_KVM_FUNC_MMIO_RGUARD_UNMAP. Those HVCs take a number of
+granules as an argument. See ``KVM_FUNC_HAS_RANGE`` in hypercalls.rst
+for a complete description.
+
 * ARM_SMCCC_KVM_FUNC_MMIO_GUARD_INFO
 
     ==============    ========    ================================
@@ -34,7 +40,9 @@
     Arguments:        r1-r3       Reserved / Must be zero
     Return Values:    (int64)     NOT_SUPPORTED(-1) on error, or
                       (uint64)    Protection Granule (PG) size in
-                                  bytes (r0)
+                                  bytes (r0). KVM_FUNC_HAS_RANGE(1)
+                                  is set (r1) if RGUARD_MAP and
+                                  RGUARD_UNMAP HVCs are available.
     ==============    ========    ================================
 
 * ARM_SMCCC_KVM_FUNC_MMIO_GUARD_ENROLL
@@ -72,3 +80,35 @@
     Return Values:    (int64)     NOT_SUPPORTED(-1) on error, or
                                   RET_SUCCESS(0) (r0)
     ==============    ========    ======================================
+
+* ARM_SMCCC_KVM_FUNC_MMIO_RGUARD_MAP
+
+    ==============    ========    ====================================
+    Function ID:      (uint32)    0xC600000A
+    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)    Number of granules to guard (r2). See
+                                  ``KVM_FUNC_HAS_RANGE`` in
+                                  hypercalls.rst for more details
+    Return Values:    (int64)     NOT_SUPPORTED(-1) on error, or
+                                  RET_SUCCESS(0) (r0)
+                      (uint64)     Number of shared granules (r1)
+    ==============    ========    ====================================
+
+* ARM_SMCCC_KVM_FUNC_MMIO_RGUARD_UNMAP
+
+    ==============    ========    ======================================
+    Function ID:      (uint32)    0xC600000B
+    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)
+                      (uint64)    Number of granules to unguard (r2). See
+                                  ``KVM_FUNC_HAS_RANGE`` in
+                                  hypercalls.rst for more details
+    Return Values:    (int64)     NOT_SUPPORTED(-1) on error, or
+                                  RET_SUCCESS(0) (r0)
+                      (uint64)     Number of shared granules (r1)
+    ==============    ========    ======================================