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